From 3146ad01b5b29c30adcf0044a52b39aa7e5796d0 Mon Sep 17 00:00:00 2001 From: Bas Pape Date: Thu, 31 Jan 2013 18:46:17 +0100 Subject: [PATCH] Refactor Cipher related things. Instead of using a hash with set keys, set the key on the relevant CoreIrc{User,Channel}'s cipher member. Let the cipher clear its own key (with appropriate checks elsewhere) Instantiate a new IrcUser when necessary (a query with someone who does not share any channels with us means there is no IrcUser for the target until he says something) --- src/core/cipher.cpp | 4 ++- src/core/coreircchannel.cpp | 7 ----- src/core/corenetwork.cpp | 50 +++++++++++++++++++------------ src/core/corenetwork.h | 2 +- src/core/coreuserinputhandler.cpp | 18 ++--------- src/core/ircparser.cpp | 2 +- 6 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/core/cipher.cpp b/src/core/cipher.cpp index 5ca31293..15a986b2 100644 --- a/src/core/cipher.cpp +++ b/src/core/cipher.cpp @@ -35,8 +35,10 @@ Cipher::~Cipher() bool Cipher::setKey(QByteArray key) { - if (key.isEmpty()) + if (key.isEmpty()) { + m_key.clear(); return false; + } if (key.mid(0, 4).toLower() == "ecb:") { diff --git a/src/core/coreircchannel.cpp b/src/core/coreircchannel.cpp index f0e65ff6..98995bff 100644 --- a/src/core/coreircchannel.cpp +++ b/src/core/coreircchannel.cpp @@ -59,13 +59,6 @@ void CoreIrcChannel::setEncrypted(bool e) if (topic().isEmpty()) return; - QByteArray key = qobject_cast(network())->cipherKey(name()); - if (key.isEmpty()) - return; - - if (!cipher()->setKey(key)) - return; - QByteArray decrypted = cipher()->decryptTopic(topic().toAscii()); setTopic(decodeString(decrypted)); } diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index 3a2c208d..512ac104 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -310,7 +310,7 @@ void CoreNetwork::removeChannelKey(const QString &channel) #ifdef HAVE_QCA2 -Cipher *CoreNetwork::cipher(const QString &target) const +Cipher *CoreNetwork::cipher(const QString &target) { if (target.isEmpty()) return 0; @@ -318,39 +318,51 @@ Cipher *CoreNetwork::cipher(const QString &target) const if (!Cipher::neededFeaturesAvailable()) return 0; - QByteArray key = cipherKey(target); - if (key.isEmpty()) - return 0; - CoreIrcChannel *channel = qobject_cast(ircChannel(target)); if (channel) { - if (channel->cipher()->setKey(key)) - return channel->cipher(); + return channel->cipher(); } - else { - CoreIrcUser *user = qobject_cast(ircUser(target)); - if (user && user->cipher()->setKey(key)) - return user->cipher(); + CoreIrcUser *user = qobject_cast(ircUser(target)); + if (user) { + return user->cipher(); + } else if (!isChannelName(target)) { + return qobject_cast(newIrcUser(target))->cipher(); } return 0; } -QByteArray CoreNetwork::cipherKey(const QString &recipient) const +QByteArray CoreNetwork::cipherKey(const QString &target) const { - return _cipherKeys.value(recipient.toLower(), QByteArray()); + CoreIrcChannel *c = qobject_cast(ircChannel(target)); + if (c) + return c->cipher()->key(); + + CoreIrcUser *u = qobject_cast(ircUser(target)); + if (u) + return u->cipher()->key(); + + return QByteArray(); } -void CoreNetwork::setCipherKey(const QString &recipient, const QByteArray &key) +void CoreNetwork::setCipherKey(const QString &target, const QByteArray &key) { - if (!key.isEmpty()) - _cipherKeys[recipient.toLower()] = key; - else - _cipherKeys.remove(recipient.toLower()); -} + CoreIrcChannel *c = qobject_cast(ircChannel(target)); + if (c) { + c->setEncrypted(c->cipher()->setKey(key)); + return; + } + CoreIrcUser *u = qobject_cast(ircUser(target)); + if (!u && !isChannelName(target)) + u = qobject_cast(newIrcUser(target)); + if (u) { + u->setEncrypted(u->cipher()->setKey(key)); + return; + } +} #endif /* HAVE_QCA2 */ bool CoreNetwork::setAutoWhoDone(const QString &channel) diff --git a/src/core/corenetwork.h b/src/core/corenetwork.h index e58945a5..7b6048a3 100644 --- a/src/core/corenetwork.h +++ b/src/core/corenetwork.h @@ -120,7 +120,7 @@ public slots: // Blowfish stuff #ifdef HAVE_QCA2 - Cipher *cipher(const QString &recipient) const; + Cipher *cipher(const QString &recipient); QByteArray cipherKey(const QString &recipient) const; void setCipherKey(const QString &recipient, const QByteArray &key); #endif diff --git a/src/core/coreuserinputhandler.cpp b/src/core/coreuserinputhandler.cpp index 930be966..03264363 100644 --- a/src/core/coreuserinputhandler.cpp +++ b/src/core/coreuserinputhandler.cpp @@ -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(network()->ircChannel(target))->setEncrypted(false); - } - else if (network()->nicks().contains(target)) { - qobject_cast(network()->ircUser(target))->setEncrypted(false); - } - emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("The key for %1 has been deleted.").arg(target)); #else @@ -560,14 +552,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(network()->ircChannel(target))->setEncrypted(true); - else if (network()->nicks().contains(target)) - qobject_cast(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 +702,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 +783,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_; diff --git a/src/core/ircparser.cpp b/src/core/ircparser.cpp index 69603c1c..f71f53c1 100644 --- a/src/core/ircparser.cpp +++ b/src/core/ircparser.cpp @@ -58,7 +58,7 @@ QByteArray IrcParser::decrypt(Network *network, const QString &bufferName, const return message; Cipher *cipher = qobject_cast(network)->cipher(bufferName); - if (!cipher) + if (!cipher || cipher->key().isEmpty()) return message; return isTopic ? cipher->decryptTopic(message) : cipher->decrypt(message); -- 2.20.1