diff --git a/.github/workflows/coverity-scan-develop.yml b/.github/workflows/coverity-scan-develop.yml index dad5224c..ed87aca5 100644 --- a/.github/workflows/coverity-scan-develop.yml +++ b/.github/workflows/coverity-scan-develop.yml @@ -34,6 +34,7 @@ jobs: python3-all \ python3-paho-mqtt \ python3-psutil \ + uthash-dev \ xsltproc - uses: vapier/coverity-scan-action@v1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f652487..851fd8c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,8 @@ include(CheckIncludeFiles) include(CheckLibraryExists) include(CheckSourceCompiles) include(GNUInstallDirs) +include(CMakePushCheckState) +include(CheckSourceCompiles) option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON) option(WITH_TLS "Include SSL/TLS support?" ON) diff --git a/ChangeLog.txt b/ChangeLog.txt index b3e338b1..01c4239f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -271,6 +271,23 @@ - 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 =================== diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index ea0b38f4..fece0bec 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -85,9 +85,9 @@ Section "Files" SecInstall File "..\build\vcpkg_installed\x86-windows\bin\sqlite3.dll" SetOutPath "$INSTDIR\devel" - File /oname=mosquitto_broker.lib "..\build\src\Release\mosquitto.lib" File "..\build\lib\Release\mosquitto.lib" File "..\build\lib\cpp\Release\mosquittopp.lib" + File "..\build\src\Release\mosquitto_broker.lib" File "..\include\mosquitto.h" File "..\include\mosquitto_broker.h" File "..\include\mosquitto_plugin.h" diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index 55a2b86d..0d72287e 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -86,9 +86,9 @@ Section "Files" SecInstall File "..\build64\vcpkg_installed\x64-windows-release\bin\sqlite3.dll" SetOutPath "$INSTDIR\devel" - File /oname=mosquitto_broker.lib "..\build64\src\Release\mosquitto.lib" File "..\build64\lib\Release\mosquitto.lib" File "..\build64\lib\cpp\Release\mosquittopp.lib" + File "..\build64\src\Release\mosquitto_broker.lib" File "..\include\mosquitto.h" File "..\include\mosquitto_broker.h" File "..\include\mosquitto_plugin.h" diff --git a/lib/handle_ping.c b/lib/handle_ping.c index cc91511e..d97c519b 100644 --- a/lib/handle_ping.c +++ b/lib/handle_ping.c @@ -42,6 +42,9 @@ int handle__pingreq(struct mosquitto *mosq) assert(mosq); 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; } 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); 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; } 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. */ #ifdef WITH_BROKER 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; } log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", SAFE_PRINT(mosq->id)); diff --git a/lib/handle_pubackcomp.c b/lib/handle_pubackcomp.c index b4715a04..9e279fbb 100644 --- a/lib/handle_pubackcomp.c +++ b/lib/handle_pubackcomp.c @@ -49,6 +49,9 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) assert(mosq); 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; } if(mosq->protocol != mosq_p_mqtt31){ @@ -77,6 +80,9 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) qos = 2; } 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; } @@ -105,6 +111,10 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) ){ 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; } }else{ @@ -113,6 +123,10 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) ){ 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; } } diff --git a/lib/handle_pubrec.c b/lib/handle_pubrec.c index 11102833..8713b0a3 100644 --- a/lib/handle_pubrec.c +++ b/lib/handle_pubrec.c @@ -48,6 +48,9 @@ int handle__pubrec(struct mosquitto *mosq) assert(mosq); 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; } if(mosq->in_packet.command != CMD_PUBREC){ @@ -59,6 +62,10 @@ int handle__pubrec(struct mosquitto *mosq) return rc; } 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; } @@ -78,12 +85,21 @@ int handle__pubrec(struct mosquitto *mosq) && reason_code != MQTT_RC_QUOTA_EXCEEDED && 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; } if(mosq->in_packet.remaining_length > 3){ rc = property__read_all(CMD_PUBREC, &mosq->in_packet, &properties); 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; } diff --git a/lib/handle_pubrel.c b/lib/handle_pubrel.c index f6b05bc0..bc53177e 100644 --- a/lib/handle_pubrel.c +++ b/lib/handle_pubrel.c @@ -51,6 +51,9 @@ int handle__pubrel(struct mosquitto *mosq) assert(mosq); 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; } 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->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; } } @@ -67,6 +74,10 @@ int handle__pubrel(struct mosquitto *mosq) return rc; } 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; } @@ -77,17 +88,26 @@ int handle__pubrel(struct mosquitto *mosq) } 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; } if(mosq->in_packet.remaining_length > 3){ 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 * User Property at the moment */ 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; + } } } diff --git a/lib/handle_suback.c b/lib/handle_suback.c index fbe4b06e..265fe8a2 100644 --- a/lib/handle_suback.c +++ b/lib/handle_suback.c @@ -48,6 +48,9 @@ int handle__suback(struct mosquitto *mosq) assert(mosq); 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; } if(mosq->in_packet.command != CMD_SUBACK){ @@ -57,6 +60,7 @@ int handle__suback(struct mosquitto *mosq) #ifdef WITH_BROKER if(mosq->bridge == NULL){ /* 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; } log__printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", SAFE_PRINT(mosq->id)); diff --git a/lib/handle_unsuback.c b/lib/handle_unsuback.c index adf0e8bc..d29c4c91 100644 --- a/lib/handle_unsuback.c +++ b/lib/handle_unsuback.c @@ -50,6 +50,9 @@ int handle__unsuback(struct mosquitto *mosq) assert(mosq); 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; } if(mosq->in_packet.command != CMD_UNSUBACK){ @@ -59,6 +62,7 @@ int handle__unsuback(struct mosquitto *mosq) #ifdef WITH_BROKER if(mosq->bridge == NULL){ /* 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; } log__printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", SAFE_PRINT(mosq->id)); diff --git a/lib/net_mosq.c b/lib/net_mosq.c index a216ab60..69428fe5 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -691,6 +691,8 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) net__init_tls(); + net__init_tls(); + #ifndef WITH_BROKER if(mosq->user_ssl_ctx){ mosq->ssl_ctx = mosq->user_ssl_ctx; diff --git a/lib/packet_mosq.c b/lib/packet_mosq.c index 6adee2bb..61ed69e1 100644 --- a/lib/packet_mosq.c +++ b/lib/packet_mosq.c @@ -486,11 +486,15 @@ static int packet__read_single(struct mosquitto *mosq, enum mosquitto_client_sta #ifdef WITH_BROKER /* Clients must send CONNECT as their first command. */ 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; }else if((mosq->in_packet.command&0xF0) == CMD_RESERVED){ if(mosq->protocol == mosq_p_mqtt5){ 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; } #else diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be11f574..8f8de9c1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -301,6 +301,7 @@ endif() set_target_properties(mosquitto PROPERTIES ENABLE_EXPORTS 1 + ARCHIVE_OUTPUT_NAME "mosquitto_broker" ) if(UNIX) diff --git a/src/conf.c b/src/conf.c index f17faa51..5df6fd62 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2474,6 +2474,10 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload, #ifdef FINAL_WITH_TLS_PSK REQUIRE_LISTENER_IF_PER_LISTENER(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); if(conf__parse_string(&token, "psk_file", &cur_security_options->psk_file, &saveptr)){ return MOSQ_ERR_INVAL; diff --git a/src/database.c b/src/database.c index 1ba76d1d..7e319970 100644 --- a/src/database.c +++ b/src/database.c @@ -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){ if(client_msg->data.mid == mid){ 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; }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; } 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){ if(client_msg->data.mid == mid){ 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; } 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){ if(client_msg->data.mid == mid){ 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; } 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){ if(client_msg->data.mid == mid){ 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; } topic = client_msg->base_msg->data.topic; diff --git a/src/handle_auth.c b/src/handle_auth.c index 8668fe73..d8d1b505 100644 --- a/src/handle_auth.c +++ b/src/handle_auth.c @@ -45,7 +45,12 @@ int handle__auth(struct mosquitto *context) 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; } if(context->in_packet.command != CMD_AUTH){ @@ -60,6 +65,8 @@ int handle__auth(struct mosquitto *context) && reason_code != MQTT_RC_REAUTHENTICATE){ 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; } @@ -68,6 +75,9 @@ int handle__auth(struct mosquitto *context) && context->state != mosq_cs_authenticating && context->state != mosq_cs_reauthenticating)){ 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; } @@ -81,6 +91,8 @@ int handle__auth(struct mosquitto *context) if(mosquitto_property_read_string(properties, MQTT_PROP_AUTHENTICATION_METHOD, &auth_method, false) == NULL){ mosquitto_property_free_all(&properties); 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; } @@ -89,6 +101,8 @@ int handle__auth(struct mosquitto *context) mosquitto_FREE(auth_method); mosquitto_property_free_all(&properties); 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; } mosquitto_FREE(auth_method); diff --git a/src/handle_connack.c b/src/handle_connack.c index e50ebd68..d3bfd0a9 100644 --- a/src/handle_connack.c +++ b/src/handle_connack.c @@ -112,6 +112,7 @@ int handle__connack(struct mosquitto *context) return MOSQ_ERR_INVAL; } 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; } if(context->in_packet.command != CMD_CONNACK){ diff --git a/src/handle_connect.c b/src/handle_connect.c index 22fe0b66..1d88132a 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -363,6 +363,8 @@ static int will__read(struct mosquitto *context, const char *clientid, struct mo goto error_cleanup; } if(!tlen){ + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: Will with empty topic.", + context->id); rc = MOSQ_ERR_PROTOCOL; goto error_cleanup; } @@ -479,12 +481,18 @@ static int read_protocol_name(struct mosquitto *context, char protocol_name[7]) uint16_t slen = 0; 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; } 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; } 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; } 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; 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; } @@ -515,8 +525,8 @@ static int read_and_verify_protocol_version(struct mosquitto *context, const cha if(!strcmp(protocol_name, PROTOCOL_NAME_v31)){ if((tmp_protocol_version&0x7F) != PROTOCOL_VERSION_v31){ if(db.config->connection_messages == true){ - log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", - tmp_protocol_version, context->address); + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol version (%d).", + context->address, context->remote_port, tmp_protocol_version); } send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); 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; }else{ if(db.config->connection_messages == true){ - log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", - tmp_protocol_version, context->address); + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol version (%d).", + context->address, context->remote_port, tmp_protocol_version); } send__connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); return MOSQ_ERR_PROTOCOL; } if((context->in_packet.command&0x0F) != 0x00){ /* 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; } }else{ if(db.config->connection_messages == true){ - log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol \"%s\" in CONNECT from %s.", - protocol_name, context->address); + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s:%d: CONNECT with invalid protocol \"%s\".", + context->address, context->remote_port, protocol_name); } 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) { 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; } if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ 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; } } @@ -596,6 +612,8 @@ static int read_and_reset_keepalive(struct mosquitto *context) keepalive__remove(context); 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; } keepalive__add(context); @@ -658,6 +676,8 @@ static int handle_zero_length_clientid(struct mosquitto *context, char **clienti uint8_t clean_start) { 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); 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){ + 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; 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; @@ -744,6 +766,8 @@ static int set_username_from_packet(struct mosquitto *context, char **username) /* Username flag given, but no username. Ignore. */ /* NOTE: Removed setting of username_flag to zero as it is unused afterwards */ }else{ + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT with username flag but no username.", + clientid); 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; @@ -765,6 +789,8 @@ static int set_password_from_packet(struct mosquitto *context, char **password) if(context->protocol == mosq_p_mqtt31){ /* Password flag given, but no password. Ignore. */ }else{ + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: CONNECT with password flag but no password.", + clientid); return MOSQ_ERR_PROTOCOL; } } @@ -781,7 +807,7 @@ static int read_and_verify_client_credentials_from_packet(struct mosquitto *cont int rc; if(username_flag){ - rc = set_username_from_packet(context, username); + rc = set_username_from_packet(context, username, clientid); if(rc != MOSQ_ERR_SUCCESS){ return rc; } @@ -795,7 +821,7 @@ static int read_and_verify_client_credentials_from_packet(struct mosquitto *cont } } if(password_flag){ - rc = set_password_from_packet(context, password); + rc = set_password_from_packet(context, password, clientid); if(rc != MOSQ_ERR_SUCCESS){ 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){ /* 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){ 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. */ 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; goto handle_connect_error; } @@ -1087,6 +1116,12 @@ int handle__connect(struct mosquitto *context) will = connect_flags & 0x04; 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); rc = verify_will_options(context, will, will_qos, will_retain, protocol_version); if(rc != MOSQ_ERR_SUCCESS){ @@ -1099,6 +1134,8 @@ int handle__connect(struct mosquitto *context) if(auth_data && !context->auth_method){ 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; goto handle_connect_error; } @@ -1123,6 +1160,8 @@ int handle__connect(struct mosquitto *context) }else{ if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){ 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; goto handle_connect_error; } diff --git a/src/handle_disconnect.c b/src/handle_disconnect.c index b87b2711..fd135fab 100644 --- a/src/handle_disconnect.c +++ b/src/handle_disconnect.c @@ -63,11 +63,15 @@ int handle__disconnect(struct mosquitto *context) mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */ 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; } 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->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); return MOSQ_ERR_PROTOCOL; } diff --git a/src/handle_publish.c b/src/handle_publish.c index 2485281b..7ad5cda7 100644 --- a/src/handle_publish.c +++ b/src/handle_publish.c @@ -181,6 +181,7 @@ int handle__accepted_publish(struct mosquitto *context, struct mosquitto__base_m rc = rc2; } }else{ + log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PUBLISH with dup = %d.", context->id, dup); return MOSQ_ERR_PROTOCOL; } }else{ @@ -210,6 +211,7 @@ int handle__publish(struct mosquitto *context) uint16_t mid = 0; 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; } @@ -264,6 +266,7 @@ int handle__publish(struct mosquitto *context) } if(mid == 0){ 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; } /* 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); if(rc){ 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; } } diff --git a/src/handle_subscribe.c b/src/handle_subscribe.c index b30a2ed6..5d6d26e0 100644 --- a/src/handle_subscribe.c +++ b/src/handle_subscribe.c @@ -49,6 +49,7 @@ int handle__subscribe(struct mosquitto *context) } 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; } 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 * return codes so needs doc changes as well. */ 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; }else{ 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/"))){ mosquitto_FREE(sub.topic_filter); 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; } diff --git a/src/handle_unsubscribe.c b/src/handle_unsubscribe.c index b5047ad4..5947d9a1 100644 --- a/src/handle_unsubscribe.c +++ b/src/handle_unsubscribe.c @@ -45,6 +45,7 @@ int handle__unsubscribe(struct mosquitto *context) } 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; } 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 * return codes so needs doc changes as well. */ 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; }else{ return rc; diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 0051b22a..212ff9d8 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -955,7 +955,9 @@ void service_install(char *name); void service_uninstall(char *name); void service_run(char *name); -DWORD WINAPI SigThreadProc(void *data); +#ifdef WIN32 +DWORD WINAPI SigThreadProc(void* data); +#endif #endif /* ============================================================ diff --git a/src/net.c b/src/net.c index 6660b76b..3f4c1374 100644 --- a/src/net.c +++ b/src/net.c @@ -407,6 +407,13 @@ int net__tls_server_ctx(struct mosquitto__listener *listener) char buf[256]; 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){ SSL_CTX_free(listener->ssl_ctx); listener->ssl_ctx = NULL; diff --git a/src/property_broker.c b/src/property_broker.c index bf3bdbef..ace5110e 100644 --- a/src/property_broker.c +++ b/src/property_broker.c @@ -44,6 +44,7 @@ int property__process_connect(struct mosquitto *context, mosquitto_property **pr case MQTT_PROP_RECEIVE_MAXIMUM: context->msgs_out.inflight_maximum = mosquitto_property_int16_value(p); 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; } 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: context->maximum_packet_size = mosquitto_property_int32_value(p); 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; } break; @@ -128,6 +130,7 @@ int property__process_will(struct mosquitto *context, struct mosquitto_message_a default: 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; break; } @@ -215,6 +218,8 @@ int property__process_disconnect(struct mosquitto *context, mosquitto_property * if(context->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; } context->session_expiry_interval = session_expiry_interval; diff --git a/src/security_default.c b/src/security_default.c index 07d97dc6..ea573b39 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -233,6 +233,7 @@ int mosquitto_security_apply_default(void) const char *username = (const char *)ASN1_STRING_get0_data(name_asn1); if(!username){ X509_free(client_cert); + client_cert = NULL; security__disconnect_auth(context); continue; } diff --git a/src/send_auth.c b/src/send_auth.c index 087d175d..b01f543b 100644 --- a/src/send_auth.c +++ b/src/send_auth.c @@ -37,6 +37,7 @@ int send__auth(struct mosquitto *context, uint8_t reason_code, const void *auth_ return MOSQ_ERR_INVAL; } 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; } diff --git a/test/broker/02-subpub-qos1-message-expiry-retain.py b/test/broker/02-subpub-qos1-message-expiry-retain.py index f1d9b85c..b83bb8d2 100755 --- a/test/broker/02-subpub-qos1-message-expiry-retain.py +++ b/test/broker/02-subpub-qos1-message-expiry-retain.py @@ -13,39 +13,39 @@ from mosq_test_helper import * -def do_test(start_broker): +def do_test(proto_ver): rc = 1 - connect_packet = mosq_test.gen_connect("02-subpub-qos1-msg-expiry-retain", proto_ver=5) - connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + keepalive = 60 + 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 - subscribe1_packet = mosq_test.gen_subscribe(mid, "02/subpub/expiry/retain/expired", 1, proto_ver=5) - suback1_packet = mosq_test.gen_suback(mid, 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=proto_ver) mid = 2 - subscribe2_packet = mosq_test.gen_subscribe(mid, "02/subpub/expiry/retain/kept", 1, proto_ver=5) - suback2_packet = mosq_test.gen_suback(mid, 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=proto_ver) - helper_connect = mosq_test.gen_connect("02-subpub-qos1-msg-expiry-retain-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 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) - puback1_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) + 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=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) mid=2 - publish2s_packet = mosq_test.gen_publish("02/subpub/expiry/retain/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=5) - puback2s_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) + 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=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) mid=1 - publish2r_packet = mosq_test.gen_publish("02/subpub/expiry/retain/kept", mid=mid, qos=1, retain=True, payload="message2", proto_ver=5) - puback2r_packet = mosq_test.gen_puback(mid, proto_ver=5, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) + 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=proto_ver, reason_code=mqtt5_rc.NO_MATCHING_SUBSCRIBERS) 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: 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: pass finally: - if start_broker: - broker.terminate() - if mosq_test.wait_for_subprocess(broker): - print("broker not terminated") - if rc == 0: rc=1 - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) - print("proto_ver=%d" % (proto_ver)) - exit(rc) - else: - return rc + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + print("proto_ver=%d" % (proto_ver)) + exit(rc) -def all_tests(start_broker=False): - return do_test(start_broker) - -if __name__ == '__main__': - all_tests(True) +do_test(proto_ver=5) +exit(0) diff --git a/test/broker/02-subpub-qos1-message-expiry-will.py b/test/broker/02-subpub-qos1-message-expiry-will.py index be9d200d..f599f558 100755 --- a/test/broker/02-subpub-qos1-message-expiry-will.py +++ b/test/broker/02-subpub-qos1-message-expiry-will.py @@ -11,31 +11,31 @@ from mosq_test_helper import * -def do_test(start_broker): +def do_test(proto_ver): rc = 1 mid = 53 + keepalive = 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) - connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5) - connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5, flags=1) + 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=proto_ver) + 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) - suback_packet = mosq_test.gen_suback(mid, 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=proto_ver) 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_connack = mosq_test.gen_connack(rc=0, proto_ver=5) + 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=proto_ver) #mid=2 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) 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: 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)) for i in range(10, 5, -1): 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: rc = 0 break @@ -59,22 +59,16 @@ def do_test(start_broker): except mosq_test.TestError: pass finally: - if start_broker: - broker.terminate() - if mosq_test.wait_for_subprocess(broker): - print("broker not terminated") - if rc == 0: rc=1 - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) - print("proto_ver=%d" % (proto_ver)) - exit(rc) - else: - return rc + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + print("proto_ver=%d" % (proto_ver)) + exit(rc) -def all_tests(start_broker=False): - return do_test(start_broker) - -if __name__ == '__main__': - all_tests(True) +do_test(proto_ver=5) +exit(0) diff --git a/test/broker/02-subpub-qos1-message-expiry.py b/test/broker/02-subpub-qos1-message-expiry.py index 21631a4a..789c1379 100755 --- a/test/broker/02-subpub-qos1-message-expiry.py +++ b/test/broker/02-subpub-qos1-message-expiry.py @@ -11,35 +11,36 @@ from mosq_test_helper import * -def do_test(start_broker): +def do_test(proto_ver): rc = 1 mid = 53 + keepalive = 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) - connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5) - connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5, flags=1) + 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=proto_ver) + 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) - suback_packet = mosq_test.gen_suback(mid, 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=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 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) mid=2 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) 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: 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)) for i in range(9, 5, -1): 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: rc = 0 break @@ -65,22 +66,16 @@ def do_test(start_broker): except mosq_test.TestError: pass finally: - if start_broker: - broker.terminate() - if mosq_test.wait_for_subprocess(broker): - print("broker not terminated") - if rc == 0: rc=1 - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) - print("proto_ver=%d" % (proto_ver)) - exit(rc) - else: - return rc + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + print("proto_ver=%d" % (proto_ver)) + exit(rc) -def all_tests(start_broker=False): - return do_test(start_broker) - -if __name__ == '__main__': - all_tests(True) +do_test(proto_ver=5) +exit(0) diff --git a/test/broker/02-subpub-qos2-pubrec-error.py b/test/broker/02-subpub-qos2-pubrec-error.py index e7ae7f66..7ae4858e 100755 --- a/test/broker/02-subpub-qos2-pubrec-error.py +++ b/test/broker/02-subpub-qos2-pubrec-error.py @@ -5,17 +5,17 @@ from mosq_test_helper import * 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) 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) pubrel_1_packet = mosq_test.gen_pubrel(mid) pubcomp_1_packet = mosq_test.gen_pubcomp(mid) 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) pubrel_2_packet = mosq_test.gen_pubrel(mid) pubcomp_2_packet = mosq_test.gen_pubcomp(mid) @@ -30,28 +30,28 @@ def helper(port): sock.close() -def do_test(start_broker): +def do_test(proto_ver): rc = 1 - connect_packet = mosq_test.gen_connect("02-subpub-qos2-pubrec-error", proto_ver=5) - connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + keepalive = 60 + 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 - subscribe_packet = mosq_test.gen_subscribe(mid, "02/subpub/error/qos2/pubrec/+", 2, proto_ver=5) - suback_packet = mosq_test.gen_suback(mid, 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=proto_ver) 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) - pubrec_1_packet = mosq_test.gen_pubrec(mid, proto_ver=5, reason_code=0x80) + 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=proto_ver, reason_code=0x80) 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) - pubrec_2_packet = mosq_test.gen_pubrec(mid, proto_ver=5) - pubrel_2_packet = mosq_test.gen_pubrel(mid, proto_ver=5) - pubcomp_2_packet = mosq_test.gen_pubcomp(mid, 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=proto_ver) + pubrel_2_packet = mosq_test.gen_pubrel(mid, proto_ver=proto_ver) + pubcomp_2_packet = mosq_test.gen_pubcomp(mid, proto_ver=proto_ver) 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: 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: pass finally: - if start_broker: - broker.terminate() - if mosq_test.wait_for_subprocess(broker): - print("broker not terminated") - if rc == 0: rc=1 - (stdo, stde) = broker.communicate() - if rc: - print(stde.decode('utf-8')) - print("proto_ver=%d" % (proto_ver)) - exit(rc) - else: - return rc + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc: + print(stde.decode('utf-8')) + print("proto_ver=%d" % (proto_ver)) + exit(rc) -def all_tests(start_broker=False): - return do_test(start_broker) - -if __name__ == '__main__': - all_tests(True) +do_test(proto_ver=5) +exit(0)