Added KdeConnectConfig class that aims to be a KConfig abstraction
Benefits: - We had config files in different paths, now they will be centralized. - Daemon, LanLinkProvider and NetworkPackage depend only on Qt now. - KConfig is accessed with strings as keys, where a typo can go unnoticed. - Daemon is now thinner, as it doesn't need to initialize config values. - QCA::Initializer is in a single place now (was in Daemon and Plugin).
This commit is contained in:
parent
7591e783ca
commit
c7c91c1289
15 changed files with 321 additions and 166 deletions
|
@ -18,6 +18,7 @@ set(kded_kdeconnect_SRCS
|
|||
kdeconnectplugin.cpp
|
||||
pluginloader.cpp
|
||||
|
||||
kdeconnectconfig.cpp
|
||||
dbushelper.cpp
|
||||
networkpackage.cpp
|
||||
filetransferjob.cpp
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "devicelink.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
#include "linkprovider.h"
|
||||
|
||||
DeviceLink::DeviceLink(const QString& deviceId, LinkProvider* parent)
|
||||
|
@ -29,5 +30,7 @@ DeviceLink::DeviceLink(const QString& deviceId, LinkProvider* parent)
|
|||
Q_ASSERT(!deviceId.isEmpty());
|
||||
|
||||
setProperty("deviceId", deviceId);
|
||||
|
||||
mPrivateKey = KdeConnectConfig::instance()->privateKey();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ public:
|
|||
virtual bool sendPackage(NetworkPackage& np) = 0;
|
||||
virtual bool sendPackageEncrypted(QCA::PublicKey& publicKey, NetworkPackage& np) = 0;
|
||||
|
||||
void setPrivateKey(const QCA::PrivateKey& privateKey) { mPrivateKey = privateKey; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void receivedPackage(const NetworkPackage& np);
|
||||
|
||||
|
|
|
@ -30,10 +30,8 @@
|
|||
#include <QTcpServer>
|
||||
#include <QUdpSocket>
|
||||
|
||||
#include <KSharedConfig>
|
||||
#include <KConfigGroup>
|
||||
|
||||
#include "landevicelink.h"
|
||||
#include <kdeconnectconfig.h>
|
||||
|
||||
void LanLinkProvider::configureSocket(QTcpSocket* socket)
|
||||
{
|
||||
|
@ -124,10 +122,7 @@ void LanLinkProvider::newUdpConnection()
|
|||
return;
|
||||
}
|
||||
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
const QString myId = config->group("myself").readEntry<QString>("id","");
|
||||
|
||||
if (receivedPackage->get<QString>("deviceId") == myId) {
|
||||
if (receivedPackage->get<QString>("deviceId") == KdeConnectConfig::instance()->deviceId()) {
|
||||
//kDebug(debugArea()) << "Ignoring my own broadcast";
|
||||
delete receivedPackage;
|
||||
return;
|
||||
|
|
|
@ -20,23 +20,14 @@
|
|||
|
||||
#include "daemon.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QUuid>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDBusConnection>
|
||||
#include <QNetworkSession>
|
||||
#include <QNetworkConfigurationManager>
|
||||
#include <QtCrypto>
|
||||
#include <QStandardPaths>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
#include <QDebug>
|
||||
|
||||
#include "core_debug.h"
|
||||
#include "dbushelper.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
#include "networkpackage.h"
|
||||
#include "backends/lan/lanlinkprovider.h"
|
||||
#include "backends/loopback/loopbacklinkprovider.h"
|
||||
|
@ -45,7 +36,6 @@
|
|||
#include "backends/devicelink.h"
|
||||
#include "backends/linkprovider.h"
|
||||
|
||||
#include <QDebug>
|
||||
struct DaemonPrivate
|
||||
{
|
||||
//Different ways to find devices and connect to them
|
||||
|
@ -53,10 +43,6 @@ struct DaemonPrivate
|
|||
|
||||
//Every known device
|
||||
QMap<QString, Device*> mDevices;
|
||||
|
||||
// The Initializer object sets things up, and also does cleanup when it goes out of scope
|
||||
// Note it's not being used anywhere. That's inteneded
|
||||
QCA::Initializer mQcaInitializer;
|
||||
};
|
||||
|
||||
Daemon::Daemon(QObject *parent)
|
||||
|
@ -65,63 +51,12 @@ Daemon::Daemon(QObject *parent)
|
|||
{
|
||||
qCDebug(KDECONNECT_CORE) << "KdeConnect daemon starting";
|
||||
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
|
||||
if (!config->group("myself").hasKey("id")) {
|
||||
QString uuid = QUuid::createUuid().toString();
|
||||
DbusHelper::filterNonExportableCharacters(uuid);
|
||||
config->group("myself").writeEntry("id", uuid);
|
||||
config->sync();
|
||||
qCDebug(KDECONNECT_CORE) << "My id:" << uuid;
|
||||
}
|
||||
|
||||
//qCDebug(KDECONNECT_CORE) << "QCA supported capabilities:" << QCA::supportedFeatures().join(",");
|
||||
if(!QCA::isSupported("rsa")) {
|
||||
//TODO: Display this in a notification or another visible way
|
||||
qCCritical(KDECONNECT_CORE) << "Error: KDE Connect could not find support for RSA in your QCA installation, if your distribution provides"
|
||||
<< "separate packages for QCA-ossl and QCA-gnupg plugins, make sure you have them installed and try again";
|
||||
return;
|
||||
}
|
||||
|
||||
const QFile::Permissions strict = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser;
|
||||
|
||||
const QString privateKeyPath = Device::privateKeyPath();
|
||||
if (!QFile::exists(privateKeyPath))
|
||||
{
|
||||
QDir::root().mkpath(QFileInfo(privateKeyPath).dir().path());
|
||||
|
||||
QFile privKey(privateKeyPath);
|
||||
|
||||
if (!privKey.open(QIODevice::ReadWrite | QIODevice::Truncate))
|
||||
{
|
||||
qCCritical(KDECONNECT_CORE) << "Error: KDE Connect could not create private keys file: " << privateKeyPath;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!privKey.setPermissions(strict))
|
||||
{
|
||||
qCDebug(KDECONNECT_CORE) << "Error: KDE Connect could not set permissions for private file: " << privateKeyPath;
|
||||
}
|
||||
|
||||
privKey.write(QCA::KeyGenerator().createRSA(2048).toPEM().toLatin1());
|
||||
}
|
||||
|
||||
if (QFile::permissions(privateKeyPath) != strict)
|
||||
{
|
||||
qCDebug(KDECONNECT_CORE) << "Error: KDE Connect detects wrong permissions for private file " << privateKeyPath;
|
||||
}
|
||||
|
||||
//Register on DBus
|
||||
QDBusConnection::sessionBus().registerService("org.kde.kdeconnect");
|
||||
QDBusConnection::sessionBus().registerObject("/modules/kdeconnect", this, QDBusConnection::ExportScriptableContents);
|
||||
|
||||
//Load backends (hardcoded by now, should be plugins in a future)
|
||||
//Load backends
|
||||
d->mLinkProviders.insert(new LanLinkProvider());
|
||||
//d->mLinkProviders.insert(new LoopbackLinkProvider());
|
||||
|
||||
//Read remebered paired devices
|
||||
const KConfigGroup& known = config->group("trusted_devices");
|
||||
const QStringList& list = known.groupList();
|
||||
const QStringList& list = KdeConnectConfig::instance()->trustedDevices();
|
||||
Q_FOREACH(const QString& id, list) {
|
||||
Device* device = new Device(this, id);
|
||||
connect(device, SIGNAL(reachableStatusChanged()),
|
||||
|
@ -147,6 +82,10 @@ Daemon::Daemon(QObject *parent)
|
|||
a, SLOT(onNetworkChange(QNetworkSession::State)));
|
||||
}
|
||||
|
||||
//Register on DBus
|
||||
QDBusConnection::sessionBus().registerService("org.kde.kdeconnect");
|
||||
QDBusConnection::sessionBus().registerObject("/modules/kdeconnect", this, QDBusConnection::ExportScriptableContents);
|
||||
|
||||
qCDebug(KDECONNECT_CORE) << "KdeConnect daemon started";
|
||||
}
|
||||
|
||||
|
@ -158,7 +97,6 @@ void Daemon::setDiscoveryEnabled(bool b)
|
|||
else
|
||||
a->onStop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Daemon::forceOnNetworkChange()
|
||||
|
@ -181,7 +119,6 @@ QStringList Daemon::devices(bool onlyReachable, bool onlyVisible) const
|
|||
|
||||
void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl)
|
||||
{
|
||||
|
||||
const QString& id = identityPackage.get<QString>("deviceId");
|
||||
|
||||
//qCDebug(KDECONNECT_CORE) << "Device discovered" << id << "via" << dl->provider()->name();
|
||||
|
@ -201,12 +138,10 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
|
|||
}
|
||||
|
||||
Q_EMIT deviceVisibilityChanged(id, true);
|
||||
|
||||
}
|
||||
|
||||
void Daemon::onDeviceReachableStatusChanged()
|
||||
{
|
||||
|
||||
Device* device = (Device*)sender();
|
||||
QString id = device->id();
|
||||
|
||||
|
@ -217,6 +152,7 @@ void Daemon::onDeviceReachableStatusChanged()
|
|||
if (!device->isReachable()) {
|
||||
|
||||
if (!device->isPaired()) {
|
||||
|
||||
qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name();
|
||||
Q_EMIT deviceRemoved(id);
|
||||
d->mDevices.remove(id);
|
||||
|
@ -224,7 +160,6 @@ void Daemon::onDeviceReachableStatusChanged()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Daemon::~Daemon()
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <KNotification>
|
||||
#include <KLocalizedString>
|
||||
#include <QIcon>
|
||||
#include <QDir>
|
||||
|
||||
#include "core_debug.h"
|
||||
#include "kdeconnectplugin.h"
|
||||
|
@ -40,39 +41,21 @@
|
|||
#include "backends/devicelink.h"
|
||||
#include "backends/linkprovider.h"
|
||||
#include "networkpackage.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(KDECONNECT_CORE, "kdeconnect.core")
|
||||
|
||||
QCA::PrivateKey initPrivateKey()
|
||||
{
|
||||
QCA::PrivateKey ret;
|
||||
QFile privKey(Device::privateKeyPath());
|
||||
if (privKey.open(QIODevice::ReadOnly))
|
||||
ret = QCA::PrivateKey::fromPEM(privKey.readAll());
|
||||
else {
|
||||
qWarning() << "Could not open the private key" << Device::privateKeyPath();
|
||||
}
|
||||
|
||||
Q_ASSERT(!ret.isNull());
|
||||
|
||||
return ret;
|
||||
}
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QCA::PrivateKey, s_privateKey, (initPrivateKey()))
|
||||
|
||||
Device::Device(QObject* parent, const QString& id)
|
||||
: QObject(parent)
|
||||
, m_deviceId(id)
|
||||
, m_pairStatus(Device::Paired)
|
||||
, m_protocolVersion(NetworkPackage::ProtocolVersion) //We don't know it yet
|
||||
{
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
KConfigGroup data = config->group("trusted_devices").group(id);
|
||||
KdeConnectConfig::DeviceInfo info = KdeConnectConfig::instance()->getTrustedDevice(id);
|
||||
|
||||
m_deviceName = data.readEntry<QString>("deviceName", QLatin1String("unnamed"));
|
||||
m_deviceType = str2type(data.readEntry<QString>("deviceType", QLatin1String("unknown")));
|
||||
|
||||
const QString& key = data.readEntry<QString>("publicKey", QString());
|
||||
m_publicKey = QCA::RSAPublicKey::fromPEM(key);
|
||||
m_deviceName = info.deviceName;
|
||||
m_deviceType = str2type(info.deviceType);
|
||||
m_publicKey = QCA::RSAPublicKey::fromPEM(info.publicKey);
|
||||
|
||||
//Register in bus
|
||||
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
|
||||
|
@ -117,8 +100,7 @@ void Device::reloadPlugins()
|
|||
|
||||
if (isPaired() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices
|
||||
|
||||
QString path = QStandardPaths::locate(QStandardPaths::ConfigLocation, "kdeconnect/", QStandardPaths::LocateDirectory) + id();
|
||||
KConfigGroup pluginStates = KSharedConfig::openConfig(path)->group("Plugins");
|
||||
KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins");
|
||||
|
||||
PluginLoader* loader = PluginLoader::instance();
|
||||
|
||||
|
@ -183,6 +165,11 @@ void Device::reloadPlugins()
|
|||
|
||||
}
|
||||
|
||||
QString Device::pluginsConfigFile() const
|
||||
{
|
||||
return KdeConnectConfig::instance()->deviceConfigDir(id()).absoluteFilePath("config");
|
||||
}
|
||||
|
||||
void Device::requestPair()
|
||||
{
|
||||
switch(m_pairStatus) {
|
||||
|
@ -226,8 +213,7 @@ void Device::unpair()
|
|||
{
|
||||
m_pairStatus = Device::NotPaired;
|
||||
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
config->group("trusted_devices").deleteGroup(id());
|
||||
KdeConnectConfig::instance()->removeTrustedDevice(id());
|
||||
|
||||
NetworkPackage np(PACKAGE_TYPE_PAIR);
|
||||
np.set("pair", false);
|
||||
|
@ -271,12 +257,9 @@ void Device::addLink(const NetworkPackage& identityPackage, DeviceLink* link)
|
|||
m_deviceName = identityPackage.get<QString>("deviceName");
|
||||
m_deviceType = str2type(identityPackage.get<QString>("deviceType"));
|
||||
|
||||
Q_ASSERT(!s_privateKey->isNull());
|
||||
link->setPrivateKey(*s_privateKey);
|
||||
|
||||
//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!
|
||||
//-- Actually, we should not destroy them or the provider will store an invalid ref!
|
||||
|
||||
connect(link, SIGNAL(receivedPackage(NetworkPackage)),
|
||||
this, SLOT(privateReceivedPackage(NetworkPackage)));
|
||||
|
@ -310,11 +293,6 @@ void Device::removeLink(DeviceLink* link)
|
|||
}
|
||||
}
|
||||
|
||||
QString Device::privateKeyPath()
|
||||
{
|
||||
return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/org.kde.kdeconnect/key.pem");
|
||||
}
|
||||
|
||||
bool Device::sendPackage(NetworkPackage& np)
|
||||
{
|
||||
if (np.type() != PACKAGE_TYPE_PAIR && isPaired()) {
|
||||
|
@ -413,8 +391,10 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
|
|||
}
|
||||
} else {
|
||||
qCDebug(KDECONNECT_CORE) << "device" << name() << "not paired, ignoring package" << np.type();
|
||||
unpair();
|
||||
|
||||
//FIXME: Uncommenting this fixes a bug where trying to pair from kde does not work, but I want to investigate the root cause of the bug first (01/03/15)
|
||||
//if (m_pairStatus != Device::Requested)
|
||||
unpair();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -423,7 +403,7 @@ bool Device::sendOwnPublicKey()
|
|||
{
|
||||
NetworkPackage np(PACKAGE_TYPE_PAIR);
|
||||
np.set("pair", true);
|
||||
np.set("publicKey", s_privateKey->toPublicKey().toPEM());
|
||||
np.set("publicKey", KdeConnectConfig::instance()->publicKey().toPEM());
|
||||
bool success = sendPackage(np);
|
||||
return success;
|
||||
}
|
||||
|
@ -466,7 +446,8 @@ void Device::setAsPaired()
|
|||
|
||||
m_pairingTimeut.stop(); //Just in case it was started
|
||||
|
||||
storeAsTrusted(); //Save to the config as trusted
|
||||
//Save device info in the config
|
||||
KdeConnectConfig::instance()->addTrustedDevice(id(), name(), type2str(m_deviceType), m_publicKey.toPEM());
|
||||
|
||||
reloadPlugins(); //Will actually load the plugins
|
||||
|
||||
|
@ -474,15 +455,6 @@ void Device::setAsPaired()
|
|||
|
||||
}
|
||||
|
||||
void Device::storeAsTrusted()
|
||||
{
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
config->group("trusted_devices").group(id()).writeEntry("publicKey", m_publicKey.toPEM());
|
||||
config->group("trusted_devices").group(id()).writeEntry("deviceName", name());
|
||||
config->group("trusted_devices").group(id()).writeEntry("deviceType", type2str(m_deviceType));
|
||||
config->sync();
|
||||
}
|
||||
|
||||
QStringList Device::availableLinks() const
|
||||
{
|
||||
QStringList sl;
|
||||
|
|
|
@ -62,7 +62,7 @@ class KDECONNECTCORE_EXPORT Device
|
|||
|
||||
public:
|
||||
/**
|
||||
* Reads the @p device from KConfig
|
||||
* Restores the @p device from the saved configuration
|
||||
*
|
||||
* We already know it but we need to wait for an incoming DeviceLink to communicate
|
||||
*/
|
||||
|
@ -86,8 +86,6 @@ public:
|
|||
void addLink(const NetworkPackage& identityPackage, DeviceLink*);
|
||||
void removeLink(DeviceLink*);
|
||||
|
||||
static QString privateKeyPath();
|
||||
|
||||
Q_SCRIPTABLE bool isPaired() const { return m_pairStatus==Device::Paired; }
|
||||
Q_SCRIPTABLE bool pairRequested() const { return m_pairStatus==Device::Requested; }
|
||||
|
||||
|
@ -97,6 +95,8 @@ public:
|
|||
Q_SCRIPTABLE QStringList loadedPlugins() const;
|
||||
Q_SCRIPTABLE bool hasPlugin(const QString& name) const;
|
||||
|
||||
Q_SCRIPTABLE QString pluginsConfigFile() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
///sends a @p np package to the device
|
||||
virtual bool sendPackage(NetworkPackage& np);
|
||||
|
@ -139,7 +139,6 @@ private:
|
|||
QSet<QString> m_outgoingCapabilities;
|
||||
|
||||
void setAsPaired();
|
||||
void storeAsTrusted();
|
||||
bool sendOwnPublicKey();
|
||||
|
||||
};
|
||||
|
|
194
core/kdeconnectconfig.cpp
Normal file
194
core/kdeconnectconfig.cpp
Normal file
|
@ -0,0 +1,194 @@
|
|||
/**
|
||||
* Copyright 2015 Albert Vaca <albertvaka@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kdeconnectconfig.h"
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QtCrypto>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <QUuid>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QApplication>
|
||||
#include <QHostInfo>
|
||||
|
||||
#include "core_debug.h"
|
||||
#include "dbushelper.h"
|
||||
|
||||
struct KdeConnectConfigPrivate {
|
||||
|
||||
// The Initializer object sets things up, and also does cleanup when it goes out of scope
|
||||
// Note it's not being used anywhere. That's inteneded
|
||||
QCA::Initializer mQcaInitializer;
|
||||
|
||||
QCA::PrivateKey privateKey;
|
||||
|
||||
KSharedConfigPtr config;
|
||||
|
||||
};
|
||||
|
||||
KdeConnectConfig* KdeConnectConfig::instance()
|
||||
{
|
||||
static KdeConnectConfig* kcc = new KdeConnectConfig();
|
||||
return kcc;
|
||||
}
|
||||
|
||||
KdeConnectConfig::KdeConnectConfig()
|
||||
: d(new KdeConnectConfigPrivate) {
|
||||
|
||||
//qCDebug(KDECONNECT_CORE) << "QCA supported capabilities:" << QCA::supportedFeatures().join(",");
|
||||
if(!QCA::isSupported("rsa")) {
|
||||
//TODO: Display this in a more visible way (notification?)
|
||||
qCCritical(KDECONNECT_CORE) << "Error: KDE Connect could not find support for RSA in your QCA installation, if your distribution provides"
|
||||
<< "separate packages for QCA-ossl and QCA-gnupg plugins, make sure you have them installed and try again";
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure base directory exists
|
||||
QDir().mkpath(baseConfigDir().path());
|
||||
|
||||
//.config/kdeconnect/config
|
||||
d->config = KSharedConfig::openConfig(baseConfigDir().absoluteFilePath("config"), KSharedConfig::SimpleConfig);
|
||||
|
||||
if (!d->config->group("myself").hasKey("id")) {
|
||||
QString uuid = QUuid::createUuid().toString();
|
||||
DbusHelper::filterNonExportableCharacters(uuid);
|
||||
d->config->group("myself").writeEntry("id", uuid);
|
||||
d->config->sync();
|
||||
qCDebug(KDECONNECT_CORE) << "My id:" << uuid;
|
||||
}
|
||||
|
||||
const QFile::Permissions strict = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser;
|
||||
|
||||
QString keyPath = privateKeyPath();
|
||||
QFile privKey(keyPath);
|
||||
if (privKey.exists() && privKey.open(QIODevice::ReadOnly))
|
||||
{
|
||||
d->privateKey = QCA::PrivateKey::fromPEM(privKey.readAll());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!privKey.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
|
||||
//TODO: Display this in a more visible way (notification?)
|
||||
qCCritical(KDECONNECT_CORE) << "Error: KDE Connect could not create private key file: " << keyPath;
|
||||
QApplication::exit(-1);
|
||||
}
|
||||
privKey.setPermissions(strict);
|
||||
|
||||
d->privateKey = QCA::KeyGenerator().createRSA(2048);
|
||||
|
||||
privKey.write(d->privateKey.toPEM().toLatin1());
|
||||
}
|
||||
|
||||
//Extra security check
|
||||
if (QFile::permissions(keyPath) != strict) {
|
||||
qCDebug(KDECONNECT_CORE) << "Error: KDE Connect detects wrong permissions for private key file " << keyPath;
|
||||
}
|
||||
}
|
||||
|
||||
QString KdeConnectConfig::name() {
|
||||
QString defaultName = qgetenv("USER") + "@" + QHostInfo::localHostName();
|
||||
QString name = d->config->group("myself").readEntry("name", defaultName);
|
||||
return name;
|
||||
}
|
||||
|
||||
void KdeConnectConfig::setName(QString name)
|
||||
{
|
||||
d->config->group("myself").writeEntry("name", name);
|
||||
d->config->sync();
|
||||
}
|
||||
|
||||
QString KdeConnectConfig::deviceType()
|
||||
{
|
||||
return "desktop"; // TODO
|
||||
}
|
||||
|
||||
QString KdeConnectConfig::deviceId() {
|
||||
return d->config->group("myself").readEntry("id", "");
|
||||
}
|
||||
|
||||
QString KdeConnectConfig::privateKeyPath()
|
||||
{
|
||||
return baseConfigDir().absoluteFilePath("privateKey.pem");
|
||||
}
|
||||
|
||||
QCA::PrivateKey KdeConnectConfig::privateKey()
|
||||
{
|
||||
return d->privateKey;
|
||||
}
|
||||
|
||||
QCA::PublicKey KdeConnectConfig::publicKey()
|
||||
{
|
||||
return d->privateKey.toPublicKey();
|
||||
}
|
||||
|
||||
QDir KdeConnectConfig::baseConfigDir()
|
||||
{
|
||||
QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||
QString kdeconnectConfigPath = QDir(configPath).absoluteFilePath("kdeconnect");
|
||||
return QDir(kdeconnectConfigPath);
|
||||
}
|
||||
|
||||
QStringList KdeConnectConfig::trustedDevices()
|
||||
{
|
||||
const KConfigGroup& known = d->config->group("trusted_devices");
|
||||
const QStringList& list = known.groupList();
|
||||
return list;
|
||||
}
|
||||
|
||||
void KdeConnectConfig::addTrustedDevice(QString id, QString name, QString type, QString publicKey)
|
||||
{
|
||||
KConfigGroup device = d->config->group("trusted_devices").group(id);
|
||||
device.writeEntry("deviceName", name);
|
||||
device.writeEntry("deviceType", type);
|
||||
device.writeEntry("publicKey", publicKey);
|
||||
d->config->sync();
|
||||
|
||||
QDir().mkpath(deviceConfigDir(id).path());
|
||||
}
|
||||
|
||||
KdeConnectConfig::DeviceInfo KdeConnectConfig::getTrustedDevice(QString id)
|
||||
{
|
||||
KConfigGroup data = d->config->group("trusted_devices").group(id);
|
||||
|
||||
KdeConnectConfig::DeviceInfo info;
|
||||
info.deviceName = data.readEntry<QString>("deviceName", QLatin1String("unnamed"));
|
||||
info.deviceType = data.readEntry<QString>("deviceType", QLatin1String("unknown"));
|
||||
info.publicKey = data.readEntry<QString>("publicKey", QString());
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void KdeConnectConfig::removeTrustedDevice(QString deviceId)
|
||||
{
|
||||
d->config->group("trusted_devices").deleteGroup(deviceId);
|
||||
}
|
||||
|
||||
QDir KdeConnectConfig::deviceConfigDir(QString deviceId)
|
||||
{
|
||||
QString deviceConfigPath = baseConfigDir().absoluteFilePath(deviceId);
|
||||
return QDir(deviceConfigPath);
|
||||
}
|
78
core/kdeconnectconfig.h
Normal file
78
core/kdeconnectconfig.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright 2015 Albert Vaca <albertvaka@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KDECONNECTCONFIG_H
|
||||
#define KDECONNECTCONFIG_H
|
||||
|
||||
#include <QtCrypto>
|
||||
#include <QDir>
|
||||
|
||||
#include "kdeconnectcore_export.h"
|
||||
|
||||
class KdeConnectConfigPrivate;
|
||||
|
||||
class KDECONNECTCORE_EXPORT KdeConnectConfig
|
||||
{
|
||||
public:
|
||||
struct DeviceInfo {
|
||||
QString deviceName;
|
||||
QString deviceType;
|
||||
QString publicKey;
|
||||
};
|
||||
|
||||
static KdeConnectConfig* instance();
|
||||
|
||||
|
||||
/*
|
||||
* Our own info
|
||||
*/
|
||||
|
||||
QString deviceId();
|
||||
QString name();
|
||||
QString deviceType();
|
||||
|
||||
QString privateKeyPath();
|
||||
QCA::PrivateKey privateKey();
|
||||
QCA::PublicKey publicKey();
|
||||
|
||||
void setName(QString name);
|
||||
|
||||
|
||||
/*
|
||||
* Trusted devices
|
||||
*/
|
||||
|
||||
QStringList trustedDevices(); //Get a list of ids
|
||||
void removeTrustedDevice(QString id);
|
||||
void addTrustedDevice(QString id, QString name, QString type, QString publicKey);
|
||||
KdeConnectConfig::DeviceInfo getTrustedDevice(QString id);
|
||||
|
||||
|
||||
QDir baseConfigDir();
|
||||
QDir deviceConfigDir(QString deviceId);
|
||||
|
||||
private:
|
||||
KdeConnectConfig();
|
||||
|
||||
private:
|
||||
QScopedPointer<KdeConnectConfigPrivate> d;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -25,10 +25,6 @@ struct KdeConnectPluginPrivate
|
|||
{
|
||||
Device* mDevice;
|
||||
QSet<QString> mOutgoingTypes;
|
||||
|
||||
// The Initializer object sets things up, and also does cleanup when it goes out of scope
|
||||
// Since the plugins use their own memory, they need their own initializer in order to send encrypted packages
|
||||
QCA::Initializer init;
|
||||
};
|
||||
|
||||
KdeConnectPlugin::KdeConnectPlugin(QObject* parent, const QVariantList& args)
|
||||
|
|
|
@ -21,23 +21,19 @@
|
|||
#include "networkpackage.h"
|
||||
#include "core_debug.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
#include <KConfigGroup>
|
||||
|
||||
#include <QMetaObject>
|
||||
#include <QMetaProperty>
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QHostInfo>
|
||||
#include <QSslKey>
|
||||
#include <QDateTime>
|
||||
#include <qjsondocument.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QtCrypto>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dbushelper.h"
|
||||
#include "filetransferjob.h"
|
||||
#include "pluginloader.h"
|
||||
#include "kdeconnectconfig.h"
|
||||
|
||||
const QCA::EncryptionAlgorithm NetworkPackage::EncryptionAlgorithm = QCA::EME_PKCS1v15;
|
||||
const int NetworkPackage::ProtocolVersion = 5;
|
||||
|
@ -53,15 +49,15 @@ NetworkPackage::NetworkPackage(const QString& type)
|
|||
|
||||
void NetworkPackage::createIdentityPackage(NetworkPackage* np)
|
||||
{
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
const QString id = config->group("myself").readEntry<QString>("id","");
|
||||
KdeConnectConfig* config = KdeConnectConfig::instance();
|
||||
const QString id = config->deviceId();
|
||||
np->mId = QString::number(QDateTime::currentMSecsSinceEpoch());
|
||||
np->mType = PACKAGE_TYPE_IDENTITY;
|
||||
np->mPayload = QSharedPointer<QIODevice>();
|
||||
np->mPayloadSize = 0;
|
||||
np->set("deviceId", id);
|
||||
np->set("deviceName", qgetenv("USER") + "@" + QHostInfo::localHostName());
|
||||
np->set("deviceType", "desktop"); //TODO: Detect laptop, tablet, phone...
|
||||
np->set("deviceName", config->name());
|
||||
np->set("deviceType", config->deviceType());
|
||||
np->set("protocolVersion", NetworkPackage::ProtocolVersion);
|
||||
np->set("SupportedIncomingInterfaces", PluginLoader::instance()->incomingInterfaces().join(","));
|
||||
np->set("SupportedOutgoingInterfaces", PluginLoader::instance()->outgoingInterfaces().join(","));
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
|
||||
#include <QDebug>
|
||||
#include <QDBusInterface>
|
||||
|
||||
#include <KSharedConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <QIcon>
|
||||
|
||||
#include "dbusinterfaces.h"
|
||||
|
|
|
@ -142,7 +142,7 @@ void KdeConnectKcm::deviceSelected(const QModelIndex& current)
|
|||
}
|
||||
}
|
||||
|
||||
//FIXME: KPluginSelector has no way to remove a list of plugins and load another, so we need to destroy and recreate it each time
|
||||
//KPluginSelector has no way to remove a list of plugins and load another, so we need to destroy and recreate it each time
|
||||
delete kcmUi->pluginSelector;
|
||||
kcmUi->pluginSelector = new KPluginSelector(this);
|
||||
kcmUi->verticalLayout_2->addWidget(kcmUi->pluginSelector);
|
||||
|
@ -159,9 +159,7 @@ void KdeConnectKcm::deviceSelected(const QModelIndex& current)
|
|||
|
||||
KService::List offers = KServiceTypeTrader::self()->query("KdeConnect/Plugin");
|
||||
QList<KPluginInfo> scriptinfos = KPluginInfo::fromServices(offers);
|
||||
|
||||
QString path = QStandardPaths::locate(QStandardPaths::ConfigLocation, "kdeconnect/", QStandardPaths::LocateDirectory);
|
||||
KSharedConfigPtr deviceConfig = KSharedConfig::openConfig(path + currentDevice->id());
|
||||
KSharedConfigPtr deviceConfig = KSharedConfig::openConfig(currentDevice->pluginsConfigFile());
|
||||
kcmUi->pluginSelector->addPlugins(scriptinfos, KPluginSelector::ReadConfigFile, i18n("Plugins"), QString(), deviceConfig);
|
||||
|
||||
connect(kcmUi->pluginSelector, SIGNAL(changed(bool)),
|
||||
|
|
10
kcm/kcm.h
10
kcm/kcm.h
|
@ -21,18 +21,10 @@
|
|||
#ifndef KDECONNECTKCM_H
|
||||
#define KDECONNECTKCM_H
|
||||
|
||||
#include <KCModule>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDBusConnection>
|
||||
|
||||
#include <kcmodule.h>
|
||||
#include <ksharedconfig.h>
|
||||
|
||||
class QModelIndex;
|
||||
class AccountsModel;
|
||||
class AccountWidget;
|
||||
class QStackedLayout;
|
||||
class QItemSelectionModel;
|
||||
class QDBusInterface;
|
||||
class DeviceDbusInterface;
|
||||
class DevicesModel;
|
||||
class DevicesSortProxyModel;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "mounter.h"
|
||||
#include "sftp_debug.h"
|
||||
#include <kdeconnectconfig.h>
|
||||
|
||||
static const char* idleTimeout_c = "idleTimeout";
|
||||
|
||||
|
@ -133,7 +134,7 @@ void Mounter::onPakcageReceived(const NetworkPackage& np)
|
|||
<< "-p" << np.get<QString>("port")
|
||||
<< "-d"
|
||||
<< "-f"
|
||||
<< "-o" << "IdentityFile=" + m_sftp->device()->privateKeyPath()
|
||||
<< "-o" << "IdentityFile=" + KdeConnectConfig::instance()->privateKeyPath()
|
||||
<< "-o" << "StrictHostKeyChecking=no" //Do not ask for confirmation because it is not a known host
|
||||
<< "-o" << "UserKnownHostsFile=/dev/null"; //Prevent storing as a known host
|
||||
|
||||
|
|
Loading…
Reference in a new issue