diff --git a/README.turnserver b/README.turnserver index 2308e320..cb339a2a 100644 --- a/README.turnserver +++ b/README.turnserver @@ -423,9 +423,9 @@ Options with required values: that other mode is dynamic. Multiple shared secrets can be used (both in the database and in the "static" fashion). ---server-name Server name used (when necessary) for - the authentication purposes (oauth). - The default value is the FQDN of the host. +--server-name Server name used for + the oAuth authentication purposes. + The default value is the realm name. --cert Certificate file, PEM format. Same file search rules applied as for the configuration diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index f52b8e47..0d1aef0b 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -210,9 +210,9 @@ # #static-auth-secret=north -# Server name used (when necessary) for -# the authentication purposes (oauth). -# The default value is the FQDN of the host. +# Server name used for +# the oAuth authentication purposes. +# The default value is the realm name. # #server-name=blackdow.carleon.gov diff --git a/examples/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh b/examples/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh index c5b959fd..fd793c72 100755 --- a/examples/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh +++ b/examples/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh @@ -31,4 +31,4 @@ fi export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/ export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/ -PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --server-name="blackdow.carleon.gov" -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --mongo-userdb="mongodb://localhost/coturn" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 --oauth $@ +PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --mongo-userdb="mongodb://localhost/coturn" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 --oauth $@ diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 2b020eea..e47caf77 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 September 2014" "" "" +.TH TURN 1 "28 September 2014" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index ca18f0d4..cd6d82f7 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 September 2014" "" "" +.TH TURN 1 "28 September 2014" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -617,9 +617,9 @@ that other mode is dynamic. Multiple shared secrets can be used .TP .B \fB\-\-server\-name\fP -Server name used (when necessary) for -the authentication purposes (oauth). -The default value is the FQDN of the host. +Server name used for +the oAuth authentication purposes. +The default value is the realm name. .TP .B \fB\-\-cert\fP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 179fbf7c..ec39407f 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "26 September 2014" "" "" +.TH TURN 1 "28 September 2014" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 39c8bb08..e0c5e432 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -464,9 +464,9 @@ static char Usage[] = "Usage: turnserver [options]\n" " That database value can be changed on-the-fly\n" " by a separate program, so this is why it is 'dynamic'.\n" " Multiple shared secrets can be used (both in the database and in the \"static\" fashion).\n" -" --server-name Server name used (when necessary) for\n" -" the authentication purposes (oauth).\n" -" The default value is the FQDN of the host.\n" +" --server-name Server name used for\n" +" the oAuth authentication purposes.\n" +" The default value is the realm name.\n" " --oauth Support oAuth authentication.\n" " -n Do not use configuration file, take all parameters from the command line only.\n" " --cert Certificate file, PEM format. Same file search rules\n" @@ -1698,34 +1698,6 @@ static void drop_privileges(void) } } -static void init_oauth_server_name(void) { - - if(!turn_params.oauth_server_name[0]) { - - struct utsname name; - - if(uname(&name)>=0) { - STRCPY(turn_params.oauth_server_name,name.nodename); - } - if(!turn_params.oauth_server_name[0]) { - STRCPY(turn_params.oauth_server_name,"coturn"); - } - - size_t slen = strlen(turn_params.oauth_server_name); - - if(get_realm(NULL)->options.name[0]) { - turn_params.oauth_server_name[slen]='.'; - ns_bcopy(get_realm(NULL)->options.name,turn_params.oauth_server_name+slen+1,strlen(get_realm(NULL)->options.name)+1); - } else { - size_t dlen = strlen(turn_params.domain); - if(dlen>0 && turn_params.domain[0] != '(') { - turn_params.oauth_server_name[slen]='.'; - ns_bcopy(turn_params.domain,turn_params.oauth_server_name+slen+1,strlen(turn_params.domain)+1); - } - } - } -} - static void init_domain(void) { #if !defined(TURN_NO_GETDOMAINNAME) @@ -1841,10 +1813,9 @@ int main(int argc, char **argv) STRCPY(get_realm(NULL)->options.name,turn_params.domain); } - init_oauth_server_name(); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); - if(turn_params.oauth) { + if(turn_params.oauth && turn_params.oauth_server_name[0]) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); } diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index a73bd589..795b724d 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1804,23 +1804,4 @@ void init_listener(void) ns_bzero(&turn_params.listener,sizeof(struct listener_server)); } -void get_oauth_server_name(const char* realm, char *server_name, size_t server_name_size) -{ - if(server_name && server_name_size) { - strncpy(server_name,turn_params.oauth_server_name,server_name_size); - if(realm && realm[0]) { - char* sat = strstr(server_name,"@"); - if(sat) { - *sat = 0; - } - size_t snl = strlen(server_name); - size_t rl = strlen(realm); - if(snl+1+rlstatus.alloc_counters); if (rp->options.perf_options.total_quota && (rp->status.total_current_allocs >= rp->options.perf_options.total_quota)) { @@ -712,17 +717,19 @@ int check_new_allocation_quota(u08bits *user, u08bits *realm) return ret; } -void release_allocation_quota(u08bits *user, u08bits *realm) +void release_allocation_quota(u08bits *user, int oauth, u08bits *realm) { if (user) { - u08bits *username = (u08bits*)get_real_username((char*)user); + u08bits *username = oauth ? (u08bits*)strdup("") : (u08bits*)get_real_username((char*)user); realm_params_t *rp = get_realm((char*)realm); ur_string_map_lock(rp->status.alloc_counters); - ur_string_map_value_type value = 0; - ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value); - if (value) { - value = (ur_string_map_value_type)(((size_t)value) - 1); - ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value); + if(username[0]) { + ur_string_map_value_type value = 0; + ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value); + if (value) { + value = (ur_string_map_value_type)(((size_t)value) - 1); + ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value); + } } if (rp->status.total_current_allocs) --(rp->status.total_current_allocs); diff --git a/src/apps/relay/userdb.h b/src/apps/relay/userdb.h index 036ea4f0..6e5b96fb 100644 --- a/src/apps/relay/userdb.h +++ b/src/apps/relay/userdb.h @@ -193,8 +193,8 @@ void add_to_secrets_list(secrets_list_t *sl, const char* elem); int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, 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 in_oauth, int *out_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); -void release_allocation_quota(u08bits *username, u08bits *realm); +int check_new_allocation_quota(u08bits *username, int oauth, u08bits *realm); +void release_allocation_quota(u08bits *username, int oauth, u08bits *realm); /////////// Handle user DB ///////////////// diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index f673ff2a..3a29e8dd 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -265,8 +265,6 @@ void get_realm_options_by_name(char *realm, realm_options_t* ro); int get_canonic_origin(const char* o, char *co, int sz); int get_default_protocol_port(const char* scheme, size_t slen); -void get_oauth_server_name(const char* realm, char *server_name, size_t server_name_size); - /////////////////////////////////////// #ifdef __cplusplus diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index e60d66b8..7e3eaf6f 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -155,7 +155,7 @@ static int inc_quota(ts_ur_super_session* ss, u08bits *username) } } - if((((turn_turnserver*)ss->server)->chquotacb)(username, (u08bits*)ss->realm_options.name)<0) { + if((((turn_turnserver*)ss->server)->chquotacb)(username, ss->oauth, (u08bits*)ss->realm_options.name)<0) { return -1; @@ -183,7 +183,7 @@ static void dec_quota(ts_ur_super_session* ss) ss->bps = 0; } - (((turn_turnserver*)ss->server)->raqcb)(ss->username, (u08bits*)ss->realm_options.name); + (((turn_turnserver*)ss->server)->raqcb)(ss->username, ss->oauth, (u08bits*)ss->realm_options.name); } } @@ -1281,8 +1281,6 @@ static int handle_turn_allocate(turn_turnserver *server, if (*err_code) { - dec_quota(ss); - if(!(*reason)) { *reason = (const u08bits *)"Cannot create relay endpoint(s)"; } @@ -1364,6 +1362,22 @@ static int handle_turn_allocate(turn_turnserver *server, return 0; } +static void copy_auth_parameters(ts_ur_super_session *orig_ss, ts_ur_super_session *ss) { + if(orig_ss && ss) { + ns_bcopy(orig_ss->nonce,ss->nonce,sizeof(ss->nonce)); + ss->nonce_expiration_time = orig_ss->nonce_expiration_time; + ns_bcopy(&(orig_ss->realm_options),&(ss->realm_options),sizeof(ss->realm_options)); + ns_bcopy(orig_ss->username,ss->username,sizeof(ss->username)); + ss->hmackey_set = orig_ss->hmackey_set; + ns_bcopy(orig_ss->hmackey,ss->hmackey,sizeof(ss->hmackey)); + ss->oauth = orig_ss->oauth; + ns_bcopy(orig_ss->origin,ss->origin,sizeof(ss->origin)); + ss->origin_set = orig_ss->origin_set; + ns_bcopy(orig_ss->pwd,ss->pwd,sizeof(ss->pwd)); + ss->max_session_time_auth = orig_ss->max_session_time_auth; + } +} + static int handle_turn_refresh(turn_turnserver *server, ts_ur_super_session *ss, stun_tid *tid, int *resp_constructed, int *err_code, const u08bits **reason, u16bits *unknown_attrs, u16bits *ua_num, @@ -1550,17 +1564,7 @@ static int handle_turn_refresh(turn_turnserver *server, int postpone_reply = 0; if(!(ss->hmackey_set)) { - ns_bcopy(orig_ss->nonce,ss->nonce,sizeof(ss->nonce)); - ss->nonce_expiration_time = orig_ss->nonce_expiration_time; - ns_bcopy(&(orig_ss->realm_options),&(ss->realm_options),sizeof(ss->realm_options)); - ns_bcopy(orig_ss->username,ss->username,sizeof(ss->username)); - ss->hmackey_set = orig_ss->hmackey_set; - ns_bcopy(orig_ss->hmackey,ss->hmackey,sizeof(ss->hmackey)); - ss->oauth = orig_ss->oauth; - ns_bcopy(orig_ss->origin,ss->origin,sizeof(ss->origin)); - ss->origin_set = orig_ss->origin_set; - ns_bcopy(orig_ss->pwd,ss->pwd,sizeof(ss->pwd)); - ss->max_session_time_auth = orig_ss->max_session_time_auth; + copy_auth_parameters(orig_ss,ss); } if(check_stun_auth(server, ss, tid, resp_constructed, err_code, reason, in_buffer, nbh, @@ -1600,11 +1604,6 @@ static int handle_turn_refresh(turn_turnserver *server, *reason = (const u08bits *)"Cannot refresh relay connection (internal error)"; } - } else if(!to_delete && orig_ss && (inc_quota(orig_ss, orig_ss->username)<0)) { - - *err_code = 486; - *reason = (const u08bits *)"Allocation Quota Reached"; - } else { //Transfer socket: @@ -1614,16 +1613,18 @@ static int handle_turn_refresh(turn_turnserver *server, ss->to_be_closed = 1; if(!s) { - dec_quota(orig_ss); *err_code = 500; } else { if(attach_socket_to_session(server, s, orig_ss) < 0) { IOA_CLOSE_SOCKET(s); *err_code = 500; - dec_quota(orig_ss); } else { + if(ss->hmackey_set) { + copy_auth_parameters(ss,orig_ss); + } + delete_session_from_mobile_map(ss); delete_session_from_mobile_map(orig_ss); put_session_into_mobile_map(orig_ss); @@ -1663,7 +1664,6 @@ static int handle_turn_refresh(turn_turnserver *server, if ((server->fingerprint) || ss->enforce_fingerprints) { if (stun_attr_add_fingerprint_str(ioa_network_buffer_data(nbh), &len) < 0) { - dec_quota(ss); *err_code = 500; ioa_network_buffer_delete(server->e, nbh); return -1; @@ -3099,11 +3099,15 @@ static int create_challenge_response(ts_ur_super_session *ss, stun_tid *tid, int if(ss->server) { turn_turnserver* server = (turn_turnserver*)ss->server; - if(server->oauth && (server->oauth_server_name)&&(server->oauth_server_name[0])) { - stun_attr_add_str(ioa_network_buffer_data(nbh), &len, + if(server->oauth) { + const char *server_name = server->oauth_server_name; + if(!(server_name && server_name[0])) { + server_name = realm; + } + stun_attr_add_str(ioa_network_buffer_data(nbh), &len, STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION, - (const u08bits*)(server->oauth_server_name), - strlen(server->oauth_server_name)); + (const u08bits*)(server_name), + strlen(server_name)); } } @@ -3286,7 +3290,6 @@ static int check_stun_auth(turn_turnserver *server, if(ss->oauth) { ss->hmackey_set = 0; STRCPY(ss->username,usname); - set_realm_hash(ss->client_socket,(u08bits*)ss->realm_options.name); } else { if(method == STUN_METHOD_ALLOCATE) { *err_code = 437; diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 91ac0136..3506e617 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -92,8 +92,8 @@ typedef struct _turn_turnserver turn_turnserver; typedef void (*get_username_resume_cb)(int success, int oauth, int max_session_time, hmackey_t hmackey, st_password_t pwd, turn_turnserver *server, u64bits ctxkey, ioa_net_data *in_buffer); typedef u08bits *(*get_user_key_cb)(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, u08bits *uname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply); -typedef int (*check_new_allocation_quota_cb)(u08bits *username, u08bits *realm); -typedef void (*release_allocation_quota_cb)(u08bits *username, u08bits *realm); +typedef int (*check_new_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm); +typedef void (*release_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm); typedef int (*send_socket_to_relay_cb)(turnserver_id id, u64bits cid, stun_tid *tid, ioa_socket_handle s, int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd, int can_resume); typedef int (*send_turn_session_info_cb)(struct turn_session_info *tsi);