@@ -160,11 +160,25 @@ static void BrokerStore_String(char* dst, int max_len,
160160 XMEMCPY (dst , src , src_len );
161161 dst [src_len ] = '\0' ;
162162}
163+ static void BrokerStore_StringSensitive (char * dst , int max_len ,
164+ const char * src , word16 src_len )
165+ {
166+ /* Wipe old value before overwriting */
167+ XMEMSET (dst , 0 , max_len );
168+ if (src_len >= (word16 )max_len ) {
169+ src_len = (word16 )(max_len - 1 );
170+ }
171+ XMEMCPY (dst , src , src_len );
172+ dst [src_len ] = '\0' ;
173+ }
163174#else
164175static void BrokerStore_String (char * * dst_ptr ,
165- const char * src , word16 src_len )
176+ const char * src , word16 src_len , int sensitive )
166177{
167178 if (* dst_ptr != NULL ) {
179+ if (sensitive ) {
180+ XMEMSET (* dst_ptr , 0 , XSTRLEN (* dst_ptr ) + 1 );
181+ }
168182 WOLFMQTT_FREE (* dst_ptr );
169183 * dst_ptr = NULL ;
170184 }
@@ -176,13 +190,17 @@ static void BrokerStore_String(char** dst_ptr,
176190}
177191#endif
178192
179- /* Wrapper macro to unify static/dynamic calling convention */
193+ /* Wrapper macros to unify static/dynamic calling convention */
180194#ifdef WOLFMQTT_STATIC_MEMORY
181195 #define BROKER_STORE_STR (dst , src , len , maxlen ) \
182196 BrokerStore_String(dst, maxlen, src, len)
197+ #define BROKER_STORE_STR_SENSITIVE (dst , src , len , maxlen ) \
198+ BrokerStore_StringSensitive(dst, maxlen, src, len)
183199#else
184200 #define BROKER_STORE_STR (dst , src , len , maxlen ) \
185- BrokerStore_String(&(dst), src, len)
201+ BrokerStore_String(&(dst), src, len, 0)
202+ #define BROKER_STORE_STR_SENSITIVE (dst , src , len , maxlen ) \
203+ BrokerStore_String(&(dst), src, len, 1)
186204#endif
187205
188206#ifdef ENABLE_MQTT_TLS
@@ -1195,9 +1213,11 @@ static void BrokerClient_Free(BrokerClient* bc)
11951213#endif
11961214#ifdef WOLFMQTT_BROKER_WILL
11971215 if (bc -> will_topic ) {
1216+ XMEMSET (bc -> will_topic , 0 , XSTRLEN (bc -> will_topic ) + 1 );
11981217 WOLFMQTT_FREE (bc -> will_topic );
11991218 }
12001219 if (bc -> will_payload ) {
1220+ XMEMSET (bc -> will_payload , 0 , bc -> will_payload_len );
12011221 WOLFMQTT_FREE (bc -> will_payload );
12021222 }
12031223#endif
@@ -1749,7 +1769,7 @@ static void BrokerSubs_ReassociateClient(MqttBroker* broker,
17491769/* -------------------------------------------------------------------------- */
17501770#ifdef WOLFMQTT_BROKER_RETAINED
17511771static int BrokerRetained_Store (MqttBroker * broker , const char * topic ,
1752- const byte * payload , word16 payload_len , word32 expiry_sec )
1772+ const byte * payload , word32 payload_len , word32 expiry_sec )
17531773{
17541774 BrokerRetainedMsg * msg = NULL ;
17551775 int rc = MQTT_CODE_SUCCESS ;
@@ -2077,6 +2097,9 @@ static int BrokerPendingWill_Add(MqttBroker* broker, BrokerClient* bc)
20772097 if (pw -> client_id ) {
20782098 WOLFMQTT_FREE (pw -> client_id );
20792099 }
2100+ if (pw -> payload ) {
2101+ WOLFMQTT_FREE (pw -> payload );
2102+ }
20802103 WOLFMQTT_FREE (pw );
20812104 }
20822105#endif
@@ -2471,6 +2494,9 @@ static int BrokerTopicMatch(const char* filter, const char* topic)
24712494 if (* f == '#' ) {
24722495 return (f [1 ] == '\0' );
24732496 }
2497+ if (* f == '+' && f [1 ] == '\0' && * t == '\0' ) {
2498+ return 1 ;
2499+ }
24742500 return (* f == '\0' && * t == '\0' );
24752501}
24762502#else
@@ -2518,6 +2544,11 @@ static int BrokerSend_SubAck(BrokerClient* bc, word16 packet_id,
25182544 }
25192545#endif
25202546
2547+ /* 1 (type) + 4 (max VBI) + remain_len */
2548+ if (1 + 4 + remain_len > (int )BROKER_CLIENT_TX_SZ (bc )) {
2549+ return MQTT_CODE_ERROR_OUT_OF_BUFFER ;
2550+ }
2551+
25212552 bc -> tx_buf [pos ++ ] = MQTT_PACKET_TYPE_SET (MQTT_PACKET_TYPE_SUBSCRIBE_ACK );
25222553 pos += MqttEncode_Vbi (& bc -> tx_buf [pos ], remain_len );
25232554 pos += MqttEncode_Num (& bc -> tx_buf [pos ], packet_id );
@@ -2670,17 +2701,29 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
26702701 mc .lwt_msg -> topic_name_len , BROKER_MAX_TOPIC_LEN );
26712702 }
26722703 if (mc .lwt_msg -> total_len > 0 && mc .lwt_msg -> buffer != NULL ) {
2673- word16 wp_len = (word16 )mc .lwt_msg -> total_len ;
2674- #ifdef WOLFMQTT_STATIC_MEMORY
2675- if (wp_len > BROKER_MAX_WILL_PAYLOAD_LEN ) {
2676- wp_len = BROKER_MAX_WILL_PAYLOAD_LEN ;
2704+ word16 wp_len ;
2705+ if (mc .lwt_msg -> total_len > BROKER_MAX_WILL_PAYLOAD_LEN ) {
2706+ WBLOG_ERR (broker ,
2707+ "broker: LWT payload too large (%u > %d) sock=%d" ,
2708+ (unsigned )mc .lwt_msg -> total_len ,
2709+ BROKER_MAX_WILL_PAYLOAD_LEN , (int )bc -> sock );
2710+ ack .return_code =
2711+ MQTT_CONNECT_ACK_CODE_REFUSED_UNAVAIL ;
2712+ goto send_connack ;
26772713 }
2714+ else {
2715+ wp_len = (word16 )mc .lwt_msg -> total_len ;
2716+ }
2717+ #ifdef WOLFMQTT_STATIC_MEMORY
26782718 XMEMCPY (bc -> will_payload , mc .lwt_msg -> buffer , wp_len );
26792719#else
26802720 bc -> will_payload = (byte * )WOLFMQTT_MALLOC (wp_len );
26812721 if (bc -> will_payload != NULL ) {
26822722 XMEMCPY (bc -> will_payload , mc .lwt_msg -> buffer , wp_len );
26832723 }
2724+ else {
2725+ wp_len = 0 ;
2726+ }
26842727#endif
26852728 bc -> will_payload_len = wp_len ;
26862729 }
@@ -2715,15 +2758,15 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
27152758 word16 ulen = 0 ;
27162759 if (MqttDecode_Num ((byte * )mc .username - MQTT_DATA_LEN_SIZE ,
27172760 & ulen , MQTT_DATA_LEN_SIZE ) == MQTT_DATA_LEN_SIZE ) {
2718- BROKER_STORE_STR (bc -> username , mc .username , ulen ,
2761+ BROKER_STORE_STR_SENSITIVE (bc -> username , mc .username , ulen ,
27192762 BROKER_MAX_USERNAME_LEN );
27202763 }
27212764 }
27222765 if (mc .password ) {
27232766 word16 plen = 0 ;
27242767 if (MqttDecode_Num ((byte * )mc .password - MQTT_DATA_LEN_SIZE ,
27252768 & plen , MQTT_DATA_LEN_SIZE ) == MQTT_DATA_LEN_SIZE ) {
2726- BROKER_STORE_STR (bc -> password , mc .password , plen ,
2769+ BROKER_STORE_STR_SENSITIVE (bc -> password , mc .password , plen ,
27272770 BROKER_MAX_PASSWORD_LEN );
27282771 }
27292772 }
@@ -2826,6 +2869,9 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
28262869 }
28272870#endif
28282871
2872+ #ifdef WOLFMQTT_BROKER_WILL
2873+ send_connack :
2874+ #endif
28292875 rc = MqttEncode_ConnectAck (bc -> tx_buf , BROKER_CLIENT_TX_SZ (bc ), & ack );
28302876 if (rc > 0 ) {
28312877 WBLOG_INFO (broker , "broker: CONNACK send sock=%d code=%d" , (int )bc -> sock ,
@@ -2910,8 +2956,9 @@ static int BrokerHandle_Subscribe(BrokerClient* bc, int rx_len,
29102956 return_codes [i ] = (byte )granted_qos ;
29112957 }
29122958
2913- rc = BrokerSend_SubAck (bc , sub .packet_id , return_codes ,
2914- sub .topic_count );
2959+ /* Use i (capped at MAX_MQTT_TOPICS) instead of sub.topic_count to
2960+ * avoid reading past the end of the return_codes array */
2961+ rc = BrokerSend_SubAck (bc , sub .packet_id , return_codes , i );
29152962
29162963#ifdef WOLFMQTT_V5
29172964 if (sub .props ) {
@@ -3054,7 +3101,7 @@ static int BrokerHandle_Publish(BrokerClient* bc, int rx_len,
30543101 }
30553102#endif
30563103 (void )BrokerRetained_Store (broker , topic , payload ,
3057- ( word16 ) pub .total_len , expiry );
3104+ pub .total_len , expiry );
30583105 }
30593106 }
30603107#endif /* WOLFMQTT_BROKER_RETAINED */
@@ -3304,6 +3351,15 @@ static int BrokerClient_Process(MqttBroker* broker, BrokerClient* bc)
33043351 ((BrokerWsCtx * )bc -> ws_ctx )-> processing = 1 ;
33053352 }
33063353#endif
3354+ /* [MQTT-3.1.0-1] First packet must be CONNECT */
3355+ if (type != MQTT_PACKET_TYPE_CONNECT && !bc -> connected ) {
3356+ WBLOG_ERR (broker ,
3357+ "broker: packet type %u before CONNECT sock=%d" ,
3358+ type , (int )bc -> sock );
3359+ BrokerSubs_RemoveClient (broker , bc );
3360+ BrokerClient_Remove (broker , bc );
3361+ return 0 ;
3362+ }
33073363 switch (type ) {
33083364 case MQTT_PACKET_TYPE_CONNECT :
33093365 {
@@ -3314,6 +3370,7 @@ static int BrokerClient_Process(MqttBroker* broker, BrokerClient* bc)
33143370 BrokerClient_Remove (broker , bc );
33153371 return 0 ;
33163372 }
3373+ bc -> connected = 1 ;
33173374 break ;
33183375 }
33193376 case MQTT_PACKET_TYPE_PUBLISH :
0 commit comments