summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Blum <alexander.blum@c3s.cc>2023-06-16 19:26:02 +0200
committerAlexander Blum <alexander.blum@c3s.cc>2023-06-16 19:26:02 +0200
commitf386cc08a2d4de3e9d51f78479eb1c6c4ca1c7f2 (patch)
treed98d429ea506800a36d2ea451e87b6a179e6305d
parentd4c841570efb995cbb5c65c660a2f4c8eded7170 (diff)
Add pass store signing key feature
-rw-r--r--README.md1
-rw-r--r--src/configdialog.cpp35
-rw-r--r--src/configdialog.h4
-rw-r--r--src/configdialog.ui5
-rw-r--r--src/mainwindow.cpp9
-rw-r--r--src/pass.cpp23
-rw-r--r--src/qtpasssettings.cpp31
-rw-r--r--src/qtpasssettings.h8
-rw-r--r--src/settingsconstants.cpp1
-rw-r--r--src/settingsconstants.h1
10 files changed, 90 insertions, 28 deletions
diff --git a/README.md b/README.md
index 6ffd46c1..43a126b3 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 (pass only).
A typical use case is to separate personal and work passwords.
> **Hint**<br>
diff --git a/src/configdialog.cpp b/src/configdialog.cpp
index 4a711b03..72b5f809 100644
--- a/src/configdialog.cpp
+++ b/src/configdialog.cpp
@@ -97,7 +97,7 @@ 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();
@@ -170,7 +170,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;
@@ -181,7 +181,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;
}
@@ -460,8 +460,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("");
@@ -469,15 +469,19 @@ 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, 0, new QTableWidgetItem(i.key()));
+ 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;
@@ -488,17 +492,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;
@@ -512,6 +522,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/mainwindow.cpp b/src/mainwindow.cpp
index 60b3d0ca..e273dbb1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -766,7 +766,7 @@ 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();
@@ -774,7 +774,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())
@@ -800,7 +800,10 @@ void MainWindow::on_profileBox_currentIndexChanged(QString name) {
QtPassSettings::setProfile(name);
- QtPassSettings::setPassStore(QtPassSettings::getProfiles()[name]);
+ QtPassSettings::setPassStore(
+ QtPassSettings::getProfiles().value(name).value("path"));
+ 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 f52c27a5..8509161f 100644
--- a/src/pass.cpp
+++ b/src/pass.cpp
@@ -242,8 +242,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";
diff --git a/src/qtpasssettings.cpp b/src/qtpasssettings.cpp
index b32a6525..83117021 100644
--- a/src/qtpasssettings.cpp
+++ b/src/qtpasssettings.cpp
@@ -58,13 +58,18 @@ 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());
+ QStringList childGroups = getInstance()->childGroups();
+ QHash<QString, QHash<QString, QString>> profiles;
+ 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 +77,14 @@ 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 +309,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..d96c70c9 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,8 @@ 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;