Use cryptographic nonce instead of counters.
This commit is contained in:
parent
48761e0e2b
commit
c50e04c9d1
|
@ -196,7 +196,6 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode)
|
||||||
|
|
||||||
if (checkVG.run(-1) && checkVG.exitCode() == 0)
|
if (checkVG.run(-1) && checkVG.exitCode() == 0)
|
||||||
{
|
{
|
||||||
qDebug() << "Trying to find LVM VG";
|
|
||||||
QList<Device *> availableDevices = scanDevices();
|
QList<Device *> availableDevices = scanDevices();
|
||||||
|
|
||||||
LvmDevice::scanSystemLVM(availableDevices);
|
LvmDevice::scanSystemLVM(availableDevices);
|
||||||
|
|
|
@ -57,7 +57,6 @@ struct ExternalCommandPrivate
|
||||||
QProcess::ProcessChannelMode processChannelMode;
|
QProcess::ProcessChannelMode processChannelMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int ExternalCommand::counter = 0;
|
|
||||||
KAuth::ExecuteJob* ExternalCommand::m_job;
|
KAuth::ExecuteJob* ExternalCommand::m_job;
|
||||||
QCA::PrivateKey* ExternalCommand::privateKey;
|
QCA::PrivateKey* ExternalCommand::privateKey;
|
||||||
QCA::Initializer* ExternalCommand::init;
|
QCA::Initializer* ExternalCommand::init;
|
||||||
|
@ -144,7 +143,7 @@ bool ExternalCommand::start(int timeout)
|
||||||
if (iface.isValid()) {
|
if (iface.isValid()) {
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
|
|
||||||
request.setNum(++counter);
|
request.setNum(getNonce(iface));
|
||||||
request.append(cmd.toUtf8());
|
request.append(cmd.toUtf8());
|
||||||
for (const auto &argument : qAsConst(d->m_Args))
|
for (const auto &argument : qAsConst(d->m_Args))
|
||||||
request.append(argument.toUtf8());
|
request.append(argument.toUtf8());
|
||||||
|
@ -204,7 +203,7 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target)
|
||||||
if (iface.isValid()) {
|
if (iface.isValid()) {
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
|
|
||||||
request.setNum(++counter);
|
request.setNum(getNonce(iface));
|
||||||
request.append(source.path().toUtf8());
|
request.append(source.path().toUtf8());
|
||||||
request.append(QByteArray::number(source.firstByte()));
|
request.append(QByteArray::number(source.firstByte()));
|
||||||
request.append(QByteArray::number(source.length()));
|
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());
|
QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus());
|
||||||
if (iface.isValid()) {
|
if (iface.isValid()) {
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
request.setNum(++counter);
|
request.setNum(getNonce(iface));
|
||||||
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
||||||
iface.call(QStringLiteral("exit"), privateKey->signMessage(hash, QCA::EMSA3_Raw));
|
iface.call(QStringLiteral("exit"), privateKey->signMessage(hash, QCA::EMSA3_Raw));
|
||||||
}
|
}
|
||||||
|
@ -420,6 +419,29 @@ void ExternalCommand::stopHelper()
|
||||||
delete init;
|
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<unsigned long long> reply = *watcher;
|
||||||
|
rval = reply;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop);
|
||||||
|
loop.exec();
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
void DBusThread::run()
|
void DBusThread::run()
|
||||||
{
|
{
|
||||||
if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface"))) {
|
if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface"))) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace QCA { class PrivateKey; class Initializer; }
|
||||||
class Report;
|
class Report;
|
||||||
class CopySource;
|
class CopySource;
|
||||||
class CopyTarget;
|
class CopyTarget;
|
||||||
|
class QDBusInterface;
|
||||||
struct ExternalCommandPrivate;
|
struct ExternalCommandPrivate;
|
||||||
|
|
||||||
class DBusThread : public QThread
|
class DBusThread : public QThread
|
||||||
|
@ -129,12 +130,13 @@ private:
|
||||||
|
|
||||||
void onFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void onFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
void onReadOutput();
|
void onReadOutput();
|
||||||
|
static unsigned long long getNonce(QDBusInterface& iface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ExternalCommandPrivate> d;
|
std::unique_ptr<ExternalCommandPrivate> d;
|
||||||
|
|
||||||
// KAuth stuff
|
// KAuth stuff
|
||||||
static unsigned int counter;
|
static unsigned long long m_Nonce;
|
||||||
static KAuth::ExecuteJob *m_job;
|
static KAuth::ExecuteJob *m_job;
|
||||||
static QCA::Initializer *init;
|
static QCA::Initializer *init;
|
||||||
static QCA::PrivateKey *privateKey;
|
static QCA::PrivateKey *privateKey;
|
||||||
|
|
|
@ -61,7 +61,7 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_publicKey = QCA::PublicKey::fromDER(args[QStringLiteral("pubkey")].toByteArray());
|
m_publicKey = QCA::PublicKey::fromDER(args[QStringLiteral("pubkey")].toByteArray());
|
||||||
m_Counter = 0;
|
m_Nonce = m_Generator.generate();
|
||||||
|
|
||||||
HelperSupport::progressStep(QVariantMap());
|
HelperSupport::progressStep(QVariantMap());
|
||||||
auto timeout = [this] () {
|
auto timeout = [this] () {
|
||||||
|
@ -90,6 +90,15 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args)
|
||||||
return reply;
|
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.
|
/** Reads the given number of bytes from the sourceDevice into the given buffer.
|
||||||
@param sourceDevice device or file to read from
|
@param sourceDevice device or file to read from
|
||||||
@param buffer buffer to store the bytes read in
|
@param buffer buffer to store the bytes read in
|
||||||
|
@ -151,7 +160,7 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const QStrin
|
||||||
{
|
{
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
|
|
||||||
request.setNum(++m_Counter);
|
request.setNum(m_Nonce);
|
||||||
request.append(sourceDevice.toUtf8());
|
request.append(sourceDevice.toUtf8());
|
||||||
request.append(QByteArray::number(sourceFirstByte));
|
request.append(QByteArray::number(sourceFirstByte));
|
||||||
request.append(QByteArray::number(sourceLength));
|
request.append(QByteArray::number(sourceLength));
|
||||||
|
@ -248,9 +257,10 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr
|
||||||
{
|
{
|
||||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||||
QVariantMap reply;
|
QVariantMap reply;
|
||||||
|
reply[QStringLiteral("success")] = true;
|
||||||
|
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
request.setNum(++m_Counter);
|
request.setNum(m_Nonce);
|
||||||
request.append(command.toUtf8());
|
request.append(command.toUtf8());
|
||||||
for (const auto &argument : arguments)
|
for (const auto &argument : arguments)
|
||||||
request.append(argument.toUtf8());
|
request.append(argument.toUtf8());
|
||||||
|
@ -281,7 +291,7 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr
|
||||||
void ExternalCommandHelper::exit(const QByteArray& signature)
|
void ExternalCommandHelper::exit(const QByteArray& signature)
|
||||||
{
|
{
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
request.setNum(++m_Counter);
|
request.setNum(m_Nonce);
|
||||||
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
||||||
if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) {
|
if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) {
|
||||||
qCritical() << xi18n("Invalid cryptographic signature");
|
qCritical() << xi18n("Invalid cryptographic signature");
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <KAuth>
|
#include <KAuth>
|
||||||
|
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
|
#include <QRandomGenerator64>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
ActionReply init(const QVariantMap& args);
|
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 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 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);
|
Q_SCRIPTABLE void exit(const QByteArray& signature);
|
||||||
|
@ -53,7 +55,8 @@ private:
|
||||||
QEventLoop m_loop;
|
QEventLoop m_loop;
|
||||||
QCA::Initializer initializer;
|
QCA::Initializer initializer;
|
||||||
QCA::PublicKey m_publicKey;
|
QCA::PublicKey m_publicKey;
|
||||||
unsigned int m_Counter;
|
QRandomGenerator64 m_Generator;
|
||||||
|
unsigned long long m_Nonce;
|
||||||
QString m_command;
|
QString m_command;
|
||||||
QString m_sourceDevice;
|
QString m_sourceDevice;
|
||||||
QProcess m_cmd;
|
QProcess m_cmd;
|
||||||
|
|
Loading…
Reference in New Issue