From 1b82b7ca9731cf1ab29515b6bfa1a3c667dcb778 Mon Sep 17 00:00:00 2001 From: mom040267 Date: Thu, 25 Sep 2014 23:12:45 +0000 Subject: [PATCH] oauth --- ChangeLog | 6 +-- src/apps/relay/netengine.c | 3 +- src/apps/relay/userdb.c | 103 +++++++++++++++++++++++++++++++++++-- src/apps/relay/userdb.h | 2 +- src/client/ns_turn_msg.c | 2 +- 5 files changed, 106 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7fe493..e7bc1dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,15 @@ 08/22/2014 Oleg Moskalenko Version 4.2.1.1 'Monza': - oAuth security implementation. (TODO) + - TLS renegotiation DoS attack prevention implemented; + - FQDN as relay-ip and listener-ip parameters (issue 6) + (patch provided by Iñaki Baz Castillo); - redis user key operation fixed. - redis, mysql and psql db operations fixed. - SHA-256 memory leak fixed. - Mobility ticket retransmission fixed. - Move debian package from SVN to GIT. - Move secondary download area to coturn.net. - - TLS renegotiation DoS attack prevention implemented; - - FQDN as relay-ip and listener-ip parameters (issue 6) - (patch provided by Iñaki Baz Castillo); 08/14/2014 Oleg Moskalenko Version 4.1.2.1 'Vitari': diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index b48e4dd..52312de 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -378,6 +378,7 @@ static void auth_server_receive_message(struct bufferevent *bev, void *ptr) if(am.ct == TURN_CREDENTIALS_SHORT_TERM) { st_password_t pwd; + am.oauth = 0; if(get_user_pwd(am.username,pwd)<0) { am.success = 0; } else { @@ -386,7 +387,7 @@ static void auth_server_receive_message(struct bufferevent *bev, void *ptr) } } else { hmackey_t key; - if(get_user_key(&(am.oauth),am.username,am.realm,key,am.in_buffer.nbh)<0) { + if(get_user_key(am.oauth,&(am.oauth),am.username,am.realm,key,am.in_buffer.nbh)<0) { am.success = 0; } else { ns_bcopy(key,am.key,sizeof(hmackey_t)); diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 6b62946..6d0025c 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -398,12 +398,107 @@ static char *get_real_username(char *usname) /* * Password retrieval */ -int get_user_key(int *oauth, u08bits *usname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh) +int get_user_key(int in_oauth, int *out_oauth, u08bits *usname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh) { - UNUSED_ARG(oauth); - int ret = -1; + if(in_oauth && out_oauth && usname && usname[0] && realm && realm[0]) { + + *out_oauth = 0; + + stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh), + ioa_network_buffer_get_size(nbh), + STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN); + if(sar) { + + int len = stun_attr_get_len(sar); + const u08bits *value = stun_attr_get_value(sar); + + *out_oauth = 1; + + if(len>0 && value) { + + turn_dbdriver_t * dbd = get_dbdriver(); + + if (dbd && dbd->get_oauth_key) { + + oauth_key_data_raw rawKey; + ns_bzero(&rawKey,sizeof(rawKey)); + + int gres = (*(dbd->get_oauth_key))(usname,&rawKey); + if(gres<0) + return ret; + + oauth_key_data okd; + ns_bzero(&okd,sizeof(okd)); + + convert_oauth_key_data_raw(&rawKey, &okd); + + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; + + oauth_key okey; + ns_bzero(&okey,sizeof(okey)); + + if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg); + return -1; + } + + oauth_token dot; + ns_bzero((&dot),sizeof(dot)); + + encoded_oauth_token etoken; + ns_bzero(&etoken,sizeof(etoken)); + + if((size_t)len > sizeof(etoken.token)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Encoded oAuth token is too large\n"); + return -1; + } + ns_bcopy(value,etoken.token,(size_t)len); + etoken.size = (size_t)len; + + if (decode_oauth_token((const u08bits *) turn_params.oauth_server_name, &etoken,&okey, &dot) < 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n"); + return -1; + } + + switch(dot.enc_block.key_length) { + case SHA1SIZEBYTES: + if(turn_params.shatype != SHATYPE_SHA1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(1): %d\n",(int)dot.enc_block.key_length); + return -1; + } + break; + case SHA256SIZEBYTES: + if(turn_params.shatype != SHATYPE_SHA256) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(2): %d\n",(int)dot.enc_block.key_length); + return -1; + } + break; + default: + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length); + return -1; + }; + + st_password_t pwdtmp; + if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, + ioa_network_buffer_data(nbh), + ioa_network_buffer_get_size(nbh), + dot.enc_block.mac_key, + pwdtmp, + turn_params.shatype,NULL)>0) { + ns_bcopy(dot.enc_block.mac_key,&key,dot.enc_block.key_length); + ret = 0; + } + } + } + } + } + + if(out_oauth && *out_oauth) + return ret; + if(turn_params.use_auth_secret_with_timestamp) { turn_time_t ctime = (turn_time_t) time(NULL); @@ -510,7 +605,7 @@ int get_user_key(int *oauth, u08bits *usname, u08bits *realm, hmackey_t key, ioa turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->get_user_key) { - ret = (*dbd->get_user_key)(usname, realm, key); + ret = (*(dbd->get_user_key))(usname, realm, key); } return ret; diff --git a/src/apps/relay/userdb.h b/src/apps/relay/userdb.h index 80fe4b0..784835b 100644 --- a/src/apps/relay/userdb.h +++ b/src/apps/relay/userdb.h @@ -188,7 +188,7 @@ void add_to_secrets_list(secrets_list_t *sl, const char* elem); /////////// USER DB CHECK ////////////////// -int get_user_key(int *oauth, u08bits *uname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh); +int get_user_key(int in_oauth, int *out_oauth, u08bits *uname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh); int get_user_pwd(u08bits *uname, st_password_t pwd); u08bits *start_user_check(turnserver_id id, turn_credential_type ct, int oauth, u08bits *uname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply); int check_new_allocation_quota(u08bits *username, u08bits *realm); diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index 25f8825..cdac678 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -1550,7 +1550,7 @@ int stun_check_message_integrity_by_key_str(turn_credential_type ct, u08bits *bu if(bcmp(old_hmac,new_hmac,shasize)) return 0; - return 1; + return +1; } /*