Merge pull request #5 from Tucos/feat-keyx
[quassel.git] / src / core / coreuserinputhandler.cpp
index 05424a6..53f4c2e 100644 (file)
@@ -207,14 +207,6 @@ void CoreUserInputHandler::handleDelkey(const BufferInfo &bufferInfo, const QStr
     }
 
     network()->setCipherKey(target, QByteArray());
-
-    if (network()->isChannelName(target) && network()->channels().contains(target)) {
-        qobject_cast<CoreIrcChannel *>(network()->ircChannel(target))->setEncrypted(false);
-    }
-    else if (network()->nicks().contains(target)) {
-        qobject_cast<CoreIrcUser *>(network()->ircUser(target))->setEncrypted(false);
-    }
-
     emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("The key for %1 has been deleted.").arg(target));
 
 #else
@@ -327,6 +319,50 @@ void CoreUserInputHandler::handleJoin(const BufferInfo &bufferInfo, const QStrin
 }
 
 
+void CoreUserInputHandler::handleKeyx(const BufferInfo &bufferInfo, const QString &msg)
+{
+#ifdef HAVE_QCA2
+    if (!bufferInfo.isValid())
+        return;
+
+    if (!Cipher::neededFeaturesAvailable())
+        return;
+
+    QStringList parms = msg.split(' ', QString::SkipEmptyParts);
+
+    if (parms.count() == 0 && !bufferInfo.bufferName().isEmpty())
+        parms.prepend(bufferInfo.bufferName());
+    else if (parms.count() != 1) {
+        emit displayMsg(Message::Info, bufferInfo.bufferName(),
+            tr("[usage] /keyx [<nick|channel>] Initiates a DH1080 key exchange with the target."));
+        return;
+    }
+
+    QString target = parms.at(0);
+
+    Cipher *cipher = network()->cipher(target);
+    if (!cipher) // happens when there is no CoreIrcChannel for the target
+        return;
+
+    QByteArray pubKey = cipher->initKeyExchange();
+    if (pubKey.isEmpty())
+        emit displayMsg(Message::Error, bufferInfo.bufferName(), tr("Failed to initiate key exchange with %1.").arg(target));
+    else {
+        QList<QByteArray> params;
+        params << serverEncode(target) << serverEncode("DH1080_INIT ") + pubKey;
+        emit putCmd("NOTICE", params);
+        emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("Initiated key exchange with %1.").arg(target));
+    }
+#else
+    Q_UNUSED(msg)
+    emit displayMsg(Message::Error, bufferInfo.bufferName(), tr("Error: Setting an encryption key requires Quassel to have been built "
+                                                                "with support for the Qt Cryptographic Architecture (QCA) library. "
+                                                                "Contact your distributor about a Quassel package with QCA "
+                                                                "support, or rebuild Quassel with QCA present."));
+#endif
+}
+
+
 void CoreUserInputHandler::handleKick(const BufferInfo &bufferInfo, const QString &msg)
 {
     QString nick = msg.section(' ', 0, 0, QString::SectionSkipEmpty);
@@ -560,14 +596,8 @@ void CoreUserInputHandler::handleSetkey(const BufferInfo &bufferInfo, const QStr
 
     QString target = parms.at(0);
     QByteArray key = parms.at(1).toLocal8Bit();
-
     network()->setCipherKey(target, key);
 
-    if (network()->isChannelName(target) && network()->channels().contains(target))
-        qobject_cast<CoreIrcChannel *>(network()->ircChannel(target))->setEncrypted(true);
-    else if (network()->nicks().contains(target))
-        qobject_cast<CoreIrcUser *>(network()->ircUser(target))->setEncrypted(true);
-
     emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("The key for %1 has been set.").arg(target));
 #else
     Q_UNUSED(msg)
@@ -716,7 +746,7 @@ void CoreUserInputHandler::putPrivmsg(const QByteArray &target, const QByteArray
         QByteArray crypted = message.left(splitPos);
         bool isEncrypted = false;
 #ifdef HAVE_QCA2
-        if (cipher && !message.isEmpty()) {
+        if (cipher && !cipher->key().isEmpty() && !message.isEmpty()) {
             isEncrypted = cipher->encrypt(crypted);
         }
 #endif
@@ -797,7 +827,7 @@ QByteArray CoreUserInputHandler::encrypt(const QString &target, const QByteArray
         return message_;
 
     Cipher *cipher = network()->cipher(target);
-    if (!cipher)
+    if (!cipher || cipher->key().isEmpty())
         return message_;
 
     QByteArray message = message_;