Merge branch 'fixes' into develop

This commit is contained in:
Roger A. Light 2026-01-15 00:49:53 +00:00
commit 81a9385877
32 changed files with 311 additions and 144 deletions

View file

@ -34,6 +34,7 @@ jobs:
python3-all \ python3-all \
python3-paho-mqtt \ python3-paho-mqtt \
python3-psutil \ python3-psutil \
uthash-dev \
xsltproc xsltproc
- uses: vapier/coverity-scan-action@v1 - uses: vapier/coverity-scan-action@v1

View file

@ -39,6 +39,8 @@ include(CheckIncludeFiles)
include(CheckLibraryExists) include(CheckLibraryExists)
include(CheckSourceCompiles) include(CheckSourceCompiles)
include(GNUInstallDirs) include(GNUInstallDirs)
include(CMakePushCheckState)
include(CheckSourceCompiles)
option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON) option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON)
option(WITH_TLS "Include SSL/TLS support?" ON) option(WITH_TLS "Include SSL/TLS support?" ON)

View file

@ -271,6 +271,23 @@
- Support for openssl < 3.0 removed. - Support for openssl < 3.0 removed.
2.0.23 - 2026-01-14
===================
Broker:
- Fix handling of disconnected sessions for `per_listener_settings true`
- Check return values of openssl *_get_ex_data() and *_set_ex_data() to
prevent possible crash. This could occur only in extremely unlikely
situations. See https://github.com/eclipse-mosquitto/mosquitto/issues/3389
Closes #3389.
- Check return value of openssl ASN1_string_[get0_]data() functions for NULL.
This prevents a crash in case of incorrect certificate handling in openssl.
Closes #3390.
- Fix potential crash on startup if a malicious/corrupt persistence file from
mosquitto 1.5 or earlier is loaded. Closes #3439.
- Limit auto_id_prefix to 50 characters. Closes #3440.
2.0.22 - 2025-07-11 2.0.22 - 2025-07-11
=================== ===================

View file

@ -85,9 +85,9 @@ Section "Files" SecInstall
File "..\build\vcpkg_installed\x86-windows\bin\sqlite3.dll" File "..\build\vcpkg_installed\x86-windows\bin\sqlite3.dll"
SetOutPath "$INSTDIR\devel" SetOutPath "$INSTDIR\devel"
File /oname=mosquitto_broker.lib "..\build\src\Release\mosquitto.lib"
File "..\build\lib\Release\mosquitto.lib" File "..\build\lib\Release\mosquitto.lib"
File "..\build\lib\cpp\Release\mosquittopp.lib" File "..\build\lib\cpp\Release\mosquittopp.lib"
File "..\build\src\Release\mosquitto_broker.lib"
File "..\include\mosquitto.h" File "..\include\mosquitto.h"
File "..\include\mosquitto_broker.h" File "..\include\mosquitto_broker.h"
File "..\include\mosquitto_plugin.h" File "..\include\mosquitto_plugin.h"

View file

@ -86,9 +86,9 @@ Section "Files" SecInstall
File "..\build64\vcpkg_installed\x64-windows-release\bin\sqlite3.dll" File "..\build64\vcpkg_installed\x64-windows-release\bin\sqlite3.dll"
SetOutPath "$INSTDIR\devel" SetOutPath "$INSTDIR\devel"
File /oname=mosquitto_broker.lib "..\build64\src\Release\mosquitto.lib"
File "..\build64\lib\Release\mosquitto.lib" File "..\build64\lib\Release\mosquitto.lib"
File "..\build64\lib\cpp\Release\mosquittopp.lib" File "..\build64\lib\cpp\Release\mosquittopp.lib"
File "..\build64\src\Release\mosquitto_broker.lib"
File "..\include\mosquitto.h" File "..\include\mosquitto.h"
File "..\include\mosquitto_broker.h" File "..\include\mosquitto_broker.h"
File "..\include\mosquitto_plugin.h" File "..\include\mosquitto_plugin.h"

View file

@ -42,6 +42,9 @@ int handle__pingreq(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGREQ before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.command != CMD_PINGREQ || mosq->in_packet.remaining_length != 0){ if(mosq->in_packet.command != CMD_PINGREQ || mosq->in_packet.remaining_length != 0){
@ -62,6 +65,9 @@ int handle__pingresp(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGRESP before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.command != CMD_PINGRESP || mosq->in_packet.remaining_length != 0){ if(mosq->in_packet.command != CMD_PINGRESP || mosq->in_packet.remaining_length != 0){
@ -71,6 +77,7 @@ int handle__pingresp(struct mosquitto *mosq)
mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */ mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */
#ifdef WITH_BROKER #ifdef WITH_BROKER
if(mosq->bridge == NULL){ if(mosq->bridge == NULL){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGRESP when not a bridge.", mosq->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", SAFE_PRINT(mosq->id)); log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", SAFE_PRINT(mosq->id));

View file

@ -49,6 +49,9 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: %s before session is active.", mosq->id, type);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->protocol != mosq_p_mqtt31){ if(mosq->protocol != mosq_p_mqtt31){
@ -77,6 +80,9 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
qos = 2; qos = 2;
} }
if(mid == 0){ if(mid == 0){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: %s with mid = 0.", mosq->id, type);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -105,6 +111,10 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
){ ){
mosquitto_property_free_all(&properties); mosquitto_property_free_all(&properties);
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: %s with reason code = %d.",
mosq->id, type, reason_code);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
}else{ }else{
@ -113,6 +123,10 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
){ ){
mosquitto_property_free_all(&properties); mosquitto_property_free_all(&properties);
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: %s with reason code = %d.",
mosq->id, type, reason_code);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }

View file

@ -48,6 +48,9 @@ int handle__pubrec(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREC before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.command != CMD_PUBREC){ if(mosq->in_packet.command != CMD_PUBREC){
@ -59,6 +62,10 @@ int handle__pubrec(struct mosquitto *mosq)
return rc; return rc;
} }
if(mid == 0){ if(mid == 0){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREC with mid = 0.",
mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -78,12 +85,21 @@ int handle__pubrec(struct mosquitto *mosq)
&& reason_code != MQTT_RC_QUOTA_EXCEEDED && reason_code != MQTT_RC_QUOTA_EXCEEDED
&& reason_code != MQTT_RC_PAYLOAD_FORMAT_INVALID){ && reason_code != MQTT_RC_PAYLOAD_FORMAT_INVALID){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREC with reason code = %d.",
mosq->id, reason_code);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.remaining_length > 3){ if(mosq->in_packet.remaining_length > 3){
rc = property__read_all(CMD_PUBREC, &mosq->in_packet, &properties); rc = property__read_all(CMD_PUBREC, &mosq->in_packet, &properties);
if(rc){ if(rc){
if(rc == MOSQ_ERR_PROTOCOL){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREC with invalid properties.", mosq->id);
#endif
}
return rc; return rc;
} }

View file

@ -51,6 +51,9 @@ int handle__pubrel(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREL before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->protocol != mosq_p_mqtt31 && mosq->in_packet.command != (CMD_PUBREL|2)){ if(mosq->protocol != mosq_p_mqtt31 && mosq->in_packet.command != (CMD_PUBREL|2)){
@ -59,6 +62,10 @@ int handle__pubrel(struct mosquitto *mosq)
if(mosq->protocol != mosq_p_mqtt31){ if(mosq->protocol != mosq_p_mqtt31){
if((mosq->in_packet.command&0x0F) != 0x02){ if((mosq->in_packet.command&0x0F) != 0x02){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREL with non-zero reserved flags (%02X).",
mosq->id, mosq->in_packet.command);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }
@ -67,6 +74,10 @@ int handle__pubrel(struct mosquitto *mosq)
return rc; return rc;
} }
if(mid == 0){ if(mid == 0){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREL with mid = 0.",
mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -77,17 +88,26 @@ int handle__pubrel(struct mosquitto *mosq)
} }
if(reason_code != MQTT_RC_SUCCESS && reason_code != MQTT_RC_PACKET_ID_NOT_FOUND){ if(reason_code != MQTT_RC_SUCCESS && reason_code != MQTT_RC_PACKET_ID_NOT_FOUND){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREL with reason code = %d.",
mosq->id, reason_code);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.remaining_length > 3){ if(mosq->in_packet.remaining_length > 3){
rc = property__read_all(CMD_PUBREL, &mosq->in_packet, &properties); rc = property__read_all(CMD_PUBREL, &mosq->in_packet, &properties);
if(rc){
return rc;
}
/* Immediately free, we don't do anything with Reason String or /* Immediately free, we don't do anything with Reason String or
* User Property at the moment */ * User Property at the moment */
mosquitto_property_free_all(&properties); mosquitto_property_free_all(&properties);
if(rc){
if(rc == MOSQ_ERR_PROTOCOL){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBREL with invalid properties.", mosq->id);
#endif
}
return rc;
}
} }
} }

View file

@ -48,6 +48,9 @@ int handle__suback(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: SUBACK before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.command != CMD_SUBACK){ if(mosq->in_packet.command != CMD_SUBACK){
@ -57,6 +60,7 @@ int handle__suback(struct mosquitto *mosq)
#ifdef WITH_BROKER #ifdef WITH_BROKER
if(mosq->bridge == NULL){ if(mosq->bridge == NULL){
/* Client is not a bridge, so shouldn't be sending SUBACK */ /* Client is not a bridge, so shouldn't be sending SUBACK */
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: SUBACK when not a bridge.", mosq->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
log__printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", SAFE_PRINT(mosq->id)); log__printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", SAFE_PRINT(mosq->id));

View file

@ -50,6 +50,9 @@ int handle__unsuback(struct mosquitto *mosq)
assert(mosq); assert(mosq);
if(mosquitto__get_state(mosq) != mosq_cs_active){ if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: UNSUBACK before session is active.", mosq->id);
#endif
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(mosq->in_packet.command != CMD_UNSUBACK){ if(mosq->in_packet.command != CMD_UNSUBACK){
@ -59,6 +62,7 @@ int handle__unsuback(struct mosquitto *mosq)
#ifdef WITH_BROKER #ifdef WITH_BROKER
if(mosq->bridge == NULL){ if(mosq->bridge == NULL){
/* Client is not a bridge, so shouldn't be sending SUBACK */ /* Client is not a bridge, so shouldn't be sending SUBACK */
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: UNSUBACK when not a bridge.", mosq->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
log__printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", SAFE_PRINT(mosq->id)); log__printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", SAFE_PRINT(mosq->id));

View file

@ -691,6 +691,8 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
net__init_tls(); net__init_tls();
net__init_tls();
#ifndef WITH_BROKER #ifndef WITH_BROKER
if(mosq->user_ssl_ctx){ if(mosq->user_ssl_ctx){
mosq->ssl_ctx = mosq->user_ssl_ctx; mosq->ssl_ctx = mosq->user_ssl_ctx;

View file

@ -486,11 +486,15 @@ static int packet__read_single(struct mosquitto *mosq, enum mosquitto_client_sta
#ifdef WITH_BROKER #ifdef WITH_BROKER
/* Clients must send CONNECT as their first command. */ /* Clients must send CONNECT as their first command. */
if(!(mosq->bridge) && state == mosq_cs_new && (mosq->in_packet.command&0xF0) != CMD_CONNECT){ if(!(mosq->bridge) && state == mosq_cs_new && (mosq->in_packet.command&0xF0) != CMD_CONNECT){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: First packet not CONNECT (%02X).",
mosq->address, mosq->remote_port, mosq->in_packet.command);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
}else if((mosq->in_packet.command&0xF0) == CMD_RESERVED){ }else if((mosq->in_packet.command&0xF0) == CMD_RESERVED){
if(mosq->protocol == mosq_p_mqtt5){ if(mosq->protocol == mosq_p_mqtt5){
send__disconnect(mosq, MQTT_RC_PROTOCOL_ERROR, NULL); send__disconnect(mosq, MQTT_RC_PROTOCOL_ERROR, NULL);
} }
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: RESERVED packet.",
mosq->address, mosq->remote_port);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
#else #else

View file

@ -301,6 +301,7 @@ endif()
set_target_properties(mosquitto PROPERTIES set_target_properties(mosquitto PROPERTIES
ENABLE_EXPORTS 1 ENABLE_EXPORTS 1
ARCHIVE_OUTPUT_NAME "mosquitto_broker"
) )
if(UNIX) if(UNIX)

View file

@ -2474,6 +2474,10 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload,
#ifdef FINAL_WITH_TLS_PSK #ifdef FINAL_WITH_TLS_PSK
REQUIRE_LISTENER_IF_PER_LISTENER(token); REQUIRE_LISTENER_IF_PER_LISTENER(token);
conf__set_cur_security_options(config, &cur_listener, &cur_security_options, token); conf__set_cur_security_options(config, &cur_listener, &cur_security_options, token);
if(cur_listener && cur_listener->certfile){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single listener.");
return MOSQ_ERR_INVAL;
}
mosquitto_FREE(cur_security_options->psk_file); mosquitto_FREE(cur_security_options->psk_file);
if(conf__parse_string(&token, "psk_file", &cur_security_options->psk_file, &saveptr)){ if(conf__parse_string(&token, "psk_file", &cur_security_options->psk_file, &saveptr)){
return MOSQ_ERR_INVAL; return MOSQ_ERR_INVAL;

View file

@ -428,8 +428,12 @@ int db__message_delete_outgoing(struct mosquitto *context, uint16_t mid, enum mo
DL_FOREACH_SAFE(context->msgs_out.inflight, client_msg, tmp){ DL_FOREACH_SAFE(context->msgs_out.inflight, client_msg, tmp){
if(client_msg->data.mid == mid){ if(client_msg->data.mid == mid){
if(client_msg->data.qos != qos){ if(client_msg->data.qos != qos){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Mismatched QoS (%d:%d) when deleting outgoing message.",
context->id, client_msg->data.qos, qos);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
}else if(qos == 2 && client_msg->data.state != expect_state && expect_state != mosq_ms_any){ }else if(qos == 2 && client_msg->data.state != expect_state && expect_state != mosq_ms_any){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Mismatched state (%d:%d) when deleting outgoing message.",
context->id, client_msg->data.state, expect_state);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
db__message_remove_inflight(context, &context->msgs_out, client_msg); db__message_remove_inflight(context, &context->msgs_out, client_msg);
@ -749,6 +753,8 @@ static inline int db__message_update_outgoing_state(struct mosquitto *context, s
DL_FOREACH(head, client_msg){ DL_FOREACH(head, client_msg){
if(client_msg->data.mid == mid){ if(client_msg->data.mid == mid){
if(client_msg->data.qos != qos){ if(client_msg->data.qos != qos){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Mismatched QoS (%d:%d) when updating outgoing message.",
context->id, client_msg->data.qos, qos);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
client_msg->data.state = (enum mosquitto_msg_state)state; client_msg->data.state = (enum mosquitto_msg_state)state;
@ -1199,6 +1205,8 @@ int db__message_remove_incoming(struct mosquitto *context, uint16_t mid)
DL_FOREACH_SAFE(context->msgs_in.inflight, client_msg, tmp){ DL_FOREACH_SAFE(context->msgs_in.inflight, client_msg, tmp){
if(client_msg->data.mid == mid){ if(client_msg->data.mid == mid){
if(client_msg->base_msg->data.qos != 2){ if(client_msg->base_msg->data.qos != 2){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Incorrect QoS (%d) when deleting incoming message.",
context->id, client_msg->base_msg->data.qos);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
db__message_remove_inflight(context, &context->msgs_in, client_msg); db__message_remove_inflight(context, &context->msgs_in, client_msg);
@ -1226,6 +1234,8 @@ int db__message_release_incoming(struct mosquitto *context, uint16_t mid)
DL_FOREACH_SAFE(context->msgs_in.inflight, client_msg, tmp){ DL_FOREACH_SAFE(context->msgs_in.inflight, client_msg, tmp){
if(client_msg->data.mid == mid){ if(client_msg->data.mid == mid){
if(client_msg->base_msg->data.qos != 2){ if(client_msg->base_msg->data.qos != 2){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Incorrect QoS (%d) when releasing incoming message.",
context->id, client_msg->base_msg->data.qos);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
topic = client_msg->base_msg->data.topic; topic = client_msg->base_msg->data.topic;

View file

@ -45,7 +45,12 @@ int handle__auth(struct mosquitto *context)
return MOSQ_ERR_INVAL; return MOSQ_ERR_INVAL;
} }
if(context->protocol != mosq_p_mqtt5 || context->auth_method == NULL){ if(context->protocol != mosq_p_mqtt5){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH packet when session not MQTT v5.0.", context->id);
return MOSQ_ERR_PROTOCOL;
}
if(context->auth_method == NULL){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH packet without existing auth-method.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(context->in_packet.command != CMD_AUTH){ if(context->in_packet.command != CMD_AUTH){
@ -60,6 +65,8 @@ int handle__auth(struct mosquitto *context)
&& reason_code != MQTT_RC_REAUTHENTICATE){ && reason_code != MQTT_RC_REAUTHENTICATE){
send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL); send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH packet with reason-code = %d.",
context->id, reason_code);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -68,6 +75,9 @@ int handle__auth(struct mosquitto *context)
&& context->state != mosq_cs_authenticating && context->state != mosq_cs_reauthenticating)){ && context->state != mosq_cs_authenticating && context->state != mosq_cs_reauthenticating)){
send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL); send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH reauthentication packet before session is active,",
context->id);
log__printf(NULL, MOSQ_LOG_INFO, " or attempted to continue authentication when no authentication in progress.");
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -81,6 +91,8 @@ int handle__auth(struct mosquitto *context)
if(mosquitto_property_read_string(properties, MQTT_PROP_AUTHENTICATION_METHOD, &auth_method, false) == NULL){ if(mosquitto_property_read_string(properties, MQTT_PROP_AUTHENTICATION_METHOD, &auth_method, false) == NULL){
mosquitto_property_free_all(&properties); mosquitto_property_free_all(&properties);
send__disconnect(context, MQTT_RC_UNSPECIFIED, NULL); send__disconnect(context, MQTT_RC_UNSPECIFIED, NULL);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH packet without auth-method property.",
context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -89,6 +101,8 @@ int handle__auth(struct mosquitto *context)
mosquitto_FREE(auth_method); mosquitto_FREE(auth_method);
mosquitto_property_free_all(&properties); mosquitto_property_free_all(&properties);
send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL); send__disconnect(context, MQTT_RC_PROTOCOL_ERROR, NULL);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: AUTH packet with non-matching auth-method property (%s:%s).",
context->id, context->auth_method, auth_method);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
mosquitto_FREE(auth_method); mosquitto_FREE(auth_method);

View file

@ -112,6 +112,7 @@ int handle__connack(struct mosquitto *context)
return MOSQ_ERR_INVAL; return MOSQ_ERR_INVAL;
} }
if(context->bridge == NULL){ if(context->bridge == NULL){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNACK when not a bridge.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(context->in_packet.command != CMD_CONNACK){ if(context->in_packet.command != CMD_CONNACK){

View file

@ -363,6 +363,8 @@ static int will__read(struct mosquitto *context, const char *clientid, struct mo
goto error_cleanup; goto error_cleanup;
} }
if(!tlen){ if(!tlen){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Will with empty topic.",
context->id);
rc = MOSQ_ERR_PROTOCOL; rc = MOSQ_ERR_PROTOCOL;
goto error_cleanup; goto error_cleanup;
} }
@ -479,12 +481,18 @@ static int read_protocol_name(struct mosquitto *context, char protocol_name[7])
uint16_t slen = 0; uint16_t slen = 0;
if(packet__read_uint16(&context->in_packet, &slen)){ if(packet__read_uint16(&context->in_packet, &slen)){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with missing protocol string length.",
context->address, context->remote_port);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(slen != 4 /* MQTT */ && slen != 6 /* MQIsdp */){ if(slen != 4 /* MQTT */ && slen != 6 /* MQIsdp */){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with incorrect protocol string length (%d).",
context->address, context->remote_port, slen);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(packet__read_bytes(&context->in_packet, protocol_name, slen)){ if(packet__read_bytes(&context->in_packet, protocol_name, slen)){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with missing protocol string.",
context->address, context->remote_port);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
protocol_name[slen] = '\0'; protocol_name[slen] = '\0';
@ -498,6 +506,8 @@ static int read_and_verify_protocol_version(struct mosquitto *context, const cha
{ {
uint8_t tmp_protocol_version = 0; uint8_t tmp_protocol_version = 0;
if(packet__read_byte(&context->in_packet, &tmp_protocol_version)){ if(packet__read_byte(&context->in_packet, &tmp_protocol_version)){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with missing protocol version.",
context->address, context->remote_port);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -515,8 +525,8 @@ static int read_and_verify_protocol_version(struct mosquitto *context, const cha
if(!strcmp(protocol_name, PROTOCOL_NAME_v31)){ if(!strcmp(protocol_name, PROTOCOL_NAME_v31)){
if((tmp_protocol_version&0x7F) != PROTOCOL_VERSION_v31){ if((tmp_protocol_version&0x7F) != PROTOCOL_VERSION_v31){
if(db.config->connection_messages == true){ if(db.config->connection_messages == true){
log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol version (%d).",
tmp_protocol_version, context->address); context->address, context->remote_port, tmp_protocol_version);
} }
send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
@ -536,20 +546,22 @@ static int read_and_verify_protocol_version(struct mosquitto *context, const cha
context->protocol = mosq_p_mqtt5; context->protocol = mosq_p_mqtt5;
}else{ }else{
if(db.config->connection_messages == true){ if(db.config->connection_messages == true){
log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol version (%d).",
tmp_protocol_version, context->address); context->address, context->remote_port, tmp_protocol_version);
} }
send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if((context->in_packet.command&0x0F) != 0x00){ if((context->in_packet.command&0x0F) != 0x00){
/* Reserved flags not set to 0, must disconnect. */ /* Reserved flags not set to 0, must disconnect. */
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with non-zero reserved flags (%02X).",
context->address, context->remote_port, context->in_packet.command);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
}else{ }else{
if(db.config->connection_messages == true){ if(db.config->connection_messages == true){
log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol \"%s\" in CONNECT from %s.", log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol \"%s\".",
protocol_name, context->address); context->address, context->remote_port, protocol_name);
} }
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -565,10 +577,14 @@ static int read_and_verify_protocol_version(struct mosquitto *context, const cha
static int read_and_verify_connect_flags(struct mosquitto *context, uint8_t *connect_flags) static int read_and_verify_connect_flags(struct mosquitto *context, uint8_t *connect_flags)
{ {
if(packet__read_byte(&context->in_packet, connect_flags)){ if(packet__read_byte(&context->in_packet, connect_flags)){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with missing connect flags.",
context->address, context->remote_port);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){
if((*connect_flags & 0x01) != 0x00){ if((*connect_flags & 0x01) != 0x00){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with non-zero connect reserved flag (%02X).",
context->address, context->remote_port, *connect_flags);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }
@ -596,6 +612,8 @@ static int read_and_reset_keepalive(struct mosquitto *context)
keepalive__remove(context); keepalive__remove(context);
if(packet__read_uint16(&context->in_packet, &(context->keepalive))){ if(packet__read_uint16(&context->in_packet, &(context->keepalive))){
log__printf(NULL, MOSQ_LOG_INFO, "%s sent CONNECT with missing keepalive.",
context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
keepalive__add(context); keepalive__add(context);
@ -658,6 +676,8 @@ static int handle_zero_length_clientid(struct mosquitto *context, char **clienti
uint8_t clean_start) uint8_t clean_start)
{ {
if(context->protocol == mosq_p_mqtt31){ if(context->protocol == mosq_p_mqtt31){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: v3.1 CONNECT with zero length clientid.",
context->address, context->remote_port);
send__connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); send__connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -672,6 +692,8 @@ static int handle_zero_length_clientid(struct mosquitto *context, char **clienti
} }
if((context->protocol == mosq_p_mqtt311 && clean_start == 0) || *allow_zero_length_clientid == false){ if((context->protocol == mosq_p_mqtt311 && clean_start == 0) || *allow_zero_length_clientid == false){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with zero length clientid when forbidden.",
context->address, context->remote_port);
uint8_t err_code = context->protocol == mosq_p_mqtt311 ? (uint8_t)CONNACK_REFUSED_IDENTIFIER_REJECTED : (uint8_t)MQTT_RC_UNSPECIFIED; uint8_t err_code = context->protocol == mosq_p_mqtt311 ? (uint8_t)CONNACK_REFUSED_IDENTIFIER_REJECTED : (uint8_t)MQTT_RC_UNSPECIFIED;
return send__connack_error_and_return(context, err_code, MOSQ_ERR_PROTOCOL); return send__connack_error_and_return(context, err_code, MOSQ_ERR_PROTOCOL);
} }
@ -731,7 +753,7 @@ static int read_and_verify_clientid_from_packet(struct mosquitto *context, char
} }
static int set_username_from_packet(struct mosquitto *context, char **username) static int set_username_from_packet(struct mosquitto *context, char **username, const char *clientid)
{ {
int rc; int rc;
@ -744,6 +766,8 @@ static int set_username_from_packet(struct mosquitto *context, char **username)
/* Username flag given, but no username. Ignore. */ /* Username flag given, but no username. Ignore. */
/* NOTE: Removed setting of username_flag to zero as it is unused afterwards */ /* NOTE: Removed setting of username_flag to zero as it is unused afterwards */
}else{ }else{
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT with username flag but no username.",
clientid);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }
@ -752,7 +776,7 @@ static int set_username_from_packet(struct mosquitto *context, char **username)
} }
static int set_password_from_packet(struct mosquitto *context, char **password) static int set_password_from_packet(struct mosquitto *context, char **password, const char *clientid)
{ {
int rc; int rc;
@ -765,6 +789,8 @@ static int set_password_from_packet(struct mosquitto *context, char **password)
if(context->protocol == mosq_p_mqtt31){ if(context->protocol == mosq_p_mqtt31){
/* Password flag given, but no password. Ignore. */ /* Password flag given, but no password. Ignore. */
}else{ }else{
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT with password flag but no password.",
clientid);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }
@ -781,7 +807,7 @@ static int read_and_verify_client_credentials_from_packet(struct mosquitto *cont
int rc; int rc;
if(username_flag){ if(username_flag){
rc = set_username_from_packet(context, username); rc = set_username_from_packet(context, username, clientid);
if(rc != MOSQ_ERR_SUCCESS){ if(rc != MOSQ_ERR_SUCCESS){
return rc; return rc;
} }
@ -795,7 +821,7 @@ static int read_and_verify_client_credentials_from_packet(struct mosquitto *cont
} }
} }
if(password_flag){ if(password_flag){
rc = set_password_from_packet(context, password); rc = set_password_from_packet(context, password, clientid);
if(rc != MOSQ_ERR_SUCCESS){ if(rc != MOSQ_ERR_SUCCESS){
return rc; return rc;
} }
@ -809,6 +835,8 @@ static int check_additional_trailing_data(struct mosquitto *context, uint8_t pro
{ {
if(context->in_packet.pos != context->in_packet.remaining_length){ if(context->in_packet.pos != context->in_packet.remaining_length){
/* Surplus data at end of packet, this must be an error. */ /* Surplus data at end of packet, this must be an error. */
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT packet with overlong remaining length (%d:%d).",
context->id, context->in_packet.pos, context->in_packet.remaining_length);
if(protocol_version == PROTOCOL_VERSION_v5){ if(protocol_version == PROTOCOL_VERSION_v5){
send__connack(context, 0, MQTT_RC_MALFORMED_PACKET, NULL); send__connack(context, 0, MQTT_RC_MALFORMED_PACKET, NULL);
} }
@ -1042,7 +1070,8 @@ int handle__connect(struct mosquitto *context)
/* Don't accept multiple CONNECT commands. */ /* Don't accept multiple CONNECT commands. */
if(context->state != mosq_cs_new){ if(context->state != mosq_cs_new){
log__printf(NULL, MOSQ_LOG_NOTICE, "Bad client %s sending multiple CONNECT messages.", context->id); log__printf(NULL, MOSQ_LOG_NOTICE, "Bad client %s:%d sending multiple CONNECT messages.",
context->address, context->remote_port);
rc = MOSQ_ERR_PROTOCOL; rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error; goto handle_connect_error;
} }
@ -1087,6 +1116,12 @@ int handle__connect(struct mosquitto *context)
will = connect_flags & 0x04; will = connect_flags & 0x04;
will_qos = (connect_flags & 0x18) >> 3; will_qos = (connect_flags & 0x18) >> 3;
if(will_qos == 3){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid Will QoS (%d).",
context->address, context->remote_port, will_qos);
rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error;
}
will_retain = ((connect_flags & 0x20) == 0x20); will_retain = ((connect_flags & 0x20) == 0x20);
rc = verify_will_options(context, will, will_qos, will_retain, protocol_version); rc = verify_will_options(context, will, will_qos, will_retain, protocol_version);
if(rc != MOSQ_ERR_SUCCESS){ if(rc != MOSQ_ERR_SUCCESS){
@ -1099,6 +1134,8 @@ int handle__connect(struct mosquitto *context)
if(auth_data && !context->auth_method){ if(auth_data && !context->auth_method){
send__connack(context, 0, MQTT_RC_PROTOCOL_ERROR, NULL); send__connack(context, 0, MQTT_RC_PROTOCOL_ERROR, NULL);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d CONNECT with missing clientid string.",
context->address, context->remote_port);
rc = MOSQ_ERR_PROTOCOL; rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error; goto handle_connect_error;
} }
@ -1123,6 +1160,8 @@ int handle__connect(struct mosquitto *context)
}else{ }else{
if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){
if(will_qos != 0 || will_retain != 0){ if(will_qos != 0 || will_retain != 0){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT without Will with non-zero QoS (%d) or retain (%d).",
clientid, will_qos, will_retain);
rc = MOSQ_ERR_PROTOCOL; rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error; goto handle_connect_error;
} }

View file

@ -63,11 +63,15 @@ int handle__disconnect(struct mosquitto *context)
mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */ mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */
if(context->in_packet.pos != context->in_packet.remaining_length){ if(context->in_packet.pos != context->in_packet.remaining_length){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: DISCONNECT packet with overlong remaining length (%d:%d).",
context->id, context->in_packet.pos, context->in_packet.remaining_length);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
log__printf(NULL, MOSQ_LOG_DEBUG, "Received DISCONNECT from %s", context->id); log__printf(NULL, MOSQ_LOG_DEBUG, "Received DISCONNECT from %s", context->id);
if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){
if((context->in_packet.command&0x0F) != 0x00){ if((context->in_packet.command&0x0F) != 0x00){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: DISCONNECT packet with incorrect flags %02X.",
context->id, context->in_packet.command);
do_disconnect(context, MOSQ_ERR_PROTOCOL); do_disconnect(context, MOSQ_ERR_PROTOCOL);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }

View file

@ -181,6 +181,7 @@ int handle__accepted_publish(struct mosquitto *context, struct mosquitto__base_m
rc = rc2; rc = rc2;
} }
}else{ }else{
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBLISH with dup = %d.", context->id, dup);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
}else{ }else{
@ -210,6 +211,7 @@ int handle__publish(struct mosquitto *context)
uint16_t mid = 0; uint16_t mid = 0;
if(context->state != mosq_cs_active){ if(context->state != mosq_cs_active){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBLISH before session is active.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
@ -264,6 +266,7 @@ int handle__publish(struct mosquitto *context)
} }
if(mid == 0){ if(mid == 0){
db__msg_store_free(base_msg); db__msg_store_free(base_msg);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBLISH packet with mid = 0.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
/* It is important to have a separate copy of mid, because msg may be /* It is important to have a separate copy of mid, because msg may be
@ -302,6 +305,8 @@ int handle__publish(struct mosquitto *context)
rc = alias__find_by_alias(context, ALIAS_DIR_R2L, (uint16_t)topic_alias, &base_msg->data.topic); rc = alias__find_by_alias(context, ALIAS_DIR_R2L, (uint16_t)topic_alias, &base_msg->data.topic);
if(rc){ if(rc){
db__msg_store_free(base_msg); db__msg_store_free(base_msg);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBLISH invalid topic alias (%d).",
context->id, topic_alias);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
} }

View file

@ -49,6 +49,7 @@ int handle__subscribe(struct mosquitto *context)
} }
if(context->state != mosq_cs_active){ if(context->state != mosq_cs_active){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: SUBSCRIBE before session is active.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(context->in_packet.command != (CMD_SUBSCRIBE|2)){ if(context->in_packet.command != (CMD_SUBSCRIBE|2)){
@ -76,6 +77,7 @@ int handle__subscribe(struct mosquitto *context)
* MOSQ_ERR_MALFORMED_PACKET, but this is would change the library * MOSQ_ERR_MALFORMED_PACKET, but this is would change the library
* return codes so needs doc changes as well. */ * return codes so needs doc changes as well. */
if(rc == MOSQ_ERR_PROTOCOL){ if(rc == MOSQ_ERR_PROTOCOL){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: SUBSCRIBE packet with invalid properties.", context->id);
return MOSQ_ERR_MALFORMED_PACKET; return MOSQ_ERR_MALFORMED_PACKET;
}else{ }else{
return rc; return rc;
@ -131,6 +133,7 @@ int handle__subscribe(struct mosquitto *context)
if(sub.options & MQTT_SUB_OPT_NO_LOCAL && !strncmp(sub.topic_filter, "$share/", strlen("$share/"))){ if(sub.options & MQTT_SUB_OPT_NO_LOCAL && !strncmp(sub.topic_filter, "$share/", strlen("$share/"))){
mosquitto_FREE(sub.topic_filter); mosquitto_FREE(sub.topic_filter);
mosquitto_FREE(payload); mosquitto_FREE(payload);
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: $share subscription with no-local set.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }

View file

@ -45,6 +45,7 @@ int handle__unsubscribe(struct mosquitto *context)
} }
if(context->state != mosq_cs_active){ if(context->state != mosq_cs_active){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: UNSUBSCRIBE before session is active.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
if(context->in_packet.command != (CMD_UNSUBSCRIBE|2)){ if(context->in_packet.command != (CMD_UNSUBSCRIBE|2)){
@ -71,6 +72,7 @@ int handle__unsubscribe(struct mosquitto *context)
* MOSQ_ERR_MALFORMED_PACKET, but this is would change the library * MOSQ_ERR_MALFORMED_PACKET, but this is would change the library
* return codes so needs doc changes as well. */ * return codes so needs doc changes as well. */
if(rc == MOSQ_ERR_PROTOCOL){ if(rc == MOSQ_ERR_PROTOCOL){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: UNSUBSCRIBE packet with invalid properties.", context->id);
return MOSQ_ERR_MALFORMED_PACKET; return MOSQ_ERR_MALFORMED_PACKET;
}else{ }else{
return rc; return rc;

View file

@ -955,7 +955,9 @@ void service_install(char *name);
void service_uninstall(char *name); void service_uninstall(char *name);
void service_run(char *name); void service_run(char *name);
DWORD WINAPI SigThreadProc(void *data); #ifdef WIN32
DWORD WINAPI SigThreadProc(void* data);
#endif
#endif #endif
/* ============================================================ /* ============================================================

View file

@ -407,6 +407,13 @@ int net__tls_server_ctx(struct mosquitto__listener *listener)
char buf[256]; char buf[256];
int rc; int rc;
if(tls_ex_index_context == -1){
tls_ex_index_context = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL);
}
if(tls_ex_index_listener == -1){
tls_ex_index_listener = SSL_get_ex_new_index(0, "listener", NULL, NULL, NULL);
}
if(listener->ssl_ctx){ if(listener->ssl_ctx){
SSL_CTX_free(listener->ssl_ctx); SSL_CTX_free(listener->ssl_ctx);
listener->ssl_ctx = NULL; listener->ssl_ctx = NULL;

View file

@ -44,6 +44,7 @@ int property__process_connect(struct mosquitto *context, mosquitto_property **pr
case MQTT_PROP_RECEIVE_MAXIMUM: case MQTT_PROP_RECEIVE_MAXIMUM:
context->msgs_out.inflight_maximum = mosquitto_property_int16_value(p); context->msgs_out.inflight_maximum = mosquitto_property_int16_value(p);
if(context->msgs_out.inflight_maximum == 0){ if(context->msgs_out.inflight_maximum == 0){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT packet with receive-maximum = 0.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
context->msgs_out.inflight_quota = context->msgs_out.inflight_maximum; context->msgs_out.inflight_quota = context->msgs_out.inflight_maximum;
@ -52,6 +53,7 @@ int property__process_connect(struct mosquitto *context, mosquitto_property **pr
case MQTT_PROP_MAXIMUM_PACKET_SIZE: case MQTT_PROP_MAXIMUM_PACKET_SIZE:
context->maximum_packet_size = mosquitto_property_int32_value(p); context->maximum_packet_size = mosquitto_property_int32_value(p);
if(context->maximum_packet_size == 0){ if(context->maximum_packet_size == 0){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT packet with maximum-packet-size = 0.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
break; break;
@ -128,6 +130,7 @@ int property__process_will(struct mosquitto *context, struct mosquitto_message_a
default: default:
msg->properties = msg_properties; msg->properties = msg_properties;
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT packet invalid property (%d).", context->id, p->identifier);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
break; break;
} }
@ -215,6 +218,8 @@ int property__process_disconnect(struct mosquitto *context, mosquitto_property *
if(context->session_expiry_interval == MQTT_SESSION_EXPIRY_IMMEDIATE if(context->session_expiry_interval == MQTT_SESSION_EXPIRY_IMMEDIATE
&& session_expiry_interval != MQTT_SESSION_EXPIRY_IMMEDIATE){ && session_expiry_interval != MQTT_SESSION_EXPIRY_IMMEDIATE){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: DISCONNECT packet with mismatched session-expiry-interval (%d:%d).",
context->id, context->session_expiry_interval, p->value.i32);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }
context->session_expiry_interval = session_expiry_interval; context->session_expiry_interval = session_expiry_interval;

View file

@ -233,6 +233,7 @@ int mosquitto_security_apply_default(void)
const char *username = (const char *)ASN1_STRING_get0_data(name_asn1); const char *username = (const char *)ASN1_STRING_get0_data(name_asn1);
if(!username){ if(!username){
X509_free(client_cert); X509_free(client_cert);
client_cert = NULL;
security__disconnect_auth(context); security__disconnect_auth(context);
continue; continue;
} }

View file

@ -37,6 +37,7 @@ int send__auth(struct mosquitto *context, uint8_t reason_code, const void *auth_
return MOSQ_ERR_INVAL; return MOSQ_ERR_INVAL;
} }
if(context->protocol != mosq_p_mqtt5){ if(context->protocol != mosq_p_mqtt5){
log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Sending AUTH packet when session not MQTT v5.0.", context->id);
return MOSQ_ERR_PROTOCOL; return MOSQ_ERR_PROTOCOL;
} }

View file

@ -13,39 +13,39 @@
from mosq_test_helper import * from mosq_test_helper import *
def do_test(start_broker): def do_test(proto_ver):
rc = 1 rc = 1
connect_packet = mosq_test.gen_connect("02-subpub-qos1-msg-expiry-retain", proto_ver=5) keepalive = 60
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) connect_packet = mosq_test.gen_connect("subpub", keepalive=keepalive, proto_ver=proto_ver)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
mid = 1 mid = 1
subscribe1_packet = mosq_test.gen_subscribe(mid, "02/subpub/expiry/retain/expired", 1, proto_ver=5) subscribe1_packet = mosq_test.gen_subscribe(mid, "subpub/expired", 1, proto_ver=proto_ver)
suback1_packet = mosq_test.gen_suback(mid, 1, proto_ver=5) suback1_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
mid = 2 mid = 2
subscribe2_packet = mosq_test.gen_subscribe(mid, "02/subpub/expiry/retain/kept", 1, proto_ver=5) subscribe2_packet = mosq_test.gen_subscribe(mid, "subpub/kept", 1, proto_ver=proto_ver)
suback2_packet = mosq_test.gen_suback(mid, 1, proto_ver=5) suback2_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
helper_connect = mosq_test.gen_connect("02-subpub-qos1-msg-expiry-retain-helper", proto_ver=5) helper_connect = mosq_test.gen_connect("helper", proto_ver=proto_ver)
helper_connack = mosq_test.gen_connack(rc=0, proto_ver=5) helper_connack = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
mid=1 mid=1
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 2) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 2)
publish1_packet = mosq_test.gen_publish("02/subpub/expiry/retain/expired", mid=mid, qos=1, retain=True, payload="message1", proto_ver=5, properties=props) publish1_packet = mosq_test.gen_publish("subpub/expired", mid=mid, qos=1, retain=True, payload="message1", proto_ver=proto_ver, properties=props)
puback1_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) puback1_packet = mosq_test.gen_puback(mid, proto_ver=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS)
mid=2 mid=2
publish2s_packet = mosq_test.gen_publish("02/subpub/expiry/retain/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=5) publish2s_packet = mosq_test.gen_publish("subpub/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=proto_ver)
puback2s_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) puback2s_packet = mosq_test.gen_puback(mid, proto_ver=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS)
mid=1 mid=1
publish2r_packet = mosq_test.gen_publish("02/subpub/expiry/retain/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=5) publish2r_packet = mosq_test.gen_publish("subpub/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=proto_ver)
puback2r_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) puback2r_packet = mosq_test.gen_puback(mid, proto_ver=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS)
port = mosq_test.get_port() port = mosq_test.get_port()
if start_broker: broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
try: try:
helper = mosq_test.do_client_connect(helper_connect, helper_connack, timeout=20, port=port) helper = mosq_test.do_client_connect(helper_connect, helper_connack, timeout=20, port=port)
@ -78,22 +78,16 @@ def do_test(start_broker):
except mosq_test.TestError: except mosq_test.TestError:
pass pass
finally: finally:
if start_broker: broker.terminate()
broker.terminate() if mosq_test.wait_for_subprocess(broker):
if mosq_test.wait_for_subprocess(broker): print("broker not terminated")
print("broker not terminated") if rc == 0: rc=1
if rc == 0: rc=1 (stdo, stde) = broker.communicate()
(stdo, stde) = broker.communicate() if rc:
if rc: print(stde.decode('utf-8'))
print(stde.decode('utf-8')) print("proto_ver=%d" % (proto_ver))
print("proto_ver=%d" % (proto_ver)) exit(rc)
exit(rc)
else:
return rc
def all_tests(start_broker=False): do_test(proto_ver=5)
return do_test(start_broker) exit(0)
if __name__ == '__main__':
all_tests(True)

View file

@ -11,31 +11,31 @@
from mosq_test_helper import * from mosq_test_helper import *
def do_test(start_broker): def do_test(proto_ver):
rc = 1 rc = 1
mid = 53 mid = 53
keepalive = 60
props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60) props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60)
connect_packet = mosq_test.gen_connect("02-subpub-qos1-msg-exp-will", proto_ver=5, clean_session=False, properties=props) connect_packet = mosq_test.gen_connect("subpub-qos1-test", keepalive=keepalive, proto_ver=proto_ver, clean_session=False, properties=props)
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5) connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5, flags=1) connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver, flags=1)
subscribe_packet = mosq_test.gen_subscribe(mid, "02/subpub/qos1/message/expiry/will", 1, proto_ver=5) subscribe_packet = mosq_test.gen_subscribe(mid, "subpub/qos1", 1, proto_ver=proto_ver)
suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=5) suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10)
helper_connect = mosq_test.gen_connect("02-subpub-qos1-msg-exp-will-helper", proto_ver=5, will_topic="02/subpub/qos1/message/expiry/will", will_qos=1, will_payload=b"message", will_properties=props, keepalive=2) helper_connect = mosq_test.gen_connect("helper", proto_ver=proto_ver, will_topic="subpub/qos1", will_qos=1, will_payload=b"message", will_properties=props, keepalive=2)
helper_connack = mosq_test.gen_connack(rc=0, proto_ver=5) helper_connack = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
#mid=2 #mid=2
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10)
publish2s_packet = mosq_test.gen_publish("02/subpub/qos1/message/expiry/will", mid=mid, qos=1, payload="message2", proto_ver=5, properties=props) publish2s_packet = mosq_test.gen_publish("subpub/qos1", mid=mid, qos=1, payload="message2", proto_ver=proto_ver, properties=props)
puback2s_packet = mosq_test.gen_puback(mid) puback2s_packet = mosq_test.gen_puback(mid)
port = mosq_test.get_port() port = mosq_test.get_port()
if start_broker: broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
try: try:
sock = mosq_test.do_client_connect(connect_packet, connack1_packet, timeout=20, port=port) sock = mosq_test.do_client_connect(connect_packet, connack1_packet, timeout=20, port=port)
@ -50,7 +50,7 @@ def do_test(start_broker):
packet = sock.recv(len(publish2s_packet)) packet = sock.recv(len(publish2s_packet))
for i in range(10, 5, -1): for i in range(10, 5, -1):
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, i) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, i)
publish2r_packet = mosq_test.gen_publish("02/subpub/qos1/message/expiry/will", mid=1, qos=1, payload="message", proto_ver=5, properties=props) publish2r_packet = mosq_test.gen_publish("subpub/qos1", mid=1, qos=1, payload="message", proto_ver=proto_ver, properties=props)
if packet == publish2r_packet: if packet == publish2r_packet:
rc = 0 rc = 0
break break
@ -59,22 +59,16 @@ def do_test(start_broker):
except mosq_test.TestError: except mosq_test.TestError:
pass pass
finally: finally:
if start_broker: broker.terminate()
broker.terminate() if mosq_test.wait_for_subprocess(broker):
if mosq_test.wait_for_subprocess(broker): print("broker not terminated")
print("broker not terminated") if rc == 0: rc=1
if rc == 0: rc=1 (stdo, stde) = broker.communicate()
(stdo, stde) = broker.communicate() if rc:
if rc: print(stde.decode('utf-8'))
print(stde.decode('utf-8')) print("proto_ver=%d" % (proto_ver))
print("proto_ver=%d" % (proto_ver)) exit(rc)
exit(rc)
else:
return rc
def all_tests(start_broker=False): do_test(proto_ver=5)
return do_test(start_broker) exit(0)
if __name__ == '__main__':
all_tests(True)

View file

@ -11,35 +11,36 @@
from mosq_test_helper import * from mosq_test_helper import *
def do_test(start_broker): def do_test(proto_ver):
rc = 1 rc = 1
mid = 53 mid = 53
keepalive = 60
props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60) props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60)
connect_packet = mosq_test.gen_connect("subpub-qos1-message-expiry", proto_ver=5, clean_session=False, properties=props) connect_packet = mosq_test.gen_connect("subpub-qos0-test", keepalive=keepalive, proto_ver=proto_ver, clean_session=False, properties=props)
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5) connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5, flags=1) connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver, flags=1)
subscribe_packet = mosq_test.gen_subscribe(mid, "subpub/qos1/message/expiry", 1, proto_ver=5) subscribe_packet = mosq_test.gen_subscribe(mid, "subpub/qos1", 1, proto_ver=proto_ver)
suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=5) suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
helper_connect = mosq_test.gen_connect("subpub-qos1-message-expiry-helper", proto_ver=5)
helper_connack = mosq_test.gen_connack(rc=0, proto_ver=5) helper_connect = mosq_test.gen_connect("helper", proto_ver=proto_ver)
helper_connack = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
mid=1 mid=1
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 1) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 1)
publish1s_packet = mosq_test.gen_publish("subpub/qos1/message/expiry", mid=mid, qos=1, payload="message1", proto_ver=5, properties=props) publish1s_packet = mosq_test.gen_publish("subpub/qos1", mid=mid, qos=1, payload="message1", proto_ver=proto_ver, properties=props)
puback1s_packet = mosq_test.gen_puback(mid) puback1s_packet = mosq_test.gen_puback(mid)
mid=2 mid=2
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, 10)
publish2s_packet = mosq_test.gen_publish("subpub/qos1/message/expiry", mid=mid, qos=1, payload="message2", proto_ver=5, properties=props) publish2s_packet = mosq_test.gen_publish("subpub/qos1", mid=mid, qos=1, payload="message2", proto_ver=proto_ver, properties=props)
puback2s_packet = mosq_test.gen_puback(mid) puback2s_packet = mosq_test.gen_puback(mid)
port = mosq_test.get_port() port = mosq_test.get_port()
if start_broker: broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
try: try:
sock = mosq_test.do_client_connect(connect_packet, connack1_packet, timeout=20, port=port) sock = mosq_test.do_client_connect(connect_packet, connack1_packet, timeout=20, port=port)
@ -56,7 +57,7 @@ def do_test(start_broker):
packet = sock.recv(len(publish2s_packet)) packet = sock.recv(len(publish2s_packet))
for i in range(9, 5, -1): for i in range(9, 5, -1):
props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, i) props = mqtt5_props.gen_uint32_prop(mqtt5_props.MESSAGE_EXPIRY_INTERVAL, i)
publish2r_packet = mosq_test.gen_publish("subpub/qos1/message/expiry", mid=2, qos=1, payload="message2", proto_ver=5, properties=props) publish2r_packet = mosq_test.gen_publish("subpub/qos1", mid=2, qos=1, payload="message2", proto_ver=proto_ver, properties=props)
if packet == publish2r_packet: if packet == publish2r_packet:
rc = 0 rc = 0
break break
@ -65,22 +66,16 @@ def do_test(start_broker):
except mosq_test.TestError: except mosq_test.TestError:
pass pass
finally: finally:
if start_broker: broker.terminate()
broker.terminate() if mosq_test.wait_for_subprocess(broker):
if mosq_test.wait_for_subprocess(broker): print("broker not terminated")
print("broker not terminated") if rc == 0: rc=1
if rc == 0: rc=1 (stdo, stde) = broker.communicate()
(stdo, stde) = broker.communicate() if rc:
if rc: print(stde.decode('utf-8'))
print(stde.decode('utf-8')) print("proto_ver=%d" % (proto_ver))
print("proto_ver=%d" % (proto_ver)) exit(rc)
exit(rc)
else:
return rc
def all_tests(start_broker=False): do_test(proto_ver=5)
return do_test(start_broker) exit(0)
if __name__ == '__main__':
all_tests(True)

View file

@ -5,17 +5,17 @@
from mosq_test_helper import * from mosq_test_helper import *
def helper(port): def helper(port):
connect_packet = mosq_test.gen_connect("02-subpub-qos2-pubrec-error-helper") connect_packet = mosq_test.gen_connect("helper")
connack_packet = mosq_test.gen_connack(rc=0) connack_packet = mosq_test.gen_connack(rc=0)
mid = 1 mid = 1
publish_1_packet = mosq_test.gen_publish("02/subpub/error/qos2/pubrec/rejected", qos=2, mid=mid, payload="rejected-message") publish_1_packet = mosq_test.gen_publish("qos2/pubrec/rejected", qos=2, mid=mid, payload="rejected-message")
pubrec_1_packet = mosq_test.gen_pubrec(mid) pubrec_1_packet = mosq_test.gen_pubrec(mid)
pubrel_1_packet = mosq_test.gen_pubrel(mid) pubrel_1_packet = mosq_test.gen_pubrel(mid)
pubcomp_1_packet = mosq_test.gen_pubcomp(mid) pubcomp_1_packet = mosq_test.gen_pubcomp(mid)
mid = 2 mid = 2
publish_2_packet = mosq_test.gen_publish("02/subpub/error/qos2/pubrec/accepted", qos=2, mid=mid, payload="accepted-message") publish_2_packet = mosq_test.gen_publish("qos2/pubrec/accepted", qos=2, mid=mid, payload="accepted-message")
pubrec_2_packet = mosq_test.gen_pubrec(mid) pubrec_2_packet = mosq_test.gen_pubrec(mid)
pubrel_2_packet = mosq_test.gen_pubrel(mid) pubrel_2_packet = mosq_test.gen_pubrel(mid)
pubcomp_2_packet = mosq_test.gen_pubcomp(mid) pubcomp_2_packet = mosq_test.gen_pubcomp(mid)
@ -30,28 +30,28 @@ def helper(port):
sock.close() sock.close()
def do_test(start_broker): def do_test(proto_ver):
rc = 1 rc = 1
connect_packet = mosq_test.gen_connect("02-subpub-qos2-pubrec-error", proto_ver=5) keepalive = 60
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) connect_packet = mosq_test.gen_connect("pub-qo2-timeout-test", keepalive=keepalive, proto_ver=proto_ver)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
mid = 1 mid = 1
subscribe_packet = mosq_test.gen_subscribe(mid, "02/subpub/error/qos2/pubrec/+", 2, proto_ver=5) subscribe_packet = mosq_test.gen_subscribe(mid, "qos2/pubrec/+", 2, proto_ver=proto_ver)
suback_packet = mosq_test.gen_suback(mid, 2, proto_ver=5) suback_packet = mosq_test.gen_suback(mid, 2, proto_ver=proto_ver)
mid = 1 mid = 1
publish_1_packet = mosq_test.gen_publish("02/subpub/error/qos2/pubrec/rejected", qos=2, mid=mid, payload="rejected-message", proto_ver=5) publish_1_packet = mosq_test.gen_publish("qos2/pubrec/rejected", qos=2, mid=mid, payload="rejected-message", proto_ver=proto_ver)
pubrec_1_packet = mosq_test.gen_pubrec(mid, proto_ver=5, reason_code=0x80) pubrec_1_packet = mosq_test.gen_pubrec(mid, proto_ver=proto_ver, reason_code=0x80)
mid = 2 mid = 2
publish_2_packet = mosq_test.gen_publish("02/subpub/error/qos2/pubrec/accepted", qos=2, mid=mid, payload="accepted-message", proto_ver=5) publish_2_packet = mosq_test.gen_publish("qos2/pubrec/accepted", qos=2, mid=mid, payload="accepted-message", proto_ver=proto_ver)
pubrec_2_packet = mosq_test.gen_pubrec(mid, proto_ver=5) pubrec_2_packet = mosq_test.gen_pubrec(mid, proto_ver=proto_ver)
pubrel_2_packet = mosq_test.gen_pubrel(mid, proto_ver=5) pubrel_2_packet = mosq_test.gen_pubrel(mid, proto_ver=proto_ver)
pubcomp_2_packet = mosq_test.gen_pubcomp(mid, proto_ver=5) pubcomp_2_packet = mosq_test.gen_pubcomp(mid, proto_ver=proto_ver)
port = mosq_test.get_port() port = mosq_test.get_port()
if start_broker: broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
try: try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port) sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
@ -72,22 +72,16 @@ def do_test(start_broker):
except mosq_test.TestError: except mosq_test.TestError:
pass pass
finally: finally:
if start_broker: broker.terminate()
broker.terminate() if mosq_test.wait_for_subprocess(broker):
if mosq_test.wait_for_subprocess(broker): print("broker not terminated")
print("broker not terminated") if rc == 0: rc=1
if rc == 0: rc=1 (stdo, stde) = broker.communicate()
(stdo, stde) = broker.communicate() if rc:
if rc: print(stde.decode('utf-8'))
print(stde.decode('utf-8')) print("proto_ver=%d" % (proto_ver))
print("proto_ver=%d" % (proto_ver)) exit(rc)
exit(rc)
else:
return rc
def all_tests(start_broker=False): do_test(proto_ver=5)
return do_test(start_broker) exit(0)
if __name__ == '__main__':
all_tests(True)