Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 27515546 authored by Vineet Garg's avatar Vineet Garg

Now per device per link type pairing handlers are there

parent 98d3cf46
......@@ -25,6 +25,7 @@
#include <QtCrypto>
#include "core/networkpackage.h"
#include "pairinghandler.h"
class NetworkPackage;
class LinkProvider;
......@@ -38,9 +39,12 @@ public:
DeviceLink(const QString& deviceId, LinkProvider* parent);
virtual ~DeviceLink() { };
virtual QString name() = 0;
const QString& deviceId() { return mDeviceId; }
LinkProvider* provider() { return mLinkProvider; }
virtual PairingHandler* createPairingHandler(Device* device) = 0;
virtual bool sendPackage(NetworkPackage& np) = 0;
virtual bool sendPackageEncrypted(QCA::PublicKey& publicKey, NetworkPackage& np) = 0;
......
......@@ -30,6 +30,7 @@
#include "uploadjob.h"
#include "downloadjob.h"
#include "socketlinereader.h"
#include "lanpairinghandler.h"
LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket)
: DeviceLink(deviceId, parent)
......@@ -49,10 +50,20 @@ LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSsl
socket->setParent(this);
}
void LanDeviceLink::setOnSsl(bool value) {
QString LanDeviceLink::name()
{
return "LanDeviceLink";
}
void LanDeviceLink::setOnSsl(bool value)
{
onSsl = value;
}
PairingHandler* LanDeviceLink::createPairingHandler(Device* device)
{
return new LanPairingHandler(device);
}
bool LanDeviceLink::sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& np)
{
......
......@@ -38,7 +38,9 @@ class LanDeviceLink
public:
LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket);
virtual QString name();
void setOnSsl(bool value);
virtual PairingHandler* createPairingHandler(Device* device);
bool sendPackage(NetworkPackage& np);
bool sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& np);
UploadJob* sendPayload(NetworkPackage&);
......
......@@ -51,8 +51,6 @@ LanLinkProvider::LanLinkProvider()
mServer = new Server(this);
connect(mServer,SIGNAL(newConnection()),this, SLOT(newConnection()));
m_pairingHandler = new LanPairingHandler();
//Detect when a network interface changes status, so we announce ourelves in the new network
QNetworkConfigurationManager* networkManager;
networkManager = new QNetworkConfigurationManager(this);
......@@ -66,7 +64,6 @@ LanLinkProvider::LanLinkProvider()
LanLinkProvider::~LanLinkProvider()
{
delete m_pairingHandler;
}
void LanLinkProvider::onStart()
......
......@@ -21,9 +21,15 @@
#include <kdeconnectconfig.h>
#include "lanpairinghandler.h"
#include "networkpackagetypes.h"
#include "landevicelink.h"
LanPairingHandler::LanPairingHandler()
LanPairingHandler::LanPairingHandler(Device* device)
: PairingHandler(device)
{
m_pairingTimeout.setSingleShot(true);
m_pairingTimeout.setInterval(30 * 1000); //30 seconds of timeout
connect(&m_pairingTimeout, SIGNAL(timeout()),
this, SLOT(pairingTimeout()));
}
void LanPairingHandler::createPairPackage(NetworkPackage& np)
......@@ -32,51 +38,74 @@ void LanPairingHandler::createPairPackage(NetworkPackage& np)
np.set("publicKey", KdeConnectConfig::instance()->publicKey().toPEM());
}
bool LanPairingHandler::packageReceived(Device *device,const NetworkPackage& np)
bool LanPairingHandler::packageReceived(const NetworkPackage& np)
{
m_pairingTimeout.stop();
//Retrieve their public key
QString keyString = np.get<QString>("publicKey");
device->setPublicKey(QCA::RSAPublicKey::fromPEM(keyString));
if (device->publicKey().isNull()) {
m_device->setPublicKey(QCA::RSAPublicKey::fromPEM(keyString));
if (m_device->publicKey().isNull()) {
return false;
}
return true;
}
bool LanPairingHandler::requestPairing(Device *device)
bool LanPairingHandler::requestPairing()
{
NetworkPackage np(PACKAGE_TYPE_PAIR);
createPairPackage(np);
bool success = device->sendPackage(np);
bool success;
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
success = dl->sendPackage(np);
}
m_pairingTimeout.start();
return success;
}
bool LanPairingHandler::acceptPairing(Device *device)
bool LanPairingHandler::acceptPairing()
{
NetworkPackage np(PACKAGE_TYPE_PAIR);
createPairPackage(np);
bool success = device->sendPackage(np);
bool success;
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
success = dl->sendPackage(np);
}
return success;
}
void LanPairingHandler::rejectPairing(Device *device)
void LanPairingHandler::rejectPairing()
{
// TODO : check status of reject pairing
NetworkPackage np(PACKAGE_TYPE_PAIR);
np.set("pair", false);
device->sendPackage(np);
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->sendPackage(np);
}
}
void LanPairingHandler::pairingDone(Device *device)
void LanPairingHandler::pairingDone()
{
// No need to worry, if either of certificate or public key is null an empty qstring will be returned
KdeConnectConfig::instance()->setDeviceProperty(device->id(), "key", device->publicKey().toPEM());
KdeConnectConfig::instance()->setDeviceProperty(device->id(), "certificate", QString(device->certificate().toPem()));
KdeConnectConfig::instance()->setDeviceProperty(m_device->id(), "key", m_device->publicKey().toPEM());
KdeConnectConfig::instance()->setDeviceProperty(m_device->id(), "certificate", QString(m_device->certificate().toPem()));
m_pairingTimeout.stop(); // Just in case it is started
}
void LanPairingHandler::unpair(Device *device) {
void LanPairingHandler::unpair() {
NetworkPackage np(PACKAGE_TYPE_PAIR);
np.set("pair", false);
bool success = device->sendPackage(np);
Q_UNUSED(success);
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->sendPackage(np);
}
}
void LanPairingHandler::pairingTimeout()
{
NetworkPackage np(PACKAGE_TYPE_PAIR);
np.set("pair", false);
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->sendPackage(np);
}
m_device->pairingTimeout();
}
......@@ -21,22 +21,34 @@
#ifndef KDECONNECT_LANPAIRINGHANDLER_H
#define KDECONNECT_LANPAIRINGHANDLER_H
#include <QTimer>
#include <backends/devicelink.h>
#include "../../device.h"
#include "../pairinghandler.h"
// This class is used pairing related stuff. It has direct access to links and can directly send packages
class LanPairingHandler
: public PairingHandler
{
private:
QTimer m_pairingTimeout;
private Q_SLOTS:
void pairingTimeout();
public:
LanPairingHandler();
LanPairingHandler(Device* device);
virtual ~LanPairingHandler() { }
virtual void createPairPackage(NetworkPackage& np) Q_DECL_OVERRIDE;
virtual bool packageReceived(Device *device,const NetworkPackage& np) Q_DECL_OVERRIDE;
virtual bool requestPairing(Device *device) Q_DECL_OVERRIDE;
virtual bool acceptPairing(Device *device) Q_DECL_OVERRIDE;
virtual void rejectPairing(Device *device) Q_DECL_OVERRIDE;
virtual void pairingDone(Device *device) Q_DECL_OVERRIDE;
virtual void unpair(Device* device) Q_DECL_OVERRIDE;
virtual bool packageReceived(const NetworkPackage& np) Q_DECL_OVERRIDE;
virtual bool requestPairing() Q_DECL_OVERRIDE;
virtual bool acceptPairing() Q_DECL_OVERRIDE;
virtual void rejectPairing() Q_DECL_OVERRIDE;
virtual void pairingDone() Q_DECL_OVERRIDE;
virtual void unpair() Q_DECL_OVERRIDE;
};
......
......@@ -25,6 +25,7 @@
#include <QSslError>
#include <QtNetwork/qsslsocket.h>
// This class overrides QTcpServer to bind QSslSocket to native socket descriptor instead of QTcpSocket
class Server
: public QTcpServer
{
......
......@@ -46,11 +46,6 @@ public:
virtual QString name() = 0;
virtual int priority() = 0;
PairingHandler* pairingHandler() { return m_pairingHandler;}
protected:
PairingHandler* m_pairingHandler;
public Q_SLOTS:
virtual void onStart() = 0;
......
......@@ -21,6 +21,7 @@
#include "loopbackdevicelink.h"
#include "loopbacklinkprovider.h"
#include "../lan/lanpairinghandler.h"
LoopbackDeviceLink::LoopbackDeviceLink(const QString& deviceId, LoopbackLinkProvider* provider)
: DeviceLink(deviceId, provider)
......@@ -28,6 +29,15 @@ LoopbackDeviceLink::LoopbackDeviceLink(const QString& deviceId, LoopbackLinkProv
}
QString LoopbackDeviceLink::name()
{
return "LoopbackDeviceLink";
}
PairingHandler* LoopbackDeviceLink::createPairingHandler(Device *device)
{
return new LanPairingHandler(device);
}
bool LoopbackDeviceLink::sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& input)
{
if (mPrivateKey.isNull() || key.isNull()) {
......
......@@ -32,6 +32,8 @@ class LoopbackDeviceLink
public:
LoopbackDeviceLink(const QString& d, LoopbackLinkProvider* a);
virtual QString name();
virtual PairingHandler* createPairingHandler(Device* device);
virtual bool sendPackage(NetworkPackage& np);
virtual bool sendPackageEncrypted(QCA::PublicKey& publicKey, NetworkPackage& np);
......
......@@ -20,6 +20,21 @@
#include "pairinghandler.h"
PairingHandler::PairingHandler() {
//gcc complains if we don't add something to compile on a class with virtual functions
PairingHandler::PairingHandler(Device* device)
{
m_device = device;
}
void PairingHandler::addLink(DeviceLink *dl)
{
m_deviceLinks.append(dl);
}
void PairingHandler::linkDestroyed(QObject* o)
{
DeviceLink* dl = static_cast<DeviceLink*>(o);
m_deviceLinks.removeOne(dl);
if (m_deviceLinks.isEmpty()) {
Q_EMIT noLinkAvailable();
}
}
\ No newline at end of file
......@@ -21,23 +21,35 @@
#ifndef KDECONNECT_PAIRINGHANDLER_H
#define KDECONNECT_PAIRINGHANDLER_H
#include "device.h"
#include "networkpackage.h"
#include "devicelink.h"
#include <networkpackage.h>
#include <device.h>
class PairingHandler {
class PairingHandler : public QObject
{
Q_OBJECT
protected:
Device* m_device;
QVector<DeviceLink*> m_deviceLinks;
public:
PairingHandler();
PairingHandler(Device* device);
virtual ~PairingHandler() { }
void addLink(DeviceLink* dl);
virtual void createPairPackage(NetworkPackage& np) = 0;
virtual bool packageReceived(Device *device,const NetworkPackage& np) = 0;
virtual bool requestPairing(Device *device) = 0;
virtual bool acceptPairing(Device *device) = 0;
virtual void rejectPairing(Device *device) = 0;
virtual void pairingDone(Device *device) = 0;
virtual void unpair(Device *device) = 0;
virtual bool packageReceived(const NetworkPackage& np) = 0;
virtual bool requestPairing() = 0;
virtual bool acceptPairing() = 0;
virtual void rejectPairing() = 0;
virtual void pairingDone() = 0;
virtual void unpair() = 0;
public Q_SLOTS:
void linkDestroyed(QObject*);
Q_SIGNALS:
void noLinkAvailable();
};
......
......@@ -58,11 +58,6 @@ Device::Device(QObject* parent, const QString& id)
m_deviceType = str2type(info.deviceType);
m_publicKey = QCA::RSAPublicKey::fromPEM(info.publicKey);
m_pairingTimeout.setSingleShot(true);
m_pairingTimeout.setInterval(30 * 1000); //30 seconds of timeout
connect(&m_pairingTimeout, SIGNAL(timeout()),
this, SLOT(pairingTimeout()));
//Register in bus
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
}
......@@ -93,7 +88,7 @@ Device::Device(QObject* parent, const NetworkPackage& identityPackage, DeviceLin
Device::~Device()
{
Q_FOREACH(PairingHandler* ph, m_pairingHandlers) delete ph; // Delete all pairing handlers on deletion of device
}
bool Device::hasPlugin(const QString& name) const
......@@ -209,8 +204,8 @@ void Device::requestPair()
m_pairStatus = Device::Requested;
//Send our own public key
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
bool success = dl->provider()->pairingHandler()->requestPairing(this);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
bool success = ph->requestPairing();
if (!success) {
m_pairStatus = Device::NotPaired;
......@@ -222,15 +217,13 @@ void Device::requestPair()
if (m_pairStatus == Device::Paired) {
return;
}
m_pairingTimeout.start();
}
void Device::unpair()
{
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->provider()->pairingHandler()->unpair(this);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
ph->unpair();
}
unpairInternal();
......@@ -249,9 +242,6 @@ void Device::unpairInternal()
void Device::pairingTimeout()
{
NetworkPackage np(PACKAGE_TYPE_PAIR);
np.set("pair", false);
sendPackage(np);
m_pairStatus = Device::NotPaired;
Q_EMIT pairingFailed(i18n("Timed out"));
}
......@@ -302,6 +292,15 @@ void Device::addLink(const NetworkPackage& identityPackage, DeviceLink* link)
plugin->connected();
}
}
// One pairing handler per type of device link, so check if there is already a pairing handler of same type, if not add it to the list
if (!m_pairingHandlers.contains(link->name())) {
PairingHandler* pairingHandler = link->createPairingHandler(this);
m_pairingHandlers.insert(link->name(), pairingHandler);
connect(m_pairingHandlers[link->name()], SIGNAL(noLinkAvailable()), this, SLOT(destroyPairingHandler()));
}
m_pairingHandlers[link->name()]->addLink(link);
connect(link, SIGNAL(destroyed(QObject*)), m_pairingHandlers[link->name()], SLOT(linkDestroyed(QObject*)));
}
void Device::linkDestroyed(QObject* o)
......@@ -321,6 +320,13 @@ void Device::removeLink(DeviceLink* link)
}
}
void Device::destroyPairingHandler()
{
PairingHandler* ph = qobject_cast<PairingHandler*>(sender());
m_pairingHandlers.remove(m_pairingHandlers.key(ph));
delete ph;
}
bool Device::sendPackage(NetworkPackage& np)
{
if (np.type() != PACKAGE_TYPE_PAIR && isPaired()) {
......@@ -349,12 +355,11 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
qCDebug(KDECONNECT_CORE) << "Already" << (wantsPair? "paired":"unpaired");
if (m_pairStatus == Device::Requested) {
m_pairStatus = Device::NotPaired;
m_pairingTimeout.stop();
Q_EMIT pairingFailed(i18n("Canceled by other peer"));
} else if (m_pairStatus == Device::Paired) {
// If other request's pairing, and we have pair status Paired, send accept pairing
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->provider()->pairingHandler()->acceptPairing(this);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
ph->acceptPairing();
}
}
return;
......@@ -362,12 +367,11 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
if (wantsPair) {
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
bool success = dl->provider()->pairingHandler()->packageReceived(this, np);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
bool success = ph->packageReceived(np);
if (!success) {
if (m_pairStatus == Device::Requested) {
m_pairStatus = Device::NotPaired;
m_pairingTimeout.stop();
}
Q_EMIT pairingFailed(i18n("Received incorrect key"));
return;
......@@ -395,7 +399,6 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
m_pairStatus = Device::NotPaired;
if (prevPairStatus == Device::Requested) {
m_pairingTimeout.stop();
Q_EMIT pairingFailed(i18n("Canceled by other peer"));
} else if (prevPairStatus == Device::Paired) {
unpairInternal();
......@@ -431,8 +434,8 @@ void Device::rejectPairing()
m_pairStatus = Device::NotPaired;
Q_FOREACH(DeviceLink* link, m_deviceLinks) {
link->provider()->pairingHandler()->rejectPairing(this);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
ph->rejectPairing();
}
Q_EMIT pairingFailed(i18n("Canceled by the user"));
......@@ -446,8 +449,8 @@ void Device::acceptPairing()
qCDebug(KDECONNECT_CORE) << "Accepted pairing";
bool success;
Q_FOREACH(DeviceLink* link, m_deviceLinks) {
success = link->provider()->pairingHandler()->acceptPairing(this);
Q_FOREACH(PairingHandler* ph, m_pairingHandlers.values()) {
success = ph->acceptPairing();
}
if (!success) {
......@@ -466,8 +469,6 @@ void Device::setAsPaired()
m_pairStatus = Device::Paired;
m_pairingTimeout.stop(); //Just in case it was started
//Save device info in the config
KdeConnectConfig::instance()->addTrustedDevice(id(), name(), type2str(m_deviceType), m_publicKey.toPEM(), QString::fromLatin1(m_certificate.toPem()));
......
......@@ -26,14 +26,14 @@
#include <QVector>
#include <QSet>
#include <QSslKey>
#include <QTimer>
#include <QtCrypto>
#include <QtNetwork/qsslcertificate.h>
#include <QSslCertificate>
#include "networkpackage.h"
class DeviceLink;
class KdeConnectPlugin;
class PairingHandler;
class KDECONNECTCORE_EXPORT Device
: public QObject
......@@ -109,6 +109,8 @@ public:
Q_SCRIPTABLE QString pluginsConfigFile() const;
void pairingTimeout();
public Q_SLOTS:
///sends a @p np package to the device
virtual bool sendPackage(NetworkPackage& np);
......@@ -124,7 +126,7 @@ public Q_SLOTS:
private Q_SLOTS:
void privateReceivedPackage(const NetworkPackage& np);
void linkDestroyed(QObject* o);
void pairingTimeout();
void destroyPairingHandler();
Q_SIGNALS:
Q_SCRIPTABLE void pluginsChanged();
......@@ -154,10 +156,10 @@ private: //Fields (TODO: dPointer!)
QVector<DeviceLink*> m_deviceLinks;
QHash<QString, KdeConnectPlugin*> m_plugins;
QMap<QString, PairingHandler*> m_pairingHandlers;
QMultiMap<QString, KdeConnectPlugin*> m_pluginsByIncomingInterface;
QMultiMap<QString, KdeConnectPlugin*> m_pluginsByOutgoingInterface;
QTimer m_pairingTimeout;
const QSet<QString> m_incomingCapabilities;
const QSet<QString> m_outgoingCapabilities;
......
......@@ -24,6 +24,8 @@
#include <KJob>
#include <KProcess>
#include <QTimer>
#include "sftpplugin.h"
class Mounter
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment