Reject DCC password out of range (#166)
* Reject DCC password out of range * Fix unit test after return value change Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
@@ -138,15 +138,23 @@ void handler_device_communication_control(uint8_t *service_request,
|
|||||||
(unsigned)timeDuration, (unsigned)state,
|
(unsigned)timeDuration, (unsigned)state,
|
||||||
characterstring_value(&password));
|
characterstring_value(&password));
|
||||||
#endif
|
#endif
|
||||||
/* bad decoding or something we didn't understand - send an abort */
|
/* bad decoding or invalid service parameter
|
||||||
|
send an abort or reject */
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
if (len == BACNET_STATUS_ABORT) {
|
||||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr, "DCC: Sending Abort!\n");
|
||||||
"DeviceCommunicationControl: "
|
|
||||||
"Sending Abort - could not decode.\n");
|
|
||||||
#endif
|
#endif
|
||||||
|
} else if (len == BACNET_STATUS_REJECT) {
|
||||||
|
len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id,
|
||||||
|
REJECT_REASON_PARAMETER_OUT_OF_RANGE);
|
||||||
|
#if PRINT_ENABLED
|
||||||
|
fprintf(stderr, "DCC: Sending Reject!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
goto DCC_ABORT;
|
goto DCC_ABORT;
|
||||||
}
|
}
|
||||||
if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) {
|
if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) {
|
||||||
|
|||||||
+17
-10
@@ -217,7 +217,7 @@ int dcc_encode_apdu(uint8_t *apdu,
|
|||||||
* enable/disable.
|
* enable/disable.
|
||||||
* @param password Pointer to the password [optional]
|
* @param password Pointer to the password [optional]
|
||||||
*
|
*
|
||||||
* @return Bytes decoded.
|
* @return Bytes decoded, or BACNET_STATUS_ABORT or BACNET_STATUS_REJECT
|
||||||
*/
|
*/
|
||||||
int dcc_decode_service_request(uint8_t *apdu,
|
int dcc_decode_service_request(uint8_t *apdu,
|
||||||
unsigned apdu_len_max,
|
unsigned apdu_len_max,
|
||||||
@@ -231,6 +231,7 @@ int dcc_decode_service_request(uint8_t *apdu,
|
|||||||
uint32_t len_value_type = 0;
|
uint32_t len_value_type = 0;
|
||||||
BACNET_UNSIGNED_INTEGER decoded_unsigned = 0;
|
BACNET_UNSIGNED_INTEGER decoded_unsigned = 0;
|
||||||
uint32_t decoded_enum = 0;
|
uint32_t decoded_enum = 0;
|
||||||
|
uint32_t password_length = 0;
|
||||||
|
|
||||||
if (apdu && apdu_len_max) {
|
if (apdu && apdu_len_max) {
|
||||||
/* Tag 0: timeDuration, in minutes --optional-- */
|
/* Tag 0: timeDuration, in minutes --optional-- */
|
||||||
@@ -243,10 +244,10 @@ int dcc_decode_service_request(uint8_t *apdu,
|
|||||||
*timeDuration = (uint16_t)decoded_unsigned;
|
*timeDuration = (uint16_t)decoded_unsigned;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_REJECT;
|
||||||
}
|
}
|
||||||
} else if (len < 0) {
|
} else if (len < 0) {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
} else if (timeDuration) {
|
} else if (timeDuration) {
|
||||||
/* zero indicates infinite duration and
|
/* zero indicates infinite duration and
|
||||||
results in no timeout */
|
results in no timeout */
|
||||||
@@ -263,7 +264,7 @@ int dcc_decode_service_request(uint8_t *apdu,
|
|||||||
(BACNET_COMMUNICATION_ENABLE_DISABLE)decoded_enum;
|
(BACNET_COMMUNICATION_ENABLE_DISABLE)decoded_enum;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((unsigned)apdu_len < apdu_len_max) {
|
if ((unsigned)apdu_len < apdu_len_max) {
|
||||||
@@ -272,7 +273,7 @@ int dcc_decode_service_request(uint8_t *apdu,
|
|||||||
/* since this is the last value of the packet,
|
/* since this is the last value of the packet,
|
||||||
if there is data here it must be the specific
|
if there is data here it must be the specific
|
||||||
context tag number or result in an error */
|
context tag number or result in an error */
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
len = bacnet_tag_number_and_value_decode(&apdu[apdu_len],
|
len = bacnet_tag_number_and_value_decode(&apdu[apdu_len],
|
||||||
apdu_len_max - apdu_len, &tag_number, &len_value_type);
|
apdu_len_max - apdu_len, &tag_number, &len_value_type);
|
||||||
@@ -282,15 +283,21 @@ int dcc_decode_service_request(uint8_t *apdu,
|
|||||||
len = bacnet_character_string_decode(&apdu[apdu_len],
|
len = bacnet_character_string_decode(&apdu[apdu_len],
|
||||||
apdu_len_max - apdu_len, len_value_type, password);
|
apdu_len_max - apdu_len, len_value_type, password);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
apdu_len += len;
|
password_length = len_value_type - 1;
|
||||||
|
if ((password_length >= 1) &&
|
||||||
|
(password_length <= 20)) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
return BACNET_STATUS_REJECT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return BACNET_STATUS_ERROR;
|
return BACNET_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
} else if (password) {
|
} else if (password) {
|
||||||
/* no optional password - set to NULL */
|
/* no optional password - set to NULL */
|
||||||
@@ -419,7 +426,7 @@ void test_DeviceCommunicationControlMalformedData(Test *pTest)
|
|||||||
ct_test(pTest, len == BACNET_STATUS_ERROR);
|
ct_test(pTest, len == BACNET_STATUS_ERROR);
|
||||||
len = dcc_decode_apdu(&payload_4[0], sizeof(payload_4), &test_invoke_id,
|
len = dcc_decode_apdu(&payload_4[0], sizeof(payload_4), &test_invoke_id,
|
||||||
&test_timeDuration, &test_enable_disable, &test_password);
|
&test_timeDuration, &test_enable_disable, &test_password);
|
||||||
ct_test(pTest, len == BACNET_STATUS_ERROR);
|
ct_test(pTest, len == BACNET_STATUS_ABORT);
|
||||||
len = dcc_decode_apdu(&payload_5[0], sizeof(payload_5), &test_invoke_id,
|
len = dcc_decode_apdu(&payload_5[0], sizeof(payload_5), &test_invoke_id,
|
||||||
&test_timeDuration, &test_enable_disable, &test_password);
|
&test_timeDuration, &test_enable_disable, &test_password);
|
||||||
ct_test(pTest, len == BACNET_STATUS_ERROR);
|
ct_test(pTest, len == BACNET_STATUS_ERROR);
|
||||||
|
|||||||
Reference in New Issue
Block a user