From 838deb445b615aa06829164deb926ad68a42ae30 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Wed, 28 Dec 2022 21:58:25 +0100 Subject: Stream: Add IQ response sender check Verifies that the sender of the response is correct, so no evil entity can inject responses. Fixes #510. --- src/client/QXmppClient.cpp | 11 +++++++---- src/client/QXmppOutgoingClient.cpp | 10 ++++++++++ src/client/QXmppOutgoingClient.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/client') diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp index 174c4219..a6d55fa8 100644 --- a/src/client/QXmppClient.cpp +++ b/src/client/QXmppClient.cpp @@ -517,12 +517,12 @@ QFuture QXmppClient::sendIq(QXmppIq &&iq, const std::opti /// QFuture QXmppClient::sendSensitiveIq(QXmppIq &&iq, const std::optional ¶ms) { - const auto sendEncrypted = [this](QFuture &&future, const QString &id) { + const auto sendEncrypted = [this](QFuture &&future, const QString &id, const QString &to) { QFutureInterface interface(QFutureInterfaceBase::Started); - await(future, this, [this, interface, id](IqEncryptResult result) mutable { + await(future, this, [this, interface, id, to](IqEncryptResult result) mutable { if (const auto *xml = std::get_if(&result)) { // encrypted successfully - auto future = d->stream->sendIq(QXmppPacket(*xml, true), id); + auto future = d->stream->QXmppStream::sendIq(QXmppPacket(*xml, true), id, to); await(future, this, [this, interface](QXmppStream::IqResult result) mutable { if (const auto encryptedDom = std::get_if(&result)) { if (!isIqResponse(*encryptedDom)) { @@ -571,10 +571,13 @@ QFuture QXmppClient::sendSensitiveIq(QXmppIq &&iq, const if (iq.id().isEmpty() || d->stream->hasIqId(iq.id())) { iq.setId(QXmppUtils::generateStanzaUuid()); } + if (iq.to().isEmpty()) { + iq.setTo(d->stream->configuration().domain()); + } if (d->encryptionExtension) { const auto id = iq.id(); - return sendEncrypted(d->encryptionExtension->encryptIq(std::move(iq), params), id); + return sendEncrypted(d->encryptionExtension->encryptIq(std::move(iq), params), id, iq.to()); } return d->stream->sendIq(std::move(iq)); } diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index 7d1ad6a3..9a8e51b8 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -316,6 +317,15 @@ bool QXmppOutgoingClient::isStreamResumed() const return d->streamResumed; } +QFuture QXmppOutgoingClient::sendIq(QXmppIq &&iq) +{ + // always set a to address (the QXmppStream needs this for matching) + if (iq.to().isEmpty()) { + iq.setTo(d->config.domain()); + } + return QXmppStream::sendIq(std::move(iq)); +} + void QXmppOutgoingClient::_q_socketDisconnected() { debug("Socket disconnected"); diff --git a/src/client/QXmppOutgoingClient.h b/src/client/QXmppOutgoingClient.h index 57e3477a..6c72d076 100644 --- a/src/client/QXmppOutgoingClient.h +++ b/src/client/QXmppOutgoingClient.h @@ -38,6 +38,7 @@ public: bool isClientStateIndicationEnabled() const; bool isStreamManagementEnabled() const; bool isStreamResumed() const; + QFuture sendIq(QXmppIq &&); /// Returns the used socket QSslSocket *socket() const { return QXmppStream::socket(); }; -- cgit v1.2.3