mirror of https://github.com/wolfSSL/wolfMQTT.git
F-7658 - Validate DISCONNECT reason codes
parent
7a3f708b3c
commit
fe5541b46d
|
|
@ -251,6 +251,46 @@ int MqttPacket_SubAckReturnCodeValid(byte code, byte protocol_level)
|
|||
}
|
||||
|
||||
#ifdef WOLFMQTT_V5
|
||||
/* [MQTT-3.14.2-1] Validate a DISCONNECT Reason Code against Table 3-10. */
|
||||
static int MqttPacket_DisconnectReasonCodeValid(byte code)
|
||||
{
|
||||
switch (code) {
|
||||
case MQTT_REASON_SUCCESS: /* 0x00 */
|
||||
case MQTT_REASON_DISCONNECT_W_WILL_MSG: /* 0x04 */
|
||||
case MQTT_REASON_UNSPECIFIED_ERR: /* 0x80 */
|
||||
case MQTT_REASON_MALFORMED_PACKET: /* 0x81 */
|
||||
case MQTT_REASON_PROTOCOL_ERR: /* 0x82 */
|
||||
case MQTT_REASON_IMPL_SPECIFIC_ERR: /* 0x83 */
|
||||
case MQTT_REASON_NOT_AUTHORIZED: /* 0x87 */
|
||||
case MQTT_REASON_SERVER_BUSY: /* 0x89 */
|
||||
case MQTT_REASON_SERVER_SHUTTING_DOWN: /* 0x8B */
|
||||
case MQTT_REASON_KEEP_ALIVE_TIMEOUT: /* 0x8D */
|
||||
case MQTT_REASON_SESSION_TAKEN_OVER: /* 0x8E */
|
||||
case MQTT_REASON_TOPIC_FILTER_INVALID: /* 0x8F */
|
||||
case MQTT_REASON_TOPIC_NAME_INVALID: /* 0x90 */
|
||||
case MQTT_REASON_RX_MAX_EXCEEDED: /* 0x93 */
|
||||
case MQTT_REASON_TOPIC_ALIAS_INVALID: /* 0x94 */
|
||||
case MQTT_REASON_PACKET_TOO_LARGE: /* 0x95 */
|
||||
case MQTT_REASON_MSG_RATE_TOO_HIGH: /* 0x96 */
|
||||
case MQTT_REASON_QUOTA_EXCEEDED: /* 0x97 */
|
||||
case MQTT_REASON_ADMIN_ACTION: /* 0x98 */
|
||||
case MQTT_REASON_PAYLOAD_FORMAT_INVALID: /* 0x99 */
|
||||
case MQTT_REASON_RETAIN_NOT_SUPPORTED: /* 0x9A */
|
||||
case MQTT_REASON_QOS_NOT_SUPPORTED: /* 0x9B */
|
||||
case MQTT_REASON_USE_ANOTHER_SERVER: /* 0x9C */
|
||||
case MQTT_REASON_SERVER_MOVED: /* 0x9D */
|
||||
case MQTT_REASON_SS_NOT_SUPPORTED: /* 0x9E */
|
||||
case MQTT_REASON_CON_RATE_EXCEED: /* 0x9F */
|
||||
case MQTT_REASON_MAX_CON_TIME: /* 0xA0 */
|
||||
case MQTT_REASON_SUB_ID_NOT_SUP: /* 0xA1 */
|
||||
case MQTT_REASON_WILDCARD_SUB_NOT_SUP: /* 0xA2 */
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [MQTT-4.8.0-1] Validate a v5 UNSUBACK Reason Code against the fixed set in
|
||||
* MQTT 5.0 section 3.11.3. Returns 1 if allowed, 0 if reserved. */
|
||||
static int MqttPacket_UnsubAckReasonCodeValid(byte code)
|
||||
|
|
@ -3681,6 +3721,9 @@ int MqttEncode_Disconnect(byte *tx_buf, int tx_buf_len,
|
|||
if ((disconnect != NULL) &&
|
||||
(disconnect->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5)) {
|
||||
|
||||
if (!MqttPacket_DisconnectReasonCodeValid(disconnect->reason_code)) {
|
||||
return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
|
||||
}
|
||||
if (disconnect->props != NULL) {
|
||||
/* Determine length of properties */
|
||||
props_len = MqttEncode_Props(MQTT_PACKET_TYPE_DISCONNECT,
|
||||
|
|
|
|||
|
|
@ -4924,6 +4924,94 @@ TEST(decode_disconnect_v5_reason_code_past_buf_rejected)
|
|||
rc = MqttDecode_Disconnect(buf, (int)sizeof(buf), &disc);
|
||||
ASSERT_EQ(MQTT_CODE_ERROR_OUT_OF_BUFFER, rc);
|
||||
}
|
||||
|
||||
/* [MQTT-3.14.2-1] Table 3-10 is the complete DISCONNECT Reason Code
|
||||
* allow-list. Each nonzero code is encoded as the sole variable-header byte. */
|
||||
TEST(encode_disconnect_v5_reason_code_allowed_set)
|
||||
{
|
||||
static const byte allowed[] = {
|
||||
MQTT_REASON_SUCCESS,
|
||||
MQTT_REASON_DISCONNECT_W_WILL_MSG,
|
||||
MQTT_REASON_UNSPECIFIED_ERR,
|
||||
MQTT_REASON_MALFORMED_PACKET,
|
||||
MQTT_REASON_PROTOCOL_ERR,
|
||||
MQTT_REASON_IMPL_SPECIFIC_ERR,
|
||||
MQTT_REASON_NOT_AUTHORIZED,
|
||||
MQTT_REASON_SERVER_BUSY,
|
||||
MQTT_REASON_SERVER_SHUTTING_DOWN,
|
||||
MQTT_REASON_KEEP_ALIVE_TIMEOUT,
|
||||
MQTT_REASON_SESSION_TAKEN_OVER,
|
||||
MQTT_REASON_TOPIC_FILTER_INVALID,
|
||||
MQTT_REASON_TOPIC_NAME_INVALID,
|
||||
MQTT_REASON_RX_MAX_EXCEEDED,
|
||||
MQTT_REASON_TOPIC_ALIAS_INVALID,
|
||||
MQTT_REASON_PACKET_TOO_LARGE,
|
||||
MQTT_REASON_MSG_RATE_TOO_HIGH,
|
||||
MQTT_REASON_QUOTA_EXCEEDED,
|
||||
MQTT_REASON_ADMIN_ACTION,
|
||||
MQTT_REASON_PAYLOAD_FORMAT_INVALID,
|
||||
MQTT_REASON_RETAIN_NOT_SUPPORTED,
|
||||
MQTT_REASON_QOS_NOT_SUPPORTED,
|
||||
MQTT_REASON_USE_ANOTHER_SERVER,
|
||||
MQTT_REASON_SERVER_MOVED,
|
||||
MQTT_REASON_SS_NOT_SUPPORTED,
|
||||
MQTT_REASON_CON_RATE_EXCEED,
|
||||
MQTT_REASON_MAX_CON_TIME,
|
||||
MQTT_REASON_SUB_ID_NOT_SUP,
|
||||
MQTT_REASON_WILDCARD_SUB_NOT_SUP
|
||||
};
|
||||
MqttDisconnect disc;
|
||||
byte buf[16];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(allowed); i++) {
|
||||
int rc;
|
||||
|
||||
XMEMSET(&disc, 0, sizeof(disc));
|
||||
XMEMSET(buf, 0xA5, sizeof(buf));
|
||||
disc.protocol_level = MQTT_CONNECT_PROTOCOL_LEVEL_5;
|
||||
disc.reason_code = allowed[i];
|
||||
rc = MqttEncode_Disconnect(buf, (int)sizeof(buf), &disc);
|
||||
ASSERT_EQ(MQTT_PACKET_TYPE_SET(MQTT_PACKET_TYPE_DISCONNECT), buf[0]);
|
||||
if (allowed[i] == MQTT_REASON_SUCCESS) {
|
||||
ASSERT_EQ(2, rc);
|
||||
ASSERT_EQ(0, buf[1]);
|
||||
}
|
||||
else {
|
||||
ASSERT_EQ(3, rc);
|
||||
ASSERT_EQ(1, buf[1]);
|
||||
ASSERT_EQ(allowed[i], buf[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* [MQTT-3.14.2-1] Values assigned only to other packet types are reserved
|
||||
* for DISCONNECT and must not be emitted. */
|
||||
TEST(encode_disconnect_v5_reason_code_out_of_table_rejected)
|
||||
{
|
||||
static const byte invalid[] = {
|
||||
MQTT_REASON_GRANTED_QOS_1,
|
||||
MQTT_REASON_CONT_AUTH,
|
||||
MQTT_REASON_BAD_AUTH_METHOD,
|
||||
MQTT_REASON_PACKET_ID_NOT_FOUND,
|
||||
0xFF
|
||||
};
|
||||
MqttDisconnect disc;
|
||||
byte buf[16];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(invalid); i++) {
|
||||
int rc;
|
||||
|
||||
XMEMSET(&disc, 0, sizeof(disc));
|
||||
XMEMSET(buf, 0xA5, sizeof(buf));
|
||||
disc.protocol_level = MQTT_CONNECT_PROTOCOL_LEVEL_5;
|
||||
disc.reason_code = invalid[i];
|
||||
rc = MqttEncode_Disconnect(buf, (int)sizeof(buf), &disc);
|
||||
ASSERT_EQ(MQTT_CODE_ERROR_BAD_ARG, rc);
|
||||
ASSERT_EQ(0xA5, buf[0]);
|
||||
}
|
||||
}
|
||||
#endif /* WOLFMQTT_V5 */
|
||||
|
||||
/* ============================================================================
|
||||
|
|
@ -6052,6 +6140,8 @@ void run_mqtt_packet_tests(void)
|
|||
RUN_TEST(decode_disconnect_v5_invalid_fixed_header_flags_rejected);
|
||||
RUN_TEST(decode_disconnect_v5_with_reason_code_accepted);
|
||||
RUN_TEST(decode_disconnect_v5_reason_code_past_buf_rejected);
|
||||
RUN_TEST(encode_disconnect_v5_reason_code_allowed_set);
|
||||
RUN_TEST(encode_disconnect_v5_reason_code_out_of_table_rejected);
|
||||
#endif
|
||||
|
||||
/* Fixed-header reserved-flag validation [MQTT-2.2.2-2] */
|
||||
|
|
|
|||
Loading…
Reference in New Issue