From c50e04c9d1581635c5a518cda08c1734155e0748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 20 Jul 2018 21:12:13 +0100 Subject: [PATCH] Use cryptographic nonce instead of counters. --- src/plugins/sfdisk/sfdiskbackend.cpp | 1 - src/util/externalcommand.cpp | 30 ++++++++++++++++++++++++---- src/util/externalcommand.h | 4 +++- src/util/externalcommandhelper.cpp | 18 +++++++++++++---- src/util/externalcommandhelper.h | 5 ++++- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index d8a5f36..357c6db 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -196,7 +196,6 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) if (checkVG.run(-1) && checkVG.exitCode() == 0) { - qDebug() << "Trying to find LVM VG"; QList availableDevices = scanDevices(); LvmDevice::scanSystemLVM(availableDevices); diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index f96cf74..a1030c0 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -57,7 +57,6 @@ struct ExternalCommandPrivate QProcess::ProcessChannelMode processChannelMode; }; -unsigned int ExternalCommand::counter = 0; KAuth::ExecuteJob* ExternalCommand::m_job; QCA::PrivateKey* ExternalCommand::privateKey; QCA::Initializer* ExternalCommand::init; @@ -144,7 +143,7 @@ bool ExternalCommand::start(int timeout) if (iface.isValid()) { QByteArray request; - request.setNum(++counter); + request.setNum(getNonce(iface)); request.append(cmd.toUtf8()); for (const auto &argument : qAsConst(d->m_Args)) request.append(argument.toUtf8()); @@ -204,7 +203,7 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target) if (iface.isValid()) { QByteArray request; - request.setNum(++counter); + request.setNum(getNonce(iface)); request.append(source.path().toUtf8()); request.append(QByteArray::number(source.firstByte())); request.append(QByteArray::number(source.length())); @@ -411,7 +410,7 @@ void ExternalCommand::stopHelper() QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); if (iface.isValid()) { QByteArray request; - request.setNum(++counter); + request.setNum(getNonce(iface)); QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512); iface.call(QStringLiteral("exit"), privateKey->signMessage(hash, QCA::EMSA3_Raw)); } @@ -420,6 +419,29 @@ void ExternalCommand::stopHelper() delete init; } +unsigned long long ExternalCommand::getNonce(QDBusInterface& iface) +{ + QDBusPendingCall pcall = iface.asyncCall(QStringLiteral("getNonce")); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall); + QEventLoop loop; + unsigned long long rval = 0; + + auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { + loop.exit(); + + if (watcher->isError()) + qWarning() << watcher->error(); + else { + QDBusPendingReply reply = *watcher; + rval = reply; + } + }; + + connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); + loop.exec(); + return rval; +} + void DBusThread::run() { if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface"))) { diff --git a/src/util/externalcommand.h b/src/util/externalcommand.h index 9f24c9f..8111a70 100644 --- a/src/util/externalcommand.h +++ b/src/util/externalcommand.h @@ -37,6 +37,7 @@ namespace QCA { class PrivateKey; class Initializer; } class Report; class CopySource; class CopyTarget; +class QDBusInterface; struct ExternalCommandPrivate; class DBusThread : public QThread @@ -129,12 +130,13 @@ private: void onFinished(int exitCode, QProcess::ExitStatus exitStatus); void onReadOutput(); + static unsigned long long getNonce(QDBusInterface& iface); private: std::unique_ptr d; // KAuth stuff - static unsigned int counter; + static unsigned long long m_Nonce; static KAuth::ExecuteJob *m_job; static QCA::Initializer *init; static QCA::PrivateKey *privateKey; diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index e12cccc..9078309 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -61,7 +61,7 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args) } m_publicKey = QCA::PublicKey::fromDER(args[QStringLiteral("pubkey")].toByteArray()); - m_Counter = 0; + m_Nonce = m_Generator.generate(); HelperSupport::progressStep(QVariantMap()); auto timeout = [this] () { @@ -90,6 +90,15 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args) return reply; } +/** Generates cryptographic nonce + * @return nonce +*/ +unsigned long long ExternalCommandHelper::getNonce() +{ + m_Nonce = m_Generator.generate(); + return m_Nonce; +} + /** Reads the given number of bytes from the sourceDevice into the given buffer. @param sourceDevice device or file to read from @param buffer buffer to store the bytes read in @@ -151,7 +160,7 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const QStrin { QByteArray request; - request.setNum(++m_Counter); + request.setNum(m_Nonce); request.append(sourceDevice.toUtf8()); request.append(QByteArray::number(sourceFirstByte)); request.append(QByteArray::number(sourceLength)); @@ -248,9 +257,10 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr { QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QVariantMap reply; + reply[QStringLiteral("success")] = true; QByteArray request; - request.setNum(++m_Counter); + request.setNum(m_Nonce); request.append(command.toUtf8()); for (const auto &argument : arguments) request.append(argument.toUtf8()); @@ -281,7 +291,7 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr void ExternalCommandHelper::exit(const QByteArray& signature) { QByteArray request; - request.setNum(++m_Counter); + request.setNum(m_Nonce); QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512); if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) { qCritical() << xi18n("Invalid cryptographic signature"); diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 60453ef..a2a309b 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -43,6 +44,7 @@ public: public Q_SLOTS: ActionReply init(const QVariantMap& args); + Q_SCRIPTABLE unsigned long long getNonce(); Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode); Q_SCRIPTABLE bool copyblocks(const QByteArray& signature, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); Q_SCRIPTABLE void exit(const QByteArray& signature); @@ -53,7 +55,8 @@ private: QEventLoop m_loop; QCA::Initializer initializer; QCA::PublicKey m_publicKey; - unsigned int m_Counter; + QRandomGenerator64 m_Generator; + unsigned long long m_Nonce; QString m_command; QString m_sourceDevice; QProcess m_cmd;