[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [ktp-text-ui/otr-proxy] lib: Add buddy authentication through manual fingerprint verification.
From:       Marcin_Ziemiński <zieminn () gmail ! com>
Date:       2014-07-31 19:27:39
Message-ID: E1XCw0p-0000BM-QF () scm ! kde ! org
[Download RAW message or body]

Git commit c76714a65c9b73894bd8c9b26610efc71bd31fc5 by Marcin Ziemiński.
Committed on 31/07/2014 at 19:26.
Pushed by mzieminski into branch 'otr-proxy'.

Add buddy authentication through manual fingerprint verification.
Fixed bug with wrong initialization of OTR trust level.

M  +33   -0    lib/channel-adapter.cpp
M  +3    -0    lib/channel-adapter.h
M  +25   -1    lib/chat-widget.cpp
M  +2    -0    lib/proxy-service.cpp
M  +121  -1    lib/proxy-service.h

http://commits.kde.org/telepathy-text-ui/c76714a65c9b73894bd8c9b26610efc71bd31fc5

diff --git a/lib/channel-adapter.cpp b/lib/channel-adapter.cpp
index 237dbaf..c2f5d32 100644
--- a/lib/channel-adapter.cpp
+++ b/lib/channel-adapter.cpp
@@ -56,6 +56,7 @@ struct ChannelAdapter::Private
 
     bool otrConnected;
     Tp::OTRTrustLevel trustLevel;
+    QString remoteFp;
 
     QMap<uint, OTRMessage> messages;
 };
@@ -172,6 +173,9 @@ void ChannelAdapter::setupOTRChannel()
     // initialize trust level property
     connect(d->otrProxy->requestPropertyTrustLevel(), \
SIGNAL(finished(Tp::PendingOperation*)),  \
SLOT(onTrustLevelPropertyGet(Tp::PendingOperation*))); +    // initialize remote \
fingerprint property +    connect(d->otrProxy->requestPropertyRemoteFingerprint(), \
SIGNAL(finished(Tp::PendingOperation*)), +            \
SLOT(onRemoteFingerprintPropertyGet(Tp::PendingOperation*)));  }
 
 Tp::OTRTrustLevel ChannelAdapter::otrTrustLevel() const
@@ -187,6 +191,7 @@ void ChannelAdapter::onTrustLevelPropertyGet(Tp::PendingOperation \
*op)  }
     Tp::PendingVariant *pv = dynamic_cast<Tp::PendingVariant*>(op);
     d->trustLevel = static_cast<Tp::OTRTrustLevel>(pv->result().toUInt(NULL));
+    Q_EMIT otrTrustLevelChanged(d->trustLevel, Tp::OTRTrustLevelNotPrivate);
 }
 
 bool ChannelAdapter::isOTRsuppored() const
@@ -206,6 +211,16 @@ void ChannelAdapter::stopOTR()
     d->otrProxy->Stop();
 }
 
+QString ChannelAdapter::remoteFingerprint() const
+{
+    return d->remoteFp;
+}
+
+QDBusPendingReply<> ChannelAdapter::trustFingerprint(const QString &fingerprint, \
bool trust) +{
+    return d->otrProxy->TrustFingerprint(fingerprint, trust);
+}
+
 void ChannelAdapter::acknowledge(const QList<Tp::ReceivedMessage> &messages)
 {
     if(messages.isEmpty()) {
@@ -306,6 +321,19 @@ void \
ChannelAdapter::onPendingMessagesPropertyGet(Tp::PendingOperation *op)  }
 }
 
+void ChannelAdapter::onRemoteFingerprintPropertyGet(Tp::PendingOperation *op)
+{
+    kDebug();
+    Tp::PendingVariant *variant = dynamic_cast<Tp::PendingVariant*>(op);
+
+    if(!variant->isError()) {
+        d->remoteFp = variant->result().toString();
+    } else {
+        kWarning() << "Could not get remote fingerprint: " << variant->errorName() \
<< " - " +            << variant->errorMessage();
+    }
+}
+
 void ChannelAdapter::onPendingMessagesRemoved(const Tp::UIntList &messageIDs)
 {
     kDebug();
@@ -332,6 +360,11 @@ void ChannelAdapter::onTrustLevelChanged(uint trustLevel)
 {
     Tp::OTRTrustLevel oldLevel = d->trustLevel;
     d->trustLevel = static_cast<Tp::OTRTrustLevel>(trustLevel);
+    // get remote's fingerprint
+    if(oldLevel == Tp::OTRTrustLevelNotPrivate) {
+        connect(d->otrProxy->requestPropertyRemoteFingerprint(), \
SIGNAL(finished(Tp::PendingOperation*)), +                \
SLOT(onRemoteFingerprintPropertyGet(Tp::PendingOperation*))); +    }
 
     Q_EMIT otrTrustLevelChanged(d->trustLevel, oldLevel);
 }
diff --git a/lib/channel-adapter.h b/lib/channel-adapter.h
index 33af748..8b8d53a 100644
--- a/lib/channel-adapter.h
+++ b/lib/channel-adapter.h
@@ -43,6 +43,8 @@ class ChannelAdapter : public QObject
 
         Tp::OTRTrustLevel otrTrustLevel() const;
         bool isOTRsuppored() const;
+        QString remoteFingerprint() const;
+        QDBusPendingReply<> trustFingerprint(const QString &fingerprint, bool \
trust);  
         bool isValid() const;
 
@@ -70,6 +72,7 @@ class ChannelAdapter : public QObject
     private Q_SLOTS:
         void onTrustLevelPropertyGet(Tp::PendingOperation *op);
         void onPendingMessagesPropertyGet(Tp::PendingOperation *op);
+        void onRemoteFingerprintPropertyGet(Tp::PendingOperation *op);
         void onMessageReceived(const Tp::MessagePartList &message);
         void onPendingMessagesRemoved(const Tp::UIntList &messageIDs);
         void onMessageSent(const Tp::MessagePartList &content, uint flags, const \
                QString &messageToken);
diff --git a/lib/chat-widget.cpp b/lib/chat-widget.cpp
index 5bb2280..8bb6d20 100644
--- a/lib/chat-widget.cpp
+++ b/lib/chat-widget.cpp
@@ -674,7 +674,31 @@ void ChatWidget::stopOtrSession()
 void ChatWidget::authenticateBuddy()
 {
     if(!d->channel.isOTRsuppored()) return;
-    // TODO use adapter
+    // TODO add smp
+    const QString fingerprint = d->channel.remoteFingerprint();
+
+    QString question = i18n("Is the following fingerprint for the contact %1 \
correct?\n%2", +            d->contactName, fingerprint);
+
+    int askResult = KMessageBox::questionYesNoCancel(this, question);
+    QDBusPendingReply<> result;
+    switch(askResult) {
+        case KMessageBox::Yes:
+            result = d->channel.trustFingerprint(fingerprint, true);
+            break;
+        case KMessageBox::No:
+            result = d->channel.trustFingerprint(fingerprint, false);
+            break;
+        default:
+            return;
+    }
+
+    result.waitForFinished();
+    if(result.isError()) {
+        kWarning() << "Could not set fingerprint trusted because of: " << \
result.error().name() +            << " -> " << result.error().message();
+        KMessageBox::error(this, i18n("%1", result.error().message()));
+    }
 }
 
 void ChatWidget::setupOTR()
diff --git a/lib/proxy-service.cpp b/lib/proxy-service.cpp
index cc97f09..470818b 100644
--- a/lib/proxy-service.cpp
+++ b/lib/proxy-service.cpp
@@ -36,6 +36,8 @@ void ProxyServiceInterface::invalidate(Tp::DBusProxy *proxy,
 {
     disconnect(this, SIGNAL(ProxyConnected(const QDBusObjectPath&)), NULL, NULL);
     disconnect(this, SIGNAL(ProxyDisconnected(const QDBusObjectPath&)), NULL, NULL);
+    disconnect(this, SIGNAL(KeyGenerationStarted(const QDBusObjectPath&)), NULL, \
NULL); +    disconnect(this, SIGNAL(KeyGenerationFinished(const QDBusObjectPath&, \
bool)), NULL, NULL);  
     Tp::AbstractInterface::invalidate(proxy, error, message);
 }
diff --git a/lib/proxy-service.h b/lib/proxy-service.h
index 46942da..b447ce0 100644
--- a/lib/proxy-service.h
+++ b/lib/proxy-service.h
@@ -22,6 +22,7 @@
 #include <TelepathyQt/DBusProxy>
 #include <TelepathyQt/Global>
 
+
 namespace Tp
 {
 class PendingVariant;
@@ -111,6 +112,38 @@ public:
     ProxyServiceInterface(const Tp::AbstractInterface& mainInterface, QObject* \
parent);  
     /**
+     * Asynchronous getter for the remote object property \c PolicySettings of type \
\c uint. +     *
+     * 
+     * \htmlonly
+     * <p>Set the OTR policy how you like it</p>
+     * \endhtmlonly
+     *
+     * \return A pending variant which will emit finished when the property has been
+     *          retrieved.
+     */
+    inline Tp::PendingVariant *requestPropertyPolicySettings() const
+    {
+        return internalRequestProperty(QLatin1String("PolicySettings"));
+    }
+
+    /**
+     * Asynchronous setter for the remote object property \c PolicySettings of type \
\c uint. +     *
+     * 
+     * \htmlonly
+     * <p>Set the OTR policy how you like it</p>
+     * \endhtmlonly
+     *
+     * \return A pending operation which will emit finished when the property has \
been +     *          set.
+     */
+    inline Tp::PendingOperation *setPropertyPolicySettings(uint newValue)
+    {
+        return internalSetProperty(QLatin1String("PolicySettings"), \
QVariant::fromValue(newValue)); +    }
+
+    /**
      * Request all of the DBus properties on the interface.
      *
      * \return A pending variant map which will emit finished when the properties \
have @@ -121,6 +154,68 @@ public:
         return internalRequestAllProperties();
     }
 
+public Q_SLOTS:
+    /**
+     * Begins a call to the D-Bus method \c GeneratePrivateKey on the remote object.
+     * 
+     * \htmlonly
+     * <p> Generate new private key for given account. </p>
+     * \endhtmlonly
+     *
+     * Note that \a timeout is ignored as of now. It will be used once
+     * http://bugreports.qt.nokia.com/browse/QTBUG-11775 is fixed.
+     *
+     * \param timeout The timeout in milliseconds.
+     */
+    inline QDBusPendingReply<> GeneratePrivateKey(const QDBusObjectPath& account, \
int timeout = -1) +    {
+        if (!invalidationReason().isEmpty()) {
+            return QDBusPendingReply<>(QDBusMessage::createError(
+                invalidationReason(),
+                invalidationMessage()
+            ));
+        }
+
+        QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), \
this->path(), +                this->staticInterfaceName(), \
QLatin1String("GeneratePrivateKey")); +        callMessage << \
QVariant::fromValue(account); +        return \
this->connection().asyncCall(callMessage, timeout); +    }
+
+    /**
+     * Begins a call to the D-Bus method \c GetFingerprintForAccount on the remote \
object. +     * 
+     * Get private key fingerprint associated with given account
+     *
+     * Note that \a timeout is ignored as of now. It will be used once
+     * http://bugreports.qt.nokia.com/browse/QTBUG-11775 is fixed.
+     *
+     *
+     * \param account
+     *     
+     *     The account the new key is generated for
+     * \param timeout The timeout in milliseconds.
+     *
+     * \return
+     *     
+     *     Fingerprint of given account&apos;s private key or an empty string 
+     *     if none exists
+     */
+    inline QDBusPendingReply<QString> GetFingerprintForAccount(const \
QDBusObjectPath& account, int timeout = -1) +    {
+        if (!invalidationReason().isEmpty()) {
+            return QDBusPendingReply<QString>(QDBusMessage::createError(
+                invalidationReason(),
+                invalidationMessage()
+            ));
+        }
+
+        QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), \
this->path(), +                this->staticInterfaceName(), \
QLatin1String("GetFingerprintForAccount")); +        callMessage << \
QVariant::fromValue(account); +        return \
this->connection().asyncCall(callMessage, timeout); +    }
+
 Q_SIGNALS:
     /**
      * Represents the signal \c ProxyConnected on the remote object.
@@ -144,11 +239,36 @@ Q_SIGNALS:
      */
     void ProxyDisconnected(const QDBusObjectPath& proxy);
 
+    /**
+     * Represents the signal \c KeyGenerationStarted on the remote object.
+     * 
+     * Signals that a new private key is being generated for account
+     *
+     * \param account
+     *     
+     *     The account the new key is generated for
+     */
+    void KeyGenerationStarted(const QDBusObjectPath& account);
+
+    /**
+     * Represents the signal \c KeyGenerationFinished on the remote object.
+     * 
+     * Signals that a new private key has just been generated for account
+     *
+     * \param account
+     *     
+     *     The account the new key has been generated for
+     *
+     * \param error
+     *     
+     *     %TRUE if error occured during generation
+     */
+    void KeyGenerationFinished(const QDBusObjectPath& account, bool error);
+
 protected:
     virtual void invalidate(Tp::DBusProxy *, const QString &, const QString &);
 };
 }
 }
 Q_DECLARE_METATYPE(Tp::Client::ProxyServiceInterface*)
-
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic