Commit b5a5416c authored by Albert Vaca Cintora's avatar Albert Vaca Cintora
Browse files

Changed QSslKeys to QCA keys that will actually allow us to encrypt things

parent 1604309a
include_directories(
${QJSON_INCLUDE_DIR}
${QCA2_INCLUDE_DIR}
)
set(kded_kdeconnect_SRCS set(kded_kdeconnect_SRCS
linkproviders/linkprovider.cpp linkproviders/linkprovider.cpp
...@@ -20,12 +25,15 @@ add_subdirectory(plugins) ...@@ -20,12 +25,15 @@ add_subdirectory(plugins)
kde4_add_plugin(kded_kdeconnect ${kded_kdeconnect_SRCS}) kde4_add_plugin(kded_kdeconnect ${kded_kdeconnect_SRCS})
find_package (QJSON REQUIRED)
find_package (QCA2 REQUIRED)
target_link_libraries(kded_kdeconnect target_link_libraries(kded_kdeconnect
${KDE4_KDECORE_LIBS} ${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS} ${KDE4_KDEUI_LIBS}
#kdnssd
qjson
${QT_QTNETWORK_LIBRARY} ${QT_QTNETWORK_LIBRARY}
${QJSON_LIBRARIES}
${QCA2_LIBRARIES}
) )
include(../cmakemacros.txt) include(../cmakemacros.txt)
......
...@@ -29,10 +29,12 @@ ...@@ -29,10 +29,12 @@
#include <QDBusConnection> #include <QDBusConnection>
#include <QNetworkSession> #include <QNetworkSession>
#include <QNetworkConfigurationManager> #include <QNetworkConfigurationManager>
#include <QSslKey> #include <QDebug>
#include <KIcon> #include <KConfig>
#include <KConfigGroup> #include <KConfigGroup>
#include <KNotification>
#include <KIcon>
K_PLUGIN_FACTORY(KdeConnectFactory, registerPlugin<Daemon>();) K_PLUGIN_FACTORY(KdeConnectFactory, registerPlugin<Daemon>();)
K_EXPORT_PLUGIN(KdeConnectFactory("kdeconnect", "kdeconnect")) K_EXPORT_PLUGIN(KdeConnectFactory("kdeconnect", "kdeconnect"))
...@@ -51,55 +53,14 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&) ...@@ -51,55 +53,14 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
qDebug() << "My id:" << uuid; qDebug() << "My id:" << uuid;
} }
if (!config->group("myself").hasKey("privateKey")) { if (!config->group("myself").hasKey("privateKey") || !config->group("myself").hasKey("publicKey")) {
//TODO: Generate
QByteArray key = QByteArray(
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIICXAIBAAKBgQCnKxy6aZrABVvbxuWqMPbohH4KRDBGqyO/OwxvUD1qHpqZ9cJT\n"
"bgttiIaXzdQny5esf6brI6Di/ssIp9awdLBlMT+eR6zR7g446tbxaCFuUiL0QIei\n"
"izEveTDNRbson/8DPJrn8/81doTeXsuV7YbqmtUGwdZ5kiocAW92ZZukdQIDAQAB\n"
"AoGBAI18yuLoMQdnQblBne8vZDumsDsmPaoCfc4EP2ETi/d+kaHPxTryABAkJq7j\n"
"kjZgdi6VGIUacbjOqK/Zxrcw/H460EwOUzh97Z4t9CDtDhz6t3ddT8CfbG2TUgbx\n"
"Vv3mSYSUDBdNBV6YY4fyLtZl6oI2V+rBaFIT48+vAK9doKlhAkEA2ZKm9dc80IjU\n"
"c/Wwn8ij+6ALs4Mpa0dPYivgZ2QhXiX5TfMymal2dDufkOH4wIUO+8vV8CSmmTRU\n"
"8Lv/B3pY7QJBAMSxeJtTSFwBcGRaZKRMIqeuZ/yMMT4EqqIh1DjBpujCRKApVpkO\n"
"kVx3Yu7xyOfniXBwujiYNSL6LrWdKykEsKkCQEr2UDgbtIRU4H4jhHtI8dbcSavL\n"
"4RVpOFymqWZ2BVke1EqbJC/1Ry687DlK4h3Sulre3BMlTZEziqB25WN6L/ECQBJv\n"
"B3yXG4rz35KoHhJ/yCeq4rf6c4r6aPt07Cy9iWT6/+96sFD72oet8KmwI0IIowrU\n"
"pb80FJbIl6QRrL/VXrECQBDdeCAG6J3Cwm4ozQiDQyiNd1qJqWc4co9savJxLtEU\n"
"s5L4Qwfrexm16oCJimGmsa5q6Y0n4f5gY+MRh3n+nQo=\n"
"-----END RSA PRIVATE KEY-----\n"
);
//Test for validity
//QSslKey privateKey(key.toAscii(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
//qDebug() << "Valid private key:" << !privateKey.isNull();
config->group("myself").writeEntry("privateKey", key);
}
if (!config->group("myself").hasKey("publicKey")) {
//TODO: Generate
QByteArray key = QByteArray(
"-----BEGIN PUBLIC KEY-----\n"
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnKxy6aZrABVvbxuWqMPbohH4K\n"
"RDBGqyO/OwxvUD1qHpqZ9cJTbgttiIaXzdQny5esf6brI6Di/ssIp9awdLBlMT+e\n"
"R6zR7g446tbxaCFuUiL0QIeiizEveTDNRbson/8DPJrn8/81doTeXsuV7YbqmtUG\n"
"wdZ5kiocAW92ZZukdQIDAQAB\n"
"-----END PUBLIC KEY-----\n"
);
//Test for validity //http://delta.affinix.com/docs/qca/rsatest_8cpp-example.html
//QSslKey publicKey(key.toAscii(), QSsl::Rsa, QSsl::Pem, QSsl::PublicKey); QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(1024);
//qDebug() << "Valid public key:" << !publicKey.isNull(); config->group("myself").writeEntry("privateKey", privateKey.toPEM());
config->group("myself").writeEntry("publicKey", key); QCA::PublicKey publicKey = privateKey.toPublicKey();
config->group("myself").writeEntry("publicKey", publicKey.toPEM());
} }
...@@ -157,7 +118,7 @@ QStringList Daemon::visibleDevices() ...@@ -157,7 +118,7 @@ QStringList Daemon::visibleDevices()
{ {
QStringList ret; QStringList ret;
Q_FOREACH(Device* device, mDevices) { Q_FOREACH(Device* device, mDevices) {
if (device->reachable()) { if (device->isReachable()) {
ret.append(device->id()); ret.append(device->id());
} }
} }
...@@ -199,9 +160,9 @@ void Daemon::onDeviceReachableStatusChanged() ...@@ -199,9 +160,9 @@ void Daemon::onDeviceReachableStatusChanged()
Device* device = (Device*)sender(); Device* device = (Device*)sender();
QString id = device->id(); QString id = device->id();
Q_EMIT deviceVisibilityChanged(id, device->reachable()); Q_EMIT deviceVisibilityChanged(id, device->isReachable());
if (!device->reachable()) { if (!device->isReachable()) {
if (!device->isPaired()) { if (!device->isPaired()) {
qDebug() << "Destroying device"; qDebug() << "Destroying device";
......
...@@ -18,32 +18,22 @@ ...@@ -18,32 +18,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef DAEMON_H #ifndef DAEMON_H
#define DAEMON_H #define DAEMON_H
#include <QObject> #include <QObject>
#include <QRegExp>
#include <map>
#include <KDEDModule>
#include <KNotification>
#include "networkpackage.h"
#include <KDE/KPluginFactory>
#include <QFile>
#include <qtextstream.h>
#include <QSet> #include <QSet>
#include <QMap>
#include <QtCrypto>
#include <KConfig> #include <KDEDModule>
#include <KPluginFactory>
#include "device.h" #include "device.h"
#include "networkpackage.h"
#include "devicelinks/devicelink.h" #include "devicelinks/devicelink.h"
#include "linkproviders/linkprovider.h" #include "linkproviders/linkprovider.h"
class QUdpSocket;
class Daemon class Daemon
: public KDEDModule : public KDEDModule
{ {
...@@ -82,6 +72,9 @@ private: ...@@ -82,6 +72,9 @@ private:
//Every known device //Every known device
QMap<QString, Device*> mDevices; QMap<QString, Device*> mDevices;
// The Initializer object sets things up, and also does cleanup when it goes out of scope
QCA::Initializer init;
}; };
#endif // UDP_WIRELESS_H #endif // UDP_WIRELESS_H
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <KNotification> #include <KNotification>
#include <KIcon> #include <KIcon>
#include <QSslKey>
#include <QDebug> #include <QDebug>
#include "plugins/kdeconnectplugin.h" #include "plugins/kdeconnectplugin.h"
...@@ -31,9 +30,9 @@ Device::Device(const QString& id) ...@@ -31,9 +30,9 @@ Device::Device(const QString& id)
m_deviceName = name; m_deviceName = name;
const QByteArray& key = data.readEntry<QByteArray>("publicKey",QByteArray()); const QByteArray& key = data.readEntry<QByteArray>("publicKey",QByteArray());
m_publicKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PublicKey); m_publicKey = QCA::RSAPublicKey::fromDER(key);
m_pairingRequested = false; m_pairStatus = Device::Paired;
//Register in bus //Register in bus
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
...@@ -47,7 +46,7 @@ Device::Device(const NetworkPackage& identityPackage, DeviceLink* dl) ...@@ -47,7 +46,7 @@ Device::Device(const NetworkPackage& identityPackage, DeviceLink* dl)
addLink(dl); addLink(dl);
m_pairingRequested = false; m_pairStatus = Device::Device::NotPaired;
//Register in bus //Register in bus
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
...@@ -72,7 +71,7 @@ void Device::reloadPlugins() ...@@ -72,7 +71,7 @@ void Device::reloadPlugins()
{ {
QMap< QString, KdeConnectPlugin* > newPluginMap; QMap< QString, KdeConnectPlugin* > newPluginMap;
if (isPaired() && reachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices
QString path = KStandardDirs().resourceDirs("config").first()+"kdeconnect/"; QString path = KStandardDirs().resourceDirs("config").first()+"kdeconnect/";
QMap<QString,QString> pluginStates = KSharedConfig::openConfig(path + id())->group("Plugins").entryMap(); QMap<QString,QString> pluginStates = KSharedConfig::openConfig(path + id())->group("Plugins").entryMap();
...@@ -134,11 +133,11 @@ QSslKey myPrivateKey() { ...@@ -134,11 +133,11 @@ QSslKey myPrivateKey() {
void Device::requestPair() void Device::requestPair()
{ {
if (isPaired() || m_pairingRequested) { if (m_pairStatus != NotPaired) {
Q_EMIT pairingFailed(i18n("Already paired")); Q_EMIT pairingFailed(i18n("Already paired"));
return; return;
} }
if (!reachable()) { if (!isReachable()) {
Q_EMIT pairingFailed(i18n("Device not reachable")); Q_EMIT pairingFailed(i18n("Device not reachable"));
return; return;
} }
...@@ -156,7 +155,7 @@ void Device::requestPair() ...@@ -156,7 +155,7 @@ void Device::requestPair()
return; return;
} }
m_pairingRequested = true; m_pairStatus = PairRequested;
pairingTimer.start(20 * 1000); pairingTimer.start(20 * 1000);
connect(&pairingTimer, SIGNAL(timeout()), connect(&pairingTimer, SIGNAL(timeout()),
this, SLOT(pairingTimeout())); this, SLOT(pairingTimeout()));
...@@ -167,14 +166,13 @@ void Device::unpair() ...@@ -167,14 +166,13 @@ void Device::unpair()
{ {
if (!isPaired()) return; if (!isPaired()) return;
m_publicKey = QSslKey(); m_pairStatus = NotPaired;
m_pairingRequested = false;
pairingTimer.stop(); pairingTimer.stop();
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
config->group("devices").deleteGroup(id()); config->group("devices").deleteGroup(id());
if (reachable()) { if (isReachable()) {
NetworkPackage np(PACKAGE_TYPE_PAIR); NetworkPackage np(PACKAGE_TYPE_PAIR);
np.set("pair", false); np.set("pair", false);
sendPackage(np); sendPackage(np);
...@@ -186,7 +184,7 @@ void Device::unpair() ...@@ -186,7 +184,7 @@ void Device::unpair()
void Device::pairingTimeout() void Device::pairingTimeout()
{ {
m_pairingRequested = false; m_pairStatus = NotPaired;
Q_EMIT Q_EMIT pairingFailed("Timed out"); Q_EMIT Q_EMIT pairingFailed("Timed out");
} }
...@@ -263,28 +261,28 @@ void Device::privateReceivedPackage(const NetworkPackage& np) ...@@ -263,28 +261,28 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
qDebug() << "Pair package"; qDebug() << "Pair package";
bool pair = np.get<bool>("pair"); bool wantsPair = np.get<bool>("pair");
if (pair == isPaired()) { if (wantsPair == isPaired()) {
qDebug() << "Already" << (pair? "paired":"unpaired"); qDebug() << "Already" << (wantsPair? "paired":"unpaired");
return; return;
} }
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc"); KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
if (pair) { if (wantsPair) {
if (m_pairingRequested) { //We started pairing if (m_pairStatus == Device::PairRequested) { //We started pairing
qDebug() << "Pair answer"; qDebug() << "Pair answer";
m_pairingRequested = false; m_pairStatus = Paired;
pairingTimer.stop(); pairingTimer.stop();
//Store as trusted device //Store as trusted device
const QByteArray& key = np.get<QByteArray>("publicKey"); const QByteArray& key = np.get<QByteArray>("publicKey");
config->group("devices").group(id()).writeEntry("publicKey",key); config->group("devices").group(id()).writeEntry("publicKey",key);
config->group("devices").group(id()).writeEntry("name",name()); config->group("devices").group(id()).writeEntry("name",name());
m_publicKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PublicKey); m_publicKey = QCA::RSAPublicKey::fromDER(key);
Q_EMIT pairingSuccesful(); Q_EMIT pairingSuccesful();
...@@ -292,8 +290,8 @@ void Device::privateReceivedPackage(const NetworkPackage& np) ...@@ -292,8 +290,8 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
qDebug() << "Pair request"; qDebug() << "Pair request";
const QString& key = np.get<QString>("publicKey"); const QByteArray& key = np.get<QByteArray>("publicKey");
m_tempPublicKey = QSslKey(key.toAscii(), QSsl::Rsa, QSsl::Pem, QSsl::PublicKey); m_publicKey = QCA::RSAPublicKey::fromDER(key);
KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent
notification->setPixmap(KIcon("dialog-information").pixmap(48, 48)); notification->setPixmap(KIcon("dialog-information").pixmap(48, 48));
...@@ -310,7 +308,7 @@ void Device::privateReceivedPackage(const NetworkPackage& np) ...@@ -310,7 +308,7 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
} else { } else {
qDebug() << "Unpair request"; qDebug() << "Unpair request";
if (m_pairingRequested) { if (m_pairStatus == PairRequested) {
pairingTimer.stop(); pairingTimer.stop();
Q_EMIT pairingFailed(i18n("Canceled by other peer")); Q_EMIT pairingFailed(i18n("Canceled by other peer"));
} }
...@@ -350,8 +348,7 @@ void Device::acceptPairing() ...@@ -350,8 +348,7 @@ void Device::acceptPairing()
} }
//Store as trusted device //Store as trusted device
m_publicKey = m_tempPublicKey; config->group("devices").group(id()).writeEntry("publicKey", m_publicKey.toDER());
config->group("devices").group(id()).writeEntry("publicKey", m_tempPublicKey.toPem());
config->group("devices").group(id()).writeEntry("name", name()); config->group("devices").group(id()).writeEntry("name", name());
reloadPlugins(); //This will load plugins reloadPlugins(); //This will load plugins
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <QMap> #include <QMap>
#include <QSslKey> #include <QSslKey>
#include <QTimer> #include <QTimer>
#include <QtCrypto>
#include "networkpackage.h" #include "networkpackage.h"
...@@ -41,6 +42,12 @@ class Device ...@@ -41,6 +42,12 @@ class Device
Q_PROPERTY(QString id READ id) Q_PROPERTY(QString id READ id)
Q_PROPERTY(QString name READ name) Q_PROPERTY(QString name READ name)
enum PairStatus {
NotPaired,
PairRequested,
Paired,
};
public: public:
//Read device from KConfig, we already know it but we need to wait for a incoming devicelink to communicate //Read device from KConfig, we already know it but we need to wait for a incoming devicelink to communicate
Device(const QString& id); Device(const QString& id);
...@@ -58,12 +65,14 @@ public: ...@@ -58,12 +65,14 @@ public:
void addLink(DeviceLink*); void addLink(DeviceLink*);
void removeLink(DeviceLink*); void removeLink(DeviceLink*);
Q_SCRIPTABLE bool isPaired() const { return m_pairStatus==Device::Paired; }
Q_SCRIPTABLE bool pairRequested() const { return m_pairStatus==Device::PairRequested; }
Q_SCRIPTABLE QStringList availableLinks() const; Q_SCRIPTABLE QStringList availableLinks() const;
Q_SCRIPTABLE bool isPaired() const { return !m_publicKey.isNull(); } Q_SCRIPTABLE bool isReachable() const { return !m_deviceLinks.empty(); }
Q_SCRIPTABLE bool pairRequested() const { return m_pairingRequested; }
Q_SCRIPTABLE bool reachable() const { return !m_deviceLinks.empty(); }
Q_SCRIPTABLE bool hasPlugin(const QString& name);
Q_SCRIPTABLE QStringList loadedPlugins(); Q_SCRIPTABLE QStringList loadedPlugins();
Q_SCRIPTABLE bool hasPlugin(const QString& name);
//Send and receive //Send and receive
Q_SIGNALS: Q_SIGNALS:
...@@ -94,9 +103,8 @@ Q_SIGNALS: ...@@ -94,9 +103,8 @@ Q_SIGNALS:
private: private:
QString m_deviceId; QString m_deviceId;
QString m_deviceName; QString m_deviceName;
QSslKey m_publicKey; QCA::PublicKey m_publicKey;
QSslKey m_tempPublicKey; PairStatus m_pairStatus;
bool m_pairingRequested;
QList<DeviceLink*> m_deviceLinks; QList<DeviceLink*> m_deviceLinks;
QMap<QString, KdeConnectPlugin*> m_plugins; QMap<QString, KdeConnectPlugin*> m_plugins;
......
...@@ -19,23 +19,26 @@ ...@@ -19,23 +19,26 @@
*/ */
#include "networkpackage.h" #include "networkpackage.h"
#include <ksharedconfig.h>
#include <kconfiggroup.h> #include <KSharedConfig>
#include <qbytearray.h> #include <KConfigGroup>
#include <qdatastream.h> #include <QByteArray>
#include <QDataStream>
#include <QHostInfo> #include <QHostInfo>
#include <sstream> #include <QSslKey>
#include <string> #include <QDateTime>
#include <QtCrypto/QtCrypto>
#include <qjson/serializer.h> #include <qjson/serializer.h>
#include <iostream>
#include <ctime>
#include <qjson/qobjecthelper.h> #include <qjson/qobjecthelper.h>
#include "encryptednetworkpackage.h"
const static int CURRENT_PACKAGE_VERSION = 1; const static int CURRENT_PACKAGE_VERSION = 1;
NetworkPackage::NetworkPackage(const QString& type) NetworkPackage::NetworkPackage(const QString& type)
{ {
mId = time(NULL); mId = QDateTime::currentMSecsSinceEpoch();
mType = type; mType = type;
mVersion = CURRENT_PACKAGE_VERSION; mVersion = CURRENT_PACKAGE_VERSION;
} }
...@@ -103,4 +106,11 @@ void NetworkPackage::createIdentityPackage(NetworkPackage* np) ...@@ -103,4 +106,11 @@ void NetworkPackage::createIdentityPackage(NetworkPackage* np)
//qDebug() << "createIdentityPackage" << np->serialize(); //qDebug() << "createIdentityPackage" << np->serialize();
} }
EncryptedNetworkPackage NetworkPackage::encrypt ( const QSslKey& key ) const
{
QByteArray serialized = serialize();
return EncryptedNetworkPackage();
}
...@@ -27,12 +27,14 @@ ...@@ -27,12 +27,14 @@
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
#include <QStringList> #include <QStringList>
#include <QSsl> #include <QSslKey>
#include <qjson/parser.h> #include <qjson/parser.h>
#include "default_args.h" #include "default_args.h"
class EncryptedNetworkPackage;
class NetworkPackage : public QObject class NetworkPackage : public QObject
{ {
Q_OBJECT Q_OBJECT
...@@ -63,6 +65,8 @@ public: ...@@ -63,6 +65,8 @@ public:
bool has(const QString& key) const { return mBody.contains(key); } bool has(const QString& key) const { return mBody.contains(key); }
EncryptedNetworkPackage encrypt(const QSslKey& key) const;
private: private:
void setId(long id) { mId = id; } void setId(long id) { mId = id; }
void setType(const QString& t) { mType = t; } void setType(const QString& t) { mType = t; }
......
find_package(KDE4 REQUIRED) find_package(KDE4 REQUIRED)
include (KDE4Defaults) find_package(QJSON REQUIRED)
find_package(QCA2 REQUIRED)
include(KDE4Defaults)
include_directories(${KDE4_INCLUDES}) include_directories(${KDE4_INCLUDES})
set(kdeconnect_battery_SRCS