summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnne Jan Brouwer <brouwer@annejan.com>2023-08-31 12:46:54 +0200
committerGitHub <noreply@github.com>2023-08-31 12:46:54 +0200
commitd591acf19b5c999c6d1dceb7b3e45d13d565d701 (patch)
tree559da03f5ad2dab9b13c74da66304c178b84dbec
parentbd1f363d72c71324232e11b2029000fb3bd5876a (diff)
parent1da3f142b53e33af3862112270cdbf2430fa1453 (diff)
Merge branch 'main' into svuorela/clazy-and-other-minor-fixes
-rw-r--r--README.md1
-rw-r--r--src/configdialog.cpp33
-rw-r--r--src/configdialog.h4
-rw-r--r--src/configdialog.ui5
-rw-r--r--src/imitatepass.cpp131
-rw-r--r--src/imitatepass.h3
-rw-r--r--src/keygendialog.ui31
-rw-r--r--src/mainwindow.cpp7
-rw-r--r--src/pass.cpp64
-rw-r--r--src/pass.h1
-rw-r--r--src/qprogressindicator.cpp26
-rw-r--r--src/qprogressindicator.h27
-rw-r--r--src/qtpasssettings.cpp47
-rw-r--r--src/qtpasssettings.h9
-rw-r--r--src/settingsconstants.cpp1
-rw-r--r--src/settingsconstants.h1
16 files changed, 337 insertions, 54 deletions
diff --git a/README.md b/README.md
index 6ffd46c1..32c1afac 100644
--- a/README.md
+++ b/README.md
@@ -79,6 +79,7 @@ qmake && make && make install
## Using profiles
Profiles allow to group passwords. Each profile might use a different git repository and/or different gpg key.
+Each profile also can be associated with a pass store singing key to verify the detached .gpg-id signature.
A typical use case is to separate personal and work passwords.
> **Hint**<br>
diff --git a/src/configdialog.cpp b/src/configdialog.cpp
index 581465b6..4c9f227d 100644
--- a/src/configdialog.cpp
+++ b/src/configdialog.cpp
@@ -98,7 +98,8 @@ ConfigDialog::ConfigDialog(MainWindow *parent)
useTemplate(QtPassSettings::isUseTemplate());
ui->profileTable->verticalHeader()->hide();
- ui->profileTable->horizontalHeader()->setStretchLastSection(true);
+ ui->profileTable->horizontalHeader()->setSectionResizeMode(
+ 1, QHeaderView::Stretch);
ui->label->setText(ui->label->text() + VERSION);
ui->comboBoxClipboard->clear();
@@ -171,7 +172,7 @@ void ConfigDialog::validate(QTableWidgetItem *item) {
for (int j = 0; j < ui->profileTable->columnCount(); j++) {
QTableWidgetItem *_item = ui->profileTable->item(i, j);
- if (_item->text().isEmpty()) {
+ if (_item->text().isEmpty() && j != 2) {
_item->setBackground(Qt::red);
status = false;
break;
@@ -182,7 +183,7 @@ void ConfigDialog::validate(QTableWidgetItem *item) {
break;
}
} else {
- if (item->text().isEmpty()) {
+ if (item->text().isEmpty() && item->column() != 2) {
item->setBackground(Qt::red);
status = false;
}
@@ -461,8 +462,8 @@ void ConfigDialog::genKey(QString batch, QDialog *dialog) {
* @param profiles
* @param profile
*/
-void ConfigDialog::setProfiles(QHash<QString, QString> profiles,
- QString profile) {
+void ConfigDialog::setProfiles(QHash<QString, QHash<QString, QString>> profiles,
+ QString currentProfile) {
// dbg()<< profiles;
if (profiles.contains("")) {
profiles.remove("");
@@ -470,15 +471,18 @@ void ConfigDialog::setProfiles(QHash<QString, QString> profiles,
}
ui->profileTable->setRowCount(profiles.count());
- QHashIterator<QString, QString> i(profiles);
+ QHashIterator<QString, QHash<QString, QString>> i(profiles);
int n = 0;
while (i.hasNext()) {
i.next();
if (!i.value().isEmpty() && !i.key().isEmpty()) {
ui->profileTable->setItem(n, 0, new QTableWidgetItem(i.key()));
- ui->profileTable->setItem(n, 1, new QTableWidgetItem(i.value()));
+ ui->profileTable->setItem(n, 1,
+ new QTableWidgetItem(i.value().value("path")));
+ ui->profileTable->setItem(
+ n, 2, new QTableWidgetItem(i.value().value("signingKey")));
// dbg()<< "naam:" + i.key();
- if (i.key() == profile)
+ if (i.key() == currentProfile)
ui->profileTable->selectRow(n);
}
++n;
@@ -489,17 +493,23 @@ void ConfigDialog::setProfiles(QHash<QString, QString> profiles,
* @brief ConfigDialog::getProfiles return profile list.
* @return
*/
-QHash<QString, QString> ConfigDialog::getProfiles() {
- QHash<QString, QString> profiles;
+QHash<QString, QHash<QString, QString>> ConfigDialog::getProfiles() {
+ QHash<QString, QHash<QString, QString>> profiles;
// Check?
for (int i = 0; i < ui->profileTable->rowCount(); ++i) {
+ QHash<QString, QString> profile;
QTableWidgetItem *pathItem = ui->profileTable->item(i, 1);
if (nullptr != pathItem) {
QTableWidgetItem *item = ui->profileTable->item(i, 0);
if (item == nullptr) {
continue;
}
- profiles.insert(item->text(), pathItem->text());
+ profile["path"] = pathItem->text();
+ QTableWidgetItem *signingKeyItem = ui->profileTable->item(i, 2);
+ if (nullptr != signingKeyItem) {
+ profile["signingKey"] = signingKeyItem->text();
+ }
+ profiles.insert(item->text(), profile);
}
}
return profiles;
@@ -513,6 +523,7 @@ void ConfigDialog::on_addButton_clicked() {
ui->profileTable->insertRow(n);
ui->profileTable->setItem(n, 0, new QTableWidgetItem());
ui->profileTable->setItem(n, 1, new QTableWidgetItem(ui->storePath->text()));
+ ui->profileTable->setItem(n, 2, new QTableWidgetItem());
ui->profileTable->selectRow(n);
ui->deleteButton->setEnabled(true);
diff --git a/src/configdialog.h b/src/configdialog.h
index a0f162b0..4460d4bf 100644
--- a/src/configdialog.h
+++ b/src/configdialog.h
@@ -31,7 +31,7 @@ public:
void useSelection(bool useSelection);
void useAutoclear(bool useAutoclear);
void useAutoclearPanel(bool useAutoclearPanel);
- QHash<QString, QString> getProfiles();
+ QHash<QString, QHash<QString, QString>> getProfiles();
void wizard();
void genKey(QString, QDialog *);
void useTrayIcon(bool useSystray);
@@ -76,7 +76,7 @@ private:
QStringList getSecretKeys();
void setGitPath(QString);
- void setProfiles(QHash<QString, QString>, QString);
+ void setProfiles(QHash<QString, QHash<QString, QString>>, QString);
void usePass(bool usePass);
void setGroupBoxState();
diff --git a/src/configdialog.ui b/src/configdialog.ui
index 874bbb3f..68281ca7 100644
--- a/src/configdialog.ui
+++ b/src/configdialog.ui
@@ -913,6 +913,11 @@
<string>Path</string>
</property>
</column>
+ <column>
+ <property name="text">
+ <string>Signing Key</string>
+ </property>
+ </column>
</widget>
</item>
<item>
diff --git a/src/imitatepass.cpp b/src/imitatepass.cpp
index 8380e521..8300cb36 100644
--- a/src/imitatepass.cpp
+++ b/src/imitatepass.cpp
@@ -90,6 +90,12 @@ void ImitatePass::OtpGenerate(QString file) {
*/
void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
file = file + ".gpg";
+ QString gpgIdPath = Pass::getGpgIdPath(file);
+ if (!verifyGpgIdFile(gpgIdPath)) {
+ emit critical(tr("Check .gpgid file signature!"),
+ tr("Signature for %1 is invalid.").arg(gpgIdPath));
+ return;
+ }
transactionHelper trans(this, PASS_INSERT);
QStringList recipients = Pass::getRecipientList(file);
if (recipients.isEmpty()) {
@@ -163,6 +169,38 @@ void ImitatePass::Remove(QString file, bool isDir) {
* path
*/
void ImitatePass::Init(QString path, const QList<UserInfo> &users) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ QStringList signingKeys =
+ QtPassSettings::getPassSigningKey().split(" ", Qt::SkipEmptyParts);
+#else
+ QStringList signingKeys =
+ QtPassSettings::getPassSigningKey().split(" ", QString::SkipEmptyParts);
+#endif
+ QString gpgIdSigFile = path + ".gpg-id.sig";
+ bool addSigFile = false;
+ if (!signingKeys.isEmpty()) {
+ QString out;
+ QStringList args =
+ QStringList{"--status-fd=1", "--list-secret-keys"} + signingKeys;
+ exec.executeBlocking(QtPassSettings::getGpgExecutable(), args, &out);
+ bool found = false;
+ for (auto &key : signingKeys) {
+ if (out.contains("[GNUPG:] KEY_CONSIDERED " + key)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ emit critical(tr("No signing key!"),
+ tr("None of the secret signing keys is available.\n"
+ "You will not be able to change the user list!"));
+ return;
+ }
+ QFileInfo checkFile(gpgIdSigFile);
+ if (!checkFile.exists() || !checkFile.isFile())
+ addSigFile = true;
+ }
+
QString gpgIdFile = path + ".gpg-id";
QFile gpgId(gpgIdFile);
bool addFile = false;
@@ -193,6 +231,20 @@ void ImitatePass::Init(QString path, const QList<UserInfo> &users) {
return;
}
+ if (!signingKeys.isEmpty()) {
+ QStringList args;
+ for (auto &key : signingKeys) {
+ args.append(QStringList{"--default-key", key});
+ }
+ args.append(QStringList{"--yes", "--detach-sign", gpgIdFile});
+ exec.executeBlocking(QtPassSettings::getGpgExecutable(), args);
+ if (!verifyGpgIdFile(gpgIdFile)) {
+ emit critical(tr("Check .gpgid file signature!"),
+ tr("Signature for %1 is invalid.").arg(gpgIdFile));
+ return;
+ }
+ }
+
if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit() &&
!QtPassSettings::getGitExecutable().isEmpty()) {
if (addFile)
@@ -200,11 +252,79 @@ void ImitatePass::Init(QString path, const QList<UserInfo> &users) {
QString commitPath = gpgIdFile;
commitPath.replace(Util::endsWithGpg(), "");
GitCommit(gpgIdFile, "Added " + commitPath + " using QtPass.");
+ if (!signingKeys.isEmpty()) {
+ if (addSigFile)
+ executeGit(GIT_ADD, {"add", pgit(gpgIdSigFile)});
+ commitPath = gpgIdSigFile;
+ commitPath.replace(QRegularExpression("\\.gpg$"), "");
+ GitCommit(gpgIdSigFile, "Added " + commitPath + " using QtPass.");
+ }
}
reencryptPath(path);
}
/**
+ * @brief ImitatePass::verifyGpgIdFile verify detached gpgid file signature.
+ * @param file which gpgid file.
+ * @return was verification succesful?
+ */
+bool ImitatePass::verifyGpgIdFile(const QString &file) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ QStringList signingKeys =
+ QtPassSettings::getPassSigningKey().split(" ", Qt::SkipEmptyParts);
+#else
+ QStringList signingKeys =
+ QtPassSettings::getPassSigningKey().split(" ", QString::SkipEmptyParts);
+#endif
+ if (signingKeys.isEmpty())
+ return true;
+ QString out;
+ QStringList args =
+ QStringList{"--verify", "--status-fd=1", pgpg(file) + ".sig", pgpg(file)};
+ exec.executeBlocking(QtPassSettings::getGpgExecutable(), args, &out);
+ QRegularExpression re(
+ "^\\[GNUPG:\\] VALIDSIG ([A-F0-9]{40}) .* ([A-F0-9]{40})\\r?$",
+ QRegularExpression::MultilineOption);
+ QRegularExpressionMatch m = re.match(out);
+ if (!m.hasMatch())
+ return false;
+ QStringList fingerprints = m.capturedTexts();
+ fingerprints.removeFirst();
+ for (auto &key : signingKeys) {
+ if (fingerprints.contains(key))
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief ImitatePass::removeDir delete folder recursive.
+ * @param dirName which folder.
+ * @return was removal succesful?
+ */
+bool ImitatePass::removeDir(const QString &dirName) {
+ bool result = true;
+ QDir dir(dirName);
+
+ if (dir.exists(dirName)) {
+ Q_FOREACH (QFileInfo info,
+ dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System |
+ QDir::Hidden | QDir::AllDirs | QDir::Files,
+ QDir::DirsFirst)) {
+ if (info.isDir())
+ result = removeDir(info.absoluteFilePath());
+ else
+ result = QFile::remove(info.absoluteFilePath());
+
+ if (!result)
+ return result;
+ }
+ result = dir.rmdir(dirName);
+ }
+ return result;
+}
+
+/**
* @brief ImitatePass::reencryptPath reencrypt all files under the chosen
* directory
*
@@ -222,10 +342,21 @@ void ImitatePass::reencryptPath(const QString &dir) {
QDir currentDir;
QDirIterator gpgFiles(dir, QStringList() << "*.gpg", QDir::Files,
QDirIterator::Subdirectories);
+ QStringList gpgIdFilesVerified;
QStringList gpgId;
while (gpgFiles.hasNext()) {
QString fileName = gpgFiles.next();
if (gpgFiles.fileInfo().path() != currentDir.path()) {
+ QString gpgIdPath = Pass::getGpgIdPath(fileName);
+ if (!gpgIdFilesVerified.contains(gpgIdPath)) {
+ if (!verifyGpgIdFile(gpgIdPath)) {
+ emit critical(tr("Check .gpgid file signature!"),
+ tr("Signature for %1 is invalid.").arg(gpgIdPath));
+ emit endReencryptPath();
+ return;
+ }
+ gpgIdFilesVerified.append(gpgIdPath);
+ }
gpgId = getRecipientList(fileName);
gpgId.sort();
}
diff --git a/src/imitatepass.h b/src/imitatepass.h
index a3fd133a..d29a25d4 100644
--- a/src/imitatepass.h
+++ b/src/imitatepass.h
@@ -11,6 +11,9 @@
class ImitatePass : public Pass, private simpleTransaction {
Q_OBJECT
+ bool verifyGpgIdFile(const QString &file);
+ bool removeDir(const QString &dirName);
+
void GitCommit(const QString &file, const QString &msg);
void executeGit(PROCESS id, const QStringList &args,
diff --git a/src/keygendialog.ui b/src/keygendialog.ui
index f6ec8b13..4f3647d5 100644
--- a/src/keygendialog.ui
+++ b/src/keygendialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>606</width>
- <height>480</height>
+ <height>497</height>
</rect>
</property>
<property name="windowTitle">
@@ -72,18 +72,6 @@
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
<item row="0" column="0">
<widget class="QLabel" name="labelEmail">
<property name="sizePolicy">
@@ -101,6 +89,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
+ <property name="buddy">
+ <cstring>email</cstring>
+ </property>
</widget>
</item>
<item row="0" column="1">
@@ -130,6 +121,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
+ <property name="buddy">
+ <cstring>name</cstring>
+ </property>
</widget>
</item>
<item row="1" column="1">
@@ -159,6 +153,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
+ <property name="buddy">
+ <cstring>passphrase1</cstring>
+ </property>
</widget>
</item>
<item row="2" column="1">
@@ -203,6 +200,13 @@
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Repeat pass</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -289,6 +293,7 @@ Expire-Date: 0
</widget>
<tabstops>
<tabstop>email</tabstop>
+ <tabstop>name</tabstop>
<tabstop>passphrase1</tabstop>
<tabstop>passphrase2</tabstop>
<tabstop>checkBox</tabstop>
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 2ea6da79..b2ad8b92 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -760,7 +760,8 @@ void MainWindow::generateKeyPair(QString batch, QDialog *keygenWindow) {
* select a more appropriate one to view too
*/
void MainWindow::updateProfileBox() {
- QHash<QString, QString> profiles = QtPassSettings::getProfiles();
+ QHash<QString, QHash<QString, QString>> profiles =
+ QtPassSettings::getProfiles();
if (profiles.isEmpty()) {
ui->profileWidget->hide();
@@ -768,7 +769,7 @@ void MainWindow::updateProfileBox() {
ui->profileWidget->show();
ui->profileBox->setEnabled(profiles.size() > 1);
ui->profileBox->clear();
- QHashIterator<QString, QString> i(profiles);
+ QHashIterator<QString, QHash<QString, QString>> i(profiles);
while (i.hasNext()) {
i.next();
if (!i.key().isEmpty())
@@ -795,6 +796,8 @@ void MainWindow::on_profileBox_currentIndexChanged(QString name) {
QtPassSettings::setProfile(name);
QtPassSettings::setPassStore(QtPassSettings::getProfiles().value(name));
+ QtPassSettings::setPassSigningKey(
+ QtPassSettings::getProfiles().value(name).value("signingKey"));
ui->statusBar->showMessage(tr("Profile changed to %1").arg(name), 2000);
QtPassSettings::getPass()->updateEnv();
diff --git a/src/pass.cpp b/src/pass.cpp
index 1e5db45d..efa665dd 100644
--- a/src/pass.cpp
+++ b/src/pass.cpp
@@ -246,8 +246,29 @@ void Pass::finished(int id, int exitCode, const QString &out,
* switching profiles)
*/
void Pass::updateEnv() {
- QStringList store = env.filter("PASSWORD_STORE_DIR=");
+ // put PASSWORD_STORE_SIGNING_KEY in env
+ QStringList envSigningKey = env.filter("PASSWORD_STORE_SIGNING_KEY=");
+ QString currentSigningKey = QtPassSettings::getPassSigningKey();
+ if (envSigningKey.isEmpty()) {
+ if (!currentSigningKey.isEmpty()) {
+ // dbg()<< "Added
+ // PASSWORD_STORE_SIGNING_KEY with" + currentSigningKey;
+ env.append("PASSWORD_STORE_SIGNING_KEY=" + currentSigningKey);
+ }
+ } else {
+ if (currentSigningKey.isEmpty()) {
+ // dbg() << "Removed
+ // PASSWORD_STORE_SIGNING_KEY";
+ env.removeAll(envSigningKey.first());
+ } else {
+ // dbg()<< "Update
+ // PASSWORD_STORE_SIGNING_KEY with " + currentSigningKey;
+ env.replaceInStrings(envSigningKey.first(),
+ "PASSWORD_STORE_SIGNING_KEY=" + currentSigningKey);
+ }
+ }
// put PASSWORD_STORE_DIR in env
+ QStringList store = env.filter("PASSWORD_STORE_DIR=");
if (store.isEmpty()) {
// dbg()<< "Added
// PASSWORD_STORE_DIR";
@@ -262,27 +283,40 @@ void Pass::updateEnv() {
}
/**
- * @brief Pass::getRecipientList return list of gpg-id's to encrypt for
- * @param for_file which file (folder) would you like recepients for
- * @return recepients gpg-id contents
+ * @brief Pass::getGpgIdPath return gpgid file path for some file (folder).
+ * @param for_file which file (folder) would you like the gpgid file path for.
+ * @return path to the gpgid file.
*/
-QStringList Pass::getRecipientList(QString for_file) {
- QDir gpgIdPath(QFileInfo(for_file.startsWith(QtPassSettings::getPassStore())
- ? for_file
- : QtPassSettings::getPassStore() + for_file)
- .absoluteDir());
+QString Pass::getGpgIdPath(QString for_file) {
+ QString passStore =
+ QDir::fromNativeSeparators(QtPassSettings::getPassStore());
+ QDir gpgIdDir(
+ QFileInfo(QDir::fromNativeSeparators(for_file).startsWith(passStore)
+ ? for_file
+ : QtPassSettings::getPassStore() + for_file)
+ .absoluteDir());
bool found = false;
- while (gpgIdPath.exists() &&
- gpgIdPath.absolutePath().startsWith(QtPassSettings::getPassStore())) {
- if (QFile(gpgIdPath.absoluteFilePath(".gpg-id")).exists()) {
+ while (gpgIdDir.exists() && gpgIdDir.absolutePath().startsWith(passStore)) {
+ if (QFile(gpgIdDir.absoluteFilePath(".gpg-id")).exists()) {
found = true;
break;
}
- if (!gpgIdPath.cdUp())
+ if (!gpgIdDir.cdUp())
break;
}
- QFile gpgId(found ? gpgIdPath.absoluteFilePath(".gpg-id")
- : QtPassSettings::getPassStore() + ".gpg-id");
+ QString gpgIdPath(found ? gpgIdDir.absoluteFilePath(".gpg-id")
+ : QtPassSettings::getPassStore() + ".gpg-id");
+
+ return gpgIdPath;
+}
+
+/**
+ * @brief Pass::getRecipientList return list of gpg-id's to encrypt for
+ * @param for_file which file (folder) would you like recepients for
+ * @return recepients gpg-id contents
+ */
+QStringList Pass::getRecipientList(QString for_file) {
+ QFile gpgId(getGpgIdPath(for_file));
if (!gpgId.open(QIODevice::ReadOnly | QIODevice::Text))
return QStringList();
QStringList recipients;
diff --git a/src/pass.h b/src/pass.h
index c7b9bfdc..acdabd36 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -50,6 +50,7 @@ public:
QList<UserInfo> listKeys(QStringList keystrings, bool secret = false);
QList<UserInfo> listKeys(QString keystring = "", bool secret = false);
void updateEnv();
+ static QString getGpgIdPath(QString for_file);
static QStringList getRecipientList(QString for_file);
// TODO(bezet): getRecipientString is useless, refactor
static QStringList getRecipientString(QString for_file,
diff --git a/src/qprogressindicator.cpp b/src/qprogressindicator.cpp
index ae90f939..1a47a524 100644
--- a/src/qprogressindicator.cpp
+++ b/src/qprogressindicator.cpp
@@ -1,3 +1,29 @@
+/*
+ * This code is based on https://github.com/mojocorp/QProgressIndicator
+ * and published under
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2011 Morgan Leborgne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#include "qprogressindicator.h"
#include <QPainter>
diff --git a/src/qprogressindicator.h b/src/qprogressindicator.h
index f5a59af4..8071965d 100644
--- a/src/qprogressindicator.h
+++ b/src/qprogressindicator.h
@@ -1,3 +1,30 @@
+/*
+ * This code is based on https://github.com/mojocorp/QProgressIndicator
+ * and published under
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2011 Morgan Leborgne
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
#ifndef QPROGRESSINDICATOR_H_
#define QPROGRESSINDICATOR_H_
diff --git a/src/qtpasssettings.cpp b/src/qtpasssettings.cpp
index b32a6525..e76ae886 100644
--- a/src/qtpasssettings.cpp
+++ b/src/qtpasssettings.cpp
@@ -58,13 +58,30 @@ void QtPassSettings::setPasswordConfiguration(
config.Characters[PasswordConfiguration::CUSTOM]);
}
-QHash<QString, QString> QtPassSettings::getProfiles() {
+QHash<QString, QHash<QString, QString>> QtPassSettings::getProfiles() {
getInstance()->beginGroup(SettingsConstants::profile);
-
- QStringList childrenKeys = getInstance()->childKeys();
- QHash<QString, QString> profiles;
- foreach (QString key, childrenKeys) {
- profiles.insert(key, getInstance()->value(key).toString());
+ QHash<QString, QHash<QString, QString>> profiles;
+
+ // migration from version <= v1.3.2: profiles datastructure
+ QStringList childKeys = getInstance()->childKeys();
+ if (!childKeys.empty()) {
+ foreach (QString key, childKeys) {
+ QHash<QString, QString> profile;
+ profile.insert("path", getInstance()->value(key).toString());
+ profile.insert("signingKey", "");
+ profiles.insert(key, profile);
+ }
+ }
+ // /migration from version <= v1.3.2
+
+ QStringList childGroups = getInstance()->childGroups();
+ foreach (QString group, childGroups) {
+ QHash<QString, QString> profile;
+ profile.insert("path", getInstance()->value(group + "/path").toString());
+ profile.insert("signingKey",
+ getInstance()->value(group + "/signingKey").toString());
+ // profiles.insert(group, getInstance()->value(group).toString());
+ profiles.insert(group, profile);
}
getInstance()->endGroup();
@@ -72,13 +89,16 @@ QHash<QString, QString> QtPassSettings::getProfiles() {
return profiles;
}
-void QtPassSettings::setProfiles(const QHash<QString, QString> &profiles) {
+void QtPassSettings::setProfiles(
+ const QHash<QString, QHash<QString, QString>> &profiles) {
getInstance()->remove(SettingsConstants::profile);
getInstance()->beginGroup(SettingsConstants::profile);
- QHash<QString, QString>::const_iterator i = profiles.begin();
+ QHash<QString, QHash<QString, QString>>::const_iterator i = profiles.begin();
for (; i != profiles.end(); ++i) {
- getInstance()->setValue(i.key(), i.value());
+ getInstance()->setValue(i.key() + "/path", i.value().value("path"));
+ getInstance()->setValue(i.key() + "/signingKey",
+ i.value().value("signingKey"));
}
getInstance()->endGroup();
@@ -303,6 +323,15 @@ void QtPassSettings::setPassStore(const QString &passStore) {
getInstance()->setValue(SettingsConstants::passStore, passStore);
}
+QString QtPassSettings::getPassSigningKey(const QString &defaultValue) {
+ return getInstance()
+ ->value(SettingsConstants::passSigningKey, defaultValue)
+ .toString();
+}
+void QtPassSettings::setPassSigningKey(const QString &passSigningKey) {
+ getInstance()->setValue(SettingsConstants::passSigningKey, passSigningKey);
+}
+
void QtPassSettings::initExecutables() {
QString passExecutable =
QtPassSettings::getPassExecutable(Util::findBinaryInPath("pass"));
diff --git a/src/qtpasssettings.h b/src/qtpasssettings.h
index e3d5b3f0..d63f37fd 100644
--- a/src/qtpasssettings.h
+++ b/src/qtpasssettings.h
@@ -108,6 +108,10 @@ public:
getPassStore(const QString &defaultValue = QVariant().toString());
static void setPassStore(const QString &passStore);
+ static QString
+ getPassSigningKey(const QString &defaultValue = QVariant().toString());
+ static void setPassSigningKey(const QString &passSigningKey);
+
static void initExecutables();
static QString
getPassExecutable(const QString &defaultValue = QVariant().toString());
@@ -210,8 +214,9 @@ public:
isTemplateAllFields(const bool &defaultValue = QVariant().toBool());
static void setTemplateAllFields(const bool &templateAllFields);
- static QHash<QString, QString> getProfiles();
- static void setProfiles(const QHash<QString, QString> &profiles);
+ static QHash<QString, QHash<QString, QString>> getProfiles();
+ static void
+ setProfiles(const QHash<QString, QHash<QString, QString>> &profiles);
static Pass *getPass();
static RealPass *getRealPass();
diff --git a/src/settingsconstants.cpp b/src/settingsconstants.cpp
index 863d110f..00b004fd 100644
--- a/src/settingsconstants.cpp
+++ b/src/settingsconstants.cpp
@@ -32,6 +32,7 @@ const QString SettingsConstants::displayAsIs = "displayAsIs";
const QString SettingsConstants::noLineWrapping = "noLineWrapping";
const QString SettingsConstants::addGPGId = "addGPGId";
const QString SettingsConstants::passStore = "passStore";
+const QString SettingsConstants::passSigningKey = "passSigningKey";
const QString SettingsConstants::passExecutable = "passExecutable";
const QString SettingsConstants::gitExecutable = "gitExecutable";
const QString SettingsConstants::gpgExecutable = "gpgExecutable";
diff --git a/src/settingsconstants.h b/src/settingsconstants.h
index bb237ab3..f95aeba2 100644
--- a/src/settingsconstants.h
+++ b/src/settingsconstants.h
@@ -31,6 +31,7 @@ public:
const static QString noLineWrapping;
const static QString addGPGId;
const static QString passStore;
+ const static QString passSigningKey;
const static QString passExecutable;
const static QString gitExecutable;
const static QString gpgExecutable;