summaryrefslogtreecommitdiffstats
path: root/src/imitatepass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imitatepass.cpp')
-rw-r--r--src/imitatepass.cpp135
1 files changed, 119 insertions, 16 deletions
diff --git a/src/imitatepass.cpp b/src/imitatepass.cpp
index 2140505b..8300cb36 100644
--- a/src/imitatepass.cpp
+++ b/src/imitatepass.cpp
@@ -1,5 +1,6 @@
#include "imitatepass.h"
#include "qtpasssettings.h"
+#include "util.h"
#include <QDirIterator>
#include <QRegularExpression>
#include <utility>
@@ -89,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()) {
@@ -112,7 +119,7 @@ void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
if (!overwrite)
executeGit(GIT_ADD, {"add", pgit(file)});
QString path = QDir(QtPassSettings::getPassStore()).relativeFilePath(file);
- path.replace(QRegularExpression("\\.gpg$"), "");
+ path.replace(Util::endsWithGpg(), "");
QString msg =
QString(overwrite ? "Edit" : "Add") + " for " + path + " using QtPass.";
GitCommit(file, msg);
@@ -127,9 +134,9 @@ void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
*/
void ImitatePass::GitCommit(const QString &file, const QString &msg) {
if (file.isEmpty())
- executeGit(GIT_COMMIT, {"commit", "-m", msg});
+ executeGit(GIT_COMMIT, {"commit", "-m", msg});
else
- executeGit(GIT_COMMIT, {"commit", "-m", msg, "--", pgit(file)});
+ executeGit(GIT_COMMIT, {"commit", "-m", msg, "--", pgit(file)});
}
/**
@@ -147,12 +154,8 @@ void ImitatePass::Remove(QString file, bool isDir) {
GitCommit(file, "Remove for " + file + " using QtPass.");
} else {
if (isDir) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QDir dir(file);
dir.removeRecursively();
-#else
- removeDir(QtPassSettings::getPassStore() + file);
-#endif
} else
QFile(file).remove();
}
@@ -166,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;
@@ -196,18 +231,73 @@ 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)
executeGit(GIT_ADD, {"add", pgit(gpgIdFile)});
QString commitPath = gpgIdFile;
- commitPath.replace(QRegularExpression("\\.gpg$"), "");
+ 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?
@@ -252,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();
}
@@ -267,10 +368,11 @@ void ImitatePass::reencryptPath(const QString &dir) {
exec.executeBlocking(QtPassSettings::getGpgExecutable(), args, &keys, &err);
QStringList actualKeys;
keys += err;
+ static const QRegularExpression newLines{"[\r\n]"};
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
- QStringList key = keys.split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+ QStringList key = keys.split(newLines, Qt::SkipEmptyParts);
#else
- QStringList key = keys.split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+ QStringList key = keys.split(newLines, QString::SkipEmptyParts);
#endif
QListIterator<QString> itr(key);
while (itr.hasNext()) {
@@ -323,7 +425,7 @@ void ImitatePass::reencryptPath(const QString &dir) {
{"add", pgit(fileName)});
QString path =
QDir(QtPassSettings::getPassStore()).relativeFilePath(fileName);
- path.replace(QRegularExpression("\\.gpg$"), "");
+ path.replace(Util::endsWithGpg(), "");
exec.executeBlocking(QtPassSettings::getGitExecutable(),
{"commit", pgit(fileName), "-m",
"Edit for " + path + " using QtPass."});
@@ -403,11 +505,12 @@ void ImitatePass::Move(const QString src, const QString dest,
executeGit(GIT_MOVE, args);
QString relSrc = QDir(QtPassSettings::getPassStore()).relativeFilePath(src);
- relSrc.replace(QRegularExpression("\\.gpg$"), "");
- QString relDest = QDir(QtPassSettings::getPassStore()).relativeFilePath(destFile);
- relDest.replace(QRegularExpression("\\.gpg$"), "");
+ relSrc.replace(Util::endsWithGpg(), "");
+ QString relDest =
+ QDir(QtPassSettings::getPassStore()).relativeFilePath(destFile);
+ relDest.replace(Util::endsWithGpg(), "");
QString message = QString("Moved for %1 to %2 using QtPass.");
- message = message.arg(relSrc).arg(relDest);
+ message = message.arg(relSrc, relDest);
GitCommit("", message);
} else {
QDir qDir;
@@ -433,7 +536,7 @@ void ImitatePass::Copy(const QString src, const QString dest,
executeGit(GIT_COPY, args);
QString message = QString("copied from %1 to %2 using QTPass.");
- message = message.arg(src).arg(dest);
+ message = message.arg(src, dest);
GitCommit("", message);
} else {
QDir qDir;