diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 84fd9742..157bd51d 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -1733,7 +1733,6 @@ ioa_socket_handle detach_ioa_socket(ioa_socket_handle s, int full_detach) ret->magic = SOCKET_MAGIC; - ret->username_hash = s->username_hash; ret->realm_hash = s->realm_hash; set_socket_ssl(ret,s->ssl); @@ -3342,14 +3341,9 @@ static u32bits string_hash(const u08bits *str) { return hash; } -int check_username_hash(ioa_socket_handle s, u08bits *username, u08bits *realm) +int check_realm_hash(ioa_socket_handle s, u08bits *realm) { if(s) { - if(username && username[0]) { - if(s->username_hash != string_hash(username)) { - return 0; - } - } if(realm && realm[0]) { if(s->realm_hash != string_hash(realm)) { return 0; @@ -3359,12 +3353,9 @@ int check_username_hash(ioa_socket_handle s, u08bits *username, u08bits *realm) return 1; } -void set_username_hash(ioa_socket_handle s, u08bits *username, u08bits *realm) +void set_realm_hash(ioa_socket_handle s, u08bits *realm) { if(s) { - if(username && username[0]) { - s->username_hash = string_hash(username); - } if(realm && realm[0]) { s->realm_hash = string_hash(realm); } diff --git a/src/apps/relay/ns_ioalib_impl.h b/src/apps/relay/ns_ioalib_impl.h index e31347f6..198e7d9a 100644 --- a/src/apps/relay/ns_ioalib_impl.h +++ b/src/apps/relay/ns_ioalib_impl.h @@ -214,7 +214,6 @@ struct _ioa_socket connect_cb conn_cb; void *conn_arg; //Transferable sockets user data - u32bits username_hash; u32bits realm_hash; //Accept: struct evconnlistener *list_ev; diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 3efc1f89..73bd096b 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -99,11 +99,12 @@ band_limit_t bps = 0; int dual_allocation = 0; int oauth = 0; -oauth_key okey; -oauth_token otoken; +oauth_key okey_array[2]; +oauth_token otoken_array[2]; -static oauth_key_data_raw okdr = { - "north","Y2FybGVvbg==",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-256-128","" +static oauth_key_data_raw okdr_array[2] = { + {"north","Y2FybGVvbg==",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-256-128",""}, + {"oldempire","YXVsY3Vz",0,0,"SHA-256","AEAD-AES-256-GCM","","",""} }; //////////////// local definitions ///////////////// @@ -225,13 +226,19 @@ int main(int argc, char **argv) exit(-1); } - oauth_key_data okd; - convert_oauth_key_data_raw(&okdr, &okd); + oauth_key_data okd_array[2]; + convert_oauth_key_data_raw(&okdr_array[0], &okd_array[0]); + convert_oauth_key_data_raw(&okdr_array[1], &okd_array[1]); char err_msg[1025] = "\0"; size_t err_msg_size = sizeof(err_msg) - 1; - if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { + if (convert_oauth_key_data(&okd_array[0], &okey_array[0], err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + exit(-1); + } + + if (convert_oauth_key_data(&okd_array[1], &okey_array[1], err_msg, err_msg_size) < 0) { fprintf(stderr, "%s\n", err_msg); exit(-1); } @@ -403,19 +410,25 @@ int main(int argc, char **argv) if(oauth) { - otoken.enc_block.lifetime = 0; - otoken.enc_block.timestamp = 0; + otoken_array[0].enc_block.lifetime = 0; + otoken_array[0].enc_block.timestamp = 0; + + otoken_array[1].enc_block.lifetime = 0; + otoken_array[1].enc_block.timestamp = 0; switch(shatype) { case SHATYPE_SHA256: - otoken.enc_block.key_length = 32; + otoken_array[0].enc_block.key_length = 32; + otoken_array[1].enc_block.key_length = 32; break; default: - otoken.enc_block.key_length = 20; + otoken_array[0].enc_block.key_length = 20; + otoken_array[1].enc_block.key_length = 20; break; }; - RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length); + RAND_bytes((unsigned char *)(otoken_array[0].enc_block.mac_key), otoken_array[0].enc_block.key_length); + RAND_bytes((unsigned char *)(otoken_array[1].enc_block.mac_key), otoken_array[1].enc_block.key_length); } if(g_use_auth_secret_with_timestamp) { diff --git a/src/apps/uclient/session.h b/src/apps/uclient/session.h index 7c078e5a..66a2d52b 100644 --- a/src/apps/uclient/session.h +++ b/src/apps/uclient/session.h @@ -85,6 +85,7 @@ typedef struct { u08bits server_name[STUN_MAX_SERVER_NAME_SIZE+1]; hmackey_t key; int key_set; + int cok; /* RFC 6062 */ app_tcp_conn_info **tcp_conn; size_t tcp_conn_number; diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index 0413285d..8412cb1a 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -1435,24 +1435,29 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) u16bits method = stun_get_method_str(message->buf, message->len); + int cok = clnet_info->cok; + if(((method == STUN_METHOD_ALLOCATE) || (method == STUN_METHOD_REFRESH)) || !(clnet_info->key_set)) { + if(!mobility) + cok=(++(clnet_info->cok))%2; + clnet_info->cok = cok; encoded_oauth_token etoken; u08bits nonce[12]; RAND_bytes((unsigned char*)nonce,12); - if(encode_oauth_token(clnet_info->server_name, &etoken, &okey, &otoken, nonce)<0) { + if(encode_oauth_token(clnet_info->server_name, &etoken, &(okey_array[cok]), &(otoken_array[cok]), nonce)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot encode token\n"); return -1; } stun_attr_add_str(message->buf, (size_t*)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN, (const u08bits*)etoken.token, (int)etoken.size); - ns_bcopy(otoken.enc_block.mac_key,clnet_info->key,otoken.enc_block.key_length); + ns_bcopy(otoken_array[cok].enc_block.mac_key,clnet_info->key,otoken_array[cok].enc_block.key_length); clnet_info->key_set = 1; } - if(stun_attr_add_integrity_by_key_str(message->buf, (size_t*)&(message->len), (u08bits*)okey.kid, + if(stun_attr_add_integrity_by_key_str(message->buf, (size_t*)&(message->len), (u08bits*)okey_array[cok].kid, clnet_info->realm, clnet_info->key, clnet_info->nonce, clnet_info->shatype)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); return -1; @@ -1488,7 +1493,9 @@ int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) hmackey_t key; st_password_t pwd; - ns_bcopy(otoken.enc_block.mac_key,key,otoken.enc_block.key_length); + int cok = clnet_info->cok; + + ns_bcopy(otoken_array[cok].enc_block.mac_key,key,otoken_array[cok].enc_block.key_length); return stun_check_message_integrity_by_key_str(get_turn_credentials_type(), message->buf, (size_t)(message->len), key, pwd, sht, NULL); diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index ffb20cbd..83e3a0be 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -87,8 +87,8 @@ extern int dual_allocation; extern char origin[STUN_MAX_ORIGIN_SIZE+1]; extern int oauth; -extern oauth_key okey; -extern oauth_token otoken; +extern oauth_key okey_array[2]; +extern oauth_token otoken_array[2]; #define is_TCP_relay() (relay_transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 1ca57230..f673ff2a 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -242,8 +242,8 @@ void set_do_not_use_df(ioa_socket_handle s); int ioa_socket_tobeclosed(ioa_socket_handle s); void set_ioa_socket_tobeclosed(ioa_socket_handle s); void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s); -int check_username_hash(ioa_socket_handle s, u08bits *username, u08bits *realm); -void set_username_hash(ioa_socket_handle s, u08bits *username, u08bits *realm); +int check_realm_hash(ioa_socket_handle s, u08bits *realm); +void set_realm_hash(ioa_socket_handle s, u08bits *realm); ////////////////// Base64 ///////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index aa1515ed..38f5269f 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -3264,7 +3264,7 @@ static int check_stun_auth(turn_turnserver *server, if(ss->oauth) { ss->hmackey_set = 0; STRCPY(ss->username,usname); - set_username_hash(ss->client_socket,ss->username,(u08bits*)ss->realm_options.name); + set_realm_hash(ss->client_socket,(u08bits*)ss->realm_options.name); } else { if(method == STUN_METHOD_ALLOCATE) { *err_code = 437; @@ -3278,7 +3278,7 @@ static int check_stun_auth(turn_turnserver *server, } } else { STRCPY(ss->username,usname); - set_username_hash(ss->client_socket,ss->username,(u08bits*)ss->realm_options.name); + set_realm_hash(ss->client_socket,(u08bits*)ss->realm_options.name); } if(server->ct != TURN_CREDENTIALS_SHORT_TERM) { @@ -4210,10 +4210,10 @@ static int create_relay_connection(turn_turnserver* server, ns_bzero(newelem, sizeof(relay_endpoint_session)); newelem->s = s; - if(!check_username_hash(newelem->s,ss->username,(u08bits*)ss->realm_options.name)) { + if(!check_realm_hash(newelem->s,(u08bits*)ss->realm_options.name)) { IOA_CLOSE_SOCKET(newelem->s); *err_code = 508; - *reason = (const u08bits *)"Cannot find a valid reserved socket for this username"; + *reason = (const u08bits *)"Cannot find a valid reserved socket for this realm"; return -1; } @@ -4251,11 +4251,11 @@ static int create_relay_connection(turn_turnserver* server, return -1; } - set_username_hash(newelem->s,ss->username,(u08bits*)ss->realm_options.name); + set_realm_hash(newelem->s,(u08bits*)ss->realm_options.name); if (rtcp_s) { if (out_reservation_token && *out_reservation_token) { - set_username_hash(rtcp_s,ss->username,(u08bits*)ss->realm_options.name); + set_realm_hash(rtcp_s,(u08bits*)ss->realm_options.name); /* OK */ } else { IOA_CLOSE_SOCKET(newelem->s);