From deeeb595b370ea95c24896dde655a5cbd42169ee Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sun, 1 Sep 2013 22:13:03 +0200 Subject: [PATCH] Implemented encryption in NetworkPackage using QCA2 Fixed some bugs in the pairing process state machine Keys are now stored in base64 in KConfig (was storing non-allowed chars) Updated NetworkPackage tests to include encryption Increased networkpackage version 1 -> 2 --- CMakeLists.txt | 2 +- daemon/CMakeLists.txt | 10 +-- daemon/daemon.cpp | 4 +- daemon/device.cpp | 89 +++++++++++-------- daemon/device.h | 9 +- daemon/devicelinks/devicelink.h | 6 +- daemon/devicelinks/landevicelink.cpp | 2 +- daemon/devicelinks/landevicelink.h | 2 +- daemon/devicelinks/loopbackdevicelink.cpp | 2 +- daemon/devicelinks/loopbackdevicelink.h | 9 +- daemon/linkproviders/linkprovider.h | 2 +- daemon/networkpackage.cpp | 52 +++++++---- daemon/networkpackage.h | 21 +++-- daemon/plugins/battery/CMakeLists.txt | 5 ++ daemon/plugins/clipboard/CMakeLists.txt | 5 ++ daemon/plugins/filetransfer/CMakeLists.txt | 5 ++ daemon/plugins/kdeconnectplugin.h | 4 + daemon/plugins/mpriscontrol/CMakeLists.txt | 5 ++ daemon/plugins/notifications/CMakeLists.txt | 5 ++ daemon/plugins/pausemusic/CMakeLists.txt | 5 ++ daemon/plugins/ping/CMakeLists.txt | 5 ++ daemon/plugins/telephony/CMakeLists.txt | 5 ++ test/CMakeLists.txt | 18 ---- tests/CMakeLists.txt | 25 ++++++ .../networkpackagetests.cpp | 53 ++++++++--- .../networkpackagetests.h | 9 +- 26 files changed, 240 insertions(+), 119 deletions(-) delete mode 100644 test/CMakeLists.txt create mode 100644 tests/CMakeLists.txt rename test/backendtests.cpp => tests/networkpackagetests.cpp (64%) rename test/backendtests.h => tests/networkpackagetests.h (87%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85de77dbc..11b350a67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,4 +18,4 @@ add_subdirectory(kcm) #add_subdirectory(kioslave) add_subdirectory(plasmoid) -add_subdirectory(test) +add_subdirectory(tests) diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 60c8ae7ce..8e6383477 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -1,3 +1,8 @@ +add_subdirectory(plugins) + +find_package (QJSON REQUIRED) +find_package (QCA2 REQUIRED) + include_directories( ${QJSON_INCLUDE_DIR} ${QCA2_INCLUDE_DIR} @@ -21,13 +26,8 @@ set(kded_kdeconnect_SRCS device.cpp ) -add_subdirectory(plugins) - kde4_add_plugin(kded_kdeconnect ${kded_kdeconnect_SRCS}) -find_package (QJSON REQUIRED) -find_package (QCA2 REQUIRED) - target_link_libraries(kded_kdeconnect ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} diff --git a/daemon/daemon.cpp b/daemon/daemon.cpp index 67e431379..29e3274bb 100644 --- a/daemon/daemon.cpp +++ b/daemon/daemon.cpp @@ -57,10 +57,10 @@ Daemon::Daemon(QObject *parent, const QList&) //http://delta.affinix.com/docs/qca/rsatest_8cpp-example.html QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(1024); - config->group("myself").writeEntry("privateKey", privateKey.toDER()); + config->group("myself").writeEntry("privateKey", privateKey.toDER().toByteArray().toBase64()); QCA::PublicKey publicKey = privateKey.toPublicKey(); - config->group("myself").writeEntry("publicKey", publicKey.toDER()); + config->group("myself").writeEntry("publicKey", publicKey.toDER().toBase64()); //TODO: Store key in a PEM file instead (KStandardDirs::locate("appdata", "private.pem")) } diff --git a/daemon/device.cpp b/daemon/device.cpp index d0a7cb4dc..7979ea647 100644 --- a/daemon/device.cpp +++ b/daemon/device.cpp @@ -30,7 +30,7 @@ Device::Device(const QString& id) m_deviceName = name; const QByteArray& key = data.readEntry("publicKey",QByteArray()); - m_publicKey = QCA::RSAPublicKey::fromDER(key); + m_publicKey = QCA::RSAPublicKey::fromDER(QByteArray::fromBase64(key)); m_pairStatus = Device::Paired; @@ -57,12 +57,12 @@ Device::~Device() } -bool Device::hasPlugin(const QString& name) +bool Device::hasPlugin(const QString& name) const { return m_plugins.contains(name); } -QStringList Device::loadedPlugins() +QStringList Device::loadedPlugins() const { return m_plugins.keys(); } @@ -94,8 +94,8 @@ void Device::reloadPlugins() } else { KdeConnectPlugin* plugin = loader->instantiatePluginForDevice(pluginName, this); - connect(this, SIGNAL(receivedPackage(const NetworkPackage&)), - plugin, SLOT(receivePackage(const NetworkPackage&))); + connect(this, SIGNAL(receivedPackage(NetworkPackage)), + plugin, SLOT(receivePackage(NetworkPackage))); newPluginMap[pluginName] = plugin; } @@ -118,25 +118,16 @@ void Device::reloadPlugins() } -//TODO -QSslKey myPrivateKey() { - - KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); - const QString& key = config->group("myself").readEntry("privateKey",QString()); - - QSslKey privateKey(key.toAscii(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); - qDebug() << "Valid public key:" << !privateKey.isNull(); - - return privateKey; - -} - void Device::requestPair() { - if (m_pairStatus != NotPaired) { + if (m_pairStatus == Paired) { Q_EMIT pairingFailed(i18n("Already paired")); return; } + if (m_pairStatus == Device::PairRequested) { + Q_EMIT pairingFailed(i18n("Pairing already requested for this device")); + return; + } if (!isReachable()) { Q_EMIT pairingFailed(i18n("Device not reachable")); return; @@ -206,9 +197,10 @@ void Device::addLink(DeviceLink* link) //the old one before this is called), so we do not have to worry about destroying old links. //Actually, we should not destroy them or the provider will store an invalid ref! - connect(link, SIGNAL(receivedPackage(NetworkPackage)), this, SLOT(privateReceivedPackage(NetworkPackage))); + connect(link, SIGNAL(receivedPackage(NetworkPackage)), + this, SLOT(privateReceivedPackage(NetworkPackage))); - qSort(m_deviceLinks.begin(),m_deviceLinks.end(),lessThan); + qSort(m_deviceLinks.begin(), m_deviceLinks.end(), lessThan); if (m_deviceLinks.size() == 1) { reloadPlugins(); //Will load the plugins @@ -237,12 +229,12 @@ void Device::removeLink(DeviceLink* link) } } -bool Device::sendPackage(const NetworkPackage& np) const +bool Device::sendPackage(NetworkPackage& np) { - //Maybe we could block here any package that is not an identity or a pairing package - if (isPaired()) { - + np.encrypt(m_publicKey); + } 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) { @@ -256,21 +248,27 @@ bool Device::sendPackage(const NetworkPackage& np) const void Device::privateReceivedPackage(const NetworkPackage& np) { - if (np.type() == PACKAGE_TYPE_PAIR) { qDebug() << "Pair package"; bool wantsPair = np.get("pair"); + if (wantsPair == isPaired()) { qDebug() << "Already" << (wantsPair? "paired":"unpaired"); + if (m_pairStatus == Device::PairRequested) { + m_pairStatus = Device::NotPaired; + pairingTimer.stop(); + Q_EMIT pairingFailed(i18n("Canceled by other peer")); + } return; } - KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); - if (wantsPair) { + const QByteArray& key = np.get("publicKey"); + m_publicKey = QCA::RSAPublicKey::fromDER(QByteArray::fromBase64(key)); + if (m_pairStatus == Device::PairRequested) { //We started pairing qDebug() << "Pair answer"; @@ -279,10 +277,10 @@ void Device::privateReceivedPackage(const NetworkPackage& np) pairingTimer.stop(); //Store as trusted device - const QByteArray& key = np.get("publicKey"); + KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); config->group("devices").group(id()).writeEntry("publicKey",key); config->group("devices").group(id()).writeEntry("name",name()); - m_publicKey = QCA::RSAPublicKey::fromDER(key); + m_publicKey = QCA::RSAPublicKey::fromDER(QByteArray::fromBase64(key)); Q_EMIT pairingSuccesful(); @@ -290,9 +288,6 @@ void Device::privateReceivedPackage(const NetworkPackage& np) qDebug() << "Pair request"; - const QByteArray& key = np.get("publicKey"); - m_publicKey = QCA::RSAPublicKey::fromDER(key); - KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent notification->setPixmap(KIcon("dialog-information").pixmap(48, 48)); notification->setComponentData(KComponentData("kdeconnect", "kdeconnect")); @@ -309,10 +304,12 @@ void Device::privateReceivedPackage(const NetworkPackage& np) qDebug() << "Unpair request"; if (m_pairStatus == PairRequested) { + m_pairStatus = Device::NotPaired; pairingTimer.stop(); Q_EMIT pairingFailed(i18n("Canceled by other peer")); + } else if (m_pairStatus == Paired) { + unpair(); } - unpair(); } @@ -323,8 +320,26 @@ void Device::privateReceivedPackage(const NetworkPackage& np) } else { - //Forward signal - Q_EMIT receivedPackage(np); + if (!np.isEncrypted()) { + //TODO: The other side doesn't know that we are already paired + qDebug() << "Warning: A paired device is sending an unencrypted package"; + + //Forward package + Q_EMIT receivedPackage(np); + + } else { + + //TODO: Do not read the key every time + KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); + const QByteArray& key = config->group("myself").readEntry("privateKey",QByteArray()); + QCA::PrivateKey privateKey = QCA::PrivateKey::fromDER(QByteArray::fromBase64(key)); + + //Emit decrypted package + NetworkPackage decryptedNp(""); + np.decrypt(privateKey, &decryptedNp); + Q_EMIT receivedPackage(decryptedNp); + } + } @@ -348,7 +363,7 @@ void Device::acceptPairing() } //Store as trusted device - config->group("devices").group(id()).writeEntry("publicKey", m_publicKey.toDER()); + config->group("devices").group(id()).writeEntry("publicKey", m_publicKey.toDER().toBase64()); config->group("devices").group(id()).writeEntry("name", name()); reloadPlugins(); //This will load plugins diff --git a/daemon/device.h b/daemon/device.h index 84cbbbf5e..e2cfc5de3 100644 --- a/daemon/device.h +++ b/daemon/device.h @@ -71,14 +71,14 @@ public: Q_SCRIPTABLE QStringList availableLinks() const; Q_SCRIPTABLE bool isReachable() const { return !m_deviceLinks.empty(); } - Q_SCRIPTABLE QStringList loadedPlugins(); - Q_SCRIPTABLE bool hasPlugin(const QString& name); + Q_SCRIPTABLE QStringList loadedPlugins() const; + Q_SCRIPTABLE bool hasPlugin(const QString& name) const; //Send and receive Q_SIGNALS: - void receivedPackage(const NetworkPackage& np); + void receivedPackage(const NetworkPackage& np) const; public Q_SLOTS: - virtual bool sendPackage(const NetworkPackage& np) const; + virtual bool sendPackage(NetworkPackage& np); //Dbus operations public Q_SLOTS: @@ -110,6 +110,7 @@ private: QMap m_plugins; QTimer pairingTimer; + }; Q_DECLARE_METATYPE(Device*) diff --git a/daemon/devicelinks/devicelink.h b/daemon/devicelinks/devicelink.h index 34a5dda51..60cafa6f8 100644 --- a/daemon/devicelinks/devicelink.h +++ b/daemon/devicelinks/devicelink.h @@ -39,10 +39,10 @@ public: const QString& deviceId() { return mDeviceId; } LinkProvider* provider() { return mLinkProvider; } - virtual bool sendPackage(const NetworkPackage& np) const = 0; + virtual bool sendPackage(const NetworkPackage& np) = 0; -signals: - void receivedPackage(const NetworkPackage& np) const; +Q_SIGNALS: + void receivedPackage(const NetworkPackage& np); private: QString mDeviceId; diff --git a/daemon/devicelinks/landevicelink.cpp b/daemon/devicelinks/landevicelink.cpp index f06c90479..38fa110dc 100644 --- a/daemon/devicelinks/landevicelink.cpp +++ b/daemon/devicelinks/landevicelink.cpp @@ -51,7 +51,7 @@ LanDeviceLink::LanDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* sock this, SLOT(dataReceived())); } -bool LanDeviceLink::sendPackage(const NetworkPackage& np) const +bool LanDeviceLink::sendPackage(const NetworkPackage& np) { int written = mSocket->write(np.serialize()); return written != -1; diff --git a/daemon/devicelinks/landevicelink.h b/daemon/devicelinks/landevicelink.h index e42225bf4..82a73bcf7 100644 --- a/daemon/devicelinks/landevicelink.h +++ b/daemon/devicelinks/landevicelink.h @@ -38,7 +38,7 @@ class LanDeviceLink public: LanDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket); - bool sendPackage(const NetworkPackage& np) const; + bool sendPackage(const NetworkPackage& np); private Q_SLOTS: void dataReceived(); diff --git a/daemon/devicelinks/loopbackdevicelink.cpp b/daemon/devicelinks/loopbackdevicelink.cpp index 92d5eacc0..cd19c919a 100644 --- a/daemon/devicelinks/loopbackdevicelink.cpp +++ b/daemon/devicelinks/loopbackdevicelink.cpp @@ -28,7 +28,7 @@ LoopbackDeviceLink::LoopbackDeviceLink(const QString& deviceId, LoopbackLinkProv } -bool LoopbackDeviceLink::sendPackage(const NetworkPackage& toSend) const +bool LoopbackDeviceLink::sendPackage(const NetworkPackage& toSend) { NetworkPackage toReceive(""); NetworkPackage::unserialize(toSend.serialize(), &toReceive); diff --git a/daemon/devicelinks/loopbackdevicelink.h b/daemon/devicelinks/loopbackdevicelink.h index 209b52f05..5372e347a 100644 --- a/daemon/devicelinks/loopbackdevicelink.h +++ b/daemon/devicelinks/loopbackdevicelink.h @@ -18,8 +18,9 @@ * along with this program. If not, see . */ -#ifndef ECHODEVICELINK_H -#define ECHODEVICELINK_H +#ifndef LOOPBACKDEVICELINK_H +#define LOOPBACKDEVICELINK_H + #include "devicelink.h" class LoopbackLinkProvider; @@ -31,8 +32,8 @@ class LoopbackDeviceLink public: LoopbackDeviceLink(const QString& d, LoopbackLinkProvider* a); - bool sendPackage(const NetworkPackage& np) const; + bool sendPackage(const NetworkPackage& np); }; -#endif // ECHODEVICELINK_H +#endif diff --git a/daemon/linkproviders/linkprovider.h b/daemon/linkproviders/linkprovider.h index 2a5cfe761..6bcdd939c 100644 --- a/daemon/linkproviders/linkprovider.h +++ b/daemon/linkproviders/linkprovider.h @@ -55,7 +55,7 @@ Q_SIGNALS: //NOTE: The provider will to destroy the DeviceLink when it's no longer accessible, // and every user should listen to the destroyed signal to remove its references. // That's the reason because there is no "onConnectionLost". - void onConnectionReceived(const NetworkPackage& identityPackage, DeviceLink*); + void onConnectionReceived(const NetworkPackage& identityPackage, DeviceLink*) const; }; diff --git a/daemon/networkpackage.cpp b/daemon/networkpackage.cpp index 117f6d4d9..c0077faf9 100644 --- a/daemon/networkpackage.cpp +++ b/daemon/networkpackage.cpp @@ -32,15 +32,15 @@ #include #include -#include "encryptednetworkpackage.h" - -const static int CURRENT_PACKAGE_VERSION = 1; +const static int CURRENT_PACKAGE_VERSION = 2; NetworkPackage::NetworkPackage(const QString& type) { - mId = QDateTime::currentMSecsSinceEpoch(); + mId = QString::number(QDateTime::currentMSecsSinceEpoch()); mType = type; + mBody = QVariantMap(); mVersion = CURRENT_PACKAGE_VERSION; + mEncrypted = false; } QByteArray NetworkPackage::serialize() const @@ -68,8 +68,8 @@ QByteArray NetworkPackage::serialize() const void NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np) { - qDebug() << "Unserialize:" << a; - + qDebug() << "Unserialize: " << a; + //Json -> QVariant QJson::Parser parser; bool ok; @@ -80,11 +80,6 @@ void NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np) } //QVariant -> Object - //NetworkPackage np; - //QJSon json(a); - //np.mId = json["id"]; - //np.mType = json["type"]; - //np.mBody = json["body"]; QJson::QObjectHelper::qvariant2qobject(variant,np); if (np->version() > CURRENT_PACKAGE_VERSION) { @@ -93,6 +88,34 @@ void NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np) } +void NetworkPackage::encrypt (QCA::PublicKey& key) +{ + qDebug() << key.toDER() << key.canEncrypt(); + + QByteArray serialized = serialize(); + QByteArray data = key.encrypt(serialized, QCA::EME_PKCS1v15).toByteArray(); + + mId = QString::number(QDateTime::currentMSecsSinceEpoch()); + mType = "kdeconnect.encrypted"; + mBody = QVariantMap(); + mBody["data"] = data.toBase64(); + mVersion = CURRENT_PACKAGE_VERSION; + mEncrypted = true; + +} + +void NetworkPackage::decrypt (QCA::PrivateKey& key, NetworkPackage* out) const +{ + QByteArray encryptedJson = QByteArray::fromBase64(get("data")); + + QCA::SecureArray decryptedJson; + key.decrypt(encryptedJson, &decryptedJson, QCA::EME_PKCS1v15); + + unserialize(decryptedJson.toByteArray(), out); +} + + + void NetworkPackage::createIdentityPackage(NetworkPackage* np) { KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); @@ -106,11 +129,4 @@ void NetworkPackage::createIdentityPackage(NetworkPackage* np) //qDebug() << "createIdentityPackage" << np->serialize(); } -EncryptedNetworkPackage NetworkPackage::encrypt ( const QSslKey& key ) const -{ - QByteArray serialized = serialize(); - return EncryptedNetworkPackage(); - -} - diff --git a/daemon/networkpackage.h b/daemon/networkpackage.h index b29b87222..6e5798b84 100644 --- a/daemon/networkpackage.h +++ b/daemon/networkpackage.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include @@ -38,24 +38,29 @@ class EncryptedNetworkPackage; class NetworkPackage : public QObject { Q_OBJECT - Q_PROPERTY( long id READ id WRITE setId ) + Q_PROPERTY( QString id READ id WRITE setId ) Q_PROPERTY( QString type READ type WRITE setType ) Q_PROPERTY( QVariantMap body READ body WRITE setBody ) Q_PROPERTY( int version READ version WRITE setVersion ) + Q_PROPERTY( bool isEncrypted READ isEncrypted WRITE setEncrypted ) public: NetworkPackage(const QString& type); - static void unserialize(const QByteArray&, NetworkPackage*); + static void unserialize(const QByteArray& json, NetworkPackage* out); QByteArray serialize() const; + void encrypt(QCA::PublicKey& key); + void decrypt(QCA::PrivateKey& key, NetworkPackage* out) const; + static void createIdentityPackage(NetworkPackage*); - long id() const { return mId; } + QString id() const { return mId; } const QString& type() const { return mType; } QVariantMap& body() { return mBody; } int version() const { return mVersion; } + bool isEncrypted() const { return mEncrypted; } //Get and set info from body. Note that id, type and version can not be accessed through these. template T get(const QString& key, const T& defaultValue = default_arg::get()) const { @@ -65,16 +70,16 @@ public: bool has(const QString& key) const { return mBody.contains(key); } - EncryptedNetworkPackage encrypt(const QSslKey& key) const; - private: - void setId(long id) { mId = id; } + void setId(QString id) { mId = id; } void setType(const QString& t) { mType = t; } void setBody(const QVariantMap& b) { mBody = b; } void setVersion(int v) { mVersion = v; } + void setEncrypted(bool b) { mEncrypted = b; } - long mId; + QString mId; QString mType; + bool mEncrypted; QVariantMap mBody; //json in the Android side int mVersion; diff --git a/daemon/plugins/battery/CMakeLists.txt b/daemon/plugins/battery/CMakeLists.txt index 66c7d8b03..ce52b3e5d 100644 --- a/daemon/plugins/battery/CMakeLists.txt +++ b/daemon/plugins/battery/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/clipboard/CMakeLists.txt b/daemon/plugins/clipboard/CMakeLists.txt index 60771e0ed..3309097d6 100644 --- a/daemon/plugins/clipboard/CMakeLists.txt +++ b/daemon/plugins/clipboard/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/filetransfer/CMakeLists.txt b/daemon/plugins/filetransfer/CMakeLists.txt index 8f170a40c..139760bc4 100644 --- a/daemon/plugins/filetransfer/CMakeLists.txt +++ b/daemon/plugins/filetransfer/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/kdeconnectplugin.h b/daemon/plugins/kdeconnectplugin.h index 45da09948..b8c9c44e8 100644 --- a/daemon/plugins/kdeconnectplugin.h +++ b/daemon/plugins/kdeconnectplugin.h @@ -49,6 +49,10 @@ public Q_SLOTS: private: Device* mDevice; + // The Initializer object sets things up, and also does cleanup when it goes out of scope + // Since the plugins use their own memory, they need their own initializer in order to send encrypted packages + QCA::Initializer init; + }; #endif diff --git a/daemon/plugins/mpriscontrol/CMakeLists.txt b/daemon/plugins/mpriscontrol/CMakeLists.txt index f330c2049..03a0b0bb8 100644 --- a/daemon/plugins/mpriscontrol/CMakeLists.txt +++ b/daemon/plugins/mpriscontrol/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/notifications/CMakeLists.txt b/daemon/plugins/notifications/CMakeLists.txt index ad9c5e04d..38fd4ad45 100644 --- a/daemon/plugins/notifications/CMakeLists.txt +++ b/daemon/plugins/notifications/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/pausemusic/CMakeLists.txt b/daemon/plugins/pausemusic/CMakeLists.txt index cc51ae9fb..9f4767851 100644 --- a/daemon/plugins/pausemusic/CMakeLists.txt +++ b/daemon/plugins/pausemusic/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/ping/CMakeLists.txt b/daemon/plugins/ping/CMakeLists.txt index 305ace1a9..56d03f224 100644 --- a/daemon/plugins/ping/CMakeLists.txt +++ b/daemon/plugins/ping/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/daemon/plugins/telephony/CMakeLists.txt b/daemon/plugins/telephony/CMakeLists.txt index fa8461a1b..e775afa71 100644 --- a/daemon/plugins/telephony/CMakeLists.txt +++ b/daemon/plugins/telephony/CMakeLists.txt @@ -2,6 +2,11 @@ find_package(KDE4 REQUIRED) find_package(QJSON REQUIRED) find_package(QCA2 REQUIRED) +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + include(KDE4Defaults) include_directories(${KDE4_INCLUDES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 979cb2051..000000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -set(kded_kdeconnect_tests_SRCS - ../daemon/networkpackage.cpp - backendtests.cpp -) - -kde4_add_unit_test(kded_kdeconnect_tests ${kded_kdeconnect_tests_SRCS}) - -target_link_libraries(kded_kdeconnect_tests - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEUI_LIBS} - kdnssd - qjson - ${QT_QTTEST_LIBRARY} - ${QT_QTNETWORK_LIBRARY} -) - -add_test(kded_kdeconnect_tests ${CMAKE_CURRENT_BINARY_DIR}/kded_kdeconnect_tests) - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..9bbb9c24f --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +find_package(QJSON REQUIRED) +find_package(QCA2 REQUIRED) + +include_directories( + ${QJSON_INCLUDE_DIR} + ${QCA2_INCLUDE_DIR} +) + +set(kdeconnect_tests_SRCS + ../daemon/networkpackage.cpp + networkpackagetests.cpp +) + +kde4_add_unit_test(kdeconnect_tests ${kdeconnect_tests_SRCS}) + +target_link_libraries(kdeconnect_tests + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} + ${QJSON_LIBRARIES} + ${QCA2_LIBRARIES} + ${QT_QTTEST_LIBRARY} + ${QT_QTNETWORK_LIBRARY} +) diff --git a/test/backendtests.cpp b/tests/networkpackagetests.cpp similarity index 64% rename from test/backendtests.cpp rename to tests/networkpackagetests.cpp index 098fbdc97..8b054145f 100644 --- a/test/backendtests.cpp +++ b/tests/networkpackagetests.cpp @@ -18,21 +18,21 @@ * along with this program. If not, see . */ -#include "backendtests.h" +#include "networkpackagetests.h" #include "../daemon/networkpackage.h" #include #include -QTEST_KDEMAIN(BackendTests, NoGUI); +QTEST_KDEMAIN(NetworkPackageTests, NoGUI); -void BackendTests::initTestCase() +void NetworkPackageTests::initTestCase() { // Called before the first testfunction is executed } -void BackendTests::dummyTest() +void NetworkPackageTests::dummyTest() { QDate date; date.setYMD( 1967, 3, 11 ); @@ -41,7 +41,7 @@ void BackendTests::dummyTest() QCOMPARE( QDate::longMonthName(date.month()), QString("March") ); } -void BackendTests::networkPackageTest() +void NetworkPackageTests::networkPackageTest() { NetworkPackage np("com.test"); @@ -64,10 +64,10 @@ void BackendTests::networkPackageTest() QCOMPARE( np.version(), np2.version() ); QCOMPARE( np.body(), np2.body() ); - QByteArray json("{ \"id\": 123, \"type\": \"test\", \"body\": { \"testing\": true }, \"version\": 3 }"); + QByteArray json("{ \"id\": \"123\", \"type\": \"test\", \"body\": { \"testing\": true }, \"version\": 3 }"); //qDebug() << json; NetworkPackage::unserialize(json,&np2); - QCOMPARE( np2.id(), long(123) ); + QCOMPARE( np2.id(), QString("123") ); QCOMPARE( np2.version(), 3 ); QCOMPARE( (np2.get("testing")), true ); QCOMPARE( (np2.get("not_testing")), false ); @@ -78,22 +78,53 @@ void BackendTests::networkPackageTest() //QtTest::ignoreMessage(QtDebugMsg, "Unserialization error: 1 \"syntax error, unexpected string\""); //QCOMPARE( np2.version(), -1 ); + +} + +void NetworkPackageTests::networkPackageEncryptionTest() +{ + + NetworkPackage original("com.test"); + original.set("hello","hola"); + + NetworkPackage copy(""); + NetworkPackage::unserialize(original.serialize(), ©); + + NetworkPackage decrypted(""); + + QCA::Initializer init; + QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(1024); + QCA::PublicKey publicKey = privateKey.toPublicKey(); + + //Encrypt and decrypt np + QCOMPARE( original.isEncrypted(), false ); + original.encrypt(publicKey); + QCOMPARE( original.isEncrypted(), true ); + original.decrypt(privateKey, &decrypted); + QCOMPARE( original.isEncrypted(), true ); + QCOMPARE( decrypted.isEncrypted(), false ); + + //np should be equal top np2 + QCOMPARE( decrypted.id(), copy.id() ); + QCOMPARE( decrypted.type(), copy.type() ); + QCOMPARE( decrypted.version(), copy.version() ); + QCOMPARE( decrypted.body(), copy.body() ); + } -void BackendTests::cleanupTestCase() +void NetworkPackageTests::cleanupTestCase() { // Called after the last testfunction was executed } -void BackendTests::init() +void NetworkPackageTests::init() { // Called before each testfunction is executed } -void BackendTests::cleanup() +void NetworkPackageTests::cleanup() { // Called after every testfunction } -#include "backendtests.moc" diff --git a/test/backendtests.h b/tests/networkpackagetests.h similarity index 87% rename from test/backendtests.h rename to tests/networkpackagetests.h index 2ed22e823..b91eab9cf 100644 --- a/test/backendtests.h +++ b/tests/networkpackagetests.h @@ -18,12 +18,12 @@ * along with this program. If not, see . */ -#ifndef BACKENDTESTS_H -#define BACKENDTESTS_H +#ifndef NETWORKPACKAGETESTS_H +#define NETWORKPACKAGETESTS_H #include -class BackendTests : public QObject +class NetworkPackageTests : public QObject { Q_OBJECT @@ -32,6 +32,7 @@ private Q_SLOTS: void dummyTest(); void networkPackageTest(); + void networkPackageEncryptionTest(); void cleanupTestCase(); @@ -40,4 +41,4 @@ private Q_SLOTS: }; -#endif // BACKENDTESTS_H +#endif