Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.3:Update
kdeconnect-kde.16873
0001-Add-a-verification-key-that-s-displayed-wh...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Add-a-verification-key-that-s-displayed-when-pairing.patch of Package kdeconnect-kde.16873
From 76075427cd5f735627eb3cc16e7340e865ab9ed9 Mon Sep 17 00:00:00 2001 From: Luca Beltrame <lbeltrame@kde.org> Date: Tue, 22 Dec 2020 17:13:00 +0100 Subject: [PATCH] Add a verification key that's displayed when pairing The key is a sha256 of both devices' certificates. Both should generate the same key, so hey user can check they are pairing against the right device. Thanks Matthias Gerstner <mgerstner@suse.de> for reporting this. --- core/backends/devicelink.h | 3 + core/backends/lan/landevicelink.cpp | 3 +- core/backends/lan/landevicelink.h | 2 +- core/backends/loopback/loopbackdevicelink.h | 3 + core/device.cpp | 41 ++++++-- core/device.h | 2 + daemon/kdeconnectd.cpp | 13 ++- kcm/kcm.cpp | 1 + kcm/kcm.ui | 109 ++++++++++++++------ 9 files changed, 131 insertions(+), 46 deletions(-) diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index c11c2796..c874a905 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -29,6 +29,7 @@ class PairingHandler; class NetworkPacket; class LinkProvider; class Device; +class QSslCertificate; class DeviceLink : public QObject @@ -58,6 +59,8 @@ public: //The daemon will periodically destroy unpaired links if this returns false virtual bool linkShouldBeKeptAlive() { return false; } + virtual QSslCertificate certificate() const = 0; + Q_SIGNALS: void pairingRequest(PairingHandler* handler); void pairingRequestExpired(PairingHandler* handler); diff --git a/core/backends/lan/landevicelink.cpp b/core/backends/lan/landevicelink.cpp index 41af6f0e..d31aecc7 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -178,8 +178,7 @@ void LanDeviceLink::setPairStatus(PairStatus status) DeviceLink::setPairStatus(status); if (status == Paired) { Q_ASSERT(KdeConnectConfig::instance().trustedDevices().contains(deviceId())); - Q_ASSERT(!m_socketLineReader->peerCertificate().isNull()); - KdeConnectConfig::instance().setDeviceProperty(deviceId(), QStringLiteral("certificate"), QString::fromLatin1(m_socketLineReader->peerCertificate().toPem().data())); + KdeConnectConfig::instance().setDeviceProperty(deviceId(), QStringLiteral("certificate"), QString::fromLatin1(certificate().toPem())); } } diff --git a/core/backends/lan/landevicelink.h b/core/backends/lan/landevicelink.h index 485c58b5..f218d063 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -56,7 +56,7 @@ public: bool linkShouldBeKeptAlive() override; QHostAddress hostAddress() const; - QSslCertificate certificate() const; + QSslCertificate certificate() const override; private Q_SLOTS: void dataReceived(); diff --git a/core/backends/loopback/loopbackdevicelink.h b/core/backends/loopback/loopbackdevicelink.h index 54b016a7..444d7c4e 100644 --- a/core/backends/loopback/loopbackdevicelink.h +++ b/core/backends/loopback/loopbackdevicelink.h @@ -22,6 +22,7 @@ #define LOOPBACKDEVICELINK_H #include "../devicelink.h" +#include <QSslCertificate> class LoopbackLinkProvider; @@ -37,6 +38,8 @@ public: void userRequestsPair() override { setPairStatus(Paired); } void userRequestsUnpair() override { setPairStatus(NotPaired); } + + QSslCertificate certificate() const override { return QSslCertificate(); } }; #endif diff --git a/core/device.cpp b/core/device.cpp index 32e20179..c30cebd5 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -23,6 +23,7 @@ #include <QVector> #include <QSet> #include <QSslCertificate> +#include <QSslKey> #include <KSharedConfig> #include <KConfigGroup> @@ -540,25 +541,47 @@ bool Device::isPluginEnabled(const QString& pluginName) const QString Device::encryptionInfo() const { QString result; - QCryptographicHash::Algorithm digestAlgorithm = QCryptographicHash::Algorithm::Sha1; + const QCryptographicHash::Algorithm digestAlgorithm = QCryptographicHash::Algorithm::Sha256; - QString localSha1 = QString::fromLatin1(KdeConnectConfig::instance().certificate().digest(digestAlgorithm).toHex()); - for (int i = 2; i<localSha1.size(); i += 3) { - localSha1.insert(i, QStringLiteral(":")); // Improve readability + QString localChecksum = QString::fromLatin1(KdeConnectConfig::instance().certificate().digest(digestAlgorithm).toHex()); + for (int i = 2; i<localChecksum.size(); i += 3) { + localChecksum.insert(i, QStringLiteral(":")); // Improve readability } - result += i18n("SHA1 fingerprint of your device certificate is: %1\n", localSha1); + result += i18n("SHA256 fingerprint of your device certificate is: %1\n", localChecksum); std::string remotePem = KdeConnectConfig::instance().getDeviceProperty(id(), QStringLiteral("certificate")).toStdString(); QSslCertificate remoteCertificate = QSslCertificate(QByteArray(remotePem.c_str(), (int)remotePem.size())); - QString remoteSha1 = QString::fromLatin1(remoteCertificate.digest(digestAlgorithm).toHex()); - for (int i = 2; i < remoteSha1.size(); i += 3) { - remoteSha1.insert(i, QStringLiteral(":")); // Improve readability + QString remoteChecksum = QString::fromLatin1(remoteCertificate.digest(digestAlgorithm).toHex()); + for (int i = 2; i < remoteChecksum.size(); i += 3) { + remoteChecksum.insert(i, QStringLiteral(":")); // Improve readability } - result += i18n("SHA1 fingerprint of remote device certificate is: %1\n", remoteSha1); + result += i18n("SHA256 fingerprint of remote device certificate is: %1\n", remoteChecksum); return result; } +QSslCertificate Device::certificate() const +{ + if (!d->m_deviceLinks.isEmpty()) { + return d->m_deviceLinks[0]->certificate(); + } + return QSslCertificate(); +} + +QByteArray Device::verificationKey() const +{ + auto a = KdeConnectConfig::instance().certificate().publicKey().toDer(); + auto b = certificate().publicKey().toDer(); + if (a < b) { + std::swap(a, b); + } + + QCryptographicHash hash(QCryptographicHash::Sha256); + hash.addData(a); + hash.addData(b); + return hash.result().toHex(); +} + QString Device::pluginIconName(const QString& pluginName) { if (hasPlugin(pluginName)) { diff --git a/core/device.h b/core/device.h index 9b6dd9bc..66fc0965 100644 --- a/core/device.h +++ b/core/device.h @@ -78,6 +78,7 @@ public: QString type() const; QString iconName() const; QString statusIconName() const; + Q_SCRIPTABLE QByteArray verificationKey() const; Q_SCRIPTABLE QString encryptionInfo() const; //Add and remove links @@ -144,6 +145,7 @@ private: //Methods void setName(const QString& name); QString iconForStatus(bool reachable, bool paired) const; + QSslCertificate certificate() const; private: class DevicePrivate; diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index a81ec3fd..a94eb0e4 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -62,14 +62,17 @@ public: notification->setIconName(QStringLiteral("dialog-information")); notification->setComponentName(QStringLiteral("kdeconnect")); notification->setTitle(QStringLiteral("KDE Connect")); - notification->setText(i18n("Pairing request from %1", device->name().toHtmlEscaped())); + notification->setText(i18n("Pairing request from %1\n<br/>Key: %2...", device->name().toHtmlEscaped(), QString::fromUtf8(device->verificationKey().left(8)))); notification->setDefaultAction(i18n("Open")); - notification->setActions(QStringList() << i18n("Accept") << i18n("Reject")); + notification->setActions(QStringList() << i18n("Accept") << i18n("Reject") << i18n("View key")); connect(notification, &KNotification::action1Activated, device, &Device::acceptPairing); connect(notification, &KNotification::action2Activated, device, &Device::rejectPairing); - connect(notification, QOverload<>::of(&KNotification::activated), this, []{ - QProcess::startDetached(QStringLiteral("kdeconnect-settings")); - }); + QString deviceId = device->id(); + auto openSettings = [this, deviceId] { + QProcess::startDetached(QStringLiteral("kdeconnect-settings"), QStringList() << QStringLiteral("--args") << deviceId); + }; + connect(notification, &KNotification::action3Activated, openSettings); + connect(notification, QOverload<>::of(&KNotification::activated), openSettings); notification->sendEvent(); } diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp index 721a5166..b21d98ad 100644 --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -235,6 +235,7 @@ void KdeConnectKcm::resetDeviceView() delete kcmUi->pluginSelector; kcmUi->pluginSelector = new KPluginSelector(this); kcmUi->deviceInfo_layout->addWidget(kcmUi->pluginSelector); + kcmUi->verificationKey->setText(i18n("Key: %1", QString::fromUtf8(currentDevice->verificationKey()))); kcmUi->pluginSelector->setConfigurationArguments(QStringList(currentDevice->id())); diff --git a/kcm/kcm.ui b/kcm/kcm.ui index 706f106b..08ea0812 100644 --- a/kcm/kcm.ui +++ b/kcm/kcm.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>965</width> + <width>1198</width> <height>528</height> </rect> </property> @@ -143,34 +143,85 @@ <enum>QLayout::SetMaximumSize</enum> </property> <item> - <widget class="QLabel" name="name_label"> - <property name="font"> - <font> - <pointsize>10</pointsize> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Device</string> - </property> - <property name="textFormat"> - <enum>Qt::PlainText</enum> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="status_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>(status)</string> - </property> - </widget> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QWidget" name="deviceAndStatus" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="deviceAndStatus_layout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="name_label"> + <property name="font"> + <font> + <pointsize>10</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Device</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="status_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>(status)</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="verificationKey"> + <property name="text"> + <string>🔑 abababab</string> + </property> + </widget> + </item> + </layout> </item> <item> <spacer name="horizontalSpacer"> -- 2.29.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor