Skip to content

Commit 17fad47

Browse files
author
Arto Kinnunen
authored
Merge pull request ARMmbed#1924 from ARMmbed/IOTTHD-1608
Update CoAP message prevalidation
2 parents 6fd6bd5 + 4177fa4 commit 17fad47

File tree

3 files changed

+55
-65
lines changed

3 files changed

+55
-65
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: 51 additions & 29 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,33 +1116,57 @@ 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 interface_id, uint8_t source_address[static 16], uint16_t source_port, uint8_t local_address[static 16], uint16_t local_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
{
1125-
protocol_interface_info_entry_t *cur;
1126-
uint_fast8_t local_addr_scope;
1121+
protocol_interface_info_entry_t *cur_local, *cur_source;
1122+
uint_fast8_t addr_scope;
11271123

11281124
(void) source_address;
11291125
(void) source_port;
11301126
(void) coap_uri;
11311127

1132-
cur = protocol_stack_interface_info_get_by_id(interface_id);
1128+
cur_local = protocol_stack_interface_info_get_by_id(local_interface_id);
1129+
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);
11331131

1134-
if (!cur) {
1135-
tr_error("No interface");
1132+
if (!cur_local) {
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 */
1145-
local_addr_scope = addr_ipv6_scope(local_address, cur);
1146-
if (local_addr_scope > IPV6_SCOPE_REALM_LOCAL) {
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 */
1150+
addr_scope = addr_ipv6_scope(local_address, cur_local);
1151+
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

1156+
if (local_interface_id != recv_interface_id) {
1157+
// message received from different interface
1158+
cur_source = protocol_stack_interface_info_get_by_id(recv_interface_id);
1159+
if (!cur_source) {
1160+
tr_deep("No cur for if %d", recv_interface_id);
1161+
return -1;
1162+
}
1163+
addr_scope = addr_ipv6_scope(source_address, cur_source);
1164+
if (addr_scope < IPV6_SCOPE_REALM_LOCAL) {
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);
1166+
return 2;
1167+
}
1168+
}
1169+
11501170
return 0;
11511171
}
11521172

@@ -1194,7 +1214,7 @@ int thread_management_server_init(int8_t interface_id)
11941214
ns_dyn_mem_free(this);
11951215
return -3;
11961216
}
1197-
coap_service_msg_prevalidate_callback_set(this->coap_service_id, coap_msg_prevalidate_cb);
1217+
coap_service_msg_prevalidate_callback_set(THREAD_MANAGEMENT_PORT, coap_msg_prevalidate_cb);
11981218
#ifdef HAVE_THREAD_ROUTER
11991219
if (thread_leader_service_init(interface_id, this->coap_service_id) != 0) {
12001220
tr_error("Thread leader service init failed");
@@ -1587,10 +1607,15 @@ int thread_management_server_commisoner_data_get(int8_t interface_id, thread_man
15871607
bool thread_management_server_source_address_check(int8_t interface_id, uint8_t source_address[16])
15881608
{
15891609
link_configuration_s *linkConfiguration;
1590-
linkConfiguration = thread_joiner_application_get_config(interface_id);
15911610

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);
15921617
if (!linkConfiguration) {
1593-
tr_error("No link configuration.");
1618+
tr_error("No link cfg for if %d", interface_id);
15941619
return false;
15951620
}
15961621

@@ -1599,15 +1624,12 @@ bool thread_management_server_source_address_check(int8_t interface_id, uint8_t
15991624
// Source address is RLOC or ALOC
16001625
} else if (memcmp(source_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0) {
16011626
// Source address is ML64 TODO this should check that destination address is ALOC or RLOC CoaP Service does not support
1602-
} else if (memcmp(ADDR_LINK_LOCAL_PREFIX, source_address, 8)) {
1603-
// Source address is from Link local address
16041627
} else {
1605-
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",
16061629
trace_ipv6_prefix(linkConfiguration->mesh_local_ula_prefix, 64),
16071630
trace_ipv6(source_address));
16081631
return false;
16091632
}
1610-
// TODO: Add other (security) related checks here
16111633

16121634
return true;
16131635
}

test/nanostack/unittest/stub/coap_service_api_stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void coap_service_request_delete_by_service_id(int8_t service_id)
100100
{
101101
}
102102

103-
int8_t coap_service_msg_prevalidate_callback_set(int8_t service_id, coap_service_msg_prevalidate_cb *msg_prevalidate_cb)
103+
int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_port, coap_service_msg_prevalidate_cb *msg_prevalidate_cb)
104104
{
105105
return 0;
106106
}

0 commit comments

Comments
 (0)