This commit is contained in:
Albert Vaca 2015-12-02 11:04:35 -08:00
parent af5be6e9e0
commit 03926cc3bf
11 changed files with 74 additions and 53 deletions

View file

@ -52,8 +52,8 @@ public:
virtual bool sendPackageEncrypted(NetworkPackage& np) = 0; virtual bool sendPackageEncrypted(NetworkPackage& np) = 0;
//user actions //user actions
virtual void requestPairing() = 0; virtual void userRequestsPair() = 0;
virtual void unpair() = 0; virtual void userRequestsUnpair() = 0;
ConnectionStarted connectionSource() const { return mConnectionSource; } ConnectionStarted connectionSource() const { return mConnectionSource; }

View file

@ -35,7 +35,7 @@ LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSsl
this, SLOT(dataReceived())); this, SLOT(dataReceived()));
//We take ownership of the socket. //We take ownership of the socket.
//When the link provider distroys us, //When the link provider destroys us,
//the socket (and the reader) will be //the socket (and the reader) will be
//destroyed as well //destroyed as well
connect(socket, SIGNAL(disconnected()), connect(socket, SIGNAL(disconnected()),
@ -57,7 +57,7 @@ bool LanDeviceLink::sendPackageEncrypted(NetworkPackage& np)
int written = mSocketLineReader->write(np.serialize()); int written = mSocketLineReader->write(np.serialize());
//TODO: Actually detect if a package is received or not, now we keep TCP //Actually we can't detect if a package is received or not. We keep TCP
//"ESTABLISHED" connections that look legit (return true when we use them), //"ESTABLISHED" connections that look legit (return true when we use them),
//but that are actually broken (until keepalive detects that they are down). //but that are actually broken (until keepalive detects that they are down).
return (written != -1); return (written != -1);
@ -86,33 +86,36 @@ UploadJob* LanDeviceLink::sendPayload(NetworkPackage& np)
void LanDeviceLink::dataReceived() void LanDeviceLink::dataReceived()
{ {
if (mSocketLineReader->bytesAvailable() == 0) return; if (mSocketLineReader->bytesAvailable() == 0) return;
const QByteArray package = mSocketLineReader->readLine();
//qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << package; //qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << package;
NetworkPackage unserialized(QString::null); const QByteArray serializedPackage = mSocketLineReader->readLine();
NetworkPackage::unserialize(package, &unserialized); NetworkPackage package(QString::null);
if (unserialized.isEncrypted()) { NetworkPackage::unserialize(serializedPackage, &package);
//mPrivateKey should always be set when device link is added to device, no null-checking done here
// TODO : Check this with old device since package through ssl in unencrypted if (package.type() == PACKAGE_TYPE_PAIR) {
unserialized.decrypt(mPrivateKey, &unserialized); //TODO: Handle pair/unpair requests and forward them (to the pairing handler?)
//qobject_cast<LanLinkProvider*>(provider())->incomingPairRequest(deviceId());
} }
if (unserialized.hasPayloadTransferInfo()) { if (!package.isEncrypted()) {
qWarning() << "Received plain-text package from paired link, ignoring!";
}
package.decrypt(mPrivateKey, &package);
if (package.hasPayloadTransferInfo()) {
//qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo"; //qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo";
QVariantMap transferInfo = unserialized.payloadTransferInfo(); QVariantMap transferInfo = package.payloadTransferInfo();
//FIXME: The next two lines shouldn't be needed! Why are they here? //FIXME: The next two lines shouldn't be needed! Why are they here?
transferInfo.insert("useSsl", true); transferInfo.insert("useSsl", true);
transferInfo.insert("deviceId", deviceId()); transferInfo.insert("deviceId", deviceId());
DownloadJob* job = new DownloadJob(mSocketLineReader->peerAddress(), transferInfo); DownloadJob* job = new DownloadJob(mSocketLineReader->peerAddress(), transferInfo);
job->start(); job->start();
unserialized.setPayload(job->getPayload(), unserialized.payloadSize()); package.setPayload(job->getPayload(), package.payloadSize());
} }
Q_EMIT receivedPackage(unserialized); Q_EMIT receivedPackage(package);
if (mSocketLineReader->bytesAvailable() > 0) { if (mSocketLineReader->bytesAvailable() > 0) {
QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection);
@ -120,12 +123,18 @@ void LanDeviceLink::dataReceived()
} }
void LanDeviceLink::requestPairing() void LanDeviceLink::userRequestsPair()
{ {
qobject_cast<LanLinkProvider*>(provider())->requestPairing(deviceId()); qobject_cast<LanLinkProvider*>(provider())->userRequestsPair(deviceId());
} }
void LanDeviceLink::unpair() void LanDeviceLink::userRequestsUnpair()
{ {
setPairStatus(NotPaired); setPairStatus(NotPaired);
} }
void LanDeviceLink::storeTrustedDeviceInformation()
{
Q_ASSERT(!m_certificate.isNull());
Q_ASSERT(!m_publicKey.isNull());
}

View file

@ -43,9 +43,10 @@ public:
bool sendPackageEncrypted(NetworkPackage& np) override; bool sendPackageEncrypted(NetworkPackage& np) override;
UploadJob* sendPayload(NetworkPackage& np); UploadJob* sendPayload(NetworkPackage& np);
virtual void unpair() override; virtual void userRequestsPair() override;
virtual void userRequestsUnpair() override;
void requestPairing(); void storeTrustedDeviceInformation();
private Q_SLOTS: private Q_SLOTS:
void dataReceived(); void dataReceived();

View file

@ -78,6 +78,8 @@ void LanLinkProvider::onStart()
bool success = mUdpServer->bind(bindAddress, port, QUdpSocket::ShareAddress); bool success = mUdpServer->bind(bindAddress, port, QUdpSocket::ShareAddress);
Q_ASSERT(success); Q_ASSERT(success);
qDebug() << "onStart";
mTcpPort = port; mTcpPort = port;
while (!mServer->listen(bindAddress, mTcpPort)) { while (!mServer->listen(bindAddress, mTcpPort)) {
mTcpPort++; mTcpPort++;
@ -93,6 +95,7 @@ void LanLinkProvider::onStart()
void LanLinkProvider::onStop() void LanLinkProvider::onStop()
{ {
qDebug() << "onStop";
mUdpServer->close(); mUdpServer->close();
mServer->close(); mServer->close();
} }
@ -129,7 +132,9 @@ void LanLinkProvider::newUdpConnection() //udpBroadcastReceived
NetworkPackage* receivedPackage = new NetworkPackage(""); NetworkPackage* receivedPackage = new NetworkPackage("");
bool success = NetworkPackage::unserialize(datagram, receivedPackage); bool success = NetworkPackage::unserialize(datagram, receivedPackage);
//qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ; //qDebug() << "udp connection from " << receivedPackage->;
qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ;
if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) { if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) {
delete receivedPackage; delete receivedPackage;
@ -442,24 +447,28 @@ void LanLinkProvider::addLink(const QString& deviceId, QSslSocket* socket, Netwo
mLinks.erase(oldLinkIterator); mLinks.erase(oldLinkIterator);
} }
mLinks[deviceLink->deviceId()] = deviceLink; mLinks[deviceId] = deviceLink;
LanPairingHandler* ph = mPairingHandlers.value(deviceLink->deviceId()); refreshPairingHandler(deviceId);
if (ph) {
ph->setDeviceLink(deviceLink);
}
Q_EMIT onConnectionReceived(*receivedPackage, deviceLink); Q_EMIT onConnectionReceived(*receivedPackage, deviceLink);
} }
void LanLinkProvider::requestPairing(const QString& deviceId) void LanLinkProvider::userRequestsPair(const QString& deviceId)
{ {
LanPairingHandler* ph = mPairingHandlers.value(deviceId); LanPairingHandler* ph = mPairingHandlers.value(deviceId);
if (!ph) { if (!ph) {
new LanPairingHandler(deviceId); ph = new LanPairingHandler(deviceId);
ph->setDeviceLink(mLinks[deviceId]);
mPairingHandlers[deviceId] = ph; mPairingHandlers[deviceId] = ph;
refreshPairingHandler(deviceId);
} }
ph->requestPairing(); ph->requestPairing();
} }
void LanLinkProvider::refreshPairingHandler(const QString& deviceId) {
LanPairingHandler* ph = mPairingHandlers.value(deviceId);
if (ph) {
ph->setDeviceLink(mLinks[deviceId]);
}
}

View file

@ -44,7 +44,7 @@ public:
QString name() override { return "LanLinkProvider"; } QString name() override { return "LanLinkProvider"; }
int priority() override { return PRIORITY_HIGH; } int priority() override { return PRIORITY_HIGH; }
void requestPairing(const QString &deviceId); void userRequestsPair(const QString &deviceId);
public Q_SLOTS: public Q_SLOTS:
virtual void onNetworkChange() override; virtual void onNetworkChange() override;
@ -65,6 +65,7 @@ private:
static void configureSocket(QSslSocket* socket); static void configureSocket(QSslSocket* socket);
void onNetworkConfigurationChanged(const QNetworkConfiguration &config); void onNetworkConfigurationChanged(const QNetworkConfiguration &config);
void addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, DeviceLink::ConnectionStarted connectionOrigin); void addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, DeviceLink::ConnectionStarted connectionOrigin);
void refreshPairingHandler(const QString &deviceId);
Server* mServer; Server* mServer;
QUdpSocket* mUdpServer; QUdpSocket* mUdpServer;

View file

@ -97,7 +97,7 @@ void LanPairingHandler::packageReceived(const NetworkPackage& np)
return; return;
} }
Daemon::instance()->requestPairing(this); Daemon::instance()->askPairingConfirmation(this);
setInternalPairStatus(RequestedByPeer); setInternalPairStatus(RequestedByPeer);
} }
@ -117,10 +117,10 @@ bool LanPairingHandler::requestPairing()
{ {
switch (m_status) { switch (m_status) {
case Paired: case Paired:
Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Already paired").toLatin1().data())); Q_EMIT pairingError(i18n("%1: Already paired", deviceLink()->name()));
return false; return false;
case Requested: case Requested:
Q_EMIT pairingError(i18n(deviceLink()->name().append(" : Pairing already requested for this device").toLatin1().data())); Q_EMIT pairingError(i18n("%1: Pairing already requested for this device", deviceLink()->name()));
return false; return false;
case RequestedByPeer: case RequestedByPeer:
qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request."; qCDebug(KDECONNECT_CORE) << deviceLink()->name() << " : Pairing already started by the other end, accepting their request.";
@ -189,4 +189,6 @@ void LanPairingHandler::setInternalPairStatus(LanPairingHandler::InternalPairSta
} else { } else {
deviceLink()->setPairStatus(DeviceLink::NotPaired); deviceLink()->setPairStatus(DeviceLink::NotPaired);
} }
qobject_cast<LanDeviceLink*>(deviceLink())->storeTrustedDeviceInformation();
//TODO: Tell link to store certificate and key
} }

View file

@ -34,6 +34,7 @@ Server::Server(QObject * parent)
} }
void Server::incomingConnection(qintptr socketDescriptor) { void Server::incomingConnection(qintptr socketDescriptor) {
qDebug() << "incomingConnection";
QSslSocket *serverSocket = new QSslSocket(parent()); QSslSocket *serverSocket = new QSslSocket(parent());
if (serverSocket->setSocketDescriptor(socketDescriptor)) { if (serverSocket->setSocketDescriptor(socketDescriptor)) {
pendingConnections.append(serverSocket); pendingConnections.append(serverSocket);
@ -45,6 +46,7 @@ void Server::incomingConnection(qintptr socketDescriptor) {
} }
QSslSocket* Server::nextPendingConnection() { QSslSocket* Server::nextPendingConnection() {
qDebug() << "nextPendingConnection (emtpy:" << pendingConnections.isEmpty() << ")";
if (pendingConnections.isEmpty()) { if (pendingConnections.isEmpty()) {
return Q_NULLPTR; return Q_NULLPTR;
} else { } else {

View file

@ -36,8 +36,8 @@ public:
virtual bool sendPackage(NetworkPackage& np) override; virtual bool sendPackage(NetworkPackage& np) override;
virtual bool sendPackageEncrypted(NetworkPackage& np) override; virtual bool sendPackageEncrypted(NetworkPackage& np) override;
virtual void requestPairing() override {} virtual void userRequestsPair() override { setPairStatus(Paired); }
virtual void unpair() override {} virtual void userRequestsUnpair() override { setPairStatus(NotPaired); }
}; };
#endif #endif

View file

@ -53,7 +53,7 @@ public:
QList<Device*> devicesList() const; QList<Device*> devicesList() const;
virtual void requestPairing(PairingHandler *d) = 0; virtual void askPairingConfirmation(PairingHandler *d) = 0;
virtual void reportError(const QString &title, const QString &description) = 0; virtual void reportError(const QString &title, const QString &description) = 0;
virtual QNetworkAccessManager* networkAccessManager(); virtual QNetworkAccessManager* networkAccessManager();

View file

@ -195,14 +195,14 @@ void Device::requestPair()
} }
Q_FOREACH(DeviceLink* dl, m_deviceLinks) { Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->requestPairing(); dl->userRequestsPair();
} }
} }
void Device::unpair() void Device::unpair()
{ {
Q_FOREACH(DeviceLink* dl, m_deviceLinks) { Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
dl->unpair(); dl->userRequestsUnpair();
} }
KdeConnectConfig::instance()->removeTrustedDevice(id()); KdeConnectConfig::instance()->removeTrustedDevice(id());
} }
@ -214,7 +214,7 @@ void Device::pairStatusChanged(DeviceLink::PairStatus status)
Q_FOREACH(DeviceLink* dl, m_deviceLinks) { Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
if (dl != sender()) { if (dl != sender()) {
dl->unpair(); dl->setPairStatus(DeviceLink::NotPaired);
} }
} }
} else { } else {
@ -294,15 +294,12 @@ void Device::removeLink(DeviceLink* link)
bool Device::sendPackage(NetworkPackage& np) bool Device::sendPackage(NetworkPackage& np)
{ {
if (np.type() != PACKAGE_TYPE_PAIR && isTrusted()) { Q_ASSERT(np.type() != PACKAGE_TYPE_PAIR);
Q_FOREACH(DeviceLink* dl, m_deviceLinks) { Q_ASSERT(isTrusted());
if (dl->sendPackageEncrypted(np)) return true;
} //Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data
} else { Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
//Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data if (dl->sendPackage(np)) return true;
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
if (dl->sendPackage(np)) return true;
}
} }
return false; return false;

View file

@ -89,7 +89,7 @@ public:
, m_nam(Q_NULLPTR) , m_nam(Q_NULLPTR)
{} {}
void requestPairing(PairingHandler* d) Q_DECL_OVERRIDE void askPairingConfirmation(PairingHandler* d) Q_DECL_OVERRIDE
{ {
KNotification* notification = new KNotification("pairingRequest"); KNotification* notification = new KNotification("pairingRequest");
notification->setIconName(QStringLiteral("dialog-information")); notification->setIconName(QStringLiteral("dialog-information"));