[SCM] ktp-common-internals packaging branch, master, updated. debian/15.12.1-2-1839-gf0635e9

Maximiliano Curia maxy at moszumanska.debian.org
Mon May 9 09:08:21 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-common-internals.git;a=commitdiff;h=30f3aae

The following commit has been merged in the master branch:
commit 30f3aae426b7f9e3de7ad9dc1127e3a1f991fea8
Author: Marcin Ziemiński <zieminn at gmail.com>
Date:   Wed Jul 30 20:44:05 2014 +0200

    Added way to asynchronously generate private keys along with dbus methods. Implemented OTR policy settings through the dbus interface.
    
    Signed-off-by: Marcin Ziemiński <zieminn at gmail.com>
---
 otr-proxy/KTpProxy/otr-manager.cpp                 | 78 ++++++++++++++---
 otr-proxy/KTpProxy/otr-manager.h                   | 45 ++++++++--
 otr-proxy/KTpProxy/otr-message.cpp                 |  5 ++
 otr-proxy/KTpProxy/otr-message.h                   |  3 +
 otr-proxy/KTpProxy/otr-proxy-channel-adaptee.cpp   | 62 ++++++++++++--
 otr-proxy/KTpProxy/otr-proxy-channel-adaptee.h     | 12 +--
 otr-proxy/KTpProxy/otr-proxy-channel.cpp           | 39 +++------
 otr-proxy/KTpProxy/otr-proxy-channel.h             | 12 ++-
 otr-proxy/KTpProxy/otr-session.cpp                 | 18 +++-
 otr-proxy/KTpProxy/otr-session.h                   |  1 +
 otr-proxy/KTpProxy/otr-utils.h                     | 37 +++++++++
 otr-proxy/KTpProxy/proxy-service-adaptee.cpp       | 68 ++++++++++++++-
 otr-proxy/KTpProxy/proxy-service-adaptee.h         | 19 ++++-
 otr-proxy/KTpProxy/proxy-service.cpp               | 62 +++++++++++++-
 otr-proxy/KTpProxy/proxy-service.h                 | 17 +++-
 otr-proxy/KTpProxy/svc-proxy-service.cpp           | 30 ++++++-
 otr-proxy/KTpProxy/svc-proxy-service.h             | 97 +++++++++++++++++++++-
 otr-proxy/spec/ChannelProxy_Interface_OTR.xml      |  2 +-
 otr-proxy/spec/ProxyService.xml                    | 80 +++++++++++++++++-
 otr-proxy/test/otr-test.cpp                        |  6 +-
 .../{alice_id_instags => alice_id.instags}         |  0
 .../{alice_id_privkeys => alice_id.privkeys}       |  0
 .../resources/{bob_id_instags => bob_id.instags}   |  0
 .../resources/{bob_id_privkeys => bob_id.privkeys} |  0
 .../resources/{john_id_instags => john_id.instags} |  0
 .../{john_id_privkeys => john_id.privkeys}         |  0
 otr-proxy/test/utils-test.cpp                      | 76 +++++++++++++++++
 27 files changed, 680 insertions(+), 89 deletions(-)

diff --git a/otr-proxy/KTpProxy/otr-manager.cpp b/otr-proxy/KTpProxy/otr-manager.cpp
index d6bb015..b9e4535 100644
--- a/otr-proxy/KTpProxy/otr-manager.cpp
+++ b/otr-proxy/KTpProxy/otr-manager.cpp
@@ -88,10 +88,9 @@ namespace {
         Q_UNUSED(accountname);
         Q_UNUSED(protocol);
         Q_UNUSED(recipient);
-        kDebug() << "Injecting: " << message;
 
         Message msg;
-        msg.setText(QString(message));
+        msg.setText(QLatin1String(message));
         msg.setType(Tp::ChannelTextMessageTypeNormal);
         msg.setDirection(MessageDirection::TO_PEER);
 
@@ -401,24 +400,24 @@ Manager::Manager(Config *otrConfig)
 {
 }
 
-UserStateBox* Manager::getUserState(const SessionContext &ctx)
+UserStateBox* Manager::getUserState(const QString &accountId)
 {
-    auto usIt = userStates.find(ctx.accountId);
+    auto usIt = userStates.find(accountId);
     if(usIt == userStates.end()) {
         // initiate new userstate
         OtrlUserState userstate = otrl_userstate_create();
 
-        QString path = config->saveLocation() + ctx.accountId + QLatin1String("_privkeys");
+        QString path = config->saveLocation() + accountId + QLatin1String(".privkeys");
         otrl_privkey_read(userstate, path.toLocal8Bit());
 
-        path = config->saveLocation() + ctx.accountId + QLatin1String("_fingerprints");
+        path = config->saveLocation() + accountId + QLatin1String(".fingerprints");
         otrl_privkey_read_fingerprints(userstate, path.toLocal8Bit(), NULL, NULL);
 
-        path = config->saveLocation() + ctx.accountId + QLatin1String("_instags");
+        path = config->saveLocation() + accountId + QLatin1String(".instags");
         otrl_instag_read(userstate, path.toLocal8Bit());
 
         UserStateBoxPtr usPtr(new UserStateBox(userstate));
-        userStates.insert(ctx.accountId, usPtr);
+        userStates.insert(accountId, usPtr);
         return usPtr.data();
     } else {
         return usIt->data();
@@ -437,22 +436,33 @@ void Manager::setPolicy(OtrlPolicy policy)
 
 void Manager::createNewPrivateKey(Session *session)
 {
-    const QString path = config->saveLocation() + session->context().accountId + QLatin1String("_privkeys");
+    const QString path = config->saveLocation() + session->context().accountId + QLatin1String(".privkeys");
     otrl_privkey_generate(session->userStateBox()->userState(),
             path.toLocal8Bit(),
             session->context().accountName.toLocal8Bit(),
             session->context().protocol.toLocal8Bit());
 }
 
+KeyGenerationThread* Manager::createNewPrivateKey(const QString &accountId, const QString &accountName)
+{
+    const QString path = config->saveLocation() + accountId + QLatin1String(".privkeys");
+    return new KeyGenerationThread(
+            accountId,
+            accountName,
+            utils::protocolFromAccountId(accountId),
+            path,
+            getUserState(accountId)->userState());
+}
+
 void Manager::saveFingerprints(Session *session)
 {
-    const QString path = config->saveLocation() + session->context().accountId + QLatin1String("_fingerprints");
+    const QString path = config->saveLocation() + session->context().accountId + QLatin1String(".fingerprints");
 	otrl_privkey_write_fingerprints(session->userStateBox()->userState(), path.toLocal8Bit());
 }
 
 void Manager::createInstag(Session *session)
 {
-    const QString path = config->saveLocation() + session->context().accountId + QLatin1String("_instags");
+    const QString path = config->saveLocation() + session->context().accountId + QLatin1String(".instags");
 	otrl_instag_generate(session->userStateBox()->userState(),
             path.toLocal8Bit(),
             session->context().accountName.toLocal8Bit(),
@@ -476,17 +486,59 @@ TrustFpResult Manager::trustFingerprint(const SessionContext &ctx, Fingerprint *
         return TrustFpResult::NO_SUCH_FINGERPRINT;
     }
 
-    UserStateBox* usBox = getUserState(ctx);
+    UserStateBox* usBox = getUserState(ctx.accountId);
     if(trust) {
         otrl_context_set_trust(fingerprint, "VERIFIED");
     } else {
         otrl_context_set_trust(fingerprint, NULL);
     }
 
-    const QString path = config->saveLocation() + ctx.accountId + QLatin1String("_fingerprints");
+    const QString path = config->saveLocation() + ctx.accountId + QLatin1String(".fingerprints");
 	otrl_privkey_write_fingerprints(usBox->userState(), path.toLocal8Bit());
 
     return TrustFpResult::OK;
 }
 
+
+KeyGenerationThread::KeyGenerationThread(
+        const QString &accountId,
+        const QString &accountName,
+        const QString &protocol,
+        const QString &path,
+        OtrlUserState userState)
+    : accountId(accountId),
+    accountName(accountName),
+    protocol(protocol),
+    path(path),
+    userState(userState),
+    err(0)
+{
+}
+
+gcry_error_t KeyGenerationThread::prepareCreation()
+{
+    return err = otrl_privkey_generate_start(userState, accountName.toLocal8Bit(), protocol.toLocal8Bit(), &newKey);
+}
+
+void KeyGenerationThread::run()
+{
+    if(!err) {
+        err = otrl_privkey_generate_calculate(newKey);
+    }
+}
+
+gcry_error_t KeyGenerationThread::error() const
+{
+    return err;
+}
+
+gcry_error_t KeyGenerationThread::finalizeCreation()
+{
+    if(!err) {
+        return err = otrl_privkey_generate_finish(userState, newKey, path.toLocal8Bit());
+    } else {
+        return err;
+    }
+}
+
 } /* namespace OTR */
diff --git a/otr-proxy/KTpProxy/otr-manager.h b/otr-proxy/KTpProxy/otr-manager.h
index 4f6bf20..cb63986 100644
--- a/otr-proxy/KTpProxy/otr-manager.h
+++ b/otr-proxy/KTpProxy/otr-manager.h
@@ -23,6 +23,8 @@
 #include "otr-config.h"
 #include "otr-session.h"
 
+#include <QThread>
+
 extern "C" {
 #include <gcrypt.h>
 #include <libotr/privkey.h>
@@ -33,17 +35,19 @@ extern "C" {
 
 namespace OTR
 {
-namespace global
-{
-    extern const OtrlMessageAppOps appOps;
-}
+    namespace global
+    {
+        extern const OtrlMessageAppOps appOps;
+    }
+
+    class KeyGenerationThread;
 
     class Manager
     {
         public:
             Manager(Config *otrConfig);
 
-            UserStateBox* getUserState(const SessionContext &ctx);
+            UserStateBox* getUserState(const QString &accountId);
 
             OtrlPolicy getPolicy() const;
             void setPolicy(OtrlPolicy policy);
@@ -53,6 +57,9 @@ namespace global
             TrustFpResult trustFingerprint(const SessionContext &ctx, Fingerprint *fingerprint, bool trust);
 
             void createNewPrivateKey(Session *session);
+            /** return nullptr if thread could not be craeted
+              otherwise returns thread which generates a new private key upon calling start method */
+            KeyGenerationThread* createNewPrivateKey(const QString &accountId, const QString &accountName);
             void createInstag(Session *session);
 
         private:
@@ -61,6 +68,34 @@ namespace global
             QMap<QString, UserStateBoxPtr> userStates;
     };
 
+    class KeyGenerationThread : public QThread
+    {
+        public:
+            KeyGenerationThread(
+                    const QString &accountId,
+                    const QString &accountName,
+                    const QString &protocol,
+                    const QString &path,
+                    OtrlUserState userState);
+
+            virtual void run();
+            gcry_error_t error() const;
+            /* has to called before the thread starts*/
+            gcry_error_t prepareCreation();
+            /* has to called after the finished() signal is emitted */
+            gcry_error_t finalizeCreation();
+
+            const QString &accountId;
+            const QString accountName;
+            const QString protocol;
+            const QString path;
+
+        private:
+            OtrlUserState userState;
+            gcry_error_t err;
+            void *newKey;
+    };
+
 } /* namespace OTR */
 
 #endif
diff --git a/otr-proxy/KTpProxy/otr-message.cpp b/otr-proxy/KTpProxy/otr-message.cpp
index 497cb25..306e870 100644
--- a/otr-proxy/KTpProxy/otr-message.cpp
+++ b/otr-proxy/KTpProxy/otr-message.cpp
@@ -73,6 +73,11 @@ namespace OTR
         return static_cast<Tp::ChannelTextMessageType>(message[0][QLatin1String("message-type")].variant().toUInt(nullptr));
     }
 
+    bool Message::isOTRmessage() const
+    {
+        return otrl_proto_message_type(text().toLocal8Bit()) != OTRL_MSGTYPE_NOTOTR;
+    }
+
     MessageDirection Message::direction() const
     {
         return dir;
diff --git a/otr-proxy/KTpProxy/otr-message.h b/otr-proxy/KTpProxy/otr-message.h
index 0f0ef90..82ebcc2 100644
--- a/otr-proxy/KTpProxy/otr-message.h
+++ b/otr-proxy/KTpProxy/otr-message.h
@@ -48,6 +48,9 @@ namespace OTR
             void setType(Tp::ChannelTextMessageType msgType);
             Tp::ChannelTextMessageType type() const;
 
+            /** returns true if it is OTR protocol specific message */
+            bool isOTRmessage() const;
+
             MessageDirection direction() const;
             void setDirection(MessageDirection direction);
 
diff --git a/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.cpp b/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.cpp
index f871294..11ef05f 100644
--- a/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.cpp
+++ b/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.cpp
@@ -19,6 +19,7 @@
 
 #include "otr-proxy-channel-adaptee.h"
 #include "otr-proxy-channel.h"
+#include "proxy-service.h"
 #include "otr-constants.h"
 #include "otr-manager.h"
 #include "constants.h"
@@ -86,12 +87,15 @@ OtrProxyChannel::Adaptee::Adaptee(OtrProxyChannel *pc,
         const QDBusConnection &dbusConnection,
         const Tp::TextChannelPtr &channel,
         const OTR::SessionContext &context,
-        OTR::Manager *manager)
-    : adaptor(new Tp::Service::ChannelProxyInterfaceOTRAdaptor(dbusConnection, this, pc->dbusObject())),
+        ProxyService *ps)
+    : QObject(pc),
+    adaptor(new Tp::Service::ChannelProxyInterfaceOTRAdaptor(dbusConnection, this, pc->dbusObject())),
     pc(pc),
     chan(channel),
     isConnected(false),
-    otrSes(this, context, manager)
+    otrSes(this, context, ps->managerOTR()),
+    ps(ps),
+    aboutToInit(false)
 {
     kDebug() << "Created OTR session for context: "
         << "Account id: " << context.accountId
@@ -130,7 +134,7 @@ uint OtrProxyChannel::Adaptee::trustLevel() const
 
 QString OtrProxyChannel::Adaptee::localFingerprint() const
 {
-    return QString::fromLatin1("not implemented");
+    return otrSes.localFingerprint();
 }
 
 QString OtrProxyChannel::Adaptee::remoteFingerprint() const
@@ -276,7 +280,14 @@ void OtrProxyChannel::Adaptee::initialize(const Tp::Service::ChannelProxyInterfa
         return;
     }
 
-    sendOTRmessage(otrSes.startSession());
+    // create private key if necessary - to avoid blocking
+    if(otrSes.localFingerprint().isEmpty() && ps->getPolicy() != OTRL_POLICY_NEVER) {
+        aboutToInit = true;
+        acquirePrivateKey();
+    } else {
+        sendOTRmessage(otrSes.startSession());
+    }
+
     context->setFinished();
 }
 
@@ -312,8 +323,14 @@ void OtrProxyChannel::Adaptee::trustFingerprint(const QString& fingerprint, bool
 void OtrProxyChannel::Adaptee::onMessageReceived(const Tp::ReceivedMessage &receivedMessage)
 {
     const uint id = receivedMessage.header()[QLatin1String("pending-message-id")].variant().toUInt(nullptr);
-    kDebug() << "Received message with id: " << id;
     OTR::Message otrMsg(receivedMessage.parts());
+    if(otrMsg.isOTRmessage() && otrSes.localFingerprint().isEmpty() && ps->getPolicy() != OTRL_POLICY_NEVER) {
+        enqueuedMessages << receivedMessage;
+        acquirePrivateKey();
+        return;
+    }
+
+    kDebug() << "Received message with id: " << id;
     const OTR::CryptResult cres = otrSes.decrypt(otrMsg);
 
     if(cres == OTR::CryptResult::CHANGED || cres == OTR::CryptResult::UNCHANGED) {
@@ -364,3 +381,36 @@ void OtrProxyChannel::Adaptee::onTrustLevelChanged(TrustLevel trustLevel)
     Q_EMIT trustLevelChanged(static_cast<uint>(trustLevel));
 }
 
+void OtrProxyChannel::Adaptee::acquirePrivateKey()
+{
+    connect(ps, SIGNAL(keyGenerationFinished(const QString&, bool)), SLOT(onKeyGenerationFinished(const QString&, bool)));
+    if(!ps->createNewPrivateKey(otrSes.context().accountId, otrSes.context().accountName)) {
+        disconnect(ps, SIGNAL(keyGenerationFinished(const QString&, bool)),
+                this, SLOT(onKeyGenerationFinished(const QString&, bool)));
+    }
+}
+
+void OtrProxyChannel::Adaptee::onKeyGenerationFinished(const QString &accountId, bool error)
+{
+    if(accountId != otrSes.context().accountId) {
+        return;
+    }
+    kDebug() << "Finished key generation for: " << accountId;
+    disconnect(ps, SIGNAL(keyGenerationFinished(const QString&, bool)),
+            this, SLOT(onKeyGenerationFinished(const QString&, bool)));
+
+    if(error) {
+        kWarning() << "Could not generate private key for " << accountId;
+        return;
+    }
+    if(!enqueuedMessages.isEmpty()) {
+        for(auto &&mes: enqueuedMessages) {
+            onMessageReceived(mes);
+        }
+        enqueuedMessages.clear();
+    } else if(aboutToInit) {
+        sendOTRmessage(otrSes.startSession());
+    }
+
+    aboutToInit = false;
+}
diff --git a/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.h b/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.h
index eedca55..c810dc6 100644
--- a/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.h
+++ b/otr-proxy/KTpProxy/otr-proxy-channel-adaptee.h
@@ -32,10 +32,7 @@
 
 using namespace OTR;
 
-namespace OTR
-{
-    class Manager;
-}
+class ProxyService;
 
 class OtrProxyChannel::Adaptee : public QObject
 {
@@ -52,7 +49,7 @@ class OtrProxyChannel::Adaptee : public QObject
                 const QDBusConnection &dbusConnection,
                 const Tp::TextChannelPtr &channel,
                 const OTR::SessionContext &context,
-                OTR::Manager *manager);
+                ProxyService *ps);
 
         QDBusObjectPath wrappedChannel() const;
         bool connected() const;
@@ -66,6 +63,7 @@ class OtrProxyChannel::Adaptee : public QObject
         void processOTRmessage(const OTR::Message &message);
     private:
         void sendOTRmessage(const OTR::Message &message);
+        void acquirePrivateKey();
 
     private Q_SLOTS:
         void connectProxy(const Tp::Service::ChannelProxyInterfaceOTRAdaptor::ConnectProxyContextPtr &context);
@@ -85,6 +83,7 @@ class OtrProxyChannel::Adaptee : public QObject
         void onPendingSendFinished(Tp::PendingOperation *pendingSend);
 
         void onTrustLevelChanged(TrustLevel trustLevel);
+        void onKeyGenerationFinished(const QString &accountId, bool error);
 
     Q_SIGNALS:
         void messageSent(const Tp::MessagePartList &content, uint flags, const QString &messageToken);
@@ -100,8 +99,11 @@ class OtrProxyChannel::Adaptee : public QObject
         Tp::TextChannelPtr chan;
         bool isConnected;
         OTR::ProxySession otrSes;
+        ProxyService *ps;
 
         QMap<uint, Tp::ReceivedMessage> messages; // queue
+        QList<Tp::ReceivedMessage> enqueuedMessages; // when there is now private key generated
+        bool aboutToInit; // user wanted to start the OTR session but no private key was available
 };
 
 #endif
diff --git a/otr-proxy/KTpProxy/otr-proxy-channel.cpp b/otr-proxy/KTpProxy/otr-proxy-channel.cpp
index b92e6ca..54c0f2d 100644
--- a/otr-proxy/KTpProxy/otr-proxy-channel.cpp
+++ b/otr-proxy/KTpProxy/otr-proxy-channel.cpp
@@ -19,6 +19,7 @@
 
 #include "otr-proxy-channel.h"
 #include "otr-proxy-channel-adaptee.h"
+#include "proxy-service.h"
 #include "constants.h"
 
 #include <TelepathyQt/Channel>
@@ -26,51 +27,31 @@
 #include <TelepathyQt/DBusError>
 #include <TelepathyQt/Connection>
 
-class OtrProxyChannel::Private
-{
-    public:
-        Private(const QDBusConnection &dbusConnection,
-                OtrProxyChannel *pc,
-                const Tp::TextChannelPtr &channel,
-                const OTR::SessionContext &context,
-                OTR::Manager *manager)
-            : adaptee(pc, dbusConnection, channel, context, manager)
-        {
-        }
-
-        Adaptee adaptee;
-};
-
 OtrProxyChannel::OtrProxyChannel(
         const QDBusConnection &dbusConnection,
         const Tp::TextChannelPtr &channel,
         const OTR::SessionContext &context,
-        OTR::Manager *manager)
+        ProxyService *ps)
     : Tp::DBusService(dbusConnection),
-    d(new Private(dbusConnection, this, channel, context, manager))
-{
-    connect(&d->adaptee, SIGNAL(closed()), SLOT(onClosed()));
-}
-
-OtrProxyChannel::~OtrProxyChannel()
+    adaptee(new Adaptee(this, dbusConnection, channel, context, ps))
 {
-    delete d;
+    connect(adaptee, SIGNAL(closed()), SLOT(onClosed()));
 }
 
 OtrProxyChannelPtr OtrProxyChannel::create(const QDBusConnection &dbusConnection, const Tp::TextChannelPtr &channel,
-                const OTR::SessionContext &context, OTR::Manager *manager)
+                const OTR::SessionContext &context, ProxyService *ps)
 {
-    return OtrProxyChannelPtr(new OtrProxyChannel(dbusConnection, channel, context, manager));
+    return OtrProxyChannelPtr(new OtrProxyChannel(dbusConnection, channel, context, ps));
 }
 
 void OtrProxyChannel::registerService(Tp::DBusError *error)
 {
     int index;
-    QString connectionId = d->adaptee.channel()->connection()->objectPath();
+    QString connectionId = adaptee->channel()->connection()->objectPath();
     index = connectionId.lastIndexOf(QChar::fromLatin1('/'));
     connectionId = connectionId.mid(index+1);
 
-    QString channelId = d->adaptee.channel()->objectPath();
+    QString channelId = adaptee->channel()->objectPath();
     index = channelId.lastIndexOf(QChar::fromLatin1('/'));
     channelId = channelId.mid(index+1);
 
@@ -86,11 +67,11 @@ QVariantMap OtrProxyChannel::immutableProperties() const
 
 Tp::TextChannelPtr OtrProxyChannel::wrappedChannel() const
 {
-    return d->adaptee.channel();
+    return adaptee->channel();
 }
 
 void OtrProxyChannel::onClosed()
 {
-    emit closed();
+    Q_EMIT closed();
 }
 
diff --git a/otr-proxy/KTpProxy/otr-proxy-channel.h b/otr-proxy/KTpProxy/otr-proxy-channel.h
index e472525..daefe67 100644
--- a/otr-proxy/KTpProxy/otr-proxy-channel.h
+++ b/otr-proxy/KTpProxy/otr-proxy-channel.h
@@ -28,6 +28,8 @@
 
 #include <QDBusObjectPath>
 
+class ProxyService;
+
 namespace OTR
 {
     class Manager;
@@ -43,12 +45,11 @@ class OtrProxyChannel : public Tp::DBusService
         OtrProxyChannel(const QDBusConnection &dbusConnection,
                 const Tp::TextChannelPtr &channel,
                 const OTR::SessionContext &context,
-                OTR::Manager *manager);
+                ProxyService *ps);
 
     public:
-        ~OtrProxyChannel();
         static OtrProxyChannelPtr create(const QDBusConnection &dbusConnection, const Tp::TextChannelPtr &channel,
-                const OTR::SessionContext &context, OTR::Manager *manager);
+                const OTR::SessionContext &context, ProxyService *ps);
 
         void registerService(Tp::DBusError *error);
 
@@ -59,7 +60,6 @@ class OtrProxyChannel : public Tp::DBusService
         Tp::TextChannelPtr wrappedChannel() const;
 
         class Adaptee;
-        friend class Adaptee;
 
     Q_SIGNALS:
         void connected(const QDBusObjectPath &proxyPath);
@@ -70,9 +70,7 @@ class OtrProxyChannel : public Tp::DBusService
         void onClosed();
 
     private:
-        class Private;
-        friend class Private;
-        Private *d;
+        Adaptee *adaptee;
 };
 
 #endif /* KTP_PROXY_OTR_PROXY_CHANNEL_HEADER */
diff --git a/otr-proxy/KTpProxy/otr-session.cpp b/otr-proxy/KTpProxy/otr-session.cpp
index 96f4eaf..e5a412e 100644
--- a/otr-proxy/KTpProxy/otr-session.cpp
+++ b/otr-proxy/KTpProxy/otr-session.cpp
@@ -74,7 +74,7 @@ namespace OTR
         tlevel(TrustLevel::NOT_PRIVATE),
         pr(parent)
     {
-        userstate = pr->getUserState(ctx);
+        userstate = pr->getUserState(ctx.accountId);
     }
 
     TrustLevel Session::trustLevel() const
@@ -122,6 +122,22 @@ namespace OTR
         }
     }
 
+    QString Session::localFingerprint() const
+    {
+        unsigned char ourRawHash[20];
+        unsigned char *res = otrl_privkey_fingerprint_raw(
+                userstate->userState(),
+                ourRawHash,
+                ctx.accountName.toLocal8Bit(),
+                ctx.protocol.toLocal8Bit());
+
+        if(res == nullptr) {
+            return QLatin1String("");
+        } else {
+            return utils::humanReadable(ourRawHash);
+        }
+    }
+
     Message Session::startSession()
     {
         Message msg;
diff --git a/otr-proxy/KTpProxy/otr-session.h b/otr-proxy/KTpProxy/otr-session.h
index b56bc4d..485aade 100644
--- a/otr-proxy/KTpProxy/otr-session.h
+++ b/otr-proxy/KTpProxy/otr-session.h
@@ -70,6 +70,7 @@ namespace OTR
             TrustLevel trustLevel() const;
             const SessionContext& context() const;
             QString remoteFingerprint() const;
+            QString localFingerprint() const;
 
             /** Returns OTR init message */
             Message startSession();
diff --git a/otr-proxy/KTpProxy/otr-utils.h b/otr-proxy/KTpProxy/otr-utils.h
index 884dcb5..81c6b2f 100644
--- a/otr-proxy/KTpProxy/otr-utils.h
+++ b/otr-proxy/KTpProxy/otr-utils.h
@@ -21,6 +21,8 @@
 #define KTP_PROXY_OTR_UTILS_HEADER
 
 #include <QString>
+#include <QStringList>
+#include <QDBusObjectPath>
 
 extern "C" {
 #include <libotr/privkey.h>
@@ -45,6 +47,41 @@ namespace utils
 
         return QString::fromLocal8Bit(human, OTRL_PRIVKEY_FPRINT_HUMAN_LEN);
     }
+
+    inline QString accountIdFor(const QDBusObjectPath &objectPath)
+    {
+        QStringList elems = objectPath.path().split(QLatin1Char('/'));
+        return QStringList(elems.mid(elems.size()-3)).join(QLatin1String("."));
+    }
+
+    inline QString accountIdFor(const QString &cmName, const QString &protocol, const QString &acc)
+    {
+        return cmName + QLatin1Char('.') + protocol + QLatin1Char('.') + acc;
+    }
+
+    inline QString cmNameFromAccountId(const QString &accountId)
+    {
+        return accountId.split(QLatin1Char('.'))[0];
+    }
+
+    inline QString protocolFromAccountId(const QString &accountId)
+    {
+        return accountId.split(QLatin1Char('.'))[1];
+    }
+
+    inline QString accFromAccountId(const QString &accountId)
+    {
+        return accountId.split(QLatin1Char('.'))[2];
+    }
+
+    inline QDBusObjectPath objectPathFor(const QString &accountId)
+    {
+        return QDBusObjectPath(
+                QLatin1String("/org/freedesktop/Telepathy/Account/") +
+                cmNameFromAccountId(accountId) + QLatin1Char('/') +
+                protocolFromAccountId(accountId) + QLatin1Char('/') +
+                accFromAccountId(accountId));
+    }
 }
 }
 
diff --git a/otr-proxy/KTpProxy/proxy-service-adaptee.cpp b/otr-proxy/KTpProxy/proxy-service-adaptee.cpp
index 379ae29..c3c21ca 100644
--- a/otr-proxy/KTpProxy/proxy-service-adaptee.cpp
+++ b/otr-proxy/KTpProxy/proxy-service-adaptee.cpp
@@ -18,22 +18,82 @@
  ***************************************************************************/
 
 #include "proxy-service-adaptee.h"
-#include "svc-proxy-service.h"
 #include "proxy-service.h"
+#include "otr-constants.h"
 
 #include <TelepathyQt/DBusObject>
 
 ProxyServiceAdaptee::ProxyServiceAdaptee(ProxyService *ps, const QDBusConnection &dbusConnection)
-    : adaptor(new Tp::Service::ProxyServiceAdaptor(dbusConnection, this, ps->dbusObject()))
+    : adaptor(new Tp::Service::ProxyServiceAdaptor(dbusConnection, this, ps->dbusObject())),
+    ps(ps)
 {
+    connect(ps, SIGNAL(keyGenerationStarted(const QString&)), SLOT(onKeyGenerationStarted(const QString&)));
+    connect(ps, SIGNAL(keyGenerationFinished(const QString&, bool)), SLOT(onKeyGenerationFinished(const QString&, bool)));
 }
+
 ProxyServiceAdaptee::~ProxyServiceAdaptee() { }
 
+uint ProxyServiceAdaptee::policy() const
+{
+    switch(ps->getPolicy()) {
+        case OTRL_POLICY_ALWAYS:
+            return 0;
+        case OTRL_POLICY_OPPORTUNISTIC:
+            return 1;
+        case OTRL_POLICY_MANUAL:
+            return 2;
+        case OTRL_POLICY_NEVER:
+        default:
+            return 3;
+    }
+}
+
+void ProxyServiceAdaptee::setPolicy(uint otrPolicy)
+{
+    switch(otrPolicy) {
+        case 0:
+            ps->setPolicy(OTRL_POLICY_ALWAYS);
+        case 1:
+            ps->setPolicy(OTRL_POLICY_OPPORTUNISTIC);
+        case 2:
+            ps->setPolicy(OTRL_POLICY_MANUAL);
+        case 3:
+            ps->setPolicy(OTRL_POLICY_NEVER);
+        default:
+            // nos uch policy
+            return;
+    }
+}
+
 void ProxyServiceAdaptee::onProxyConnected(const QDBusObjectPath &proxyPath)
 {
-    emit proxyconnected(proxyPath);
+    Q_EMIT proxyConnected(proxyPath);
 }
 void ProxyServiceAdaptee::onProxyDisconnected(const QDBusObjectPath &proxyPath)
 {
-    emit proxydisconnected(proxyPath);
+    Q_EMIT proxyDisconnected(proxyPath);
+}
+
+void ProxyServiceAdaptee::onKeyGenerationStarted(const QString &accountId)
+{
+    Q_EMIT(keyGenerationStarted(OTR::utils::objectPathFor(accountId)));
+}
+
+void ProxyServiceAdaptee::onKeyGenerationFinished(const QString &accountId, bool error)
+{
+    Q_EMIT(keyGenerationFinished(OTR::utils::objectPathFor(accountId), error));
+}
+
+void ProxyServiceAdaptee::generatePrivateKey(const QDBusObjectPath &accountPath,
+        const Tp::Service::ProxyServiceAdaptor::GeneratePrivateKeyContextPtr &context)
+{
+    Tp::AccountPtr ac = ps->accountManager()->accountForObjectPath(accountPath.path());
+    if(ac->isValidAccount() &&
+            ps->createNewPrivateKey(OTR::utils::accountIdFor(accountPath), ac->normalizedName())) {
+        context->setFinished();
+    } else {
+        // TODO better errors
+        context->setFinishedWithError(TP_QT_ERROR_INVALID_ARGUMENT,
+                QLatin1String("Could not generate private key for given account"));
+    }
 }
diff --git a/otr-proxy/KTpProxy/proxy-service-adaptee.h b/otr-proxy/KTpProxy/proxy-service-adaptee.h
index c43113c..a18e8d0 100644
--- a/otr-proxy/KTpProxy/proxy-service-adaptee.h
+++ b/otr-proxy/KTpProxy/proxy-service-adaptee.h
@@ -23,6 +23,8 @@
 #include <QDBusObjectPath>
 #include <QDBusConnection>
 
+#include "svc-proxy-service.h"
+
 namespace Tp
 {
 namespace Service
@@ -36,20 +38,33 @@ class ProxyServiceAdaptee : public QObject
 {
     Q_OBJECT
 
+        Q_PROPERTY(uint policySettings READ policy WRITE setPolicy)
+
     public:
         ProxyServiceAdaptee(ProxyService *ps, const QDBusConnection &dbusConnection);
         ~ProxyServiceAdaptee();
 
+        uint policy() const;
+        void setPolicy(uint otrPolicy);
+
     Q_SIGNALS:
-        void proxyconnected(const QDBusObjectPath &proxyPath);
-        void proxydisconnected(const QDBusObjectPath &proxyPath);
+        void proxyConnected(const QDBusObjectPath &proxyPath);
+        void proxyDisconnected(const QDBusObjectPath &proxyPath);
+        void keyGenerationStarted(const QDBusObjectPath &accountPath);
+        void keyGenerationFinished(const QDBusObjectPath &accountPath, bool error);
 
     public Q_SLOTS:
         void onProxyConnected(const QDBusObjectPath &proxyPath);
         void onProxyDisconnected(const QDBusObjectPath &proxyPath);
+        void generatePrivateKey(const QDBusObjectPath &accountPath,
+                const Tp::Service::ProxyServiceAdaptor::GeneratePrivateKeyContextPtr &context);
+    private Q_SLOTS:
+        void onKeyGenerationStarted(const QString &accountId);
+        void onKeyGenerationFinished(const QString &accountId, bool error);
 
     private:
         Tp::Service::ProxyServiceAdaptor *adaptor;
+        ProxyService *ps;
 };
 
 #endif
diff --git a/otr-proxy/KTpProxy/proxy-service.cpp b/otr-proxy/KTpProxy/proxy-service.cpp
index c250826..ae0eb89 100644
--- a/otr-proxy/KTpProxy/proxy-service.cpp
+++ b/otr-proxy/KTpProxy/proxy-service.cpp
@@ -21,6 +21,7 @@
 #include "proxy-observer.h"
 #include "otr-proxy-channel.h"
 #include "otr-config.h"
+#include "otr-utils.h"
 #include "pending-curry-operation.h"
 #include "constants.h"
 
@@ -55,7 +56,8 @@ ProxyService::ProxyService(const QDBusConnection &dbusConnection, OTR::Config *c
     adaptee(this, dbusConnection),
     observer(new ProxyObserver(this)),
     registrar(Tp::ClientRegistrar::create(dbusConnection)),
-    manager(config)
+    manager(config),
+    am(Tp::AccountManager::create(dbusConnection))
 {
 }
 
@@ -64,6 +66,16 @@ ProxyService::~ProxyService()
     registrar->unregisterClients();
 }
 
+OTR::Manager* ProxyService::managerOTR()
+{
+    return &manager;
+}
+
+Tp::AccountManagerPtr ProxyService::accountManager()
+{
+    return am;
+}
+
 void ProxyService::addChannel(const Tp::ChannelPtr &channel, const Tp::AccountPtr &account)
 {
     Tp::TextChannelPtr textChannel = Tp::TextChannel::create(channel->connection(), channel->objectPath(), QVariantMap());
@@ -101,6 +113,16 @@ QVariantMap ProxyService::immutableProperties() const
     return QVariantMap();
 }
 
+OtrlPolicy ProxyService::getPolicy() const
+{
+    return manager.getPolicy();
+}
+
+void ProxyService::setPolicy(OtrlPolicy otrPolicy)
+{
+    manager.setPolicy(otrPolicy);
+}
+
 void ProxyService::onChannelProxyClosed()
 {
     OtrProxyChannel *proxyChannel = dynamic_cast<OtrProxyChannel*>(QObject::sender());
@@ -124,13 +146,13 @@ void ProxyService::onChannelReady(Tp::PendingOperation *pendingChanReady)
     Tp::DBusError error;
     OTR::SessionContext ctx =
     {
-        pendingReady->account->uniqueIdentifier().replace(QChar('/'), QChar('_')),
+        OTR::utils::accountIdFor(QDBusObjectPath(pendingReady->account->objectPath())),
         pendingReady->account->normalizedName(),
         textChannel->targetId(),
         textChannel->connection()->protocolName()
     };
 
-    OtrProxyChannelPtr proxyChannel = OtrProxyChannel::create(dbusConnection(), textChannel, ctx, &manager);
+    OtrProxyChannelPtr proxyChannel = OtrProxyChannel::create(dbusConnection(), textChannel, ctx, this);
     proxyChannel->registerService(&error);
 
     if(error.isValid()) {
@@ -154,3 +176,37 @@ void ProxyService::onChannelReady(Tp::PendingOperation *pendingChanReady)
     kDebug() << "Installed proxy: " << proxyChannel->objectPath() << "
"
         << " for the channel: " << textChannel->objectPath();
 }
+
+bool ProxyService::createNewPrivateKey(const QString &accountId, const QString &accountName)
+{
+    kDebug() << "Generating new private key for " << accountId;
+    OTR::KeyGenerationThread *keyThread = manager.createNewPrivateKey(accountId, accountName);
+    if(keyThread) {
+        if(keyThread->prepareCreation()) {
+            // alredy started creation for this account
+            kDebug() << "Cannot prepare key generation for " << accountId;
+            return false;
+        }
+        connect(keyThread, SIGNAL(finished()), SLOT(onKeyGenerationThreadFinished()));
+        keyThread->start();
+        Q_EMIT keyGenerationStarted(accountId);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void ProxyService::onKeyGenerationThreadFinished()
+{
+    OTR::KeyGenerationThread *thread = dynamic_cast<OTR::KeyGenerationThread*>(QObject::sender());
+    kDebug() << "Finished generating a new private key for " << thread->accountId;
+
+    if(thread->error() || thread->finalizeCreation()) {
+        kDebug() << "Error generating private key for " << thread->accountId;
+        Q_EMIT keyGenerationFinished(thread->accountId, true);
+    } else{
+        Q_EMIT keyGenerationFinished(thread->accountId, false);
+    }
+
+    thread->deleteLater();
+}
diff --git a/otr-proxy/KTpProxy/proxy-service.h b/otr-proxy/KTpProxy/proxy-service.h
index fae4a9e..5cdb72b 100644
--- a/otr-proxy/KTpProxy/proxy-service.h
+++ b/otr-proxy/KTpProxy/proxy-service.h
@@ -28,6 +28,7 @@
 #include <TelepathyQt/AbstractClientObserver>
 #include <TelepathyQt/Types>
 #include <TelepathyQt/DBusService>
+#include <TelepathyQt/AccountManager>
 
 #include <QDBusConnection>
 #include <QMap>
@@ -52,12 +53,23 @@ class ProxyService : public Tp::DBusService
         void registerService(Tp::DBusError *error);
 
         QVariantMap immutableProperties() const;
+        OtrlPolicy getPolicy() const;
+        void setPolicy(OtrlPolicy otrPolicy);
 
-    private Q_SLOTS:
-        void onChannelProxyClosed();
+        /** returns false if key cannot be generated - i.e. incorrect id */
+        bool createNewPrivateKey(const QString &accountId, const QString &accountName);
+
+        OTR::Manager* managerOTR();
+        Tp::AccountManagerPtr accountManager();
 
     private Q_SLOTS:
+        void onChannelProxyClosed();
         void onChannelReady(Tp::PendingOperation *pendingChanReady);
+        void onKeyGenerationThreadFinished();
+
+    Q_SIGNALS:
+        void keyGenerationStarted(const QString &accountId);
+        void keyGenerationFinished(const QString &accountId, bool error);
 
     private:
         ProxyServiceAdaptee adaptee;
@@ -65,6 +77,7 @@ class ProxyService : public Tp::DBusService
         ProxyObserverPtr observer;
         Tp::ClientRegistrarPtr registrar;
         OTR::Manager manager;
+        Tp::AccountManagerPtr am;
 };
 
 #endif
diff --git a/otr-proxy/KTpProxy/svc-proxy-service.cpp b/otr-proxy/KTpProxy/svc-proxy-service.cpp
index d2f949e..0be1c16 100644
--- a/otr-proxy/KTpProxy/svc-proxy-service.cpp
+++ b/otr-proxy/KTpProxy/svc-proxy-service.cpp
@@ -11,13 +11,39 @@ namespace Service
 ProxyServiceAdaptor::ProxyServiceAdaptor(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
     : Tp::AbstractAdaptor(bus, adaptee, parent)
 {
-    connect(adaptee, SIGNAL(proxyconnected(const QDBusObjectPath&)), SIGNAL(ProxyConnected(const QDBusObjectPath&)));
-    connect(adaptee, SIGNAL(proxydisconnected(const QDBusObjectPath&)), SIGNAL(ProxyDisconnected(const QDBusObjectPath&)));
+    connect(adaptee, SIGNAL(proxyConnected(const QDBusObjectPath&)), SIGNAL(ProxyConnected(const QDBusObjectPath&)));
+    connect(adaptee, SIGNAL(proxyDisconnected(const QDBusObjectPath&)), SIGNAL(ProxyDisconnected(const QDBusObjectPath&)));
+    connect(adaptee, SIGNAL(keyGenerationStarted(const QDBusObjectPath&)), SIGNAL(KeyGenerationStarted(const QDBusObjectPath&)));
+    connect(adaptee, SIGNAL(keyGenerationFinished(const QDBusObjectPath&, bool)), SIGNAL(KeyGenerationFinished(const QDBusObjectPath&, bool)));
 }
 
 ProxyServiceAdaptor::~ProxyServiceAdaptor()
 {
 }
 
+uint ProxyServiceAdaptor::PolicySettings() const
+{
+    return qvariant_cast< uint >(adaptee()->property("policySettings"));
+}
+
+void ProxyServiceAdaptor::SetPolicySettings(const uint &newValue)
+{
+    adaptee()->setProperty("policySettings", qVariantFromValue(newValue));
+}
+
+void ProxyServiceAdaptor::GeneratePrivateKey(const QDBusObjectPath& account, const QDBusMessage& dbusMessage)
+{
+    if (!adaptee()->metaObject()->indexOfMethod("generatePrivateKey(QDBusObjectPath,Tp::Service::ProxyServiceAdaptor::GeneratePrivateKeyContextPtr)") == -1) {
+        dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
+        return;
+    }
+
+    GeneratePrivateKeyContextPtr ctx = GeneratePrivateKeyContextPtr(
+            new Tp::MethodInvocationContext<  >(dbusConnection(), dbusMessage));
+    QMetaObject::invokeMethod(adaptee(), "generatePrivateKey",
+        Q_ARG(QDBusObjectPath, account),
+        Q_ARG(Tp::Service::ProxyServiceAdaptor::GeneratePrivateKeyContextPtr, ctx));
+}
+
 }
 }
diff --git a/otr-proxy/KTpProxy/svc-proxy-service.h b/otr-proxy/KTpProxy/svc-proxy-service.h
index 5e9416b..d083ad5 100644
--- a/otr-proxy/KTpProxy/svc-proxy-service.h
+++ b/otr-proxy/KTpProxy/svc-proxy-service.h
@@ -15,6 +15,7 @@
 #include <QObject>
 #include <QtDBus>
 
+
 namespace Tp
 {
 namespace Service
@@ -33,31 +34,90 @@ class TP_QT_EXPORT ProxyServiceAdaptor : public Tp::AbstractAdaptor
     Q_CLASSINFO("D-Bus Interface", "org.kde.TelepathyProxy.ProxyService")
     Q_CLASSINFO("D-Bus Introspection", ""
 "  <interface name=\"org.kde.TelepathyProxy.ProxyService\">
"
+"    <property access=\"readwrite\" type=\"u\" name=\"PolicySettings\"/>
"
+"    <method name=\"GeneratePrivateKey\">
"
+"      <arg direction=\"in\" type=\"o\" name=\"account\"/>
"
+"    </method>
"
 "    <signal name=\"ProxyConnected\">
"
 "      <arg type=\"o\" name=\"proxy\"/>
"
 "    </signal>
"
 "    <signal name=\"ProxyDisconnected\">
"
 "      <arg type=\"o\" name=\"proxy\"/>
"
 "    </signal>
"
+"    <signal name=\"KeyGenerationStarted\">
"
+"      <arg type=\"o\" name=\"account\"/>
"
+"    </signal>
"
+"    <signal name=\"KeyGenerationFinished\">
"
+"      <arg type=\"o\" name=\"account\"/>
"
+"      <arg type=\"b\" name=\"error\"/>
"
+"    </signal>
"
 "  </interface>
"
 "")
+    Q_PROPERTY(uint PolicySettings READ PolicySettings WRITE SetPolicySettings)
 
 public:
     ProxyServiceAdaptor(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent);
     virtual ~ProxyServiceAdaptor();
 
+    typedef Tp::MethodInvocationContextPtr<  > GeneratePrivateKeyContextPtr;
+
+public: // PROPERTIES
+    /**
+     * Return the value of the exported D-Bus object property 
-- 
ktp-common-internals packaging



More information about the pkg-kde-commits mailing list