diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index 59af7ef10..f97b0bec8 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -15,6 +15,7 @@ class PairingHandler; class NetworkPacket; class LinkProvider; class Device; +class QSslCertificate; class DeviceLink : public QObject @@ -44,6 +45,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 b3900f7d4..3469b21c4 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -164,8 +164,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 2d8f3e5a8..fa6ca7732 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -42,7 +42,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 0b24ebfff..04872c36a 100644 --- a/core/backends/loopback/loopbackdevicelink.h +++ b/core/backends/loopback/loopbackdevicelink.h @@ -8,6 +8,7 @@ #define LOOPBACKDEVICELINK_H #include "../devicelink.h" +#include class LoopbackLinkProvider; @@ -23,6 +24,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 62c79f7eb..9a63b506b 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -537,25 +538,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; im_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 cc0dd3f20..6f704e5ca 100644 --- a/core/device.h +++ b/core/device.h @@ -64,6 +64,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 @@ -132,6 +133,7 @@ private: //Methods void setName(const QString& name); void setType(const QString& strtype); QString iconForStatus(bool reachable, bool paired) const; + QSslCertificate certificate() const; private: class DevicePrivate; diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index cd37d3676..113919fc1 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -49,14 +49,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
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, [this, device] { - openConfiguration(device->id()); - }); + QString deviceId = device->id(); + auto openSettings = [this, deviceId] { + openConfiguration(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 6d41d927f..cb447a43f 100644 --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -221,6 +221,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 706f106ba..08ea0812b 100644 --- a/kcm/kcm.ui +++ b/kcm/kcm.ui @@ -6,7 +6,7 @@ 0 0 - 965 + 1198 528 @@ -143,34 +143,85 @@ QLayout::SetMaximumSize - - - - 10 - 75 - true - - - - Device - - - Qt::PlainText - - - - - - - - 0 - 0 - - - - (status) - - + + + + + + 0 + 0 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 10 + 75 + true + + + + Device + + + Qt::PlainText + + + + + + + + 0 + 0 + + + + (status) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 🔑 abababab + + + +