From 451ec4e34e5e34fc6d89ce2ebe00c342d6c52e9c Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Mon, 8 Aug 2022 19:36:50 +0200 Subject: Client: e2ee: Check IQ response is valid before decrypting This way the extensions don't need to check that. --- src/client/QXmppClient.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/client/QXmppClient.cpp') diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp index b422842c..18adddb6 100644 --- a/src/client/QXmppClient.cpp +++ b/src/client/QXmppClient.cpp @@ -34,6 +34,12 @@ using MessageEncryptResult = QXmppE2eeExtension::MessageEncryptResult; using IqEncryptResult = QXmppE2eeExtension::IqEncryptResult; using IqDecryptResult = QXmppE2eeExtension::IqDecryptResult; +static bool isIqResponse(const QDomElement &el) +{ + auto type = el.attribute("type"); + return el.tagName() == "iq" && (type == "result" || type == "error"); +} + /// \cond QXmppClientPrivate::QXmppClientPrivate(QXmppClient *qq) : clientPresence(QXmppPresence::Available), @@ -521,9 +527,15 @@ QFuture QXmppClient::sendSensitiveIq(QXmppIq &&iq, const auto future = d->stream->sendIq(QXmppPacket(*xml, true), id); await(future, this, [this, interface](QXmppStream::IqResult result) mutable { if (const auto encryptedDom = std::get_if(&result)) { - // received result (should be encrypted) - if (d->encryptionExtension) { - // decrypt + if (!isIqResponse(*encryptedDom)) { + QXmpp::SendError err { + QStringLiteral("Invalid IQ response received."), + QXmpp::SendError::EncryptionError + }; + interface.reportResult(err); + interface.reportFinished(); + } else if (d->encryptionExtension) { + // try to decrypt the result (should be encrypted) auto future = d->encryptionExtension->decryptIq(*encryptedDom); await(future, this, [interface, encryptedDom = *encryptedDom](IqDecryptResult result) mutable { if (const auto dom = std::get_if(&result)) { -- cgit v1.2.3