From 03926cc3bfce04b3acc7a582abd8d2264f21cff2 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Wed, 2 Dec 2015 11:04:35 -0800 Subject: [PATCH] WIPx4 --- core/backends/devicelink.h | 4 +- core/backends/lan/landevicelink.cpp | 47 ++++++++++++--------- core/backends/lan/landevicelink.h | 5 ++- core/backends/lan/lanlinkprovider.cpp | 29 ++++++++----- core/backends/lan/lanlinkprovider.h | 3 +- core/backends/lan/lanpairinghandler.cpp | 8 ++-- core/backends/lan/server.cpp | 2 + core/backends/loopback/loopbackdevicelink.h | 4 +- core/daemon.h | 2 +- core/device.cpp | 21 ++++----- daemon/kdeconnectd.cpp | 2 +- 11 files changed, 74 insertions(+), 53 deletions(-) diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index 1de418591..b9de66ad7 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -52,8 +52,8 @@ public: virtual bool sendPackageEncrypted(NetworkPackage& np) = 0; //user actions - virtual void requestPairing() = 0; - virtual void unpair() = 0; + virtual void userRequestsPair() = 0; + virtual void userRequestsUnpair() = 0; ConnectionStarted connectionSource() const { return mConnectionSource; } diff --git a/core/backends/lan/landevicelink.cpp b/core/backends/lan/landevicelink.cpp index 2d3470d48..44f281763 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -35,7 +35,7 @@ LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSsl this, SLOT(dataReceived())); //We take ownership of the socket. - //When the link provider distroys us, + //When the link provider destroys us, //the socket (and the reader) will be //destroyed as well connect(socket, SIGNAL(disconnected()), @@ -57,7 +57,7 @@ bool LanDeviceLink::sendPackageEncrypted(NetworkPackage& np) int written = mSocketLineReader->write(np.serialize()); - //TODO: Actually detect if a package is received or not, now we keep TCP + //Actually we can't detect if a package is received or not. We keep TCP //"ESTABLISHED" connections that look legit (return true when we use them), //but that are actually broken (until keepalive detects that they are down). return (written != -1); @@ -86,33 +86,36 @@ UploadJob* LanDeviceLink::sendPayload(NetworkPackage& np) void LanDeviceLink::dataReceived() { - if (mSocketLineReader->bytesAvailable() == 0) return; - - const QByteArray package = mSocketLineReader->readLine(); - //qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << package; - NetworkPackage unserialized(QString::null); - NetworkPackage::unserialize(package, &unserialized); - if (unserialized.isEncrypted()) { - //mPrivateKey should always be set when device link is added to device, no null-checking done here - // TODO : Check this with old device since package through ssl in unencrypted - unserialized.decrypt(mPrivateKey, &unserialized); + const QByteArray serializedPackage = mSocketLineReader->readLine(); + NetworkPackage package(QString::null); + NetworkPackage::unserialize(serializedPackage, &package); + + if (package.type() == PACKAGE_TYPE_PAIR) { + //TODO: Handle pair/unpair requests and forward them (to the pairing handler?) + //qobject_cast(provider())->incomingPairRequest(deviceId()); } - if (unserialized.hasPayloadTransferInfo()) { + if (!package.isEncrypted()) { + qWarning() << "Received plain-text package from paired link, ignoring!"; + } + + package.decrypt(mPrivateKey, &package); + + if (package.hasPayloadTransferInfo()) { //qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo"; - QVariantMap transferInfo = unserialized.payloadTransferInfo(); + QVariantMap transferInfo = package.payloadTransferInfo(); //FIXME: The next two lines shouldn't be needed! Why are they here? transferInfo.insert("useSsl", true); transferInfo.insert("deviceId", deviceId()); DownloadJob* job = new DownloadJob(mSocketLineReader->peerAddress(), transferInfo); job->start(); - unserialized.setPayload(job->getPayload(), unserialized.payloadSize()); + package.setPayload(job->getPayload(), package.payloadSize()); } - Q_EMIT receivedPackage(unserialized); + Q_EMIT receivedPackage(package); if (mSocketLineReader->bytesAvailable() > 0) { QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection); @@ -120,12 +123,18 @@ void LanDeviceLink::dataReceived() } -void LanDeviceLink::requestPairing() +void LanDeviceLink::userRequestsPair() { - qobject_cast(provider())->requestPairing(deviceId()); + qobject_cast(provider())->userRequestsPair(deviceId()); } -void LanDeviceLink::unpair() +void LanDeviceLink::userRequestsUnpair() { setPairStatus(NotPaired); } + +void LanDeviceLink::storeTrustedDeviceInformation() +{ + Q_ASSERT(!m_certificate.isNull()); + Q_ASSERT(!m_publicKey.isNull()); +} diff --git a/core/backends/lan/landevicelink.h b/core/backends/lan/landevicelink.h index 5bc7a8f21..48c379eed 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -43,9 +43,10 @@ public: bool sendPackageEncrypted(NetworkPackage& np) override; UploadJob* sendPayload(NetworkPackage& np); - virtual void unpair() override; + virtual void userRequestsPair() override; + virtual void userRequestsUnpair() override; - void requestPairing(); + void storeTrustedDeviceInformation(); private Q_SLOTS: void dataReceived(); diff --git a/core/backends/lan/lanlinkprovider.cpp b/core/backends/lan/lanlinkprovider.cpp index 2ec250c0a..118ed9587 100644 --- a/core/backends/lan/lanlinkprovider.cpp +++ b/core/backends/lan/lanlinkprovider.cpp @@ -78,6 +78,8 @@ void LanLinkProvider::onStart() bool success = mUdpServer->bind(bindAddress, port, QUdpSocket::ShareAddress); Q_ASSERT(success); + qDebug() << "onStart"; + mTcpPort = port; while (!mServer->listen(bindAddress, mTcpPort)) { mTcpPort++; @@ -93,6 +95,7 @@ void LanLinkProvider::onStart() void LanLinkProvider::onStop() { + qDebug() << "onStop"; mUdpServer->close(); mServer->close(); } @@ -129,7 +132,9 @@ void LanLinkProvider::newUdpConnection() //udpBroadcastReceived NetworkPackage* receivedPackage = new NetworkPackage(""); bool success = NetworkPackage::unserialize(datagram, receivedPackage); - //qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ; + //qDebug() << "udp connection from " << receivedPackage->; + + qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ; if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) { delete receivedPackage; @@ -442,24 +447,28 @@ void LanLinkProvider::addLink(const QString& deviceId, QSslSocket* socket, Netwo mLinks.erase(oldLinkIterator); } - mLinks[deviceLink->deviceId()] = deviceLink; - LanPairingHandler* ph = mPairingHandlers.value(deviceLink->deviceId()); - if (ph) { - ph->setDeviceLink(deviceLink); - } - + mLinks[deviceId] = deviceLink; + refreshPairingHandler(deviceId); Q_EMIT onConnectionReceived(*receivedPackage, deviceLink); } -void LanLinkProvider::requestPairing(const QString& deviceId) +void LanLinkProvider::userRequestsPair(const QString& deviceId) { LanPairingHandler* ph = mPairingHandlers.value(deviceId); if (!ph) { - new LanPairingHandler(deviceId); - ph->setDeviceLink(mLinks[deviceId]); + ph = new LanPairingHandler(deviceId); mPairingHandlers[deviceId] = ph; + refreshPairingHandler(deviceId); } ph->requestPairing(); } + +void LanLinkProvider::refreshPairingHandler(const QString& deviceId) { + LanPairingHandler* ph = mPairingHandlers.value(deviceId); + if (ph) { + ph->setDeviceLink(mLinks[deviceId]); + + } +} diff --git a/core/backends/lan/lanlinkprovider.h b/core/backends/lan/lanlinkprovider.h index 28149e453..aff0d1976 100644 --- a/core/backends/lan/lanlinkprovider.h +++ b/core/backends/lan/lanlinkprovider.h @@ -44,7 +44,7 @@ public: QString name() override { return "LanLinkProvider"; } int priority() override { return PRIORITY_HIGH; } - void requestPairing(const QString &deviceId); + void userRequestsPair(const QString &deviceId); public Q_SLOTS: virtual void onNetworkChange() override; @@ -65,6 +65,7 @@ private: static void configureSocket(QSslSocket* socket); void onNetworkConfigurationChanged(const QNetworkConfiguration &config); void addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, DeviceLink::ConnectionStarted connectionOrigin); + void refreshPairingHandler(const QString &deviceId); Server* mServer; QUdpSocket* mUdpServer; diff --git a/core/backends/lan/lanpairinghandler.cpp b/core/backends/lan/lanpairinghandler.cpp index d28456ced..d531c4ec2 100644 --- a/core/backends/lan/lanpairinghandler.cpp +++ b/core/backends/lan/lanpairinghandler.cpp @@ -97,7 +97,7 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np) return; } - Daemon::instance()->requestPairing(this); + Daemon::instance()->askPairingConfirmation(this); setInternalPairStatus(RequestedByPeer); } @@ -117,10 +117,10 @@ bool LanPairingHandler::requestPairing() { switch (m_status) { case Paired: - Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Already paired").toLatin1().data())); + Q_EMIT pairingError(i18n("%1: Already paired", deviceLink()->name())); return false; case Requested: - Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Pairing already requested for this device").toLatin1().data())); + Q_EMIT pairingError(i18n("%1: Pairing already requested for this device", deviceLink()->name())); return false; case RequestedByPeer: qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request."; @@ -189,4 +189,6 @@ void LanPairingHandler::setInternalPairStatus(LanPairingHandler::InternalPairSta } else { deviceLink()->setPairStatus(DeviceLink::NotPaired); } + qobject_cast(deviceLink())->storeTrustedDeviceInformation(); + //TODO: Tell link to store certificate and key } diff --git a/core/backends/lan/server.cpp b/core/backends/lan/server.cpp index 4a80191a5..5992f8953 100644 --- a/core/backends/lan/server.cpp +++ b/core/backends/lan/server.cpp @@ -34,6 +34,7 @@ Server::Server(QObject * parent) } void Server::incomingConnection(qintptr socketDescriptor) { + qDebug() << "incomingConnection"; QSslSocket *serverSocket = new QSslSocket(parent()); if (serverSocket->setSocketDescriptor(socketDescriptor)) { pendingConnections.append(serverSocket); @@ -45,6 +46,7 @@ void Server::incomingConnection(qintptr socketDescriptor) { } QSslSocket* Server::nextPendingConnection() { + qDebug() << "nextPendingConnection (emtpy:" << pendingConnections.isEmpty() << ")"; if (pendingConnections.isEmpty()) { return Q_NULLPTR; } else { diff --git a/core/backends/loopback/loopbackdevicelink.h b/core/backends/loopback/loopbackdevicelink.h index b1e4e832f..3bba5782a 100644 --- a/core/backends/loopback/loopbackdevicelink.h +++ b/core/backends/loopback/loopbackdevicelink.h @@ -36,8 +36,8 @@ public: virtual bool sendPackage(NetworkPackage& np) override; virtual bool sendPackageEncrypted(NetworkPackage& np) override; - virtual void requestPairing() override {} - virtual void unpair() override {} + virtual void userRequestsPair() override { setPairStatus(Paired); } + virtual void userRequestsUnpair() override { setPairStatus(NotPaired); } }; #endif diff --git a/core/daemon.h b/core/daemon.h index 908c1e3c1..6cc43af23 100644 --- a/core/daemon.h +++ b/core/daemon.h @@ -53,7 +53,7 @@ public: QList devicesList() const; - virtual void requestPairing(PairingHandler *d) = 0; + virtual void askPairingConfirmation(PairingHandler *d) = 0; virtual void reportError(const QString &title, const QString &description) = 0; virtual QNetworkAccessManager* networkAccessManager(); diff --git a/core/device.cpp b/core/device.cpp index 95aed4850..b99ccefb0 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -195,14 +195,14 @@ void Device::requestPair() } Q_FOREACH(DeviceLink* dl, m_deviceLinks) { - dl->requestPairing(); + dl->userRequestsPair(); } } void Device::unpair() { Q_FOREACH(DeviceLink* dl, m_deviceLinks) { - dl->unpair(); + dl->userRequestsUnpair(); } KdeConnectConfig::instance()->removeTrustedDevice(id()); } @@ -214,7 +214,7 @@ void Device::pairStatusChanged(DeviceLink::PairStatus status) Q_FOREACH(DeviceLink* dl, m_deviceLinks) { if (dl != sender()) { - dl->unpair(); + dl->setPairStatus(DeviceLink::NotPaired); } } } else { @@ -294,15 +294,12 @@ void Device::removeLink(DeviceLink* link) bool Device::sendPackage(NetworkPackage& np) { - if (np.type() != PACKAGE_TYPE_PAIR && isTrusted()) { - Q_FOREACH(DeviceLink* dl, m_deviceLinks) { - if (dl->sendPackageEncrypted(np)) return true; - } - } else { - //Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data - Q_FOREACH(DeviceLink* dl, m_deviceLinks) { - if (dl->sendPackage(np)) return true; - } + Q_ASSERT(np.type() != PACKAGE_TYPE_PAIR); + Q_ASSERT(isTrusted()); + + //Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data + Q_FOREACH(DeviceLink* dl, m_deviceLinks) { + if (dl->sendPackage(np)) return true; } return false; diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index d612c40b4..6dc939bed 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -89,7 +89,7 @@ public: , m_nam(Q_NULLPTR) {} - void requestPairing(PairingHandler* d) Q_DECL_OVERRIDE + void askPairingConfirmation(PairingHandler* d) Q_DECL_OVERRIDE { KNotification* notification = new KNotification("pairingRequest"); notification->setIconName(QStringLiteral("dialog-information"));