Skip to content

Commit 4177fa4

Browse files
author
Arto Kinnunen
committed
Prevalidate CoAP msg source address
1 parent be46564 commit 4177fa4

File tree

2 files changed

+37
-60
lines changed

2 files changed

+37
-60
lines changed

source/6LoWPAN/Thread/thread_leader_service.c

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,6 @@ static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source
393393

394394
response_ptr = payload;
395395

396-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
397-
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
398-
goto send_error_response;
399-
}
400-
401396
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_CHANNEL, &ptr) &&
402397
(linkConfiguration->rfChannel != common_read_16_bit(&ptr[1]) || linkConfiguration->channel_page != *ptr)) {
403398
tr_debug("Channel changed");
@@ -559,11 +554,6 @@ static int thread_leader_service_pending_set_cb(int8_t service_id, uint8_t sourc
559554

560555
tr_info("thread management Pending set");
561556

562-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
563-
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
564-
goto send_error_response;
565-
}
566-
567557
if (2 <= thread_meshcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &session_id)) {
568558
// Session id present must be valid
569559
if (cur->thread_info->registered_commissioner.session_id != session_id) {
@@ -660,7 +650,6 @@ static int thread_leader_service_pending_set_cb(int8_t service_id, uint8_t sourc
660650
static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
661651
{
662652
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
663-
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
664653
uint16_t session_id;
665654
uint16_t br_locator;
666655
uint8_t payload[5]; // 4 + 1
@@ -682,10 +671,6 @@ static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t
682671

683672
tr_info("thread management commissioner set");
684673

685-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
686-
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
687-
goto send_error_response;
688-
}
689674
//Check if the CoAp payload is greater than maximum commissioner data size and reject
690675
if (request_ptr->payload_len > THREAD_MAX_COMMISSIONER_DATA_SIZE) {
691676
tr_error("Payload length greater than maximum commissioner data size");
@@ -725,9 +710,7 @@ static int thread_leader_service_commissioner_set_cb(int8_t service_id, uint8_t
725710
send_response:
726711
// build response
727712
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, ret == 0 ? 1 : 0xff);
728-
729-
send_error_response:
730-
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
713+
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
731714
return 0;
732715
}
733716

@@ -1050,7 +1033,6 @@ static int thread_leader_service_release_cb(int8_t service_id, uint8_t source_ad
10501033
static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
10511034
{
10521035
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
1053-
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
10541036
uint8_t payload[79];// max length for commissioner id is 64 + 4 byte header + 4 + 1 + 4 + 2
10551037
uint8_t *ptr;
10561038
uint16_t session_id = 0;
@@ -1067,11 +1049,6 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
10671049

10681050
tr_debug("Thread management commissioner petition");
10691051

1070-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
1071-
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
1072-
goto send_error_response;
1073-
}
1074-
10751052
// save values from message
10761053
tlv_length = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_ID, &tlv_data_ptr);
10771054

@@ -1098,8 +1075,7 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
10981075

10991076
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
11001077

1101-
send_error_response:
1102-
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
1078+
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
11031079
return 0;
11041080
}
11051081

@@ -1110,7 +1086,6 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
11101086
static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
11111087
{
11121088
thread_leader_service_t *this = thread_leader_service_find_by_service(service_id);
1113-
sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
11141089
uint8_t payload[5]; //status 4 + 1
11151090
uint8_t *ptr;
11161091
uint16_t session_id = 0;
@@ -1125,12 +1100,6 @@ static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t sourc
11251100

11261101
tr_debug("Thread management commissioner keep alive");
11271102

1128-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
1129-
response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
1130-
ptr = payload;
1131-
goto send_error_response;
1132-
}
1133-
11341103
if (2 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_COMMISSIONER_SESSION_ID, &ptr)) {
11351104
session_id = common_read_16_bit(ptr);
11361105
}
@@ -1149,8 +1118,7 @@ static int thread_leader_service_petition_ka_cb(int8_t service_id, uint8_t sourc
11491118
ptr = payload;
11501119
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, state == true ? 1 : 0xff);
11511120

1152-
send_error_response:
1153-
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
1121+
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload, ptr - payload);
11541122
return 0;
11551123
}
11561124

source/6LoWPAN/Thread/thread_management_server.c

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@
7272

7373
#ifdef HAVE_THREAD
7474

75+
#define TRACE_DEEP
76+
#ifdef TRACE_DEEP
77+
#define tr_deep tr_debug
78+
#else
79+
#define tr_deep(...)
80+
#endif
81+
7582
typedef struct scan_query {
7683
int8_t coap_service_id;
7784
uint8_t channel_mask[6]; //<!** first byte is channel page
@@ -395,19 +402,14 @@ static int thread_management_server_pending_get_respond(int8_t interface_id, int
395402
static int thread_management_server_get_command_cb(int8_t service_id, uint8_t source_address[16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
396403
{
397404
(void) source_port;
405+
(void) source_address;
398406

399407
thread_management_server_t *this = thread_management_find_by_service(service_id);
400408

401409
if (!this) {
402410
return -1;
403411
}
404412

405-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
406-
// request is coming from illegal address, return error immediately
407-
coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_BAD_REQUEST, COAP_CT_OCTET_STREAM, NULL, 0);
408-
return 0;
409-
}
410-
411413
return thread_management_server_tmf_get_request_handler(this->interface_id, service_id, request_ptr);
412414

413415
}
@@ -418,7 +420,6 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
418420
(void) source_port;
419421
protocol_interface_info_entry_t *cur;
420422
thread_management_server_t *this = thread_management_find_by_service(service_id);
421-
sn_coap_msg_code_e return_code = COAP_MSG_CODE_RESPONSE_CHANGED;
422423
uint8_t response_msg[2 + 2 + 2 + 2 + 2 + 16 + 2 + 2];
423424
uint8_t *request_tlv_ptr = NULL;
424425
uint16_t request_tlv_len;
@@ -434,11 +435,6 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
434435
}
435436
payload_ptr = ptr = response_msg;
436437

437-
if (!thread_management_server_source_address_check(this->interface_id, source_address)) {
438-
return_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
439-
goto send_response;
440-
}
441-
442438
if (!cur->thread_info->registered_commissioner.commissioner_valid) {
443439
//Error in message is responded with Thread status or if we have access rights problem
444440
tr_warn("No registered commissioner");
@@ -466,7 +462,7 @@ static int thread_management_server_commissioner_get_cb(int8_t service_id, uint8
466462
goto send_response;
467463
}
468464
send_response:
469-
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, return_code, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr);
465+
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr);
470466
return 0;
471467
}
472468

@@ -1120,7 +1116,7 @@ static int thread_management_server_announce_begin_cb(int8_t service_id, uint8_t
11201116
return 0;
11211117
}
11221118

1123-
static int coap_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_address[static 16], uint16_t local_port, int8_t source_interface_id, uint8_t source_address[static 16], uint16_t source_port, char *coap_uri)
1119+
static int coap_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_address[static 16], uint16_t local_port, int8_t recv_interface_id, uint8_t source_address[static 16], uint16_t source_port, char *coap_uri)
11241120
{
11251121
protocol_interface_info_entry_t *cur_local, *cur_source;
11261122
uint_fast8_t addr_scope;
@@ -1131,31 +1127,42 @@ static int coap_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_addr
11311127

11321128
cur_local = protocol_stack_interface_info_get_by_id(local_interface_id);
11331129

1130+
tr_debug("coap_msg_prevalidate_cb %s to %s from %s to port %d", coap_uri, trace_ipv6(local_address), trace_ipv6(source_address), local_port);
1131+
11341132
if (!cur_local) {
1135-
tr_error("No interface");
1133+
tr_error("No interface for %d", local_interface_id);
11361134
return -1;
11371135
}
11381136

11391137
if (local_port != THREAD_MANAGEMENT_PORT) {
11401138
// Message not sent to THREAD_MANAGEMENT_PORT, let it come through
1139+
tr_deep("Message %s port %d is not mgmt port", coap_uri, local_port);
11411140
return 0;
11421141
}
11431142

1144-
/* check our address scope */
1143+
// check message source address
1144+
if (!thread_management_server_source_address_check(local_interface_id, source_address)) {
1145+
tr_deep("Drop CoAP msg %s from %s", coap_uri, trace_ipv6(source_address));
1146+
return 3;
1147+
}
1148+
1149+
/* check our local address scope */
11451150
addr_scope = addr_ipv6_scope(local_address, cur_local);
11461151
if (addr_scope > IPV6_SCOPE_REALM_LOCAL) {
1152+
tr_deep("Drop CoAP msg %s to %s due %d", coap_uri, trace_ipv6(local_address), addr_scope);
11471153
return 1;
11481154
}
11491155

1150-
if (local_interface_id != source_interface_id) {
1156+
if (local_interface_id != recv_interface_id) {
11511157
// message received from different interface
1152-
cur_source = protocol_stack_interface_info_get_by_id(source_interface_id);
1158+
cur_source = protocol_stack_interface_info_get_by_id(recv_interface_id);
11531159
if (!cur_source) {
1160+
tr_deep("No cur for if %d", recv_interface_id);
11541161
return -1;
11551162
}
11561163
addr_scope = addr_ipv6_scope(source_address, cur_source);
11571164
if (addr_scope < IPV6_SCOPE_REALM_LOCAL) {
1158-
tr_error("AWH: Drop %s from %s-%d to %s-%d", coap_uri, trace_ipv6(source_address), local_interface_id, trace_ipv6(local_address), source_interface_id);
1165+
tr_deep("Drop CoAP msg %s from %s to %s due %d", coap_uri, trace_ipv6(source_address), trace_ipv6(local_address), addr_scope);
11591166
return 2;
11601167
}
11611168
}
@@ -1600,10 +1607,15 @@ int thread_management_server_commisoner_data_get(int8_t interface_id, thread_man
16001607
bool thread_management_server_source_address_check(int8_t interface_id, uint8_t source_address[16])
16011608
{
16021609
link_configuration_s *linkConfiguration;
1603-
linkConfiguration = thread_joiner_application_get_config(interface_id);
16041610

1611+
if (memcmp(ADDR_LINK_LOCAL_PREFIX, source_address, 8) == 0) {
1612+
// Source address is from Link local address
1613+
return true;
1614+
}
1615+
1616+
linkConfiguration = thread_joiner_application_get_config(interface_id);
16051617
if (!linkConfiguration) {
1606-
tr_error("No link configuration.");
1618+
tr_error("No link cfg for if %d", interface_id);
16071619
return false;
16081620
}
16091621

@@ -1612,15 +1624,12 @@ bool thread_management_server_source_address_check(int8_t interface_id, uint8_t
16121624
// Source address is RLOC or ALOC
16131625
} else if (memcmp(source_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0) {
16141626
// Source address is ML64 TODO this should check that destination address is ALOC or RLOC CoaP Service does not support
1615-
} else if (memcmp(ADDR_LINK_LOCAL_PREFIX, source_address, 8)) {
1616-
// Source address is from Link local address
16171627
} else {
1618-
tr_error("Message out of thread network; ML prefix: %s, src addr: %s",
1628+
tr_deep("Message out of thread network; ML prefix: %s, src addr: %s",
16191629
trace_ipv6_prefix(linkConfiguration->mesh_local_ula_prefix, 64),
16201630
trace_ipv6(source_address));
16211631
return false;
16221632
}
1623-
// TODO: Add other (security) related checks here
16241633

16251634
return true;
16261635
}

0 commit comments

Comments
 (0)