[SCM] kdeconnect packaging branch, master, updated. debian/0.9g-1-1183-g9d69498

Maximiliano Curia maxy at moszumanska.debian.org
Fri Oct 14 14:28:52 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/kdeconnect.git;a=commitdiff;h=6acb420

The following commit has been merged in the master branch:
commit 6acb4204a20ab4426a1cab3eeed898734e543048
Author: Vineet Garg <grgvineet at gmail.com>
Date:   Wed Aug 12 23:42:27 2015 +0530

    Added KdeConnectConfigTest, TestSslSocketLineReader, LanLinkProviderTest
---
 core/device.cpp                   |   1 -
 core/kdeconnectconfig.cpp         |   3 +-
 tests/CMakeLists.txt              |  33 ++++
 tests/kdeconnectconfigtest.cpp    |  99 +++++++++++
 tests/lanlinkprovidertest.cpp     | 356 ++++++++++++++++++++++++++++++++++++++
 tests/testsslsocketlinereader.cpp | 310 +++++++++++++++++++++++++++++++++
 6 files changed, 799 insertions(+), 3 deletions(-)

diff --git a/core/device.cpp b/core/device.cpp
index 76d2182..8681952 100644
--- a/core/device.cpp
+++ b/core/device.cpp
@@ -370,7 +370,6 @@ void Device::rejectPairing()
 
     m_pairStatus = Device::NotPaired;
 
-    qDebug(KDECONNECT_CORE) << "Pairing handler count " << m_pairingHandlers.size();
     Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
             ph->rejectPairing();
     }
diff --git a/core/kdeconnectconfig.cpp b/core/kdeconnectconfig.cpp
index d0e2768..c4d9509 100644
--- a/core/kdeconnectconfig.cpp
+++ b/core/kdeconnectconfig.cpp
@@ -121,7 +121,7 @@ KdeConnectConfig::KdeConnectConfig()
         QDateTime startTime = QDateTime::currentDateTime();
         QDateTime endTime = startTime.addYears(10);
         QCA::CertificateInfo certificateInfo;
-        certificateInfo.insert(QCA::CommonName,d->config->value("id", "unknown id").toString());
+        certificateInfo.insert(QCA::CommonName,deviceId());
         certificateInfo.insert(QCA::Organization,"KDE");
         certificateInfo.insert(QCA::OrganizationalUnit,"Kde connect");
         certificateOptions.setFormat(QCA::PKCS10);
@@ -131,7 +131,6 @@ KdeConnectConfig::KdeConnectConfig()
         certificateOptions.setValidityPeriod(startTime, endTime);
         certificateOptions.setFormat(QCA::PKCS10);
 
-//        d->certificate = QCA::Certificate(certificateOptions, d->privateKey);
         d->certificate = QSslCertificate(QCA::Certificate(certificateOptions, d->privateKey).toPEM().toLatin1());
 
         if (!cert.open(QIODevice::ReadWrite | QIODevice::Truncate))  {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 94fdc60..ba25567 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -7,7 +7,9 @@ include_directories(
 
 set(kdeconnect_libraries
     kdeconnectcore
+    KF5::I18n
     KF5::KIOWidgets
+    Qt5::DBus
     Qt5::Network
     Qt5::Test
     qca-qt5
@@ -15,3 +17,34 @@ set(kdeconnect_libraries
 
 ecm_add_test(networkpackagetests.cpp LINK_LIBRARIES ${kdeconnect_libraries})
 ecm_add_test(testsocketlinereader.cpp ../core/backends/lan/socketlinereader.cpp ../core/backends/lan/server.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries})
+
+set(testsslsocketlinereader_sources
+    ../core/backends/lan/server.cpp
+    ../core/backends/lan/socketlinereader.cpp
+)
+ecm_add_test(testsslsocketlinereader.cpp ${testsslsocketlinereader_sources} TEST_NAME testsslsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries})
+
+set(kdeconnectconfigtest_sources
+    ../core/backends/pairinghandler.cpp
+    ../core/dbushelper.cpp
+    ../core/device.cpp
+    ../core/pluginloader.cpp
+)
+ecm_add_test(kdeconnectconfigtest.cpp ${kdeconnectconfigtest_sources} TEST_NAME kdeconnectconfgtest LINK_LIBRARIES ${kdeconnect_libraries})
+
+set(lanlinkprovidertest_sources
+    ../core/core_debug.h
+    ../core/backends/devicelink.cpp
+    ../core/backends/lan/downloadjob.cpp
+    ../core/backends/lan/landevicelink.cpp
+    ../core/backends/lan/lanlinkprovider.cpp
+    ../core/backends/lan/lanpairinghandler.cpp
+    ../core/backends/lan/server.cpp
+    ../core/backends/lan/socketlinereader.cpp
+    ../core/backends/lan/uploadjob.cpp
+    ../core/backends/linkprovider.cpp
+    ../core/backends/pairinghandler.cpp
+    ../core/device.cpp
+    ../core/pluginloader.cpp
+)
+ecm_add_test(lanlinkprovidertest.cpp  ${lanlinkprovidertest_sources}  TEST_NAME lanlinkprovidertest LINK_LIBRARIES ${kdeconnect_libraries})
diff --git a/tests/kdeconnectconfigtest.cpp b/tests/kdeconnectconfigtest.cpp
new file mode 100644
index 0000000..b928f1a
--- /dev/null
+++ b/tests/kdeconnectconfigtest.cpp
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2015 Vineet Garg <grgvineet at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+
+#include "../core/kdeconnectconfig.h"
+
+#include <QtTest>
+
+/*
+ * This class tests the working of kdeconnect config that certificate and key is generated and saved properly
+ */
+class KdeConnectConfigTest : public QObject
+{
+Q_OBJECT
+
+private Q_SLOTS:
+    void initTestCase();
+    void addTrustedDevice();
+
+    void remoteCertificateTest();
+
+    void removeTrustedDevice();
+
+private:
+    KdeConnectConfig* kcc;
+};
+
+void KdeConnectConfigTest::initTestCase()
+{
+    kcc = KdeConnectConfig::instance();
+
+    QVERIFY2(!kcc->publicKey().isNull(), "Public key not generated, is null");
+    QVERIFY2(!kcc->privateKey().isNull(), "Private key not generated, is null");
+    QVERIFY2(!kcc->certificate().isNull(), "Certificate not generated, is null");
+    QVERIFY2(QFile::exists(kcc->privateKeyPath()), "Private key file does not exists, private key not saved properly");
+    QVERIFY2(QFile::exists(kcc->certificatePath()), "Certificate file does not exists, certificate not saved properly");
+
+}
+
+void KdeConnectConfigTest::addTrustedDevice()
+{
+    kcc->addTrustedDevice("testdevice", "Test Device", "phone");
+    KdeConnectConfig::DeviceInfo devInfo = kcc->getTrustedDevice("testdevice");
+    QCOMPARE(devInfo.deviceName, QString("Test Device"));
+    QCOMPARE(devInfo.deviceType, QString("phone"));
+}
+
+// This checks whether certificate is generated correctly and stored correctly or not
+void KdeConnectConfigTest::remoteCertificateTest()
+{
+    QSslCertificate certificate = kcc->certificate(); // Using same certificate as of device
+
+    QCOMPARE(certificate.serialNumber().toInt(0,16), 10);
+    QCOMPARE(certificate.subjectInfo(QSslCertificate::SubjectInfo::CommonName).first(), kcc->deviceId());
+    QCOMPARE(certificate.subjectInfo(QSslCertificate::SubjectInfo::Organization).first(), QString("KDE"));
+    QCOMPARE(certificate.subjectInfo(QSslCertificate::OrganizationalUnitName).first(), QString("Kde connect"));
+
+    kcc->setDeviceProperty("testdevice","certificate", QString::fromLatin1(certificate.toPem()));
+
+    KdeConnectConfig::DeviceInfo devInfo = kcc->getTrustedDevice("testdevice");
+    QSslCertificate devCertificate = QSslCertificate::fromData(devInfo.certificate.toLatin1()).first();
+
+    QCOMPARE(devCertificate.serialNumber().toInt(0,16), 10);
+    QCOMPARE(devCertificate.subjectInfo(QSslCertificate::SubjectInfo::CommonName).first(), kcc->deviceId());
+    QCOMPARE(devCertificate.subjectInfo(QSslCertificate::SubjectInfo::Organization).first(), QString("KDE"));
+    QCOMPARE(devCertificate.subjectInfo(QSslCertificate::OrganizationalUnitName).first(), QString("Kde connect"));
+
+}
+
+
+void KdeConnectConfigTest::removeTrustedDevice()
+{
+    kcc->removeTrustedDevice("testdevice");
+    KdeConnectConfig::DeviceInfo devInfo = kcc->getTrustedDevice("testdevice");
+    QCOMPARE(devInfo.deviceName, QString("unnamed"));
+    QCOMPARE(devInfo.deviceType, QString("unknown"));
+}
+
+QTEST_GUILESS_MAIN(KdeConnectConfigTest)
+
+#include "kdeconnectconfigtest.moc"
diff --git a/tests/lanlinkprovidertest.cpp b/tests/lanlinkprovidertest.cpp
new file mode 100644
index 0000000..2849513
--- /dev/null
+++ b/tests/lanlinkprovidertest.cpp
@@ -0,0 +1,356 @@
+/**
+ * Copyright 2015 Vineet Garg <grgvineet at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This class tests the behaviour of the class LanLinkProvider, be sure to kill process kdeconnectd to avoid any port binding issues
+
+
+#include "../core/backends/lan/lanlinkprovider.h"
+#include "../core/backends/lan/server.h"
+#include "../core/backends/lan/socketlinereader.h"
+#include "../core/kdeconnectconfig.h"
+
+#include <QAbstractSocket>
+#include <QSslSocket>
+#include <QtTest>
+#include <QUdpSocket>
+
+/*
+ * This class tests the working of LanLinkProvider under different conditions that when identity package is received over TCP, over UDP and same when the device is paired.
+ * It depends on KdeConnectConfig since LanLinkProvider internally uses it.
+ */
+class LanLinkProviderTest : public QObject
+{
+    Q_OBJECT
+public Q_SLOTS:
+    void initTestCase();
+
+private Q_SLOTS:
+
+    void pairedDeviceTcpPackageReceived();
+    void pairedDeviceUdpPackageReceived();
+
+    void unpairedDeviceTcpPackageReceived();
+    void unpairedDeviceUdpPackageReceived();
+
+
+private:
+    const int PORT = 8520;
+    // Add some private fields here
+    LanLinkProvider mLanLinkProvider;
+    QEventLoop mLoop;
+    Server* mServer;
+    SocketLineReader* mReader;
+    QUdpSocket* mUdpSocket;
+    QString mIdentityPackage;
+
+    // Attributes for test device
+    QString deviceId;
+    QString name;
+    QCA::PrivateKey privateKey;
+    QSslCertificate certificate;
+
+    QSslCertificate generateCertificate(QString&, QCA::PrivateKey&);
+    void addTrustedDevice();
+    void removeTrustedDevice();
+    void setSocketAttributes(QSslSocket *socket);
+    void testIdentityPackage(QByteArray& identityPackage);
+    
+};
+
+void LanLinkProviderTest::initTestCase()
+{
+    removeTrustedDevice(); // Remove trusted device if left by chance by any test
+
+    deviceId = QString("testdevice");
+    name = QString("Test Device");
+    privateKey = QCA::KeyGenerator().createRSA(2048);
+    certificate = generateCertificate(deviceId, privateKey);
+
+    mLanLinkProvider.onStart();
+
+    mIdentityPackage = QString("{\"id\":1439365924847,\"type\":\"kdeconnect.identity\",\"body\":{\"deviceId\":\"testdevice\",\"deviceName\":\"Test Device\",\"protocolVersion\":6,\"deviceType\":\"phone\",\"tcpPort\":") + QString::number(PORT) + QString("}}");
+}
+
+void LanLinkProviderTest::pairedDeviceTcpPackageReceived()
+{
+    KdeConnectConfig* kcc = KdeConnectConfig::instance();
+    addTrustedDevice();
+
+    QUdpSocket* mUdpServer = new QUdpSocket;
+    mUdpServer->bind(QHostAddress::Any, 1714, QUdpSocket::ShareAddress);
+
+    connect(mUdpServer, SIGNAL(readyRead()), &mLoop, SLOT(quit()));
+    mLanLinkProvider.onNetworkChange();
+    mLoop.exec();
+    disconnect(mUdpServer, SIGNAL(readyRead()), &mLoop, SLOT(quit())); // This avoids strange behaviour of mLoop due to incoming udp package
+
+    QByteArray datagram;
+    datagram.resize(mUdpServer->pendingDatagramSize());
+    QHostAddress sender;
+
+    mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender);
+
+    testIdentityPackage(datagram);
+
+    QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram);
+    QJsonObject body = jsonDocument.object().value("body").toObject();
+    int tcpPort = body.value("tcpPort").toInt();
+
+    QSslSocket socket;
+    connect(&socket, SIGNAL(connected()), &mLoop, SLOT(quit()));
+    connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &mLoop, SLOT(quit()));
+
+    socket.connectToHost(sender, tcpPort);
+    mLoop.exec();
+
+    QVERIFY2(socket.isOpen(), "Socket disconnected immediately");
+
+    socket.write(mIdentityPackage.toLatin1());
+    socket.waitForBytesWritten(2000);
+
+    connect(&socket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    connect(&socket, SIGNAL(sslErrors(const QList<QSslError>&)), &mLoop, SLOT(quit()));
+
+    setSocketAttributes(&socket);
+    socket.addCaCertificate(kcc->certificate());
+    socket.setPeerVerifyMode(QSslSocket::VerifyPeer);
+    socket.setPeerVerifyName(kcc->name());
+
+    socket.startServerEncryption();
+    mLoop.exec();
+
+    QCOMPARE(socket.sslErrors().size(), 0);
+    QVERIFY2(socket.isValid(), "Server socket disconnected");
+    QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted");
+    QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null");
+
+    removeTrustedDevice();
+    delete mUdpServer;
+}
+
+void LanLinkProviderTest::pairedDeviceUdpPackageReceived()
+{
+    KdeConnectConfig* kcc = KdeConnectConfig::instance();
+    addTrustedDevice();
+
+    mServer = new Server(this);
+    mUdpSocket = new QUdpSocket(this);
+
+    mServer->listen(QHostAddress::Any, PORT);
+
+    connect(mServer, SIGNAL(newConnection()), &mLoop, SLOT(quit()));
+
+    qint64 bytesWritten = mUdpSocket->writeDatagram(mIdentityPackage.toLatin1(), QHostAddress::LocalHost, 1714); // write an identity package to udp socket here, we do not broadcast it here
+    QCOMPARE(bytesWritten, mIdentityPackage.size());
+
+    // We should have an incoming connection now, wait for incoming connection
+    mLoop.exec();
+
+    QSslSocket* serverSocket = mServer->nextPendingConnection();
+
+    QVERIFY2(serverSocket != 0, "Server socket is null");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+
+    mReader = new SocketLineReader(serverSocket, this);
+    connect(mReader, SIGNAL(readyRead()), &mLoop, SLOT(quit()));
+    mLoop.exec();
+
+    QByteArray receivedPackage = mReader->readLine();
+    testIdentityPackage(receivedPackage);
+    // Received identiy package from LanLinkProvider now start ssl
+
+    connect(serverSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError>&)), &mLoop, SLOT(quit()));
+
+    setSocketAttributes(serverSocket);
+    serverSocket->addCaCertificate(kcc->certificate());
+    serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+    serverSocket->setPeerVerifyName(kcc->deviceId());
+
+
+    serverSocket->startClientEncryption(); // Its TCP server. but SSL client
+    mLoop.exec();
+
+    QCOMPARE(serverSocket->sslErrors().size(), 0);
+    QVERIFY2(serverSocket->isValid(), "Server socket disconnected");
+    QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted");
+    QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null");
+
+    removeTrustedDevice();
+
+    delete mServer;
+    delete mUdpSocket;
+}
+
+void LanLinkProviderTest::unpairedDeviceTcpPackageReceived()
+{
+    QUdpSocket* mUdpServer = new QUdpSocket;
+    mUdpServer->bind(QHostAddress::Any, 1714, QUdpSocket::ShareAddress);
+
+    connect(mUdpServer, SIGNAL(readyRead()), &mLoop, SLOT(quit()));
+    mLanLinkProvider.onNetworkChange();
+    mLoop.exec();
+    disconnect(mUdpServer, SIGNAL(readyRead()), &mLoop, SLOT(quit()));
+
+    QByteArray datagram;
+    datagram.resize(mUdpServer->pendingDatagramSize());
+    QHostAddress sender;
+
+    mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender);
+
+    testIdentityPackage(datagram);
+
+    QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram);
+    QJsonObject body = jsonDocument.object().value("body").toObject();
+    int tcpPort = body.value("tcpPort").toInt();
+
+    QSslSocket socket;
+    connect(&socket, SIGNAL(connected()), &mLoop, SLOT(quit()));
+    connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &mLoop, SLOT(quit()));
+
+    socket.connectToHost(sender, tcpPort);
+    mLoop.exec();
+
+    QVERIFY2(socket.isOpen(), "Socket disconnected immediately");
+
+    socket.write(mIdentityPackage.toLatin1());
+    socket.waitForBytesWritten(2000);
+
+    connect(&socket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    // We don't take care for sslErrors signal here, but signal will emit still we will get successful connection
+
+    setSocketAttributes(&socket);
+    socket.setPeerVerifyMode(QSslSocket::QueryPeer);
+
+    socket.startServerEncryption();
+
+    mLoop.exec();
+
+    QVERIFY2(socket.isValid(), "Server socket disconnected");
+    QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted");
+    QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null");
+
+    delete mUdpServer;
+}
+
+void LanLinkProviderTest::unpairedDeviceUdpPackageReceived()
+{
+    mServer = new Server(this);
+    mUdpSocket = new QUdpSocket(this);
+
+    mServer->listen(QHostAddress::Any, PORT);
+
+    connect(mServer, SIGNAL(newConnection()), &mLoop, SLOT(quit()));
+
+    qint64 bytesWritten = mUdpSocket->writeDatagram(mIdentityPackage.toLatin1(), QHostAddress::LocalHost, 1714); // write an identity package to udp socket here, we do not broadcast it here
+    QCOMPARE(bytesWritten, mIdentityPackage.size());
+
+    // We should have an incoming connection now, wait for incoming connection
+    mLoop.exec();
+
+    QSslSocket* serverSocket = mServer->nextPendingConnection();
+
+    QVERIFY2(serverSocket != 0, "Server socket is null");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+
+    mReader = new SocketLineReader(serverSocket, this);
+    connect(mReader, SIGNAL(readyRead()), &mLoop, SLOT(quit()));
+    mLoop.exec();
+
+    QByteArray receivedPackage = mReader->readLine();
+    QVERIFY2(!receivedPackage.isEmpty(), "Empty package received");
+
+    testIdentityPackage(receivedPackage);
+
+    // Received identity package from LanLinkProvider now start ssl
+
+    connect(serverSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    connect(serverSocket, SIGNAL(disconnected()), &mLoop, SLOT(quit()));
+
+    setSocketAttributes(serverSocket);
+    serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer);
+    serverSocket->startClientEncryption(); // Its TCP server. but SSL client
+    mLoop.exec();
+
+    QVERIFY2(serverSocket->isValid(), "Server socket disconnected");
+    QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted");
+    QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null");
+
+    delete mServer;
+    delete mUdpSocket;
+}
+
+void LanLinkProviderTest::testIdentityPackage(QByteArray &identityPackage)
+{
+    QJsonDocument jsonDocument = QJsonDocument::fromJson(identityPackage);
+    QJsonObject jsonObject = jsonDocument.object();
+    QJsonObject body = jsonObject.value("body").toObject();
+
+    QCOMPARE(jsonObject.value("type").toString(), QString("kdeconnect.identity"));
+    QVERIFY2(body.contains("deviceName"), "Device name not found in identity package");
+    QVERIFY2(body.contains("deviceId"), "Device id not found in identity package");
+    QVERIFY2(body.contains("protocolVersion"), "Protocol version not found in identity package");
+    QVERIFY2(body.contains("deviceType"), "Device type not found in identity package");
+}
+
+QSslCertificate LanLinkProviderTest::generateCertificate(QString& commonName, QCA::PrivateKey& privateKey)
+{
+    QDateTime startTime = QDateTime::currentDateTime();
+    QDateTime endTime = startTime.addYears(10);
+    QCA::CertificateInfo certificateInfo;
+    certificateInfo.insert(QCA::CommonName,commonName);
+    certificateInfo.insert(QCA::Organization,"KDE");
+    certificateInfo.insert(QCA::OrganizationalUnit,"Kde connect");
+
+    QCA::CertificateOptions certificateOptions(QCA::PKCS10);
+    certificateOptions.setSerialNumber(10);
+    certificateOptions.setInfo(certificateInfo);
+    certificateOptions.setValidityPeriod(startTime, endTime);
+    certificateOptions.setFormat(QCA::PKCS10);
+
+    QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privateKey).toPEM().toLatin1());
+    return certificate;
+}
+
+void LanLinkProviderTest::setSocketAttributes(QSslSocket *socket) {
+
+    socket->setPrivateKey(QSslKey(privateKey.toPEM().toLatin1(), QSsl::Rsa));
+    socket->setLocalCertificate(certificate);
+
+}
+
+void LanLinkProviderTest::addTrustedDevice()
+{
+    KdeConnectConfig *kcc = KdeConnectConfig::instance();
+    kcc->addTrustedDevice(deviceId, name, QString("phone"));
+    kcc->setDeviceProperty(deviceId, QString("certificate"), QString::fromLatin1(certificate.toPem()));
+    kcc->setDeviceProperty(deviceId, QString("publicKey"), privateKey.toPublicKey().toPEM());
+}
+
+void LanLinkProviderTest::removeTrustedDevice()
+{
+    KdeConnectConfig *kcc = KdeConnectConfig::instance();
+    kcc->removeTrustedDevice(deviceId);
+}
+
+
+QTEST_GUILESS_MAIN(LanLinkProviderTest)
+
+#include "lanlinkprovidertest.moc"
diff --git a/tests/testsslsocketlinereader.cpp b/tests/testsslsocketlinereader.cpp
new file mode 100644
index 0000000..64599a8
--- /dev/null
+++ b/tests/testsslsocketlinereader.cpp
@@ -0,0 +1,310 @@
+/**
+ * Copyright 2015 Vineet Garg <albertvaka at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../core/backends/lan/server.h"
+#include "../core/backends/lan/socketlinereader.h"
+
+#include <QSslKey>
+#include <QtCrypto>
+#include <QTest>
+#include <QTimer>
+
+/*
+ * This class tests the behaviour of socket line reader when the connection if over ssl. Since SSL takes part below application layer,
+ * working of SocketLineReader should be same.
+ */
+class TestSslSocketLineReader : public QObject
+{
+    Q_OBJECT
+public Q_SLOTS:
+    void newPackage();
+
+private Q_SLOTS:
+
+    void initTestCase();
+    void init();
+    void cleanup();
+    void cleanupTestCase();
+
+    void testTrustedDevice();
+    void testUntrustedDevice();
+    void testTrustedDeviceWithWrongCertificate();
+
+
+private:
+    const int PORT = 7894;
+    QTimer mTimer;
+    QCA::Initializer mQcaInitializer;
+    QEventLoop mLoop;
+    QList<QByteArray> mPackages;
+    Server *mServer;
+    QSslSocket *mClientSocket;
+    SocketLineReader *mReader;
+
+private:
+    void setSocketAttributes(QSslSocket* socket, QString deviceName);
+};
+
+void TestSslSocketLineReader::initTestCase()
+{
+    mServer = new Server(this);
+
+    QVERIFY2(mServer->listen(QHostAddress::LocalHost, PORT), "Failed to create local tcp server");
+
+    mTimer.setInterval(10 * 1000);//Ten second is more enough for this test, just used this so that to break mLoop if stuck
+    mTimer.setSingleShot(true);
+    connect(&mTimer, SIGNAL(timeout()), &mLoop, SLOT(quit()));
+
+    mTimer.start();
+}
+
+void TestSslSocketLineReader::init()
+{
+    mClientSocket = new QSslSocket(this);
+    mClientSocket->connectToHost(QHostAddress::LocalHost, PORT);
+    connect(mClientSocket, SIGNAL(connected()), &mLoop, SLOT(quit()));
+
+    mLoop.exec();
+
+    QVERIFY2(mClientSocket->isOpen(), "Could not connect to local tcp server");
+}
+
+void TestSslSocketLineReader::cleanup()
+{
+    mClientSocket->disconnectFromHost();
+    delete mClientSocket;
+}
+
+void TestSslSocketLineReader::cleanupTestCase()
+{
+    delete mServer;
+}
+
+void TestSslSocketLineReader::testTrustedDevice()
+{
+
+    int maxAttemps = 5;
+    QCOMPARE(true, mServer->hasPendingConnections());
+    while(!mServer->hasPendingConnections() && maxAttemps > 0) {
+        --maxAttemps;
+        QTest::qSleep(1000);
+    }
+
+    QSslSocket *serverSocket = mServer->nextPendingConnection();
+
+    QVERIFY2(serverSocket != 0, "Null socket returned by server");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+
+    setSocketAttributes(serverSocket, QString("Test Server"));
+    setSocketAttributes(mClientSocket, QString("Test Client"));
+
+    serverSocket->setPeerVerifyName("Test Client");
+    serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+    serverSocket->addCaCertificate(mClientSocket->localCertificate());
+
+    mClientSocket->setPeerVerifyName("Test Server");
+    mClientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+    mClientSocket->addCaCertificate(serverSocket->localCertificate());
+
+    connect(mClientSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    serverSocket->startServerEncryption();
+    mClientSocket->startClientEncryption();
+    mLoop.exec();
+
+    // Both client and server socket should be encrypted here and should have remote certificate because VerifyPeer is used
+    QVERIFY2(mClientSocket->isOpen(), "Client socket already closed");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+    QVERIFY2(mClientSocket->isEncrypted(), "Client is not encrypted");
+    QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted");
+    QVERIFY2(!mClientSocket->peerCertificate().isNull(), "Server certificate not received");
+    QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received");
+
+    QList<QByteArray> dataToSend;
+    dataToSend << "foobar
" << "barfoo
" << "foobar?
" << "
" << "barfoo!
" << "panda
";
+    Q_FOREACH(const QByteArray &line, dataToSend) {
+        mClientSocket->write(line);
+    }
+    mClientSocket->flush();
+
+    mPackages.clear();
+
+    mReader = new SocketLineReader(serverSocket, this);
+    connect(mReader, SIGNAL(readyRead()), this,SLOT(newPackage()));
+    mLoop.exec();
+
+    /* remove the empty line before compare */
+    dataToSend.removeOne("
");
+
+    QCOMPARE(mPackages.count(), 5);//We expect 5 Packages
+    for(int x = 0;x < 5; ++x) {
+        QCOMPARE(mPackages[x], dataToSend[x]);
+    }
+
+    delete mReader;
+}
+
+void TestSslSocketLineReader::testUntrustedDevice()
+{
+    int maxAttemps = 5;
+    QCOMPARE(true, mServer->hasPendingConnections());
+    while(!mServer->hasPendingConnections() && maxAttemps > 0) {
+        --maxAttemps;
+        QTest::qSleep(1000);
+    }
+
+    QSslSocket *serverSocket = mServer->nextPendingConnection();
+
+    QVERIFY2(serverSocket != 0, "Null socket returned by server");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+
+    setSocketAttributes(serverSocket, QString("Test Server"));
+    setSocketAttributes(mClientSocket, QString("Test Client"));
+
+    serverSocket->setPeerVerifyName("Test Client");
+    serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer);
+
+    mClientSocket->setPeerVerifyName("Test Server");
+    mClientSocket->setPeerVerifyMode(QSslSocket::QueryPeer);
+
+    connect(mClientSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit()));
+    serverSocket->startServerEncryption();
+    mClientSocket->startClientEncryption();
+    mLoop.exec();
+
+    QVERIFY2(mClientSocket->isOpen(), "Client socket already closed");
+    QVERIFY2(serverSocket->isOpen(), "Server socket already closed");
+    QVERIFY2(mClientSocket->isEncrypted(), "Client is not encrypted");
+    QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted");
+    QVERIFY2(!mClientSocket->peerCertificate().isNull(), "Server certificate not received");
+    QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received");
+
+    QList<QByteArray> dataToSend;
+    dataToSend << "foobar
" << "barfoo
" << "foobar?
" << "
" << "barfoo!
" << "panda
";
+    Q_FOREACH(const QByteArray &line, dataToSend) {
+            mClientSocket->write(line);
+        }
+    mClientSocket->flush();
+
+    mPackages.clear();
+
+    mReader = new SocketLineReader(serverSocket, this);
+    connect(mReader, SIGNAL(readyRead()), SLOT(newPackage()));
+    mLoop.exec();
+
+    /* remove the empty line before compare */
+    dataToSend.removeOne("
");
+
+    QCOMPARE(mPackages.count(), 5);//We expect 5 Packages
+    for(int x = 0;x < 5; ++x) {
+        QCOMPARE(mPackages[x], dataToSend[x]);
+    }
+
+    delete mReader;
+}
+
+void TestSslSocketLineReader::testTrustedDeviceWithWrongCertificate()
+{
+    int maxAttemps = 5;
+    while(!mServer->hasPendingConnections() && maxAttemps > 0) {
+        --maxAttemps;
+        QTest::qSleep(1000);
+    }
+
+    QSslSocket *serverSocket = mServer->nextPendingConnection();
+
+    QVERIFY2(serverSocket != 0, "Could not open a connection to the client");
+
+    setSocketAttributes(serverSocket, QString("Test Server"));
+    setSocketAttributes(mClientSocket, QString("Test Client"));
+
+    // Not adding other device certificate to list of CA certificate, and using VerifyPeer. This should lead to handshake failure
+    serverSocket->setPeerVerifyName("Test Client");
+    serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+
+    mClientSocket->setPeerVerifyName("Test Server");
+    mClientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+
+    connect(serverSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit())); // Encrypted signal should never be emitted
+    connect(mClientSocket, SIGNAL(encrypted()), &mLoop, SLOT(quit())); // Encrypted signal should never be emitted
+    connect(serverSocket, SIGNAL(disconnected()), &mLoop, SLOT(quit()));
+    connect(mClientSocket, SIGNAL(disconnected()), &mLoop, SLOT(quit()));
+
+    serverSocket->startServerEncryption();
+    mClientSocket->startClientEncryption();
+    mLoop.exec();
+
+    QVERIFY2(!serverSocket->isEncrypted(), "Server is encrypted, it should not");
+    QVERIFY2(!mClientSocket->isEncrypted(), "lient is encrypted, it should now");
+
+    if (serverSocket->state() != QAbstractSocket::UnconnectedState) mLoop.exec(); // Wait until serverSocket is disconnected, It should be in disconnected state
+    if (mClientSocket->state() != QAbstractSocket::UnconnectedState) mLoop.exec(); // Wait until mClientSocket is disconnected, It should be in disconnected state
+
+    QCOMPARE((int)mClientSocket->state(), 0);
+    QCOMPARE((int)serverSocket->state(), 0);
+
+}
+
+void TestSslSocketLineReader::newPackage()
+{
+    if (!mReader->bytesAvailable()) {
+        return;
+    }
+
+    int maxLoops = 5;
+    while(mReader->bytesAvailable() > 0 && maxLoops > 0) {
+        --maxLoops;
+        const QByteArray package = mReader->readLine();
+        if (!package.isEmpty()) {
+            mPackages.append(package);
+        }
+
+        if (mPackages.count() == 5) {
+            mLoop.exit();
+        }
+    }
+}
+
+void TestSslSocketLineReader::setSocketAttributes(QSslSocket *socket, QString deviceName) {
+
+    QDateTime startTime = QDateTime::currentDateTime();
+    QDateTime endTime = startTime.addYears(10);
+    QCA::CertificateInfo certificateInfo;
+    certificateInfo.insert(QCA::CommonName,deviceName);
+    certificateInfo.insert(QCA::Organization,"KDE");
+    certificateInfo.insert(QCA::OrganizationalUnit,"Kde connect");
+
+    QCA::CertificateOptions certificateOptions(QCA::PKCS10);
+    certificateOptions.setSerialNumber(10);
+    certificateOptions.setInfo(certificateInfo);
+    certificateOptions.setValidityPeriod(startTime, endTime);
+    certificateOptions.setFormat(QCA::PKCS10);
+
+    QCA::PrivateKey privKey = QCA::KeyGenerator().createRSA(2048);
+    QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privKey).toPEM().toLatin1());
+
+    socket->setPrivateKey(QSslKey(privKey.toPEM().toLatin1(), QSsl::Rsa));
+    socket->setLocalCertificate(certificate);
+
+}
+
+QTEST_GUILESS_MAIN(TestSslSocketLineReader)
+
+#include "testsslsocketlinereader.moc"
+

-- 
kdeconnect packaging



More information about the pkg-kde-commits mailing list