From f3826419eb5c3c44b6d080502284a94f9e6c9f1c Mon Sep 17 00:00:00 2001 From: Wiebe Cazemier Date: Mon, 28 Aug 2023 13:28:29 +0200 Subject: [PATCH] When disbaled, reject retained messages on wills Also more generally not allow setting of retained messages when disabled. --- mqttpacket.cpp | 19 ++++++++++++++++--- subscriptionstore.cpp | 5 +++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mqttpacket.cpp b/mqttpacket.cpp index 533bd1e6..92e05c63 100644 --- a/mqttpacket.cpp +++ b/mqttpacket.cpp @@ -569,11 +569,24 @@ ConnectData MqttPacket::parseConnectData() result.client_id = readBytesToString(); - result.willpublish.qos = result.will_qos; - result.willpublish.retain = result.will_retain; - if (result.will_flag) { + result.willpublish.qos = result.will_qos; + result.willpublish.retain = result.will_retain; + + if (result.will_retain) + { + if (settings.retainedMessagesMode == RetainedMessagesMode::DisconnectWithError) + throw ProtocolError("Option 'retained_messages_mode' set to 'disconnect_with_error' and received a will with retain.", ReasonCodes::RetainNotSupported); + else if (settings.retainedMessagesMode == RetainedMessagesMode::Downgrade) + { + result.willpublish.retain = false; + result.will_retain = false; + } + else if (settings.retainedMessagesMode == RetainedMessagesMode::Drop) + result.will_flag = false; // This will make us not pick up later, and we still parse the bytes from the packet. + } + result.willpublish.client_id = result.client_id; if (protocolVersion == ProtocolVersion::Mqtt5) diff --git a/subscriptionstore.cpp b/subscriptionstore.cpp index 231617a7..c4573e5f 100644 --- a/subscriptionstore.cpp +++ b/subscriptionstore.cpp @@ -713,6 +713,11 @@ void SubscriptionStore::setRetainedMessage(const Publish &publish, const std::ve { assert(!subtopics.empty()); + const Settings *settings = ThreadGlobals::getSettings(); + + if (settings->retainedMessagesMode != RetainedMessagesMode::Enabled) + return; + RetainedMessageNode *deepestNode = &retainedMessagesRoot; if (!subtopics.empty() && !subtopics[0].empty() > 0 && subtopics[0][0] == '$') deepestNode = &retainedMessagesRootDollar;