int read_mobility_ticket(app_ur_conn_info *clnet_info, stun_buffer *message) { int ret = 0; if(clnet_info && message) { stun_attr_ref s_mobile_id_sar = stun_attr_get_first_by_type(message, STUN_ATTRIBUTE_MOBILITY_TICKET); if(s_mobile_id_sar) { int smid_len = stun_attr_get_len(s_mobile_id_sar); if(smid_len>0 && (((size_t)smid_len)<sizeof(clnet_info->s_mobile_id))) { const u08bits* smid_val = stun_attr_get_value(s_mobile_id_sar); if(smid_val) { ns_bcopy(smid_val, clnet_info->s_mobile_id, (size_t)smid_len); clnet_info->s_mobile_id[smid_len] = 0; if (clnet_verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: smid=%s\n", __FUNCTION__, clnet_info->s_mobile_id); } } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: smid_len=%d\n", __FUNCTION__, smid_len); ret = -1; } } } return ret; }
static int pgsql_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) { int ret = -1; PGconn * pqc = get_pqdb_connection(); if(pqc) { char statement[TURN_LONG_STRING_SIZE]; /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ snprintf(statement,sizeof(statement),"select hmackey from turnusers_lt where name='%s' and realm='%s'",usname,realm); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res)!=1)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { char *kval = PQgetvalue(res,0,0); int len = PQgetlength(res,0,0); if(kval) { size_t sz = get_hmackey_size(SHATYPE_DEFAULT); if(((size_t)len<sz*2)||(strlen(kval)<sz*2)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s, user %s\n",kval,usname); } else if(convert_string_key_to_binary(kval, key, sz)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n",kval,usname); } else { ret = 0; } } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong hmackey data for user %s: NULL\n",usname); } } if(res) PQclear(res); } return ret; }
void addr_debug_print(int verbose, const ioa_addr *addr, const s08bits* s) { if (verbose) { if (!addr) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: EMPTY\n", s); } else { s08bits addrbuf[INET6_ADDRSTRLEN]; if (!s) s = ""; if (addr->ss.sa_family == AF_INET) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv4. %s: %s:%d\n", s, inet_ntop(AF_INET, &addr->s4.sin_addr, addrbuf, INET6_ADDRSTRLEN), nswap16(addr->s4.sin_port)); } else if (addr->ss.sa_family == AF_INET6) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv6. %s: %s:%d\n", s, inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrbuf, INET6_ADDRSTRLEN), nswap16(addr->s6.sin6_port)); } else { if (addr_any_no_port(addr)) { TURN_LOG_FUNC( TURN_LOG_LEVEL_INFO, "IP. %s: 0.0.0.0:%d\n", s, nswap16(addr->s4.sin_port)); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrong IP address family: %d\n", s, (int) (addr->ss.sa_family)); } } } } }
static int create_server_listener(tls_listener_relay_server_type* server) { FUNCSTART; if(!server) return -1; evutil_socket_t tls_listen_fd = -1; tls_listen_fd = socket(server->addr.ss.ss_family, SOCK_STREAM, 0); if (tls_listen_fd < 0) { perror("socket"); return -1; } if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); } if(addr_bind(tls_listen_fd,&server->addr)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr); socket_closesocket(tls_listen_fd); return -1; } socket_tcp_set_keepalive(tls_listen_fd); socket_set_nonblocking(tls_listen_fd); server->l = evconnlistener_new(server->e->event_base, server_input_handler, server, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, tls_listen_fd); if(!(server->l)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create TLS listener\n"); socket_closesocket(tls_listen_fd); return -1; } if(addr_get_from_sock(tls_listen_fd, &(server->addr))) { perror("Cannot get local socket addr"); socket_closesocket(tls_listen_fd); return -1; } if(!no_tcp && !no_tls) addr_debug_print(server->verbose, &server->addr,"TCP/TLS listener opened on "); else if(!no_tls) addr_debug_print(server->verbose, &server->addr,"TLS listener opened on "); else if(!no_tcp) addr_debug_print(server->verbose, &server->addr,"TCP listener opened on "); FUNCEND; return 0; }
static int create_server_socket(dtls_listener_relay_server_type* server) { FUNCSTART; if(!server) return -1; clean_server(server); ioa_socket_raw udp_listen_fd = -1; udp_listen_fd = socket(server->addr.ss.ss_family, SOCK_DGRAM, 0); if (udp_listen_fd < 0) { perror("socket"); return -1; } server->udp_listen_s = create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr)); server->udp_listen_s->listener_server = server; set_sock_buf_size(udp_listen_fd,UR_SERVER_SOCK_BUF_SIZE); if(sock_bind_to_device(udp_listen_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); } if(addr_bind(udp_listen_fd,&server->addr)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind UDP/DTLS listener socket to addr %s\n",saddr); return -1; } server->udp_listen_ev = event_new(server->e->event_base,udp_listen_fd, EV_READ|EV_PERSIST,udp_server_input_handler,server); event_add(server->udp_listen_ev,NULL); if(addr_get_from_sock(udp_listen_fd, &(server->addr))) { perror("Cannot get local socket addr"); return -1; } if(!no_udp && !no_dtls) addr_debug_print(server->verbose, &server->addr,"UDP/DTLS listener opened on "); else if(!no_dtls) addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on "); else if(!no_udp) addr_debug_print(server->verbose, &server->addr,"UDP listener opened on "); FUNCEND; return 0; }
static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *arg) { UNUSED_ARG(l); tcp_listener_relay_server_type * server = (tcp_listener_relay_server_type*) arg; if(!(server->e->connect_cb)) { close(fd); return; } FUNCSTART; if (!server) return; if (server->stats) ++(*(server->stats)); ioa_addr client_addr; ns_bcopy(sa,&client_addr,socklen); addr_debug_print(server->verbose, &client_addr,"tcp connected to"); ioa_socket_handle ioas = create_ioa_socket_from_fd( server->e, fd, TCP_SOCKET, CLIENT_SOCKET, &client_addr, &(server->addr)); if (ioas) { ioa_net_data nd = { &client_addr, NULL, 0, TTL_IGNORE, TOS_IGNORE }; int rc = server->e->connect_cb(server->e, ioas, &nd); if (rc < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create tcp session\n"); IOA_CLOSE_SOCKET(ioas); } } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from FD\n"); close(fd); } FUNCEND ; }
static PGconn *get_pqdb_connection(void) { persistent_users_db_t *pud = get_persistent_users_db(); PGconn *pqdbconnection = (PGconn*)pthread_getspecific(connection_key); if(pqdbconnection) { ConnStatusType status = PQstatus(pqdbconnection); if(status != CONNECTION_OK) { PQfinish(pqdbconnection); pqdbconnection = NULL; (void) pthread_setspecific(connection_key, pqdbconnection); } } if(!pqdbconnection) { char *errmsg=NULL; PQconninfoOption *co = PQconninfoParse(pud->userdb, &errmsg); if(!co) { if(errmsg) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection <%s>, connection string format error: %s\n",pud->userdb,errmsg); turn_free(errmsg,strlen(errmsg)+1); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, unknown connection string format error\n",pud->userdb); } } else { PQconninfoFree(co); if(errmsg) turn_free(errmsg,strlen(errmsg)+1); pqdbconnection = PQconnectdb(pud->userdb); if(!pqdbconnection) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",pud->userdb); } else { ConnStatusType status = PQstatus(pqdbconnection); if(status != CONNECTION_OK) { PQfinish(pqdbconnection); pqdbconnection = NULL; TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",pud->userdb); } else if(!donot_print_connection_success){ TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL DB connection success: %s\n",pud->userdb); donot_print_connection_success = 1; } } } if(pqdbconnection) { (void) pthread_setspecific(connection_key, pqdbconnection); } } return pqdbconnection; }
static int mongo_set_user_key(u08bits *usname, u08bits *realm, const char *key) { mongoc_collection_t * collection = mongo_get_collection("turnusers_lt"); if(!collection) return -1; bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "name", (const char *)usname); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); bson_t doc; bson_init(&doc); BSON_APPEND_UTF8(&doc, "name", (const char *)usname); BSON_APPEND_UTF8(&doc, "realm", (const char *)realm); BSON_APPEND_UTF8(&doc, "hmackey", (const char *)key); int ret = -1; if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information\n"); } else { ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&doc); bson_destroy(&query); return ret; }
static int init_server(tls_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, ioa_engine_new_connection_event_handler send_socket, struct relay_server *relay_server) { if(!server) return -1; server->connect_cb = send_socket; server->relay_server = relay_server; if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a TCP/TLS listener for address: %s\n",local_address); return -1; } server->verbose=verbose; server->e = e; return create_server_listener(server); }
static int mongo_set_oauth_key(oauth_key_data_raw *key) { mongoc_collection_t * collection = mongo_get_collection("oauth_key"); if(!collection) return -1; bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "kid", (const char *)key->kid); bson_t doc; bson_init(&doc); BSON_APPEND_UTF8(&doc, "kid", (const char *)key->kid); BSON_APPEND_UTF8(&doc, "as_rs_alg", (const char *)key->as_rs_alg); BSON_APPEND_UTF8(&doc, "ikm_key", (const char *)key->ikm_key); BSON_APPEND_INT64(&doc, "timestamp", (int64_t)key->timestamp); BSON_APPEND_INT32(&doc, "lifetime", (int32_t)key->lifetime); int ret = -1; if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information\n"); } else { ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&doc); bson_destroy(&query); return ret; }
static ioa_socket_handle dtls_accept_client_connection( dtls_listener_relay_server_type* server, SSL *ssl, ioa_addr *remote_addr, ioa_addr *local_addr, u08bits *s, int len) { FUNCSTART; if (!ssl) return NULL; int rc = ssl_read(server->udp_listen_s->fd, ssl, (s08bits*)s, ioa_network_buffer_get_capacity(), server->verbose, &len); if (rc < 0) return NULL; addr_debug_print(server->verbose, remote_addr, "Accepted connection from"); ioa_socket_handle ioas = create_ioa_socket_from_ssl(server->e, server->udp_listen_s, ssl, DTLS_SOCKET, CLIENT_SOCKET, remote_addr, local_addr); if(ioas) { ioas->listener_server = server; addr_cpy(&(server->sm.m.sm.nd.src_addr),remote_addr); server->sm.m.sm.nd.recv_ttl = TTL_IGNORE; server->sm.m.sm.nd.recv_tos = TOS_IGNORE; server->sm.m.sm.s = ioas; } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from SSL\n"); } FUNCEND ; return ioas; }
static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; /* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */ snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'",(const char*)kid); PGconn * pqc = get_pqdb_connection(); if(pqc) { PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res)!=1)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { STRCPY(key->ikm_key,PQgetvalue(res,0,0)); key->timestamp = (u64bits)strtoll(PQgetvalue(res,0,1),NULL,10); key->lifetime = (u32bits)strtol(PQgetvalue(res,0,2),NULL,10); STRCPY(key->as_rs_alg,PQgetvalue(res,0,3)); STRCPY(key->realm,PQgetvalue(res,0,4)); STRCPY(key->kid,kid); ret = 0; } if(res) { PQclear(res); } } return ret; }
void delete_tcp_connection(tcp_connection *tc) { if(tc) { if(tc->done) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed tcp data connection: 0x%lx\n",__FUNCTION__); return; } tc->done = 1; IOA_EVENT_DEL(tc->peer_conn_timeout); IOA_EVENT_DEL(tc->conn_bind_timeout); allocation *a = (allocation*)(tc->owner); if(a) { ur_map *map = a->tcp_connections; if(map) { ur_map_del(map, (ur_map_key_type)(tc->id),NULL); } tcp_connection_list *tcl = &(a->tcl); while(tcl->next) { if((void*)(tcl->next) == (void*)tc) { tcl->next = tc->list.next; break; } else { tcl=tcl->next; } } } set_ioa_socket_sub_session(tc->client_s,NULL); IOA_CLOSE_SOCKET(tc->client_s); set_ioa_socket_sub_session(tc->peer_s,NULL); IOA_CLOSE_SOCKET(tc->peer_s); turn_free(tc,sizeof(tcp_connection)); } }
static int mongo_set_admin_user(const u08bits *usname, const u08bits *realm, const password_t pwd) { mongoc_collection_t * collection = mongo_get_collection("admin_user"); if(!collection) return -1; bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "name", (const char *)usname); bson_t doc; bson_init(&doc); BSON_APPEND_UTF8(&doc, "name", (const char *)usname); BSON_APPEND_UTF8(&doc, "realm", (const char *)realm); BSON_APPEND_UTF8(&doc, "password", (const char *)pwd); int ret = -1; if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating admin user information\n"); } else { ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&doc); bson_destroy(&query); return ret; }
static int pgsql_set_oauth_key(oauth_key_data_raw *key) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; PGconn *pqc = get_pqdb_connection(); if(pqc) { snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')", key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime, key->as_rs_alg,key->realm); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { if(res) { PQclear(res); } snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime, key->as_rs_alg,key->realm,key->kid); res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n",PQerrorMessage(pqc)); } else { ret = 0; } } else { ret = 0; } if(res) { PQclear(res); } } return ret; }
static int mongo_add_origin(u08bits *origin, u08bits *realm) { mongoc_collection_t * collection = mongo_get_collection("realm"); if(!collection) return -1; int ret = -1; u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; if(!realm) realm=realm0; bson_t query, doc, child; bson_init(&query); BSON_APPEND_UTF8(&query, "realm", (const char *)realm); bson_init(&doc); bson_append_document_begin(&doc, "$addToSet", -1, &child); BSON_APPEND_UTF8(&child, "origin", (const char *)origin); bson_append_document_end(&doc, &child); if (!mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating realm origin information\n"); } else { ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&doc); return ret; }
static int pgsql_list_admin_users(int no_print) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; donot_print_connection_success=1; PGconn *pqc = get_pqdb_connection(); if(pqc) { snprintf(statement,sizeof(statement),"select name,realm,password from admin_user order by realm,name"); } PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { int i = 0; ret = 0; for(i=0;i<PQntuples(res);i++) { char *kval = PQgetvalue(res,i,0); ++ret; if(kval && !no_print) { char *rval = PQgetvalue(res,i,1); if(rval && *rval) { printf("%s[%s]\n",kval,rval); } else { printf("%s\n",kval); } } } } if(res) { PQclear(res); } return ret; }
static int pgsql_get_auth_secrets(secrets_list_t *sl, u08bits *realm) { int ret = -1; PGconn * pqc = get_pqdb_connection(); if(pqc) { char statement[TURN_LONG_STRING_SIZE]; snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { int i = 0; for(i=0;i<PQntuples(res);i++) { char *kval = PQgetvalue(res,i,0); if(kval) { add_to_secrets_list(sl,kval); } } ret = 0; } if(res) { PQclear(res); } } return ret; }
static int pgsql_get_admin_user(const u08bits *usname, u08bits *realm, password_t pwd) { int ret = -1; realm[0]=0; pwd[0]=0; PGconn * pqc = get_pqdb_connection(); if(pqc) { char statement[TURN_LONG_STRING_SIZE]; snprintf(statement,sizeof(statement),"select realm,password from admin_user where name='%s'",usname); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res)!=1)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { const char *kval = PQgetvalue(res,0,0); if(kval) { strncpy((char*)realm,kval,STUN_MAX_REALM_SIZE); } kval = (const char*) PQgetvalue(res,0,1); if(kval) { strncpy((char*)pwd,kval,STUN_MAX_PWD_SIZE); } ret = 0; } if(res) PQclear(res); } return ret; }
static int pgsql_set_admin_user(const u08bits *usname, const u08bits *realm, const password_t pwd) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; donot_print_connection_success=1; PGconn *pqc = get_pqdb_connection(); if(pqc) { snprintf(statement,sizeof(statement),"insert into admin_user (realm,name,password) values('%s','%s','%s')",realm,usname,pwd); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { if(res) { PQclear(res); } snprintf(statement,sizeof(statement),"update admin_user set password='******',realm='%s' where name='%s'",pwd,realm,usname); res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n",PQerrorMessage(pqc)); } else { ret = 0; } } if(res) { PQclear(res); } } return ret; }
static int pgsql_set_user_key(u08bits *usname, u08bits *realm, const char *key) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; PGconn *pqc = get_pqdb_connection(); if(pqc) { snprintf(statement,sizeof(statement),"insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')",realm,usname,key); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { if(res) { PQclear(res); } snprintf(statement,sizeof(statement),"update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'",key,usname,realm); res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user information: %s\n",PQerrorMessage(pqc)); } else { ret = 0; } } if(res) { PQclear(res); } } return ret; }
static int pgsql_set_realm_option_one(u08bits *realm, unsigned long value, const char* opt) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; PGconn *pqc = get_pqdb_connection(); if(pqc) { { snprintf(statement,sizeof(statement),"delete from turn_realm_option where realm='%s' and opt='%s'",realm,opt); PGresult *res = PQexec(pqc, statement); if(res) { PQclear(res); } } if(value>0) { snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting realm option information: %s\n",PQerrorMessage(pqc)); } else { ret = 0; } if(res) { PQclear(res); } } } return ret; }
static int mongo_del_origin(u08bits *origin) { mongoc_collection_t * collection = mongo_get_collection("realm"); if(!collection) return -1; int ret = -1; bson_t query, doc, child; bson_init(&query); bson_init(&doc); bson_append_document_begin(&doc, "$pull", -1, &child); BSON_APPEND_UTF8(&child, "origin", (const char *)origin); bson_append_document_end(&doc, &child); if (!mongoc_collection_update(collection, MONGOC_UPDATE_MULTI_UPDATE, &query, &doc, NULL, NULL)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting origin information\n"); } else { ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&doc); return ret; }
static int init_server(dtls_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, turn_turnserver *ts) { if(!server) return -1; server->dtls_ctx = e->dtls_ctx; server->ts = ts; server->children_ss = ur_addr_map_create(65535); if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a UDP/DTLS listener for address: %s\n",local_address); return -1; } server->slen0 = get_ioa_addr_len(&(server->addr)); server->verbose=verbose; server->e = e; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method: %s\n",event_base_get_method(server->e->event_base)); if(server->dtls_ctx) { #if defined(REQUEST_CLIENT_CERT) /* If client has to authenticate, then */ SSL_CTX_set_verify(server->dtls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback); #endif SSL_CTX_set_read_ahead(server->dtls_ctx, 1); #if !defined(TURN_NO_DTLS) SSL_CTX_set_cookie_generate_cb(server->dtls_ctx, generate_cookie); SSL_CTX_set_cookie_verify_cb(server->dtls_ctx, verify_cookie); #endif } return create_server_socket(server); }
static mongoc_collection_t * mongo_get_collection(const char * name) { MONGO * mc = get_mongodb_connection(); if(!mc) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error getting a connection to MongoDB\n"); return NULL; } mongoc_collection_t * collection; collection = mongoc_client_get_collection(mc->client, mc->database, name); if (!collection) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MongoDB collection '%s'\n", name); } return collection; }
static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) { oauth_key_data_raw key_; oauth_key_data_raw *key=&key_; int ret = -1; char statement[TURN_LONG_STRING_SIZE]; snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid"); PGconn * pqc = get_pqdb_connection(); if(pqc) { PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { int i = 0; for(i=0;i<PQntuples(res);i++) { STRCPY(key->ikm_key,PQgetvalue(res,i,0)); key->timestamp = (u64bits)strtoll(PQgetvalue(res,i,1),NULL,10); key->lifetime = (u32bits)strtol(PQgetvalue(res,i,2),NULL,10); STRCPY(key->as_rs_alg,PQgetvalue(res,i,3)); STRCPY(key->realm,PQgetvalue(res,i,4)); STRCPY(key->kid,PQgetvalue(res,i,5)); if(kids) { add_to_secrets_list(kids,key->kid); add_to_secrets_list(teas,key->as_rs_alg); add_to_secrets_list(realms,key->realm); { char ts[256]; snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); add_to_secrets_list(tss,ts); } { char lt[256]; snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); add_to_secrets_list(lts,lt); } } else { printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n", key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg,key->realm); } ret = 0; } } if(res) { PQclear(res); } } return ret; }
static MONGO * get_mongodb_connection(void) { persistent_users_db_t * pud = get_persistent_users_db(); MONGO * mydbconnection = (MONGO *) pthread_getspecific(connection_key); if (!mydbconnection) { mongoc_init(); mongoc_log_set_handler(&mongo_logger, NULL); mydbconnection = (MONGO *) turn_malloc(sizeof(MONGO)); mydbconnection->uri = mongoc_uri_new(pud->userdb); if (!mydbconnection->uri) { TURN_LOG_FUNC( TURN_LOG_LEVEL_ERROR, "Cannot open parse MongoDB URI <%s>, connection string format error\n", pud->userdb); MongoFree(mydbconnection); mydbconnection = NULL; } else { mydbconnection->client = mongoc_client_new_from_uri( mydbconnection->uri); if (!mydbconnection->client) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MongoDB connection\n"); MongoFree(mydbconnection); mydbconnection = NULL; } else { mydbconnection->database = mongoc_uri_get_database( mydbconnection->uri); if (!mydbconnection->database) mydbconnection->database = MONGO_DEFAULT_DB; if(mydbconnection) { (void) pthread_setspecific(connection_key, mydbconnection); } TURN_LOG_FUNC( TURN_LOG_LEVEL_INFO, "Opened MongoDB URI <%s>\n", pud->userdb); } } } return mydbconnection; }
static int mongo_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) { mongoc_collection_t * collection = mongo_get_collection("oauth_key"); if (!collection) return -1; bson_t query; bson_init(&query); BSON_APPEND_UTF8(&query, "kid", (const char *)kid); bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "lifetime", 1); BSON_APPEND_INT32(&fields, "timestamp", 1); BSON_APPEND_INT32(&fields, "as_rs_alg", 1); BSON_APPEND_INT32(&fields, "ikm_key", 1); mongoc_cursor_t * cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL); int ret = -1; ns_bzero(key,sizeof(oauth_key_data_raw)); STRCPY(key->kid,kid); if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'oauth_key'\n"); } else { const bson_t * item; uint32_t length; bson_iter_t iter; if (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length)); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length)); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { key->timestamp = (u64bits)bson_iter_int64(&iter); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { key->lifetime = (u32bits)bson_iter_int32(&iter); } ret = 0; } mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
static int pgsql_list_origins(u08bits *realm, secrets_list_t *origins, secrets_list_t *realms) { int ret = -1; u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; if(!realm) realm=realm0; donot_print_connection_success = 1; PGconn *pqc = get_pqdb_connection(); if(pqc) { char statement[TURN_LONG_STRING_SIZE]; if(realm && realm[0]) { snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm where realm='%s' order by origin",realm); } else { snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm order by realm,origin"); } PGresult *res = PQexec(pqc, statement); if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc)); } else { int i = 0; for(i=0;i<PQntuples(res);i++) { char *kval = PQgetvalue(res,i,0); if(kval) { char *rval = PQgetvalue(res,i,1); if(rval) { if(origins) { add_to_secrets_list(origins,kval); if(realms) { if(rval && *rval) { add_to_secrets_list(realms,rval); } else { add_to_secrets_list(realms,(char*)realm); } } } else { printf("%s ==>> %s\n",kval,rval); } } } } ret = 0; } if(res) { PQclear(res); } } return ret; }
void rollover_logfile(void) { if(to_syslog || !(log_fn[0])) return; { FILE *f = fopen(log_fn,"r"); if(!f) { fprintf(stderr, "log file is damaged\n"); reset_rtpprintf(); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file reopened: %s\n", log_fn); return; } else { fclose(f); } } if(simple_log) return; log_lock(); if(_rtpfile && log_fn[0] && (_rtpfile != stdout)) { char logf[FILE_STR_LEN]; set_log_file_name(log_fn_base,logf); if(strcmp(log_fn,logf)) { fclose(_rtpfile); log_fn[0]=0; _rtpfile = fopen(logf, "w"); if(_rtpfile) { STRCPY(log_fn,logf); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn); } else { _rtpfile = stdout; } } } log_unlock(); }