summaryrefslogtreecommitdiffstats
path: root/tinyNET/src/stun/tnet_stun_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyNET/src/stun/tnet_stun_pkt.c')
-rwxr-xr-xtinyNET/src/stun/tnet_stun_pkt.c1245
1 files changed, 623 insertions, 622 deletions
diff --git a/tinyNET/src/stun/tnet_stun_pkt.c b/tinyNET/src/stun/tnet_stun_pkt.c
index e4d559d..a996897 100755
--- a/tinyNET/src/stun/tnet_stun_pkt.c
+++ b/tinyNET/src/stun/tnet_stun_pkt.c
@@ -36,716 +36,717 @@
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
{
- extern const tsk_object_def_t *tnet_stun_pkt_def_t;
- if (!pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
- TSK_DEBUG_ERROR("Failed to create STUN pkt object");
- return -2;
- }
- if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
- TSK_OBJECT_SAFE_FREE(*pp_attr);
- return -3;
- }
- if (pc_transac_id) {
- memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
- }
- else {
- tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
- }
- (*pp_attr)->e_type = e_type;
- (*pp_attr)->u_length = u_length;
- return 0;
+ extern const tsk_object_def_t *tnet_stun_pkt_def_t;
+ if (!pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create STUN pkt object");
+ return -2;
+ }
+ if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
+ TSK_OBJECT_SAFE_FREE(*pp_attr);
+ return -3;
+ }
+ if (pc_transac_id) {
+ memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
+ }
+ else {
+ tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
+ }
+ (*pp_attr)->e_type = e_type;
+ (*pp_attr)->u_length = u_length;
+ return 0;
}
int tnet_stun_pkt_attr_add(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
{
- if (!p_self || !pp_attr || !*pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
- return 0;
+ if (!p_self || !pp_attr || !*pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
+ return 0;
}
int tnet_stun_pkt_attrs_add(tnet_stun_pkt_t* p_self, ...)
{
- va_list ap;
- int ret = 0;
- tnet_stun_pkt_attr_add_t e_add_attr;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- va_start(ap, p_self);
-
- while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
- switch (e_add_attr) {
- case tnet_stun_pkt_attr_add_vdata: {
- // (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
- enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
- const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
- uint16_t U_DATA_SIZE = tsk_va_arg_u16(ap);
- tnet_stun_attr_vdata_t *p_attr;
- if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_address: {
- // (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
- enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
- enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
- uint16_t U_PORT = tsk_va_arg_u16(ap);
- const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
- tnet_stun_attr_address_t *p_attr;
- if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_error_code: {
- // (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR)
- uint8_t U8_CLASS = tsk_va_arg_u8(ap);
- uint8_t U8_NUMBER = tsk_va_arg_u8(ap);
- const char* PC_REASON_STR = va_arg(ap, const char*);
- tnet_stun_attr_error_code_t *p_attr;
- if ((ret = tnet_stun_attr_error_code_create(U8_CLASS, U8_NUMBER, PC_REASON_STR, (uint16_t)tsk_strlen(PC_REASON_STR), &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_unknown_attrs: {
- // (...)
- tsk_buffer_t* p_buffer = tsk_buffer_create_null();
- tnet_stun_attr_vdata_t *p_attr;
- uint16_t u_16;
- if (!p_buffer) {
- TSK_DEBUG_ERROR("Failed to create buffer");
- ret = -4;
- goto bail;
- }
- while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
- if (e_add_attr != tnet_stun_pkt_attr_add_unknown_attrs_val) {
- TSK_OBJECT_SAFE_FREE(p_buffer);
- TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
- ret = -3;
- goto bail;
- }
- u_16 = tsk_va_arg_u16(ap);
- tsk_buffer_append(p_buffer, &u_16, 2);
- }
- if ((ret = tnet_stun_attr_vdata_create(tnet_stun_attr_type_unknown_attrs, p_buffer->data, (uint16_t)p_buffer->size, &p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_buffer);
- goto bail;
- }
- TSK_OBJECT_SAFE_FREE(p_buffer);
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- default: {
- TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
- ret = -2;
- goto bail;
- }
- }
- }
+ va_list ap;
+ int ret = 0;
+ tnet_stun_pkt_attr_add_t e_add_attr;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ va_start(ap, p_self);
+
+ while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
+ switch (e_add_attr) {
+ case tnet_stun_pkt_attr_add_vdata: {
+ // (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
+ enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
+ const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
+ uint16_t U_DATA_SIZE = tsk_va_arg_u16(ap);
+ tnet_stun_attr_vdata_t *p_attr;
+ if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_address: {
+ // (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
+ enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
+ enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
+ uint16_t U_PORT = tsk_va_arg_u16(ap);
+ const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
+ tnet_stun_attr_address_t *p_attr;
+ if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_error_code: {
+ // (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR)
+ uint8_t U8_CLASS = tsk_va_arg_u8(ap);
+ uint8_t U8_NUMBER = tsk_va_arg_u8(ap);
+ const char* PC_REASON_STR = va_arg(ap, const char*);
+ tnet_stun_attr_error_code_t *p_attr;
+ if ((ret = tnet_stun_attr_error_code_create(U8_CLASS, U8_NUMBER, PC_REASON_STR, (uint16_t)tsk_strlen(PC_REASON_STR), &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_unknown_attrs: {
+ // (...)
+ tsk_buffer_t* p_buffer = tsk_buffer_create_null();
+ tnet_stun_attr_vdata_t *p_attr;
+ uint16_t u_16;
+ if (!p_buffer) {
+ TSK_DEBUG_ERROR("Failed to create buffer");
+ ret = -4;
+ goto bail;
+ }
+ while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
+ if (e_add_attr != tnet_stun_pkt_attr_add_unknown_attrs_val) {
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
+ ret = -3;
+ goto bail;
+ }
+ u_16 = tsk_va_arg_u16(ap);
+ tsk_buffer_append(p_buffer, &u_16, 2);
+ }
+ if ((ret = tnet_stun_attr_vdata_create(tnet_stun_attr_type_unknown_attrs, p_buffer->data, (uint16_t)p_buffer->size, &p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ goto bail;
+ }
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ default: {
+ TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
+ ret = -2;
+ goto bail;
+ }
+ }
+ }
bail:
- va_end(ap);
- return ret;
+ va_end(ap);
+ return ret;
}
int tnet_stun_pkt_attr_remove(struct tnet_stun_pkt_s* p_self, enum tnet_stun_attr_type_e e_type)
{
- tsk_list_item_t* pc_item;
- tnet_stun_attr_t* pc_attr;
- if (!p_self || !p_self->p_list_attrs) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ tsk_list_item_t* pc_item;
+ tnet_stun_attr_t* pc_attr;
+ if (!p_self || !p_self->p_list_attrs) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
again:
- tsk_list_foreach(pc_item, p_self->p_list_attrs) {
- if ((pc_attr = (tnet_stun_attr_t*)pc_item->data)) {
- if (pc_attr->hdr.e_type == e_type) {
- tsk_list_remove_item(p_self->p_list_attrs, pc_item);
- goto again;
- }
- }
- }
- return 0;
+ tsk_list_foreach(pc_item, p_self->p_list_attrs) {
+ if ((pc_attr = (tnet_stun_attr_t*)pc_item->data)) {
+ if (pc_attr->hdr.e_type == e_type) {
+ tsk_list_remove_item(p_self->p_list_attrs, pc_item);
+ goto again;
+ }
+ }
+ }
+ return 0;
}
int tnet_stun_pkt_attr_find(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type, tsk_size_t u_index, const tnet_stun_attr_t** ppc_attr)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- if (!pc_self || !ppc_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *ppc_attr = tsk_null;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if (pc_attr->hdr.e_type == e_type && !u_index--) {
- *ppc_attr = pc_attr;
- break;
- }
- }
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ if (!pc_self || !ppc_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *ppc_attr = tsk_null;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if (pc_attr->hdr.e_type == e_type && !u_index--) {
+ *ppc_attr = pc_attr;
+ break;
+ }
+ }
+ }
+ return 0;
}
tsk_bool_t tnet_stun_pkt_attr_exists(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type)
{
- const tnet_stun_attr_t* pc_attr;
- int ret = tnet_stun_pkt_attr_find(pc_self, e_type, 0, &pc_attr);
- return (pc_attr && (ret == 0));
+ const tnet_stun_attr_t* pc_attr;
+ int ret = tnet_stun_pkt_attr_find(pc_self, e_type, 0, &pc_attr);
+ return (pc_attr && (ret == 0));
}
int tnet_stun_pkt_get_size_in_octetunits_without_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- if (!pc_self || !p_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *p_size = kStunPktHdrSizeInOctets;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
- return ret;
- }
- *p_size += n_size;
- }
- }
- if (pc_self->opt.fingerprint) {
- *p_size += kStunAttrHdrSizeInOctets + 4;
- }
- if (pc_self->opt.dontfrag) {
- *p_size += kStunAttrHdrSizeInOctets;
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ if (!pc_self || !p_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *p_size = kStunPktHdrSizeInOctets;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
+ return ret;
+ }
+ *p_size += n_size;
+ }
+ }
+ if (pc_self->opt.fingerprint) {
+ *p_size += kStunAttrHdrSizeInOctets + 4;
+ }
+ if (pc_self->opt.dontfrag) {
+ *p_size += kStunAttrHdrSizeInOctets;
+ }
+ return 0;
}
int tnet_stun_pkt_get_size_in_octetunits_with_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- if (!pc_self || !p_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *p_size = kStunPktHdrSizeInOctets;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
- return ret;
- }
- *p_size += n_size;
- }
- }
- if (pc_self->opt.fingerprint) {
- *p_size += kStunAttrHdrSizeInOctets + 4;
- }
- if (pc_self->opt.dontfrag) {
- *p_size += kStunAttrHdrSizeInOctets;
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ if (!pc_self || !p_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *p_size = kStunPktHdrSizeInOctets;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
+ return ret;
+ }
+ *p_size += n_size;
+ }
+ }
+ if (pc_self->opt.fingerprint) {
+ *p_size += kStunAttrHdrSizeInOctets + 4;
+ }
+ if (pc_self->opt.dontfrag) {
+ *p_size += kStunAttrHdrSizeInOctets;
+ }
+ return 0;
}
int tnet_stun_pkt_write_with_padding(const tnet_stun_pkt_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- uint8_t *_p_buff_ptr = p_buff_ptr, *_p_msg_int_start;
- if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
- return ret;
- }
- if ((n_buff_size < *p_written)) {
- TSK_DEBUG_ERROR("Buffer too short: %u<%u", (unsigned)n_buff_size, (unsigned)*p_written);
- return -1;
- }
-
- // write header
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
- *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(kStunMagicCookie);
- memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
-
- p_buff_ptr += kStunPktHdrSizeInOctets;
- n_buff_size -= kStunPktHdrSizeInOctets;
-
- // write attributes
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((pc_attr->hdr.e_type == tnet_stun_attr_type_message_integrity)) {
- continue; // because 'MESSAGE-INTEGRITY' must be the latest attribute
- }
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
- return ret;
- }
- p_buff_ptr += n_size;
- n_buff_size -= n_size;
- }
- }
-
- // DONT-FRAGMENT
- if (pc_self->opt.dontfrag && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_dont_fragment, &pc_attr) == 0 && !pc_attr) {
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_dont_fragment); // Type
- *((uint16_t*)&p_buff_ptr[2]) = 0; // Length
- p_buff_ptr += 4;
- }
-
- // MESSAGE-INTEGRITY
- if (!tsk_strnullORempty(pc_self->p_pwd) && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_message_integrity, &pc_attr) == 0 && pc_attr) {
- /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
- The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
-
- For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
- For short-term credentials ==> key = SASLprep(password)
- */
-
- tsk_sha1digest_t hmac;
- const tnet_stun_attr_vdata_t *pc_attr_username = tsk_null, *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
- static const uint16_t kMsgIntTotalLength = kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE;
- _p_msg_int_start = p_buff_ptr;
-
- // write attribute
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
- return ret;
- }
- p_buff_ptr += n_size;
- n_buff_size -= n_size;
-
- // Length (must be correct before computing message integrity)
- *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets));
-
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_username, (const tnet_stun_attr_t**)&pc_attr_username))) {
- return ret;
- }
- if (pc_attr_username) {
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm))) {
- return ret;
- }
- if (pc_attr_realm) {
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce))) {
- return ret;
- }
- }
- }
- if (pc_attr_username && pc_attr_realm && pc_attr_nonce) {
- // LONG-TERM
- char* p_keystr = tsk_null;
- tsk_md5digest_t md5;
- tsk_sprintf(&p_keystr, "%s:%s:%s", pc_attr_username->p_data_ptr, pc_attr_realm->p_data_ptr, pc_self->p_pwd);
- TSK_MD5_DIGEST_CALC(p_keystr, (tsk_size_t)tsk_strlen(p_keystr), md5);
- hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
- TSK_FREE(p_keystr);
- }
- else {
- // SHORT-TERM
- hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), pc_self->p_pwd, (tsk_size_t)tsk_strlen(pc_self->p_pwd), hmac);
- }
-
- // update MESSAGE-INTEGRITY attribute value
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, hmac, TSK_SHA1_DIGEST_SIZE))) {
- return ret;
- }
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, _p_msg_int_start, kMsgIntTotalLength, &n_size))) {
- return ret;
- }
- }
-
- // Length before computing FINGERPRINT
- *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets + ((pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) ? 8 : 0)));
-
- if (pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) {
- /* RFC 5389 - 15.5. FINGERPRINT
- The FINGERPRINT attribute MAY be present in all STUN messages. The
- value of the attribute is computed as the CRC-32 of the STUN message
- up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
- the 32-bit value 0x5354554e
- */
- uint32_t u_fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, _p_buff_ptr, (int32_t)(p_buff_ptr - _p_buff_ptr)) ^ kStunFingerprintXorConst;
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_fingerprint); // Type
- *((uint16_t*)&p_buff_ptr[2]) = tnet_htons(4); // Length
- *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(u_fingerprint);
- p_buff_ptr += 8;
- }
-
- *p_written = (tsk_size_t)(p_buff_ptr - _p_buff_ptr);
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ uint8_t *_p_buff_ptr = p_buff_ptr, *_p_msg_int_start;
+ if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
+ return ret;
+ }
+ if ((n_buff_size < *p_written)) {
+ TSK_DEBUG_ERROR("Buffer too short: %u<%u", (unsigned)n_buff_size, (unsigned)*p_written);
+ return -1;
+ }
+
+ // write header
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
+ *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(kStunMagicCookie);
+ memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
+
+ p_buff_ptr += kStunPktHdrSizeInOctets;
+ n_buff_size -= kStunPktHdrSizeInOctets;
+
+ // write attributes
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((pc_attr->hdr.e_type == tnet_stun_attr_type_message_integrity)) {
+ continue; // because 'MESSAGE-INTEGRITY' must be the latest attribute
+ }
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
+ return ret;
+ }
+ p_buff_ptr += n_size;
+ n_buff_size -= n_size;
+ }
+ }
+
+ // DONT-FRAGMENT
+ if (pc_self->opt.dontfrag && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_dont_fragment, &pc_attr) == 0 && !pc_attr) {
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_dont_fragment); // Type
+ *((uint16_t*)&p_buff_ptr[2]) = 0; // Length
+ p_buff_ptr += 4;
+ }
+
+ // MESSAGE-INTEGRITY
+ if (!tsk_strnullORempty(pc_self->p_pwd) && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_message_integrity, &pc_attr) == 0 && pc_attr) {
+ /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
+ The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
+
+ For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
+ For short-term credentials ==> key = SASLprep(password)
+ */
+
+ tsk_sha1digest_t hmac;
+ const tnet_stun_attr_vdata_t *pc_attr_username = tsk_null, *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
+ static const uint16_t kMsgIntTotalLength = kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE;
+ _p_msg_int_start = p_buff_ptr;
+
+ // write attribute
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
+ return ret;
+ }
+ p_buff_ptr += n_size;
+ n_buff_size -= n_size;
+
+ // Length (must be correct before computing message integrity)
+ *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets));
+
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_username, (const tnet_stun_attr_t**)&pc_attr_username))) {
+ return ret;
+ }
+ if (pc_attr_username) {
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm))) {
+ return ret;
+ }
+ if (pc_attr_realm) {
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce))) {
+ return ret;
+ }
+ }
+ }
+ if (pc_attr_username && pc_attr_realm && pc_attr_nonce) {
+ // LONG-TERM
+ char* p_keystr = tsk_null;
+ tsk_md5digest_t md5;
+ tsk_sprintf(&p_keystr, "%s:%s:%s", pc_attr_username->p_data_ptr, pc_attr_realm->p_data_ptr, pc_self->p_pwd);
+ TSK_MD5_DIGEST_CALC(p_keystr, (tsk_size_t)tsk_strlen(p_keystr), md5);
+ hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
+ TSK_FREE(p_keystr);
+ }
+ else {
+ // SHORT-TERM
+ hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), pc_self->p_pwd, (tsk_size_t)tsk_strlen(pc_self->p_pwd), hmac);
+ }
+
+ // update MESSAGE-INTEGRITY attribute value
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, hmac, TSK_SHA1_DIGEST_SIZE))) {
+ return ret;
+ }
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, _p_msg_int_start, kMsgIntTotalLength, &n_size))) {
+ return ret;
+ }
+ }
+
+ // Length before computing FINGERPRINT
+ *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets + ((pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) ? 8 : 0)));
+
+ if (pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) {
+ /* RFC 5389 - 15.5. FINGERPRINT
+ The FINGERPRINT attribute MAY be present in all STUN messages. The
+ value of the attribute is computed as the CRC-32 of the STUN message
+ up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
+ the 32-bit value 0x5354554e
+ */
+ uint32_t u_fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, _p_buff_ptr, (int32_t)(p_buff_ptr - _p_buff_ptr)) ^ kStunFingerprintXorConst;
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_fingerprint); // Type
+ *((uint16_t*)&p_buff_ptr[2]) = tnet_htons(4); // Length
+ *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(u_fingerprint);
+ p_buff_ptr += 8;
+ }
+
+ *p_written = (tsk_size_t)(p_buff_ptr - _p_buff_ptr);
+ return 0;
}
int tnet_stun_pkt_write_with_padding_2(const struct tnet_stun_pkt_s* pc_self, struct tsk_buffer_s** pp_buff)
{
- tsk_size_t u_buff_size;
- int ret;
- if (!pc_self || !pp_buff) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pp_buff = tsk_null;
- if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, &u_buff_size))) {
- goto bail;
- }
- u_buff_size += kStunBuffMinPad;
- if (!(*pp_buff = tsk_buffer_create(tsk_null, u_buff_size))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding(pc_self, (*pp_buff)->data, (*pp_buff)->size, &(*pp_buff)->size))) {
- goto bail;
- }
+ tsk_size_t u_buff_size;
+ int ret;
+ if (!pc_self || !pp_buff) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pp_buff = tsk_null;
+ if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, &u_buff_size))) {
+ goto bail;
+ }
+ u_buff_size += kStunBuffMinPad;
+ if (!(*pp_buff = tsk_buffer_create(tsk_null, u_buff_size))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_write_with_padding(pc_self, (*pp_buff)->data, (*pp_buff)->size, &(*pp_buff)->size))) {
+ goto bail;
+ }
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(*pp_buff);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(*pp_buff);
+ }
+ return ret;
}
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
{
- if (!pb_is_complete) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pb_is_complete = tsk_false;
- if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
- tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
- *pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
- }
- return 0;
+ if (!pb_is_complete) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pb_is_complete = tsk_false;
+ if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
+ tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
+ *pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
+ }
+ return 0;
}
int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet_stun_pkt_t** pp_pkt)
{
- tsk_bool_t b_is_complete;
- uint16_t PayloadLengthInOctets;
- tnet_stun_pkt_type_t Type;
- tnet_stun_transac_id_t transac_id;
- uint32_t MagicCookie;
- int ret;
-
- if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!TNET_STUN_BUFF_IS_STUN2(pc_buff_ptr, n_buff_size)) {
- TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
- return -2;
- }
- if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
- return ret;
- }
- if (!b_is_complete) {
- TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
- return -3;
- }
-
- // read the header
- Type = tnet_ntohs_2(&pc_buff_ptr[0]);
- PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
- MagicCookie = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
- if (MagicCookie != kStunMagicCookieLong) {
- TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie", MagicCookie);
- return -4;
- }
- memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
- // create the pkt
- if ((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, (const tnet_stun_transac_id_t*)&transac_id, pp_pkt))) {
- return ret;
- }
-
- if (PayloadLengthInOctets > 0) {
- tnet_stun_attr_t* p_attr;
- tsk_size_t n_consumed_octets;
- pc_buff_ptr += kStunPktHdrSizeInOctets;
- do {
- if ((ret = tnet_stun_attr_read((const tnet_stun_transac_id_t*)&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
- return ret;
- }
- if ((ret = tnet_stun_pkt_attr_add((*pp_pkt), &p_attr))) {
- TSK_OBJECT_SAFE_FREE((*pp_pkt));
- return ret;
- }
- PayloadLengthInOctets -= (uint16_t)n_consumed_octets;
- pc_buff_ptr += n_consumed_octets;
- } while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
- }
-
- return 0;
+ tsk_bool_t b_is_complete;
+ uint16_t PayloadLengthInOctets;
+ tnet_stun_pkt_type_t Type;
+ tnet_stun_transac_id_t transac_id;
+ uint32_t MagicCookie;
+ int ret;
+
+ if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!TNET_STUN_BUFF_IS_STUN2(pc_buff_ptr, n_buff_size)) {
+ TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
+ return -2;
+ }
+ if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
+ return ret;
+ }
+ if (!b_is_complete) {
+ TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
+ return -3;
+ }
+
+ // read the header
+ Type = tnet_ntohs_2(&pc_buff_ptr[0]);
+ PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
+ MagicCookie = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
+ if (MagicCookie != kStunMagicCookieLong) {
+ TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie", MagicCookie);
+ return -4;
+ }
+ memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
+ // create the pkt
+ if ((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, (const tnet_stun_transac_id_t*)&transac_id, pp_pkt))) {
+ return ret;
+ }
+
+ if (PayloadLengthInOctets > 0) {
+ tnet_stun_attr_t* p_attr;
+ tsk_size_t n_consumed_octets;
+ pc_buff_ptr += kStunPktHdrSizeInOctets;
+ do {
+ if ((ret = tnet_stun_attr_read((const tnet_stun_transac_id_t*)&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
+ return ret;
+ }
+ if ((ret = tnet_stun_pkt_attr_add((*pp_pkt), &p_attr))) {
+ TSK_OBJECT_SAFE_FREE((*pp_pkt));
+ return ret;
+ }
+ PayloadLengthInOctets -= (uint16_t)n_consumed_octets;
+ pc_buff_ptr += n_consumed_octets;
+ }
+ while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
+ }
+
+ return 0;
}
int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name, const char* pc_pwd, const char* pc_realm, const char* pc_nonce)
{
- const tnet_stun_attr_t* pc_attr;
- int ret;
- static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
- static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
- if (!p_self /*|| !pc_usr_name*/ || !pc_pwd /*|| !pc_realm || !pc_nonce*/) { // "username", "realm" and "nonce" are null for short-term authentication
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- // USERNAME
- if (pc_usr_name) { // LONG-TERM, optional for SHORT-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_usr_name, (uint16_t)tsk_strlen(pc_usr_name)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(pc_usr_name),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // REALM
- if (pc_realm) { // LONG-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_realm, (uint16_t)tsk_strlen(pc_realm)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_REALM_ZT(pc_realm),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // NONCE
- if (pc_nonce) { // LONG-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_nonce, (uint16_t)tsk_strlen(pc_nonce)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_NONCE_ZT(pc_nonce),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // MESSAGE-INTEGRITY
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
- goto bail;
- }
- if (!pc_attr) {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(__pc_sha1digestEmpty, __u_sha1digestEmpty),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
-
- // PASSWORD
- tsk_strupdate(&p_self->p_pwd, pc_pwd);
+ const tnet_stun_attr_t* pc_attr;
+ int ret;
+ static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
+ static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
+ if (!p_self /*|| !pc_usr_name*/ || !pc_pwd /*|| !pc_realm || !pc_nonce*/) { // "username", "realm" and "nonce" are null for short-term authentication
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ // USERNAME
+ if (pc_usr_name) { // LONG-TERM, optional for SHORT-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_usr_name, (uint16_t)tsk_strlen(pc_usr_name)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(pc_usr_name),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // REALM
+ if (pc_realm) { // LONG-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_realm, (uint16_t)tsk_strlen(pc_realm)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_REALM_ZT(pc_realm),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // NONCE
+ if (pc_nonce) { // LONG-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_nonce, (uint16_t)tsk_strlen(pc_nonce)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_NONCE_ZT(pc_nonce),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // MESSAGE-INTEGRITY
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr) {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(__pc_sha1digestEmpty, __u_sha1digestEmpty),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+
+ // PASSWORD
+ tsk_strupdate(&p_self->p_pwd, pc_pwd);
bail:
- return ret;
+ return ret;
}
// pc_resp = 401 or 438
int tnet_stun_pkt_auth_prepare_2(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_resp)
{
- const tnet_stun_attr_vdata_t* pc_attr;
- const char *pc_nonce, *pc_realm;
- int ret;
- if (!p_self || !pc_usr_name || !pc_pwd || !pc_resp) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- // NONCE
- if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
- TSK_DEBUG_ERROR("Invalid NONCE in 401");
- ret = -3;
- goto bail;
- }
- pc_nonce = (const char*)pc_attr->p_data_ptr;
- // REALM
- if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
- TSK_DEBUG_ERROR("Invalid REALM in 401");
- ret = -3;
- goto bail;
- }
- pc_realm = (const char*)pc_attr->p_data_ptr;
-
- if ((ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, pc_realm, pc_nonce))) {
- goto bail;
- }
-
- // TRANSACTION-ID
- if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
- goto bail;
- }
+ const tnet_stun_attr_vdata_t* pc_attr;
+ const char *pc_nonce, *pc_realm;
+ int ret;
+ if (!p_self || !pc_usr_name || !pc_pwd || !pc_resp) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ // NONCE
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
+ TSK_DEBUG_ERROR("Invalid NONCE in 401");
+ ret = -3;
+ goto bail;
+ }
+ pc_nonce = (const char*)pc_attr->p_data_ptr;
+ // REALM
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
+ TSK_DEBUG_ERROR("Invalid REALM in 401");
+ ret = -3;
+ goto bail;
+ }
+ pc_realm = (const char*)pc_attr->p_data_ptr;
+
+ if ((ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, pc_realm, pc_nonce))) {
+ goto bail;
+ }
+
+ // TRANSACTION-ID
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
+ goto bail;
+ }
bail:
- return ret;
+ return ret;
}
int tnet_stun_pkt_auth_copy(tnet_stun_pkt_t* p_self, const char* pc_usr_name, const char* pc_pwd, const tnet_stun_pkt_t* pc_pkt)
{
- const tnet_stun_attr_vdata_t *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
- int ret;
- tsk_bool_t b_ok;
- if (!p_self || !pc_pwd || !pc_usr_name || !pc_pkt) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- b_ok =
- (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm)) == 0 && pc_attr_realm
- && (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce)) == 0 && pc_attr_nonce;
-
- if (b_ok && (ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, (const char*)pc_attr_realm->p_data_ptr, (const char*)pc_attr_nonce->p_data_ptr))) {
- goto bail;
- }
+ const tnet_stun_attr_vdata_t *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
+ int ret;
+ tsk_bool_t b_ok;
+ if (!p_self || !pc_pwd || !pc_usr_name || !pc_pkt) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ b_ok =
+ (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm)) == 0 && pc_attr_realm
+ && (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce)) == 0 && pc_attr_nonce;
+
+ if (b_ok && (ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, (const char*)pc_attr_realm->p_data_ptr, (const char*)pc_attr_nonce->p_data_ptr))) {
+ goto bail;
+ }
bail:
- return ret;
+ return ret;
}
int tnet_stun_pkt_get_errorcode(const struct tnet_stun_pkt_s* pc_self, uint16_t* pu_code)
{
- const tnet_stun_attr_error_code_t* pc_attr;
- int ret;
- if (!pc_self && !pu_code) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pu_code = 0;
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr))) {
- return ret;
- }
- if (pc_attr) {
- *pu_code = (pc_attr->u_class * 100) + pc_attr->u_number;
- }
- return 0;
+ const tnet_stun_attr_error_code_t* pc_attr;
+ int ret;
+ if (!pc_self && !pu_code) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pu_code = 0;
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr))) {
+ return ret;
+ }
+ if (pc_attr) {
+ *pu_code = (pc_attr->u_class * 100) + pc_attr->u_number;
+ }
+ return 0;
}
int tnet_stun_pkt_process_err420(struct tnet_stun_pkt_s *p_self, const struct tnet_stun_pkt_s *pc_pkt_resp420)
{
- const tnet_stun_attr_vdata_t* pc_attr;
- uint16_t u16;
- int ret;
- tsk_bool_t b_done = tsk_false;
- if (!p_self || !pc_pkt_resp420) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
- TSK_DEBUG_ERROR("UNKNOWN-ATTRIBUTES missing in 420");
- ret = -3;
- goto bail;
- }
- for (u16 = 0; u16 < pc_attr->u_data_size; u16 += 2) {
- switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
- case tnet_stun_attr_type_dont_fragment: {
- p_self->opt.dontfrag = 0;
- b_done = tsk_true;
- break;
- }
- case tnet_stun_attr_type_fingerprint: {
- p_self->opt.fingerprint = 0;
- b_done = tsk_true;
- break;
- }
- }
- }
-
- if (b_done) {
- // TRANSACTION-ID
- if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
- goto bail;
- }
- }
+ const tnet_stun_attr_vdata_t* pc_attr;
+ uint16_t u16;
+ int ret;
+ tsk_bool_t b_done = tsk_false;
+ if (!p_self || !pc_pkt_resp420) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
+ TSK_DEBUG_ERROR("UNKNOWN-ATTRIBUTES missing in 420");
+ ret = -3;
+ goto bail;
+ }
+ for (u16 = 0; u16 < pc_attr->u_data_size; u16 += 2) {
+ switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
+ case tnet_stun_attr_type_dont_fragment: {
+ p_self->opt.dontfrag = 0;
+ b_done = tsk_true;
+ break;
+ }
+ case tnet_stun_attr_type_fingerprint: {
+ p_self->opt.fingerprint = 0;
+ b_done = tsk_true;
+ break;
+ }
+ }
+ }
+
+ if (b_done) {
+ // TRANSACTION-ID
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
+ goto bail;
+ }
+ }
bail:
- return ret;
+ return ret;
}
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
{
- tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
- if (p_pkt) {
- p_pkt->opt.fingerprint = kStunOptFingerPrint;
- p_pkt->opt.dontfrag = kStunOptDontFragment;
- }
- return self;
+ tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
+ if (p_pkt) {
+ p_pkt->opt.fingerprint = kStunOptFingerPrint;
+ p_pkt->opt.dontfrag = kStunOptDontFragment;
+ }
+ return self;
}
static tsk_object_t* tnet_stun_pkt_dtor(tsk_object_t * self)
{
- tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
- if (p_pkt) {
+ tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
+ if (p_pkt) {
#if PRINT_DESTROYED_MSG
- TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
+ TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
#endif
- TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
- TSK_FREE(p_pkt->p_pwd);
- }
- return self;
+ TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
+ TSK_FREE(p_pkt->p_pwd);
+ }
+ return self;
}
static const tsk_object_def_t tnet_stun_pkt_def_s = {
- sizeof(tnet_stun_pkt_t),
- tnet_stun_pkt_ctor,
- tnet_stun_pkt_dtor,
- tsk_null,
+ sizeof(tnet_stun_pkt_t),
+ tnet_stun_pkt_ctor,
+ tnet_stun_pkt_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_stun_pkt_def_t = &tnet_stun_pkt_def_s;
OpenPOWER on IntegriCloud