Add DeviceInfo class
Equivalent to this Android MR (see description there): https://invent.kde.org/network/kdeconnect-android/-/merge_requests/374
This commit is contained in:
parent
70bb10d105
commit
db546e7608
27 changed files with 450 additions and 412 deletions
|
@ -14,14 +14,15 @@
|
|||
#include "core_debug.h"
|
||||
#include "multiplexchannel.h"
|
||||
|
||||
BluetoothDeviceLink::BluetoothDeviceLink(const QString &deviceId,
|
||||
LinkProvider *parent,
|
||||
BluetoothDeviceLink::BluetoothDeviceLink(const DeviceInfo &deviceInfo,
|
||||
BluetoothLinkProvider *parent,
|
||||
ConnectionMultiplexer *connection,
|
||||
QSharedPointer<MultiplexChannel> socket)
|
||||
: DeviceLink(deviceId, parent)
|
||||
: DeviceLink(deviceInfo.id, parent)
|
||||
, mSocketReader(new DeviceLineReader(socket.data(), this))
|
||||
, mConnection(connection)
|
||||
, mChannel(socket)
|
||||
, mDeviceInfo(deviceInfo)
|
||||
{
|
||||
connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived);
|
||||
|
||||
|
@ -69,8 +70,3 @@ void BluetoothDeviceLink::dataReceived()
|
|||
QMetaObject::invokeMethod(this, &BluetoothDeviceLink::dataReceived, Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
QSslCertificate BluetoothDeviceLink::certificate() const
|
||||
{
|
||||
return QSslCertificate({}); // TODO Not sure what to do here. For LanDeviceLink we use the SSL connection's certificate, but we don't have that here
|
||||
}
|
||||
|
|
|
@ -17,17 +17,24 @@
|
|||
|
||||
class ConnectionMultiplexer;
|
||||
class MultiplexChannel;
|
||||
class BluetoothLinkProvider;
|
||||
|
||||
class KDECONNECTCORE_EXPORT BluetoothDeviceLink : public DeviceLink
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BluetoothDeviceLink(const QString &deviceId, LinkProvider *parent, ConnectionMultiplexer *connection, QSharedPointer<MultiplexChannel> socket);
|
||||
BluetoothDeviceLink(const DeviceInfo &deviceInfo,
|
||||
BluetoothLinkProvider *parent,
|
||||
ConnectionMultiplexer *connection,
|
||||
QSharedPointer<MultiplexChannel> socket);
|
||||
|
||||
bool sendPacket(NetworkPacket &np) override;
|
||||
|
||||
QSslCertificate certificate() const override;
|
||||
DeviceInfo deviceInfo() const override
|
||||
{
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
private Q_SLOTS:
|
||||
void dataReceived();
|
||||
|
@ -36,6 +43,7 @@ private:
|
|||
DeviceLineReader *mSocketReader;
|
||||
ConnectionMultiplexer *mConnection;
|
||||
QSharedPointer<MultiplexChannel> mChannel;
|
||||
DeviceInfo mDeviceInfo;
|
||||
|
||||
void sendMessage(const QString mMessage);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "bluetoothdevicelink.h"
|
||||
#include "connectionmultiplexer.h"
|
||||
#include "core_debug.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
#include "multiplexchannel.h"
|
||||
|
||||
#include <QBluetoothServiceInfo>
|
||||
|
@ -83,13 +84,7 @@ void BluetoothLinkProvider::connectError()
|
|||
void BluetoothLinkProvider::addLink(BluetoothDeviceLink *deviceLink, const QString &deviceId)
|
||||
{
|
||||
QMap<QString, DeviceLink *>::iterator oldLinkIterator = mLinks.find(deviceId);
|
||||
if (oldLinkIterator != mLinks.end()) {
|
||||
DeviceLink *oldLink = oldLinkIterator.value();
|
||||
disconnect(oldLink, SIGNAL(destroyed(QObject *)), this, SLOT(deviceLinkDestroyed(QObject *)));
|
||||
oldLink->deleteLater();
|
||||
mLinks.erase(oldLinkIterator);
|
||||
}
|
||||
|
||||
delete oldLinkIterator.value(); // not calling deleteLater because this triggers onLinkDestroyed
|
||||
mLinks[deviceId] = deviceLink;
|
||||
}
|
||||
|
||||
|
@ -187,22 +182,22 @@ void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer
|
|||
// TODO?
|
||||
// disconnect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
|
||||
|
||||
const QString &deviceId = receivedPacket.get<QString>(QStringLiteral("deviceId"));
|
||||
BluetoothDeviceLink *deviceLink = new BluetoothDeviceLink(deviceId, this, mSockets[peer], socket);
|
||||
QSslCertificate receivedCertificate(receivedPacket.get<QString>(QStringLiteral("certificate")).toLatin1());
|
||||
DeviceInfo deviceInfo = deviceInfo.FromIdentityPacketAndCert(receivedPacket, receivedCertificate);
|
||||
BluetoothDeviceLink *deviceLink = new BluetoothDeviceLink(deviceInfo, this, mSockets[peer], socket);
|
||||
|
||||
NetworkPacket np2;
|
||||
NetworkPacket::createIdentityPacket(&np2);
|
||||
success = deviceLink->sendPacket(np2);
|
||||
DeviceInfo myDeviceInfo = KdeConnectConfig::instance().deviceInfo();
|
||||
NetworkPacket myIdentity = myDeviceInfo.toIdentityPacket();
|
||||
myIdentity.set(QStringLiteral("certificate"), QString::fromLatin1(myDeviceInfo.certificate.toPem()));
|
||||
success = deviceLink->sendPacket(myIdentity);
|
||||
|
||||
if (success) {
|
||||
qCDebug(KDECONNECT_CORE) << "Handshaking done (I'm the new device)";
|
||||
|
||||
connect(deviceLink, SIGNAL(destroyed(QObject *)), this, SLOT(deviceLinkDestroyed(QObject *)));
|
||||
|
||||
Q_EMIT onConnectionReceived(receivedPacket, deviceLink);
|
||||
Q_EMIT onConnectionReceived(deviceLink);
|
||||
|
||||
// We kill any possible link from this same device
|
||||
addLink(deviceLink, deviceId);
|
||||
addLink(deviceLink, deviceInfo.id);
|
||||
|
||||
} else {
|
||||
// Connection might be lost. Delete it.
|
||||
|
@ -246,9 +241,10 @@ void BluetoothLinkProvider::serverNewConnection()
|
|||
return;
|
||||
}
|
||||
|
||||
NetworkPacket np2;
|
||||
NetworkPacket::createIdentityPacket(&np2);
|
||||
socket->write(np2.serialize());
|
||||
DeviceInfo myDeviceInfo = KdeConnectConfig::instance().deviceInfo();
|
||||
NetworkPacket myIdentity = myDeviceInfo.toIdentityPacket();
|
||||
myIdentity.set(QStringLiteral("certificate"), QString::fromLatin1(myDeviceInfo.certificate.toPem()));
|
||||
socket->write(myIdentity.serialize());
|
||||
|
||||
qCDebug(KDECONNECT_CORE()) << "Sent identity packet to" << socket->peerAddress();
|
||||
}
|
||||
|
@ -281,24 +277,20 @@ void BluetoothLinkProvider::serverDataReceived(const QBluetoothAddress &peer, QS
|
|||
|
||||
qCDebug(KDECONNECT_CORE()) << "Received identity packet from" << peer;
|
||||
|
||||
const QString &deviceId = receivedPacket.get<QString>(QStringLiteral("deviceId"));
|
||||
BluetoothDeviceLink *deviceLink = new BluetoothDeviceLink(deviceId, this, mSockets[peer], socket);
|
||||
QSslCertificate receivedCertificate(receivedPacket.get<QString>(QStringLiteral("certificate")).toLatin1());
|
||||
DeviceInfo deviceInfo = deviceInfo.FromIdentityPacketAndCert(receivedPacket, receivedCertificate);
|
||||
BluetoothDeviceLink *deviceLink = new BluetoothDeviceLink(deviceInfo, this, mSockets[peer], socket);
|
||||
|
||||
connect(deviceLink, SIGNAL(destroyed(QObject *)), this, SLOT(deviceLinkDestroyed(QObject *)));
|
||||
Q_EMIT onConnectionReceived(deviceLink);
|
||||
|
||||
Q_EMIT onConnectionReceived(receivedPacket, deviceLink);
|
||||
|
||||
addLink(deviceLink, deviceId);
|
||||
addLink(deviceLink, deviceInfo.id);
|
||||
}
|
||||
|
||||
void BluetoothLinkProvider::deviceLinkDestroyed(QObject *destroyedDeviceLink)
|
||||
void BluetoothLinkProvider::onLinkDestroyed(const QString &deviceId, DeviceLink *oldPtr)
|
||||
{
|
||||
const QString id = destroyedDeviceLink->property("deviceId").toString();
|
||||
qCDebug(KDECONNECT_CORE()) << "Device disconnected:" << id;
|
||||
QMap<QString, DeviceLink *>::iterator oldLinkIterator = mLinks.find(id);
|
||||
if (oldLinkIterator != mLinks.end() && oldLinkIterator.value() == destroyedDeviceLink) {
|
||||
mLinks.erase(oldLinkIterator);
|
||||
}
|
||||
qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider deviceLinkDestroyed" << deviceId;
|
||||
DeviceLink *link = mLinks.take(deviceId);
|
||||
Q_ASSERT(link == oldPtr);
|
||||
}
|
||||
|
||||
void BluetoothLinkProvider::socketDisconnected(const QBluetoothAddress &peer, MultiplexChannel *socket)
|
||||
|
|
|
@ -41,10 +41,10 @@ public Q_SLOTS:
|
|||
virtual void onNetworkChange() override;
|
||||
virtual void onStart() override;
|
||||
virtual void onStop() override;
|
||||
virtual void onLinkDestroyed(const QString &deviceId, DeviceLink *oldPtr) override;
|
||||
void connectError();
|
||||
|
||||
private Q_SLOTS:
|
||||
void deviceLinkDestroyed(QObject *destroyedDeviceLink);
|
||||
void socketDisconnected(const QBluetoothAddress &peerAddress, MultiplexChannel *socket);
|
||||
|
||||
void serverNewConnection();
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
*/
|
||||
|
||||
#include "devicelink.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
|
||||
#include "linkprovider.h"
|
||||
|
||||
DeviceLink::DeviceLink(const QString &deviceId, LinkProvider *parent)
|
||||
: QObject(parent)
|
||||
, m_deviceId(deviceId)
|
||||
, m_linkProvider(parent)
|
||||
{
|
||||
Q_ASSERT(!deviceId.isEmpty());
|
||||
|
||||
setProperty("deviceId", deviceId);
|
||||
connect(this, &QObject::destroyed, [this, deviceId, parent]() {
|
||||
parent->onLinkDestroyed(deviceId, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,42 +9,29 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include "deviceinfo.h"
|
||||
#include "networkpacket.h"
|
||||
|
||||
class PairingHandler;
|
||||
class NetworkPacket;
|
||||
class LinkProvider;
|
||||
class Device;
|
||||
class QSslCertificate;
|
||||
|
||||
class DeviceLink : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
DeviceLink(const QString &deviceId, LinkProvider *parent);
|
||||
~DeviceLink() override = default;
|
||||
|
||||
const QString &deviceId() const
|
||||
QString deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
}
|
||||
LinkProvider *provider()
|
||||
{
|
||||
return m_linkProvider;
|
||||
return deviceInfo().id;
|
||||
}
|
||||
|
||||
virtual bool sendPacket(NetworkPacket &np) = 0;
|
||||
|
||||
virtual QSslCertificate certificate() const = 0;
|
||||
virtual DeviceInfo deviceInfo() const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void receivedPacket(const NetworkPacket &np);
|
||||
|
||||
private:
|
||||
const QString m_deviceId;
|
||||
LinkProvider *m_linkProvider;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,14 +15,15 @@
|
|||
#include "plugins/share/shareplugin.h"
|
||||
#include "socketlinereader.h"
|
||||
|
||||
LanDeviceLink::LanDeviceLink(const QString &deviceId, LinkProvider *parent, QSslSocket *socket, ConnectionStarted connectionSource)
|
||||
: DeviceLink(deviceId, parent)
|
||||
LanDeviceLink::LanDeviceLink(const DeviceInfo &deviceInfo, LanLinkProvider *parent, QSslSocket *socket)
|
||||
: DeviceLink(deviceInfo.id, parent)
|
||||
, m_socketLineReader(nullptr)
|
||||
, m_deviceInfo(deviceInfo)
|
||||
{
|
||||
reset(socket, connectionSource);
|
||||
reset(socket);
|
||||
}
|
||||
|
||||
void LanDeviceLink::reset(QSslSocket *socket, ConnectionStarted connectionSource)
|
||||
void LanDeviceLink::reset(QSslSocket *socket)
|
||||
{
|
||||
if (m_socketLineReader) {
|
||||
disconnect(m_socketLineReader->m_socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater);
|
||||
|
@ -39,10 +40,6 @@ void LanDeviceLink::reset(QSslSocket *socket, ConnectionStarted connectionSource
|
|||
// the socket (and the reader) will be
|
||||
// destroyed as well
|
||||
socket->setParent(m_socketLineReader);
|
||||
|
||||
m_connectionSource = connectionSource;
|
||||
|
||||
QString certString = KdeConnectConfig::instance().getDeviceProperty(deviceId(), QStringLiteral("certificate"));
|
||||
}
|
||||
|
||||
QHostAddress LanDeviceLink::hostAddress() const
|
||||
|
@ -98,7 +95,7 @@ void LanDeviceLink::dataReceived()
|
|||
return;
|
||||
|
||||
const QByteArray serializedPacket = m_socketLineReader->readLine();
|
||||
NetworkPacket packet((QString()));
|
||||
NetworkPacket packet;
|
||||
NetworkPacket::unserialize(serializedPacket, &packet);
|
||||
|
||||
// qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << serializedPacket;
|
||||
|
@ -127,8 +124,3 @@ void LanDeviceLink::dataReceived()
|
|||
QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
QSslCertificate LanDeviceLink::certificate() const
|
||||
{
|
||||
return m_socketLineReader->peerCertificate();
|
||||
}
|
||||
|
|
|
@ -9,16 +9,17 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QSslCertificate>
|
||||
#include <QSslSocket>
|
||||
#include <QString>
|
||||
|
||||
#include "backends/devicelink.h"
|
||||
#include "compositeuploadjob.h"
|
||||
#include "deviceinfo.h"
|
||||
#include "uploadjob.h"
|
||||
#include <kdeconnectcore_export.h>
|
||||
|
||||
class SocketLineReader;
|
||||
class LanLinkProvider;
|
||||
|
||||
class KDECONNECTCORE_EXPORT LanDeviceLink : public DeviceLink
|
||||
{
|
||||
|
@ -27,13 +28,17 @@ class KDECONNECTCORE_EXPORT LanDeviceLink : public DeviceLink
|
|||
public:
|
||||
enum ConnectionStarted : bool { Locally, Remotely };
|
||||
|
||||
LanDeviceLink(const QString &deviceId, LinkProvider *parent, QSslSocket *socket, ConnectionStarted connectionSource);
|
||||
void reset(QSslSocket *socket, ConnectionStarted connectionSource);
|
||||
LanDeviceLink(const DeviceInfo &deviceInfo, LanLinkProvider *parent, QSslSocket *socket);
|
||||
void reset(QSslSocket *socket);
|
||||
|
||||
bool sendPacket(NetworkPacket &np) override;
|
||||
|
||||
DeviceInfo deviceInfo() const override
|
||||
{
|
||||
return m_deviceInfo;
|
||||
}
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
QSslCertificate certificate() const override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void dataReceived();
|
||||
|
@ -42,6 +47,7 @@ private:
|
|||
SocketLineReader *m_socketLineReader;
|
||||
ConnectionStarted m_connectionSource;
|
||||
QPointer<CompositeUploadJob> m_compositeUploadJob;
|
||||
DeviceInfo m_deviceInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "landevicelink.h"
|
||||
#include "qtcompat_p.h"
|
||||
|
||||
#define MIN_VERSION_WITH_SSL_SUPPORT 6
|
||||
|
||||
static const int MAX_UNPAIRED_CONNECTIONS = 42;
|
||||
static const int MAX_REMEMBERED_IDENTITY_PACKETS = 42;
|
||||
|
||||
|
@ -137,8 +135,7 @@ void LanLinkProvider::broadcastToNetwork()
|
|||
|
||||
QList<QHostAddress> destinations = getBroadcastAddresses();
|
||||
|
||||
NetworkPacket np;
|
||||
NetworkPacket::createIdentityPacket(&np);
|
||||
NetworkPacket np = KdeConnectConfig::instance().deviceInfo().toIdentityPacket();
|
||||
np.set(QStringLiteral("tcpPort"), m_tcpPort);
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)
|
||||
// On macOS and FreeBSD, the too large UDP packet (larger than MTU) causes
|
||||
|
@ -235,7 +232,7 @@ void LanLinkProvider::udpBroadcastReceived()
|
|||
if (sender.isLoopback() && !m_testMode)
|
||||
continue;
|
||||
|
||||
NetworkPacket *receivedPacket = new NetworkPacket(QLatin1String(""));
|
||||
NetworkPacket *receivedPacket = new NetworkPacket();
|
||||
bool success = NetworkPacket::unserialize(datagram, receivedPacket);
|
||||
|
||||
// qCDebug(KDECONNECT_CORE) << "udp connection from " << receivedPacket->;
|
||||
|
@ -298,8 +295,7 @@ void LanLinkProvider::connectError(QAbstractSocket::SocketError socketError)
|
|||
|
||||
qCDebug(KDECONNECT_CORE) << "Socket error" << socketError;
|
||||
qCDebug(KDECONNECT_CORE) << "Fallback (1), try reverse connection (send udp packet)" << socket->errorString();
|
||||
NetworkPacket np(QLatin1String(""));
|
||||
NetworkPacket::createIdentityPacket(&np);
|
||||
NetworkPacket np = KdeConnectConfig::instance().deviceInfo().toIdentityPacket();
|
||||
np.set(QStringLiteral("tcpPort"), m_tcpPort);
|
||||
m_udpSocket.writeDatagram(np.serialize(), m_receivedIdentityPackets[socket].sender, m_udpBroadcastPort);
|
||||
|
||||
|
@ -335,8 +331,7 @@ void LanLinkProvider::tcpSocketConnected()
|
|||
// qCDebug(KDECONNECT_CORE) << "tcpSocketConnected" << socket->isWritable();
|
||||
|
||||
// If network is on ssl, do not believe when they are connected, believe when handshake is completed
|
||||
NetworkPacket np2(QLatin1String(""));
|
||||
NetworkPacket::createIdentityPacket(&np2);
|
||||
NetworkPacket np2 = KdeConnectConfig::instance().deviceInfo().toIdentityPacket();
|
||||
socket->write(np2.serialize());
|
||||
bool success = socket->waitForBytesWritten();
|
||||
|
||||
|
@ -344,33 +339,26 @@ void LanLinkProvider::tcpSocketConnected()
|
|||
qCDebug(KDECONNECT_CORE) << "TCP connection done (i'm the existing device)";
|
||||
|
||||
// if ssl supported
|
||||
if (receivedPacket->get<int>(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) {
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceId);
|
||||
configureSslSocket(socket, deviceId, isDeviceTrusted);
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceId);
|
||||
configureSslSocket(socket, deviceId, isDeviceTrusted);
|
||||
|
||||
qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";
|
||||
qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";
|
||||
|
||||
connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted);
|
||||
connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted);
|
||||
|
||||
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &LanLinkProvider::sslErrors);
|
||||
|
||||
socket->startServerEncryption();
|
||||
|
||||
return; // Return statement prevents from deleting received packet, needed in slot "encrypted"
|
||||
} else {
|
||||
qWarning() << receivedPacket->get<QString>(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work";
|
||||
// addLink(deviceId, socket, receivedPacket, LanDeviceLink::Remotely);
|
||||
}
|
||||
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &LanLinkProvider::sslErrors);
|
||||
|
||||
socket->startServerEncryption();
|
||||
} else {
|
||||
// I think this will never happen, but if it happens the deviceLink
|
||||
//(or the socket that is now inside it) might not be valid. Delete them.
|
||||
// The socket doesn't seem to work, so we can't create the connection.
|
||||
|
||||
qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)";
|
||||
m_udpSocket.writeDatagram(np2.serialize(), m_receivedIdentityPackets[socket].sender, m_udpBroadcastPort);
|
||||
}
|
||||
|
||||
delete m_receivedIdentityPackets.take(socket).np;
|
||||
// We don't delete the socket because now it's owned by the LanDeviceLink
|
||||
// Cleanup the network packet now. The socket should be deleted via the disconnected() signal.
|
||||
// We don't do this on success, because it is done later in the encrypted() slot.
|
||||
delete m_receivedIdentityPackets.take(socket).np;
|
||||
}
|
||||
}
|
||||
|
||||
void LanLinkProvider::encrypted()
|
||||
|
@ -382,20 +370,14 @@ void LanLinkProvider::encrypted()
|
|||
return;
|
||||
|
||||
Q_ASSERT(socket->mode() != QSslSocket::UnencryptedMode);
|
||||
LanDeviceLink::ConnectionStarted connectionOrigin = (socket->mode() == QSslSocket::SslClientMode) ? LanDeviceLink::Locally : LanDeviceLink::Remotely;
|
||||
|
||||
NetworkPacket *receivedPacket = m_receivedIdentityPackets[socket].np;
|
||||
const QString &deviceId = socket->peerCertificate().subjectDisplayName();
|
||||
NetworkPacket *identityPacket = m_receivedIdentityPackets[socket].np;
|
||||
|
||||
if (m_links.contains(deviceId) && m_links[deviceId]->certificate() != socket->peerCertificate()) {
|
||||
socket->disconnectFromHost();
|
||||
qCWarning(KDECONNECT_CORE) << "Got connection for the same deviceId but certificates don't match. Ignoring " << deviceId;
|
||||
return;
|
||||
}
|
||||
DeviceInfo deviceInfo = DeviceInfo::FromIdentityPacketAndCert(*identityPacket, socket->peerCertificate());
|
||||
|
||||
addLink(deviceId, socket, receivedPacket, connectionOrigin);
|
||||
addLink(socket, deviceInfo);
|
||||
|
||||
// Copied from tcpSocketConnected slot, now delete received packet
|
||||
// We don't delete the socket because now it's owned by the LanDeviceLink
|
||||
delete m_receivedIdentityPackets.take(socket).np;
|
||||
}
|
||||
|
||||
|
@ -472,7 +454,7 @@ void LanLinkProvider::dataReceived()
|
|||
|
||||
qCDebug(KDECONNECT_CORE) << "LanLinkProvider received reply:" << data;
|
||||
|
||||
NetworkPacket *np = new NetworkPacket(QLatin1String(""));
|
||||
NetworkPacket *np = new NetworkPacket();
|
||||
bool success = NetworkPacket::unserialize(data, np);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||
|
@ -510,37 +492,25 @@ void LanLinkProvider::dataReceived()
|
|||
// This socket will now be owned by the LanDeviceLink or we don't want more data to be received, forget about it
|
||||
disconnect(socket, &QIODevice::readyRead, this, &LanLinkProvider::dataReceived);
|
||||
|
||||
if (np->get<int>(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) {
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceId);
|
||||
configureSslSocket(socket, deviceId, isDeviceTrusted);
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceId);
|
||||
configureSslSocket(socket, deviceId, isDeviceTrusted);
|
||||
|
||||
qCDebug(KDECONNECT_CORE) << "Starting client ssl (but I'm the server TCP socket)";
|
||||
qCDebug(KDECONNECT_CORE) << "Starting client ssl (but I'm the server TCP socket)";
|
||||
|
||||
connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted);
|
||||
connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted);
|
||||
|
||||
if (isDeviceTrusted) {
|
||||
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &LanLinkProvider::sslErrors);
|
||||
}
|
||||
|
||||
socket->startClientEncryption();
|
||||
|
||||
} else {
|
||||
qWarning() << np->get<QString>(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work";
|
||||
// addLink(deviceId, socket, np, LanDeviceLink::Locally);
|
||||
delete m_receivedIdentityPackets.take(socket).np;
|
||||
if (isDeviceTrusted) {
|
||||
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &LanLinkProvider::sslErrors);
|
||||
}
|
||||
|
||||
socket->startClientEncryption();
|
||||
}
|
||||
|
||||
void LanLinkProvider::deviceLinkDestroyed(QObject *destroyedDeviceLink)
|
||||
void LanLinkProvider::onLinkDestroyed(const QString &deviceId, DeviceLink *oldPtr)
|
||||
{
|
||||
const QString id = destroyedDeviceLink->property("deviceId").toString();
|
||||
// qCDebug(KDECONNECT_CORE) << "deviceLinkDestroyed" << id;
|
||||
QMap<QString, LanDeviceLink *>::iterator linkIterator = m_links.find(id);
|
||||
Q_ASSERT(linkIterator != m_links.end());
|
||||
if (linkIterator != m_links.end()) {
|
||||
Q_ASSERT(linkIterator.value() == destroyedDeviceLink);
|
||||
m_links.erase(linkIterator);
|
||||
}
|
||||
qCDebug(KDECONNECT_CORE) << "LanLinkProvider deviceLinkDestroyed" << deviceId;
|
||||
DeviceLink *link = m_links.take(deviceId);
|
||||
Q_ASSERT(link == oldPtr);
|
||||
}
|
||||
|
||||
void LanLinkProvider::configureSslSocket(QSslSocket *socket, const QString &deviceId, bool isDeviceTrusted)
|
||||
|
@ -558,8 +528,8 @@ void LanLinkProvider::configureSslSocket(QSslSocket *socket, const QString &devi
|
|||
sslConfig.setPrivateKey(privateKey);
|
||||
|
||||
if (isDeviceTrusted) {
|
||||
QString certString = KdeConnectConfig::instance().getDeviceProperty(deviceId, QStringLiteral("certificate"), QString());
|
||||
sslConfig.setCaCertificates({QSslCertificate(certString.toLatin1())});
|
||||
QSslCertificate certificate = KdeConnectConfig::instance().getTrustedDeviceCertificate(deviceId);
|
||||
sslConfig.setCaCertificates({certificate});
|
||||
sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer);
|
||||
} else {
|
||||
sslConfig.setPeerVerifyMode(QSslSocket::QueryPeer);
|
||||
|
@ -622,31 +592,41 @@ void LanLinkProvider::configureSocket(QSslSocket *socket)
|
|||
#endif
|
||||
}
|
||||
|
||||
void LanLinkProvider::addLink(const QString &deviceId, QSslSocket *socket, NetworkPacket *receivedPacket, LanDeviceLink::ConnectionStarted connectionOrigin)
|
||||
void LanLinkProvider::addLink(QSslSocket *socket, const DeviceInfo &deviceInfo)
|
||||
{
|
||||
QString certDeviceId = socket->peerCertificate().subjectDisplayName();
|
||||
if (deviceInfo.id != certDeviceId) {
|
||||
socket->disconnectFromHost();
|
||||
qCWarning(KDECONNECT_CORE) << "DeviceID in cert doesn't match deviceID in identity packet. " << deviceInfo.id << " vs " << certDeviceId;
|
||||
return;
|
||||
}
|
||||
|
||||
// Socket disconnection will now be handled by LanDeviceLink
|
||||
disconnect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
|
||||
|
||||
LanDeviceLink *deviceLink;
|
||||
// Do we have a link for this device already?
|
||||
QMap<QString, LanDeviceLink *>::iterator linkIterator = m_links.find(deviceId);
|
||||
QMap<QString, LanDeviceLink *>::iterator linkIterator = m_links.find(deviceInfo.id);
|
||||
if (linkIterator != m_links.end()) {
|
||||
// qCDebug(KDECONNECT_CORE) << "Reusing link to" << deviceId;
|
||||
deviceLink = linkIterator.value();
|
||||
deviceLink->reset(socket, connectionOrigin);
|
||||
if (deviceLink->deviceInfo().certificate != deviceInfo.certificate) {
|
||||
qWarning() << "LanLink was asked to replace a socket but the certificate doesn't match, aborting";
|
||||
return;
|
||||
}
|
||||
// qCDebug(KDECONNECT_CORE) << "Reusing link to" << deviceId;
|
||||
deviceLink->reset(socket);
|
||||
} else {
|
||||
deviceLink = new LanDeviceLink(deviceId, this, socket, connectionOrigin);
|
||||
deviceLink = new LanDeviceLink(deviceInfo, this, socket);
|
||||
// Socket disconnection will now be handled by LanDeviceLink
|
||||
disconnect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceId);
|
||||
bool isDeviceTrusted = KdeConnectConfig::instance().trustedDevices().contains(deviceInfo.id);
|
||||
if (!isDeviceTrusted && m_links.size() > MAX_UNPAIRED_CONNECTIONS) {
|
||||
qCWarning(KDECONNECT_CORE) << "Too many unpaired devices to remember them all. Ignoring " << deviceId;
|
||||
qCWarning(KDECONNECT_CORE) << "Too many unpaired devices to remember them all. Ignoring " << deviceInfo.id;
|
||||
socket->disconnectFromHost();
|
||||
socket->deleteLater();
|
||||
return;
|
||||
}
|
||||
connect(deviceLink, &QObject::destroyed, this, &LanLinkProvider::deviceLinkDestroyed);
|
||||
m_links[deviceId] = deviceLink;
|
||||
m_links[deviceInfo.id] = deviceLink;
|
||||
}
|
||||
Q_EMIT onConnectionReceived(*receivedPacket, deviceLink);
|
||||
Q_EMIT onConnectionReceived(deviceLink);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
void onNetworkChange() override;
|
||||
void onLinkDestroyed(const QString &deviceId, DeviceLink *oldPtr) override;
|
||||
void onStart() override;
|
||||
void onStop() override;
|
||||
void tcpSocketConnected();
|
||||
|
@ -59,13 +60,12 @@ private Q_SLOTS:
|
|||
void udpBroadcastReceived();
|
||||
void newConnection();
|
||||
void dataReceived();
|
||||
void deviceLinkDestroyed(QObject *destroyedDeviceLink);
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
void broadcastToNetwork();
|
||||
|
||||
private:
|
||||
void onNetworkConfigurationChanged(const QNetworkConfiguration &config);
|
||||
void addLink(const QString &deviceId, QSslSocket *socket, NetworkPacket *receivedPacket, LanDeviceLink::ConnectionStarted connectionOrigin);
|
||||
void addLink(QSslSocket *socket, const DeviceInfo &deviceInfo);
|
||||
QList<QHostAddress> getBroadcastAddresses();
|
||||
void sendBroadcasts(QUdpSocket &socket, const NetworkPacket &np, const QList<QHostAddress> &addresses);
|
||||
|
||||
|
|
|
@ -28,14 +28,12 @@ public Q_SLOTS:
|
|||
virtual void onStart() = 0;
|
||||
virtual void onStop() = 0;
|
||||
virtual void onNetworkChange() = 0;
|
||||
virtual void onLinkDestroyed(const QString &deviceId, DeviceLink *oldPtr) = 0;
|
||||
|
||||
void suspend(bool suspend);
|
||||
|
||||
Q_SIGNALS:
|
||||
// NOTE: The provider will 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 NetworkPacket &identityPacket, DeviceLink *);
|
||||
void onConnectionReceived(DeviceLink *);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
|
||||
#include "loopbackdevicelink.h"
|
||||
|
||||
#include "kdeconnectconfig.h"
|
||||
#include "loopbacklinkprovider.h"
|
||||
|
||||
LoopbackDeviceLink::LoopbackDeviceLink(const QString &deviceId, LoopbackLinkProvider *provider)
|
||||
: DeviceLink(deviceId, provider)
|
||||
LoopbackDeviceLink::LoopbackDeviceLink(LoopbackLinkProvider *parent)
|
||||
: DeviceLink(KdeConnectConfig::instance().deviceId(), parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -29,3 +30,8 @@ bool LoopbackDeviceLink::sendPacket(NetworkPacket &input)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
DeviceInfo LoopbackDeviceLink::deviceInfo() const
|
||||
{
|
||||
return KdeConnectConfig::instance().deviceInfo();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define LOOPBACKDEVICELINK_H
|
||||
|
||||
#include "../devicelink.h"
|
||||
#include <QSslCertificate>
|
||||
#include "deviceinfo.h"
|
||||
|
||||
class LoopbackLinkProvider;
|
||||
|
||||
|
@ -16,14 +16,11 @@ class LoopbackDeviceLink : public DeviceLink
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LoopbackDeviceLink(const QString &d, LoopbackLinkProvider *a);
|
||||
LoopbackDeviceLink(LoopbackLinkProvider *a);
|
||||
|
||||
bool sendPacket(NetworkPacket &np) override;
|
||||
virtual bool sendPacket(NetworkPacket &np) override;
|
||||
|
||||
QSslCertificate certificate() const override
|
||||
{
|
||||
return QSslCertificate();
|
||||
}
|
||||
virtual DeviceInfo deviceInfo() const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
#include "core_debug.h"
|
||||
|
||||
LoopbackLinkProvider::LoopbackLinkProvider()
|
||||
: identityPacket(PACKET_TYPE_IDENTITY)
|
||||
{
|
||||
NetworkPacket::createIdentityPacket(&identityPacket);
|
||||
}
|
||||
|
||||
LoopbackLinkProvider::~LoopbackLinkProvider()
|
||||
|
@ -20,8 +18,8 @@ LoopbackLinkProvider::~LoopbackLinkProvider()
|
|||
|
||||
void LoopbackLinkProvider::onNetworkChange()
|
||||
{
|
||||
LoopbackDeviceLink *newLoopbackDeviceLink = new LoopbackDeviceLink(QStringLiteral("loopback"), this);
|
||||
Q_EMIT onConnectionReceived(identityPacket, newLoopbackDeviceLink);
|
||||
LoopbackDeviceLink *newLoopbackDeviceLink = new LoopbackDeviceLink(this);
|
||||
Q_EMIT onConnectionReceived(newLoopbackDeviceLink);
|
||||
|
||||
if (loopbackDeviceLink) {
|
||||
delete loopbackDeviceLink;
|
||||
|
|
|
@ -26,10 +26,12 @@ public:
|
|||
void onStart() override;
|
||||
void onStop() override;
|
||||
void onNetworkChange() override;
|
||||
void onLinkDestroyed(const QString &, DeviceLink *) override
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
QPointer<LoopbackDeviceLink> loopbackDeviceLink;
|
||||
NetworkPacket identityPacket;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -158,24 +158,24 @@ QMap<QString, QString> Daemon::deviceNames(bool onlyReachable, bool onlyTrusted)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Daemon::onNewDeviceLink(const NetworkPacket &identityPacket, DeviceLink *dl)
|
||||
void Daemon::onNewDeviceLink(DeviceLink *link)
|
||||
{
|
||||
const QString &id = identityPacket.get<QString>(QStringLiteral("deviceId"));
|
||||
const QString &id = link->deviceId();
|
||||
|
||||
// qCDebug(KDECONNECT_CORE) << "Device discovered" << id << "via" << dl->provider()->name();
|
||||
// qCDebug(KDECONNECT_CORE) << "Device discovered" << id << "via" << dl->name();
|
||||
|
||||
if (d->m_devices.contains(id)) {
|
||||
qCDebug(KDECONNECT_CORE) << "It is a known device" << identityPacket.get<QString>(QStringLiteral("deviceName"));
|
||||
qCDebug(KDECONNECT_CORE) << "It is a known device" << link->deviceInfo().name;
|
||||
Device *device = d->m_devices[id];
|
||||
bool wasReachable = device->isReachable();
|
||||
device->addLink(identityPacket, dl);
|
||||
device->addLink(link);
|
||||
if (!wasReachable) {
|
||||
Q_EMIT deviceVisibilityChanged(id, true);
|
||||
Q_EMIT deviceListChanged();
|
||||
}
|
||||
} else {
|
||||
qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPacket.get<QString>(QStringLiteral("deviceName"));
|
||||
Device *device = new Device(this, identityPacket, dl);
|
||||
qCDebug(KDECONNECT_CORE) << "It is a new device" << link->deviceInfo().name;
|
||||
Device *device = new Device(this, link);
|
||||
addDevice(device);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ Q_SIGNALS:
|
|||
Q_SCRIPTABLE void customDevicesChanged(const QStringList &customDevices);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onNewDeviceLink(const NetworkPacket &identityPacket, DeviceLink *dl);
|
||||
void onNewDeviceLink(DeviceLink *dl);
|
||||
void onDeviceStatusChanged();
|
||||
|
||||
private:
|
||||
|
|
213
core/device.cpp
213
core/device.cpp
|
@ -32,8 +32,8 @@
|
|||
class Device::DevicePrivate
|
||||
{
|
||||
public:
|
||||
DevicePrivate(const QString &id)
|
||||
: m_deviceId(id)
|
||||
DevicePrivate(const DeviceInfo &deviceInfo)
|
||||
: m_deviceInfo(deviceInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -43,17 +43,13 @@ public:
|
|||
m_deviceLinks.clear();
|
||||
}
|
||||
|
||||
const QString m_deviceId;
|
||||
QString m_deviceName;
|
||||
DeviceType m_deviceType;
|
||||
int m_protocolVersion;
|
||||
DeviceInfo m_deviceInfo;
|
||||
|
||||
QVector<DeviceLink *> m_deviceLinks;
|
||||
QHash<QString, KdeConnectPlugin *> m_plugins;
|
||||
|
||||
QMultiMap<QString, KdeConnectPlugin *> m_pluginsByIncomingCapability;
|
||||
QSet<QString> m_supportedPlugins;
|
||||
QSet<QString> m_allPlugins;
|
||||
PairingHandler* m_pairingHandler;
|
||||
};
|
||||
|
||||
|
@ -64,38 +60,31 @@ static void warn(const QString &info)
|
|||
|
||||
Device::Device(QObject *parent, const QString &id)
|
||||
: QObject(parent)
|
||||
, d(new Device::DevicePrivate(id))
|
||||
{
|
||||
DeviceInfo info = KdeConnectConfig::instance().getTrustedDevice(id);
|
||||
d = new Device::DevicePrivate(info);
|
||||
|
||||
d->m_pairingHandler = new PairingHandler(this, PairState::Paired);
|
||||
|
||||
d->m_protocolVersion = NetworkPacket::s_protocolVersion;
|
||||
KdeConnectConfig::DeviceInfo info = KdeConnectConfig::instance().getTrustedDevice(d->m_deviceId);
|
||||
|
||||
d->m_deviceName = info.deviceName;
|
||||
d->m_deviceType = str2type(info.deviceType);
|
||||
d->m_supportedPlugins = PluginLoader::instance()->getPluginList().toSet(); // Assume every plugin is supported until we get the capabilities
|
||||
|
||||
// Register in bus
|
||||
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
|
||||
|
||||
// Assume every plugin is supported until addLink is called and we can get the actual list
|
||||
d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet();
|
||||
d->m_supportedPlugins = d->m_allPlugins;
|
||||
|
||||
connect(d->m_pairingHandler, &PairingHandler::incomingPairRequest, this, &Device::pairingHandler_incomingPairRequest);
|
||||
connect(d->m_pairingHandler, &PairingHandler::pairingFailed, this, &Device::pairingHandler_pairingFailed);
|
||||
connect(d->m_pairingHandler, &PairingHandler::pairingSuccessful, this, &Device::pairingHandler_pairingSuccessful);
|
||||
connect(d->m_pairingHandler, &PairingHandler::unpaired, this, &Device::pairingHandler_unpaired);
|
||||
}
|
||||
|
||||
Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink *dl)
|
||||
Device::Device(QObject *parent, DeviceLink *dl)
|
||||
: QObject(parent)
|
||||
, d(new Device::DevicePrivate(identityPacket.get<QString>(QStringLiteral("deviceId"))))
|
||||
{
|
||||
d->m_pairingHandler = new PairingHandler(this, PairState::NotPaired);
|
||||
d->m_deviceName = identityPacket.get<QString>(QStringLiteral("deviceName"));
|
||||
d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet();
|
||||
d = new Device::DevicePrivate(dl->deviceInfo());
|
||||
|
||||
addLink(identityPacket, dl);
|
||||
d->m_pairingHandler = new PairingHandler(this, PairState::NotPaired);
|
||||
d->m_supportedPlugins = PluginLoader::instance()->getPluginList().toSet(); // Assume every plugin is supported until we get the capabilities
|
||||
|
||||
addLink(dl);
|
||||
|
||||
// Register in bus
|
||||
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
|
||||
|
@ -109,6 +98,10 @@ Device::Device(QObject *parent, const NetworkPacket &identityPacket, DeviceLink
|
|||
connect(d->m_pairingHandler, &PairingHandler::pairingFailed, this, &Device::pairingHandler_pairingFailed);
|
||||
connect(d->m_pairingHandler, &PairingHandler::pairingSuccessful, this, &Device::pairingHandler_pairingSuccessful);
|
||||
connect(d->m_pairingHandler, &PairingHandler::unpaired, this, &Device::pairingHandler_unpaired);
|
||||
|
||||
if (protocolVersion() != NetworkPacket::s_protocolVersion) {
|
||||
qCWarning(KDECONNECT_CORE) << name() << " uses a different protocol version" << protocolVersion() << "expected" << NetworkPacket::s_protocolVersion;
|
||||
}
|
||||
}
|
||||
|
||||
Device::~Device()
|
||||
|
@ -118,17 +111,17 @@ Device::~Device()
|
|||
|
||||
QString Device::id() const
|
||||
{
|
||||
return d->m_deviceId;
|
||||
return d->m_deviceInfo.id;
|
||||
}
|
||||
|
||||
QString Device::name() const
|
||||
{
|
||||
return d->m_deviceName;
|
||||
return d->m_deviceInfo.name;
|
||||
}
|
||||
|
||||
QString Device::type() const
|
||||
DeviceType Device::type() const
|
||||
{
|
||||
return type2str(d->m_deviceType);
|
||||
return d->m_deviceInfo.type;
|
||||
}
|
||||
|
||||
bool Device::isReachable() const
|
||||
|
@ -138,7 +131,7 @@ bool Device::isReachable() const
|
|||
|
||||
int Device::protocolVersion()
|
||||
{
|
||||
return d->m_protocolVersion;
|
||||
return d->m_deviceInfo.protocolVersion;
|
||||
}
|
||||
|
||||
QStringList Device::supportedPlugins() const
|
||||
|
@ -158,6 +151,8 @@ QStringList Device::loadedPlugins() const
|
|||
|
||||
void Device::reloadPlugins()
|
||||
{
|
||||
qCDebug(KDECONNECT_CORE) << name() << "- reload plugins";
|
||||
|
||||
QHash<QString, KdeConnectPlugin *> newPluginMap, oldPluginMap = d->m_plugins;
|
||||
QMultiMap<QString, KdeConnectPlugin *> newPluginsByIncomingCapability;
|
||||
|
||||
|
@ -254,8 +249,7 @@ void Device::pairingHandler_incomingPairRequest()
|
|||
void Device::pairingHandler_pairingSuccessful()
|
||||
{
|
||||
Q_ASSERT(d->m_pairingHandler->pairState() == PairState::Paired);
|
||||
KdeConnectConfig::instance().addTrustedDevice(id(), name(), type());
|
||||
KdeConnectConfig::instance().setDeviceProperty(d->m_deviceId, QStringLiteral("certificate"), QString::fromLatin1(certificate().toPem()));
|
||||
KdeConnectConfig::instance().addTrustedDevice(d->m_deviceInfo);
|
||||
reloadPlugins(); // Will load/unload plugins
|
||||
Q_EMIT pairStateChanged(pairStateAsInt());
|
||||
}
|
||||
|
@ -276,49 +270,53 @@ void Device::pairingHandler_unpaired()
|
|||
Q_EMIT pairStateChanged(pairStateAsInt());
|
||||
}
|
||||
|
||||
void Device::addLink(const NetworkPacket &identityPacket, DeviceLink *link)
|
||||
void Device::addLink(DeviceLink *link)
|
||||
{
|
||||
// qCDebug(KDECONNECT_CORE) << "Adding link to" << id() << "via" << link->provider();
|
||||
|
||||
setName(identityPacket.get<QString>(QStringLiteral("deviceName")));
|
||||
setType(identityPacket.get<QString>(QStringLiteral("deviceType")));
|
||||
|
||||
if (d->m_deviceLinks.contains(link)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_protocolVersion = identityPacket.get<int>(QStringLiteral("protocolVersion"), -1);
|
||||
if (d->m_protocolVersion != NetworkPacket::s_protocolVersion) {
|
||||
qCWarning(KDECONNECT_CORE) << d->m_deviceName << "- warning, device uses a different protocol version" << d->m_protocolVersion << "expected"
|
||||
<< NetworkPacket::s_protocolVersion;
|
||||
}
|
||||
|
||||
connect(link, &QObject::destroyed, this, &Device::linkDestroyed);
|
||||
|
||||
d->m_deviceLinks.append(link);
|
||||
|
||||
// Theoretically we will never add two links from the same provider (the provider should destroy
|
||||
// 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, &QObject::destroyed, this, &Device::linkDestroyed);
|
||||
connect(link, &DeviceLink::receivedPacket, this, &Device::privateReceivedPacket);
|
||||
|
||||
const bool capabilitiesSupported = identityPacket.has(QStringLiteral("incomingCapabilities")) || identityPacket.has(QStringLiteral("outgoingCapabilities"));
|
||||
if (capabilitiesSupported) {
|
||||
const QSet<QString> outgoingCapabilities = identityPacket.get<QStringList>(QStringLiteral("outgoingCapabilities")).toSet(),
|
||||
incomingCapabilities = identityPacket.get<QStringList>(QStringLiteral("incomingCapabilities")).toSet();
|
||||
|
||||
d->m_supportedPlugins = PluginLoader::instance()->pluginsForCapabilities(incomingCapabilities, outgoingCapabilities);
|
||||
// qDebug() << "new plugins for" << m_deviceName << m_supportedPlugins << incomingCapabilities << outgoingCapabilities;
|
||||
} else {
|
||||
d->m_supportedPlugins = PluginLoader::instance()->getPluginList().toSet();
|
||||
}
|
||||
|
||||
reloadPlugins();
|
||||
bool hasChanges = updateDeviceInfo(link->deviceInfo());
|
||||
|
||||
if (d->m_deviceLinks.size() == 1) {
|
||||
Q_EMIT reachableChanged(true);
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
if (hasChanges) {
|
||||
reloadPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
bool Device::updateDeviceInfo(const DeviceInfo &newDeviceInfo)
|
||||
{
|
||||
bool hasChanges = false;
|
||||
if (d->m_deviceInfo.name != newDeviceInfo.name || d->m_deviceInfo.type != newDeviceInfo.type) {
|
||||
hasChanges = true;
|
||||
d->m_deviceInfo.name = newDeviceInfo.name;
|
||||
d->m_deviceInfo.type = newDeviceInfo.type;
|
||||
Q_EMIT typeChanged(d->m_deviceInfo.type.toString());
|
||||
Q_EMIT nameChanged(d->m_deviceInfo.name);
|
||||
if (isPaired()) {
|
||||
KdeConnectConfig::instance().updateTrustedDeviceInfo(d->m_deviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (d->m_deviceInfo.outgoingCapabilities != newDeviceInfo.outgoingCapabilities
|
||||
|| d->m_deviceInfo.incomingCapabilities != newDeviceInfo.incomingCapabilities) {
|
||||
if (!newDeviceInfo.incomingCapabilities.isEmpty() && !newDeviceInfo.outgoingCapabilities.isEmpty()) {
|
||||
hasChanges = true;
|
||||
d->m_supportedPlugins = PluginLoader::instance()->pluginsForCapabilities(newDeviceInfo.incomingCapabilities, newDeviceInfo.outgoingCapabilities);
|
||||
qDebug() << "new capabilities for " << name();
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
void Device::linkDestroyed(QObject *o)
|
||||
|
@ -395,17 +393,6 @@ bool Device::isPairRequestedByPeer() const
|
|||
return d->m_pairingHandler->pairState() == PairState::RequestedByPeer;
|
||||
}
|
||||
|
||||
|
||||
QStringList Device::availableLinks() const
|
||||
{
|
||||
QStringList sl;
|
||||
sl.reserve(d->m_deviceLinks.size());
|
||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
||||
sl.append(dl->provider()->name());
|
||||
}
|
||||
return sl;
|
||||
}
|
||||
|
||||
QHostAddress Device::getLocalIpAddress() const
|
||||
{
|
||||
for (DeviceLink *dl : qAsConst(d->m_deviceLinks)) {
|
||||
|
@ -417,78 +404,14 @@ QHostAddress Device::getLocalIpAddress() const
|
|||
return QHostAddress::Null;
|
||||
}
|
||||
|
||||
Device::DeviceType Device::str2type(const QString &deviceType)
|
||||
QString Device::iconName() const
|
||||
{
|
||||
if (deviceType == QLatin1String("desktop"))
|
||||
return Desktop;
|
||||
if (deviceType == QLatin1String("laptop"))
|
||||
return Laptop;
|
||||
if (deviceType == QLatin1String("smartphone") || deviceType == QLatin1String("phone"))
|
||||
return Phone;
|
||||
if (deviceType == QLatin1String("tablet"))
|
||||
return Tablet;
|
||||
if (deviceType == QLatin1String("tv"))
|
||||
return Tv;
|
||||
return Unknown;
|
||||
}
|
||||
|
||||
QString Device::type2str(Device::DeviceType deviceType)
|
||||
{
|
||||
if (deviceType == Desktop)
|
||||
return QStringLiteral("desktop");
|
||||
if (deviceType == Laptop)
|
||||
return QStringLiteral("laptop");
|
||||
if (deviceType == Phone)
|
||||
return QStringLiteral("smartphone");
|
||||
if (deviceType == Tablet)
|
||||
return QStringLiteral("tablet");
|
||||
if (deviceType == Tv)
|
||||
return QStringLiteral("tv");
|
||||
return QStringLiteral("unknown");
|
||||
return d->m_deviceInfo.type.icon();
|
||||
}
|
||||
|
||||
QString Device::statusIconName() const
|
||||
{
|
||||
return iconForStatus(isReachable(), isPaired());
|
||||
}
|
||||
|
||||
QString Device::iconName() const
|
||||
{
|
||||
return iconForStatus(true, false);
|
||||
}
|
||||
|
||||
QString Device::iconForStatus(bool reachable, bool trusted) const
|
||||
{
|
||||
Device::DeviceType deviceType = d->m_deviceType;
|
||||
if (deviceType == Device::Unknown) {
|
||||
deviceType = Device::Phone; // Assume phone if we don't know the type
|
||||
} else if (deviceType == Device::Desktop) {
|
||||
deviceType = Device::Device::Laptop; // We don't have desktop icon yet
|
||||
}
|
||||
|
||||
QString status = (reachable ? (trusted ? QStringLiteral("connected") : QStringLiteral("disconnected")) : QStringLiteral("trusted"));
|
||||
QString type = type2str(deviceType);
|
||||
|
||||
return type + status;
|
||||
}
|
||||
|
||||
void Device::setName(const QString &name)
|
||||
{
|
||||
if (d->m_deviceName != name) {
|
||||
d->m_deviceName = name;
|
||||
KdeConnectConfig::instance().setDeviceProperty(d->m_deviceId, QStringLiteral("name"), name);
|
||||
Q_EMIT nameChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::setType(const QString &strtype)
|
||||
{
|
||||
auto type = str2type(strtype);
|
||||
if (d->m_deviceType != type) {
|
||||
d->m_deviceType = type;
|
||||
KdeConnectConfig::instance().setDeviceProperty(d->m_deviceId, QStringLiteral("type"), strtype);
|
||||
Q_EMIT typeChanged(strtype);
|
||||
}
|
||||
return d->m_deviceInfo.type.iconForStatus(isReachable(), isPaired());
|
||||
}
|
||||
|
||||
KdeConnectPlugin *Device::plugin(const QString &pluginName) const
|
||||
|
@ -498,7 +421,8 @@ KdeConnectPlugin *Device::plugin(const QString &pluginName) const
|
|||
|
||||
void Device::setPluginEnabled(const QString &pluginName, bool enabled)
|
||||
{
|
||||
if (!d->m_allPlugins.contains(pluginName)) {
|
||||
if (!PluginLoader::instance()->doesPluginExist(pluginName)) {
|
||||
qWarning() << "Tried to enable a plugin that doesn't exist" << pluginName;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -529,9 +453,7 @@ QString Device::encryptionInfo() const
|
|||
}
|
||||
result += i18n("SHA256 fingerprint of your device certificate is: %1\n", localChecksum);
|
||||
|
||||
std::string remotePem = KdeConnectConfig::instance().getDeviceProperty(id(), QStringLiteral("certificate")).toStdString();
|
||||
QSslCertificate remoteCertificate = QSslCertificate(QByteArray(remotePem.c_str(), (int)remotePem.size()));
|
||||
QString remoteChecksum = QString::fromLatin1(remoteCertificate.digest(digestAlgorithm).toHex());
|
||||
QString remoteChecksum = QString::fromLatin1(certificate().digest(digestAlgorithm).toHex());
|
||||
for (int i = 2; i < remoteChecksum.size(); i += 3) {
|
||||
remoteChecksum.insert(i, QStringLiteral(":")); // Improve readability
|
||||
}
|
||||
|
@ -542,10 +464,7 @@ QString Device::encryptionInfo() const
|
|||
|
||||
QSslCertificate Device::certificate() const
|
||||
{
|
||||
if (!d->m_deviceLinks.isEmpty()) {
|
||||
return d->m_deviceLinks[0]->certificate();
|
||||
}
|
||||
return QSslCertificate();
|
||||
return d->m_deviceInfo.certificate;
|
||||
}
|
||||
|
||||
QByteArray Device::verificationKey() const
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <QString>
|
||||
|
||||
#include "backends/devicelink.h"
|
||||
#include "deviceinfo.h"
|
||||
#include "networkpacket.h"
|
||||
#include "pairstate.h"
|
||||
|
||||
|
@ -22,7 +23,7 @@ class KDECONNECTCORE_EXPORT Device : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device")
|
||||
Q_PROPERTY(QString type READ type NOTIFY typeChanged)
|
||||
Q_PROPERTY(QString type READ typeAsString NOTIFY typeChanged)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString iconName READ iconName CONSTANT)
|
||||
Q_PROPERTY(QString statusIconName READ statusIconName NOTIFY statusIconNameChanged)
|
||||
|
@ -34,15 +35,6 @@ class KDECONNECTCORE_EXPORT Device : public QObject
|
|||
Q_PROPERTY(QStringList supportedPlugins READ supportedPlugins NOTIFY pluginsChanged)
|
||||
|
||||
public:
|
||||
enum DeviceType {
|
||||
Unknown,
|
||||
Desktop,
|
||||
Laptop,
|
||||
Phone,
|
||||
Tablet,
|
||||
Tv,
|
||||
};
|
||||
|
||||
/**
|
||||
* Restores the @p device from the saved configuration
|
||||
*
|
||||
|
@ -55,7 +47,7 @@ public:
|
|||
*
|
||||
* We know everything but we don't trust it yet
|
||||
*/
|
||||
Device(QObject *parent, const NetworkPacket &np, DeviceLink *dl);
|
||||
Device(QObject *parent, DeviceLink *link);
|
||||
|
||||
~Device() override;
|
||||
|
||||
|
@ -65,23 +57,27 @@ public:
|
|||
{
|
||||
return QStringLiteral("/modules/kdeconnect/devices/") + id();
|
||||
}
|
||||
QString type() const;
|
||||
DeviceType type() const;
|
||||
QString typeAsString() const
|
||||
{
|
||||
return type().toString();
|
||||
};
|
||||
QString iconName() const;
|
||||
QString statusIconName() const;
|
||||
Q_SCRIPTABLE QByteArray verificationKey() const;
|
||||
Q_SCRIPTABLE QString encryptionInfo() const;
|
||||
|
||||
// Add and remove links
|
||||
void addLink(const NetworkPacket &identityPacket, DeviceLink *);
|
||||
void removeLink(DeviceLink *);
|
||||
void addLink(DeviceLink *link);
|
||||
void removeLink(DeviceLink *link);
|
||||
|
||||
bool updateDeviceInfo(const DeviceInfo &deviceInfo);
|
||||
|
||||
PairState pairState() const;
|
||||
Q_SCRIPTABLE int pairStateAsInt() const; // Hack because qdbus doesn't like enums
|
||||
Q_SCRIPTABLE bool isPaired() const;
|
||||
Q_SCRIPTABLE bool isPairRequested() const;
|
||||
Q_SCRIPTABLE bool isPairRequestedByPeer() const;
|
||||
|
||||
Q_SCRIPTABLE QStringList availableLinks() const;
|
||||
virtual bool isReachable() const;
|
||||
|
||||
Q_SCRIPTABLE QStringList loadedPlugins() const;
|
||||
|
@ -132,12 +128,6 @@ Q_SIGNALS:
|
|||
Q_SCRIPTABLE void statusIconNameChanged();
|
||||
|
||||
private: // Methods
|
||||
static DeviceType str2type(const QString &deviceType);
|
||||
static QString type2str(DeviceType deviceType);
|
||||
|
||||
void setName(const QString &name);
|
||||
void setType(const QString &strtype);
|
||||
QString iconForStatus(bool reachable, bool paired) const;
|
||||
QSslCertificate certificate() const;
|
||||
|
||||
private:
|
||||
|
|
149
core/deviceinfo.h
Normal file
149
core/deviceinfo.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Albert Vaca <albertvaka@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#ifndef DEVICE_INFO_H
|
||||
#define DEVICE_INFO_H
|
||||
|
||||
#include "networkpacket.h"
|
||||
#include <QSet>
|
||||
#include <QSslCertificate>
|
||||
#include <QString>
|
||||
|
||||
struct DeviceType {
|
||||
enum Value {
|
||||
Unknown,
|
||||
Desktop,
|
||||
Laptop,
|
||||
Phone,
|
||||
Tablet,
|
||||
Tv,
|
||||
};
|
||||
|
||||
static DeviceType FromString(const QString &deviceType)
|
||||
{
|
||||
if (deviceType == QLatin1String("desktop"))
|
||||
return DeviceType::Desktop;
|
||||
if (deviceType == QLatin1String("laptop"))
|
||||
return DeviceType::Laptop;
|
||||
if (deviceType == QLatin1String("smartphone") || deviceType == QLatin1String("phone"))
|
||||
return DeviceType::Phone;
|
||||
if (deviceType == QLatin1String("tablet"))
|
||||
return DeviceType::Tablet;
|
||||
if (deviceType == QLatin1String("tv"))
|
||||
return DeviceType::Tv;
|
||||
return DeviceType::Unknown;
|
||||
}
|
||||
|
||||
QString toString() const
|
||||
{
|
||||
if (value == DeviceType::Desktop)
|
||||
return QStringLiteral("desktop");
|
||||
if (value == DeviceType::Laptop)
|
||||
return QStringLiteral("laptop");
|
||||
if (value == DeviceType::Phone)
|
||||
return QStringLiteral("phone");
|
||||
if (value == DeviceType::Tablet)
|
||||
return QStringLiteral("tablet");
|
||||
if (value == DeviceType::Tv)
|
||||
return QStringLiteral("tv");
|
||||
return QStringLiteral("unknown");
|
||||
}
|
||||
|
||||
QString icon() const
|
||||
{
|
||||
return iconForStatus(true, false);
|
||||
}
|
||||
|
||||
QString iconForStatus(bool reachable, bool trusted) const
|
||||
{
|
||||
QString type;
|
||||
switch (value) {
|
||||
case DeviceType::Unknown:
|
||||
case DeviceType::Phone:
|
||||
type = QStringLiteral("smartphone");
|
||||
break;
|
||||
case DeviceType::Desktop: // We don't have desktop icon yet
|
||||
case DeviceType::Laptop:
|
||||
type = QStringLiteral("laptop");
|
||||
break;
|
||||
default:
|
||||
type = toString();
|
||||
}
|
||||
QString status = (reachable ? (trusted ? QStringLiteral("connected") : QStringLiteral("disconnected")) : QStringLiteral("trusted"));
|
||||
return type + status;
|
||||
}
|
||||
|
||||
constexpr DeviceType(Value value)
|
||||
: value(value)
|
||||
{
|
||||
}
|
||||
constexpr bool operator==(DeviceType a) const
|
||||
{
|
||||
return value == a.value;
|
||||
}
|
||||
constexpr bool operator!=(DeviceType a) const
|
||||
{
|
||||
return value != a.value;
|
||||
}
|
||||
|
||||
private:
|
||||
Value value;
|
||||
};
|
||||
|
||||
struct DeviceInfo {
|
||||
QString id;
|
||||
QSslCertificate certificate;
|
||||
QString name;
|
||||
DeviceType type;
|
||||
int protocolVersion;
|
||||
QSet<QString> incomingCapabilities;
|
||||
QSet<QString> outgoingCapabilities;
|
||||
|
||||
DeviceInfo(const QString &id,
|
||||
const QSslCertificate &certificate,
|
||||
const QString &name,
|
||||
DeviceType type,
|
||||
int protocolVersion = 0,
|
||||
const QSet<QString> &incomingCapabilities = QSet<QString>(),
|
||||
const QSet<QString> &outgoingCapabilities = QSet<QString>())
|
||||
: id(id)
|
||||
, certificate(certificate)
|
||||
, name(name)
|
||||
, type(type)
|
||||
, protocolVersion(protocolVersion)
|
||||
, incomingCapabilities(incomingCapabilities)
|
||||
, outgoingCapabilities(outgoingCapabilities)
|
||||
{
|
||||
}
|
||||
|
||||
NetworkPacket toIdentityPacket()
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_IDENTITY);
|
||||
np.set(QStringLiteral("deviceId"), id);
|
||||
np.set(QStringLiteral("deviceName"), name);
|
||||
np.set(QStringLiteral("deviceType"), type.toString());
|
||||
np.set(QStringLiteral("protocolVersion"), protocolVersion);
|
||||
np.set(QStringLiteral("incomingCapabilities"), incomingCapabilities.values());
|
||||
np.set(QStringLiteral("outgoingCapabilities"), outgoingCapabilities.values());
|
||||
return np;
|
||||
}
|
||||
|
||||
static DeviceInfo FromIdentityPacketAndCert(const NetworkPacket &np, const QSslCertificate &certificate)
|
||||
{
|
||||
QStringList incomingCapabilities = np.get<QStringList>(QStringLiteral("incomingCapabilities"));
|
||||
QStringList outgoingCapabilities = np.get<QStringList>(QStringLiteral("outgoingCapabilities"));
|
||||
|
||||
return DeviceInfo(np.get<QString>(QStringLiteral("deviceId")),
|
||||
certificate,
|
||||
np.get<QString>(QStringLiteral("deviceName")),
|
||||
DeviceType::FromString(np.get<QString>(QStringLiteral("deviceType"))),
|
||||
np.get<int>(QStringLiteral("protocolVersion"), -1),
|
||||
QSet<QString>(incomingCapabilities.begin(), incomingCapabilities.end()),
|
||||
QSet<QString>(outgoingCapabilities.begin(), outgoingCapabilities.end()));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,6 +24,8 @@
|
|||
#include "core_debug.h"
|
||||
#include "daemon.h"
|
||||
#include "dbushelper.h"
|
||||
#include "deviceinfo.h"
|
||||
#include "pluginloader.h"
|
||||
|
||||
const QFile::Permissions strictPermissions = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser;
|
||||
|
||||
|
@ -105,24 +107,24 @@ void KdeConnectConfig::setName(const QString &name)
|
|||
d->m_config->sync();
|
||||
}
|
||||
|
||||
QString KdeConnectConfig::deviceType()
|
||||
DeviceType KdeConnectConfig::deviceType()
|
||||
{
|
||||
#ifdef SAILFISHOS
|
||||
return QStringLiteral("phone");
|
||||
return DeviceType::Phone;
|
||||
#else
|
||||
const QByteArrayList platforms = qgetenv("PLASMA_PLATFORM").split(':');
|
||||
|
||||
if (platforms.contains("phone")) {
|
||||
return QStringLiteral("phone");
|
||||
return DeviceType::Phone;
|
||||
} else if (platforms.contains("tablet")) {
|
||||
return QStringLiteral("tablet");
|
||||
return DeviceType::Tablet;
|
||||
} else if (platforms.contains("mediacenter")) {
|
||||
return QStringLiteral("tv");
|
||||
return DeviceType::Tv;
|
||||
}
|
||||
|
||||
// TODO non-Plasma mobile platforms
|
||||
|
||||
return QStringLiteral("desktop");
|
||||
return DeviceType::Desktop;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -146,6 +148,17 @@ QSslCertificate KdeConnectConfig::certificate()
|
|||
return d->m_certificate;
|
||||
}
|
||||
|
||||
DeviceInfo KdeConnectConfig::deviceInfo()
|
||||
{
|
||||
return DeviceInfo(deviceId(),
|
||||
certificate(),
|
||||
name(),
|
||||
deviceType(),
|
||||
NetworkPacket::s_protocolVersion,
|
||||
PluginLoader::instance()->incomingCapabilities().toSet(),
|
||||
PluginLoader::instance()->outgoingCapabilities().toSet());
|
||||
}
|
||||
|
||||
QDir KdeConnectConfig::baseConfigDir()
|
||||
{
|
||||
QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
|
||||
|
@ -159,27 +172,54 @@ QStringList KdeConnectConfig::trustedDevices()
|
|||
return list;
|
||||
}
|
||||
|
||||
void KdeConnectConfig::addTrustedDevice(const QString &id, const QString &name, const QString &type)
|
||||
void KdeConnectConfig::addTrustedDevice(const DeviceInfo &deviceInfo)
|
||||
{
|
||||
d->m_trustedDevices->beginGroup(id);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("name"), name);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("type"), type);
|
||||
d->m_trustedDevices->beginGroup(deviceInfo.id);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("name"), deviceInfo.name);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("type"), deviceInfo.type.toString());
|
||||
QString certString = QString::fromLatin1(deviceInfo.certificate.toPem());
|
||||
d->m_trustedDevices->setValue(QStringLiteral("certificate"), certString);
|
||||
d->m_trustedDevices->endGroup();
|
||||
d->m_trustedDevices->sync();
|
||||
|
||||
QDir().mkpath(deviceConfigDir(id).path());
|
||||
QDir().mkpath(deviceConfigDir(deviceInfo.id).path());
|
||||
}
|
||||
|
||||
KdeConnectConfig::DeviceInfo KdeConnectConfig::getTrustedDevice(const QString &id)
|
||||
void KdeConnectConfig::updateTrustedDeviceInfo(const DeviceInfo &deviceInfo)
|
||||
{
|
||||
if (!trustedDevices().contains(deviceInfo.id)) {
|
||||
// do not store values for untrusted devices (it would make them trusted)
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_trustedDevices->beginGroup(deviceInfo.id);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("name"), deviceInfo.name);
|
||||
d->m_trustedDevices->setValue(QStringLiteral("type"), deviceInfo.type.toString());
|
||||
d->m_trustedDevices->endGroup();
|
||||
d->m_trustedDevices->sync();
|
||||
}
|
||||
|
||||
QSslCertificate KdeConnectConfig::getTrustedDeviceCertificate(const QString &id)
|
||||
{
|
||||
d->m_trustedDevices->beginGroup(id);
|
||||
QString certString = d->m_trustedDevices->value(QStringLiteral("certificate"), QString()).toString();
|
||||
d->m_trustedDevices->endGroup();
|
||||
return QSslCertificate(certString.toLatin1());
|
||||
}
|
||||
|
||||
DeviceInfo KdeConnectConfig::getTrustedDevice(const QString &id)
|
||||
{
|
||||
d->m_trustedDevices->beginGroup(id);
|
||||
|
||||
KdeConnectConfig::DeviceInfo info;
|
||||
info.deviceName = d->m_trustedDevices->value(QStringLiteral("name"), QLatin1String("unnamed")).toString();
|
||||
info.deviceType = d->m_trustedDevices->value(QStringLiteral("type"), QLatin1String("unknown")).toString();
|
||||
QString certString = d->m_trustedDevices->value(QStringLiteral("certificate"), QString()).toString();
|
||||
QSslCertificate certificate(certString.toLatin1());
|
||||
QString name = d->m_trustedDevices->value(QStringLiteral("name"), QLatin1String("unnamed")).toString();
|
||||
QString typeString = d->m_trustedDevices->value(QStringLiteral("type"), QLatin1String("unknown")).toString();
|
||||
DeviceType type = DeviceType::FromString(typeString);
|
||||
|
||||
d->m_trustedDevices->endGroup();
|
||||
return info;
|
||||
|
||||
return DeviceInfo(id, certificate, name, type);
|
||||
}
|
||||
|
||||
void KdeConnectConfig::removeTrustedDevice(const QString &deviceId)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <QDir>
|
||||
|
||||
#include "deviceinfo.h"
|
||||
#include "kdeconnectcore_export.h"
|
||||
|
||||
class QSslCertificate;
|
||||
|
@ -16,11 +17,6 @@ class QSslCertificate;
|
|||
class KDECONNECTCORE_EXPORT KdeConnectConfig
|
||||
{
|
||||
public:
|
||||
struct DeviceInfo {
|
||||
QString deviceName;
|
||||
QString deviceType;
|
||||
};
|
||||
|
||||
static KdeConnectConfig &instance();
|
||||
|
||||
/*
|
||||
|
@ -29,11 +25,11 @@ public:
|
|||
|
||||
QString deviceId();
|
||||
QString name();
|
||||
QString deviceType();
|
||||
|
||||
DeviceType deviceType();
|
||||
QSslCertificate certificate();
|
||||
DeviceInfo deviceInfo();
|
||||
QString privateKeyPath();
|
||||
QString certificatePath();
|
||||
QSslCertificate certificate();
|
||||
|
||||
void setName(const QString &name);
|
||||
|
||||
|
@ -43,8 +39,10 @@ public:
|
|||
|
||||
QStringList trustedDevices(); // list of ids
|
||||
void removeTrustedDevice(const QString &id);
|
||||
void addTrustedDevice(const QString &id, const QString &name, const QString &type);
|
||||
KdeConnectConfig::DeviceInfo getTrustedDevice(const QString &id);
|
||||
void addTrustedDevice(const DeviceInfo &deviceInfo);
|
||||
void updateTrustedDeviceInfo(const DeviceInfo &deviceInfo);
|
||||
DeviceInfo getTrustedDevice(const QString &id);
|
||||
QSslCertificate getTrustedDeviceCertificate(const QString &id);
|
||||
|
||||
void setDeviceProperty(const QString &deviceId, const QString &name, const QString &value);
|
||||
QString getDeviceProperty(const QString &deviceId, const QString &name, const QString &defaultValue = QString());
|
||||
|
|
|
@ -41,22 +41,6 @@ NetworkPacket::NetworkPacket(const QString &type, const QVariantMap &body)
|
|||
{
|
||||
}
|
||||
|
||||
void NetworkPacket::createIdentityPacket(NetworkPacket *np)
|
||||
{
|
||||
np->m_id = QString::number(QDateTime::currentMSecsSinceEpoch());
|
||||
np->m_type = PACKET_TYPE_IDENTITY;
|
||||
np->m_payload = QSharedPointer<QIODevice>();
|
||||
np->m_payloadSize = 0;
|
||||
np->set(QStringLiteral("deviceId"), KdeConnectConfig::instance().deviceId());
|
||||
np->set(QStringLiteral("deviceName"), KdeConnectConfig::instance().name());
|
||||
np->set(QStringLiteral("deviceType"), KdeConnectConfig::instance().deviceType());
|
||||
np->set(QStringLiteral("protocolVersion"), NetworkPacket::s_protocolVersion);
|
||||
np->set(QStringLiteral("incomingCapabilities"), PluginLoader::instance()->incomingCapabilities());
|
||||
np->set(QStringLiteral("outgoingCapabilities"), PluginLoader::instance()->outgoingCapabilities());
|
||||
|
||||
// qCDebug(KDECONNECT_CORE) << "createIdentityPacket" << np->serialize();
|
||||
}
|
||||
|
||||
QByteArray NetworkPacket::serialize() const
|
||||
{
|
||||
// Object -> QVariant
|
||||
|
|
|
@ -32,12 +32,10 @@ class KDECONNECTCORE_EXPORT NetworkPacket
|
|||
public:
|
||||
const static int s_protocolVersion;
|
||||
|
||||
explicit NetworkPacket(const QString &type = QStringLiteral("empty"), const QVariantMap &body = {});
|
||||
explicit NetworkPacket(const QString &type = QString(), const QVariantMap &body = {});
|
||||
NetworkPacket(const NetworkPacket &other) = default; // Copy constructor, required for QMetaType and queued signals
|
||||
NetworkPacket &operator=(const NetworkPacket &other) = default;
|
||||
|
||||
static void createIdentityPacket(NetworkPacket *);
|
||||
|
||||
QByteArray serialize() const;
|
||||
static bool unserialize(const QByteArray &json, NetworkPacket *out);
|
||||
|
||||
|
|
|
@ -52,6 +52,11 @@ QStringList PluginLoader::getPluginList() const
|
|||
return plugins.keys();
|
||||
}
|
||||
|
||||
bool PluginLoader::doesPluginExist(const QString &name) const
|
||||
{
|
||||
return plugins.contains(name);
|
||||
}
|
||||
|
||||
KPluginMetaData PluginLoader::getPluginInfo(const QString &name) const
|
||||
{
|
||||
return plugins.value(name);
|
||||
|
@ -116,7 +121,7 @@ QSet<QString> PluginLoader::pluginsForCapabilities(const QSet<QString> &incoming
|
|||
{
|
||||
QSet<QString> ret;
|
||||
|
||||
QString myDeviceType = KdeConnectConfig::instance().deviceType();
|
||||
QString myDeviceType = KdeConnectConfig::instance().deviceType().toString();
|
||||
|
||||
for (const KPluginMetaData &service : qAsConst(plugins)) {
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
static PluginLoader *instance();
|
||||
|
||||
QStringList getPluginList() const;
|
||||
bool doesPluginExist(const QString &name) const;
|
||||
KPluginMetaData getPluginInfo(const QString &name) const;
|
||||
KdeConnectPlugin *instantiatePluginForDevice(const QString &name, Device *device) const;
|
||||
|
||||
|
|
|
@ -84,24 +84,18 @@ private Q_SLOTS:
|
|||
const QString destFile = QDir::tempPath() + QStringLiteral("/kdeconnect-test-sentfile");
|
||||
QFile(destFile).remove();
|
||||
|
||||
const QString deviceId = KdeConnectConfig::instance().deviceId(), deviceName = QStringLiteral("testdevice"),
|
||||
deviceType = KdeConnectConfig::instance().deviceType();
|
||||
|
||||
KdeConnectConfig::instance().addTrustedDevice(deviceId, deviceName, deviceType);
|
||||
KdeConnectConfig::instance().setDeviceProperty(
|
||||
deviceId,
|
||||
QStringLiteral("certificate"),
|
||||
QString::fromLatin1(KdeConnectConfig::instance().certificate().toPem())); // Using same certificate from kcc, instead of generating
|
||||
DeviceInfo deviceInfo = KdeConnectConfig::instance().deviceInfo();
|
||||
KdeConnectConfig::instance().addTrustedDevice(deviceInfo);
|
||||
|
||||
// We need the device to be loaded on the daemon, otherwise CompositeUploadJob will get a null device
|
||||
Device *device = new Device(this, deviceId);
|
||||
Device *device = new Device(this, deviceInfo.id);
|
||||
m_daemon->addDevice(device);
|
||||
|
||||
QSharedPointer<QFile> f(new QFile(aFile));
|
||||
NetworkPacket np(PACKET_TYPE_SHARE_REQUEST);
|
||||
np.setPayload(f, f->size());
|
||||
|
||||
CompositeUploadJob *job = new CompositeUploadJob(deviceId, false);
|
||||
CompositeUploadJob *job = new CompositeUploadJob(deviceInfo.id, false);
|
||||
UploadJob *uj = new UploadJob(np);
|
||||
job->addSubjob(uj);
|
||||
|
||||
|
|
Loading…
Reference in a new issue