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-paho-mqtt \
python3-psutil \
uthash-dev \
xsltproc
- uses: vapier/coverity-scan-action@v1

View file

@ -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)

View file

@ -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
===================

View file

@ -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"

View file

@ -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"

View file

@ -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));

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}
}

View file

@ -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));

View file

@ -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));

View file

@ -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;

View file

@ -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

View file

@ -301,6 +301,7 @@ endif()
set_target_properties(mosquitto PROPERTIES
ENABLE_EXPORTS 1
ARCHIVE_OUTPUT_NAME "mosquitto_broker"
)
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
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;

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){
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;

View file

@ -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);

View file

@ -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){

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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
/* ============================================================

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)