Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #6
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	;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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);
}
Beispiel #10
0
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;
}
Beispiel #12
0
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));
	}
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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;
}
Beispiel #23
0
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);
}
Beispiel #25
0
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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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();
}