Implement SSH key file path env substitution

Supports all platforms, including Windows with %FOO% syntax.

Fixes #3523
This commit is contained in:
Toni Spets 2019-11-02 11:25:13 +02:00 committed by Jonathan White
parent 47ce81c9a6
commit 6fc7be78ea
6 changed files with 56 additions and 1 deletions

View File

@ -324,6 +324,29 @@ namespace Tools
return QUuid::fromRfc4122(QByteArray::fromHex(uuid.toLatin1()));
}
QString envSubstitute(const QString& filepath, QProcessEnvironment environment)
{
QString subbed = filepath;
#if defined(Q_OS_WIN)
QRegularExpression varRe("\\%([A-Za-z][A-Za-z0-9_]*)\\%");
#else
QRegularExpression varRe("\\$([A-Za-z][A-Za-z0-9_]*)");
subbed.replace("~", environment.value("HOME"));
#endif
QRegularExpressionMatch match;
do {
match = varRe.match(subbed);
if (match.hasMatch()) {
subbed.replace(match.capturedStart(), match.capturedLength(), environment.value(match.captured(1)));
}
} while (match.hasMatch());
return subbed;
}
Buffer::Buffer()
: raw(nullptr)
, size(0)

View File

@ -22,6 +22,7 @@
#include "core/Global.h"
#include <QObject>
#include <QProcessEnvironment>
#include <QString>
#include <QUuid>
@ -48,6 +49,8 @@ namespace Tools
bool useWildcards = false,
bool exactMatch = false,
bool caseSensitive = false);
QString envSubstitute(const QString& filepath,
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment());
template <typename RandomAccessIterator, typename T>
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)

View File

@ -17,6 +17,7 @@
*/
#include "KeeAgentSettings.h"
#include "core/Tools.h"
KeeAgentSettings::KeeAgentSettings()
: m_lifetimeConstraintDuration(600)
@ -115,6 +116,11 @@ const QString KeeAgentSettings::fileName() const
return m_fileName;
}
const QString KeeAgentSettings::fileNameEnvSubst(QProcessEnvironment environment) const
{
return Tools::envSubstitute(m_fileName, environment);
}
void KeeAgentSettings::setAllowUseOfSshKey(bool allowUseOfSshKey)
{
m_allowUseOfSshKey = allowUseOfSshKey;
@ -361,7 +367,7 @@ bool KeeAgentSettings::toOpenSSHKey(const Entry* entry, OpenSSHKey& key, bool de
fileName = m_attachmentName;
privateKeyData = entry->attachments()->value(fileName);
} else {
QFile localFile(m_fileName);
QFile localFile(fileNameEnvSubst());
QFileInfo localFileInfo(localFile);
fileName = localFileInfo.fileName();

View File

@ -54,6 +54,7 @@ public:
const QString attachmentName() const;
bool saveAttachmentToTempFile() const;
const QString fileName() const;
const QString fileNameEnvSubst(QProcessEnvironment environment = QProcessEnvironment::systemEnvironment()) const;
void setAllowUseOfSshKey(bool allowUseOfSshKey);
void setAddAtDatabaseOpen(bool addAtDatabaseOpen);

View File

@ -64,3 +64,24 @@ void TestTools::testIsBase64()
QVERIFY(not Tools::isBase64(QByteArray("abc_")));
QVERIFY(not Tools::isBase64(QByteArray("123")));
}
void TestTools::testEnvSubstitute()
{
QProcessEnvironment environment;
#if defined(Q_OS_WIN)
environment.insert("HOMEDRIVE", "C:");
environment.insert("HOMEPATH", "\\Users\\User");
QCOMPARE(Tools::envSubstitute("%HOMEDRIVE%%HOMEPATH%\\.ssh\\id_rsa", environment),
QString("C:\\Users\\User\\.ssh\\id_rsa"));
QCOMPARE(Tools::envSubstitute("start%EMPTY%%EMPTY%%%HOMEDRIVE%%end", environment), QString("start%C:%end"));
#else
environment.insert("HOME", QString("/home/user"));
environment.insert("USER", QString("user"));
QCOMPARE(Tools::envSubstitute("~/.ssh/id_rsa", environment), QString("/home/user/.ssh/id_rsa"));
QCOMPARE(Tools::envSubstitute("$HOME/.ssh/id_rsa", environment), QString("/home/user/.ssh/id_rsa"));
QCOMPARE(Tools::envSubstitute("start/$EMPTY$$EMPTY$HOME/end", environment), QString("start/$/home/user/end"));
#endif
}

View File

@ -27,6 +27,7 @@ private slots:
void testHumanReadableFileSize();
void testIsHex();
void testIsBase64();
void testEnvSubstitute();
};
#endif // KEEPASSX_TESTTOOLS_H