diff --git a/examples/scripts/longtermsecuredb/secure_relay_with_db_sqlite.sh b/examples/scripts/longtermsecuredb/secure_relay_with_db_sqlite.sh new file mode 100755 index 00000000..c160af38 --- /dev/null +++ b/examples/scripts/longtermsecuredb/secure_relay_with_db_sqlite.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# This is an example how to start a TURN Server in +# secure mode with SQLite database for users +# with the long-term credentials mechanism. +# +# We start here a TURN Server listening on IPv4 address +# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as +# IPv4 relay address, and we use ::1 as IPv6 relay address. +# +# Other options: +# +# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps). +# 2) use fingerprints (-f) +# 3) use 3 relay threads (-m 3) +# 4) use min UDP relay port 32355 and max UDP relay port 65535 +# 5) "-r north.gov" means "use authentication realm north.gov" +# 6) --db= +# means that local database will be used. +# 7) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name. +# 8) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name. +# 9) "--log-file=stdout" means that all log output will go to the stdout. +# 10) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2 +# 11) --oauth - accept oAuth security dialog +# Other parameters (config file name, etc) are default. + +if [ -d examples ] ; then + cd examples +fi + +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/ +export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/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 --db="var/db/turndb" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 --oauth $@ + diff --git a/examples/scripts/restapi/secure_relay_secret_with_db_mongo.sh b/examples/scripts/restapi/secure_relay_secret_with_db_mongo.sh new file mode 100755 index 00000000..fdc41ec8 --- /dev/null +++ b/examples/scripts/restapi/secure_relay_secret_with_db_mongo.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# This is an example how to start a TURN Server in +# secure 'dynamic' 'secret' mode (see TURNServerRESTAPI.pdf) +# with MongoDB database for users information +# with the long-term credentials mechanism. +# +# We start here a TURN Server listening on IPv4 address +# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as +# IPv4 relay address, and we use ::1 as IPv6 relay address. +# +# Other options: +# +# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps). +# 2) use fingerprints (-f) +# 3) use 3 relay threads (-m 3) +# 4) use min UDP relay port 32355 and max UDP relay port 65535 +# 5) --use-auth-secret means that we are using 'secret' authentication mode. +# Absense of --static-auth-secret value means that we will be taking the secret value +# from the database ('dynamic' mode). +# 6) --realm=north.gov sets realm value as "north.gov". +# 7) --mongo-userdb="mongodb://localhost/coturn" +# means that local MongoDB database "coturn" will be used. +# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name. +# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name. +# 10) "--log-file=stdout" means that all log output will go to the stdout. +# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2 +# Other parameters (config file name, etc) are default. + +if [ -d examples ] ; then + cd examples +fi + +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/ +export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/ + +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 --use-auth-secret --realm=north.gov --mongo-userdb="mongodb://localhost/coturn" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@ diff --git a/examples/scripts/restapi/secure_relay_secret_with_db_sqlite.sh b/examples/scripts/restapi/secure_relay_secret_with_db_sqlite.sh new file mode 100755 index 00000000..c4fa65e1 --- /dev/null +++ b/examples/scripts/restapi/secure_relay_secret_with_db_sqlite.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# This is an example how to start a TURN Server in +# secure 'dynamic' 'secret' mode (see TURNServerRESTAPI.pdf) +# with SQLite database for users information +# with the long-term credentials mechanism. +# +# We start here a TURN Server listening on IPv4 address +# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as +# IPv4 relay address, and we use ::1 as IPv6 relay address. +# +# Other options: +# +# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps). +# 2) use fingerprints (-f) +# 3) use 3 relay threads (-m 3) +# 4) use min UDP relay port 32355 and max UDP relay port 65535 +# 5) --use-auth-secret means that we are using 'secret' authentication mode. +# Absense of --static-auth-secret value means that we will be taking the secret value +# from the database ('dynamic' mode). +# 6) --realm=north.gov sets realm value as "north.gov". +# 7) --db= +# means that local SQLite database will be used. +# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name. +# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name. +# 10) "--log-file=stdout" means that all log output will go to the stdout. +# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2 +# Other parameters (config file name, etc) are default. + +if [ -d examples ] ; then + cd examples +fi + +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/ +export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/ + +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 --use-auth-secret --realm=north.gov --db="var/db/turndb" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@ diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index 128476d4..026b8d1e 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -235,11 +235,14 @@ fi %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_psql.sh %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_redis.sh +%{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_sqlite.sh %dir %{_datadir}/%{name}/scripts/restapi %{_datadir}/%{name}/scripts/restapi/secure_relay_secret.sh %{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_mysql.sh %{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_psql.sh %{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_redis.sh +%{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_mongo.sh +%{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_sqlite.sh %{_datadir}/%{name}/scripts/restapi/secure_udp_client_with_secret.sh %{_datadir}/%{name}/scripts/restapi/shared_secret_maintainer.pl %dir %{_datadir}/%{name}/scripts/selfloadbalance diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index fa4b6cb0..08d0d0be 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -34,6 +34,10 @@ #include +#include +#include +#include + /////////////////////////////////////////////////////////////////////////////////////////////////////////// static int sqlite_init_multithreaded(void) { @@ -56,181 +60,227 @@ static int sqlite_init_multithreaded(void) { return 0; } -#if 0 - static int donot_print_connection_success = 0; -static PGconn *get_pqdb_connection(void) { - persistent_users_db_t *pud = get_persistent_users_db(); - - PGconn *pqdbconnection = (PGconn*)(pud->connection); - if(pqdbconnection) { - ConnStatusType status = PQstatus(pqdbconnection); - if(status != CONNECTION_OK) { - PQfinish(pqdbconnection); - pqdbconnection = NULL; - } - } - 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); +static void fix_user_directory(char *dir0) { + char *dir = dir0; + while(*dir == ' ') ++dir; + if(*dir == '~') { + char *home=getenv("HOME"); + if(!home) { + struct passwd *pwd = getpwuid(getuid()); + if(!pwd) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory (1)\n"); } 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); + home = pwd->pw_dir; + if(!home) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot figure out the user's HOME directory\n"); + return; } } } - pud->connection = pqdbconnection; + size_t szh = strlen(home); + size_t sz = strlen(dir0)+1+szh; + char* dir_fixed = (char*)turn_malloc(sz); + strncpy(dir_fixed,home,szh); + strncpy(dir_fixed+szh,dir+1,(sz-szh-1)); + strncpy(dir0,dir_fixed,sz); + turn_free(dir_fixed,sz); + } +} + +static void init_sqlite_database(sqlite3 *sqliteconnection) { + + const char * statements[] = { + "CREATE TABLE turnusers_lt ( realm varchar(512) default '', name varchar(512), hmackey char(128), PRIMARY KEY (realm,name))", + "CREATE TABLE turnusers_st (name varchar(512) PRIMARY KEY, password varchar(512))", + "CREATE TABLE turn_secret (realm varchar(512) default '', value varchar(512), primary key (realm,value))", + "CREATE TABLE allowed_peer_ip (realm varchar(512) default '', ip_range varchar(256), primary key (realm,ip_range))", + "CREATE TABLE denied_peer_ip (realm varchar(512) default '', ip_range varchar(256), primary key (realm,ip_range))", + "CREATE TABLE turn_origin_to_realm (origin varchar(512),realm varchar(512),primary key (origin))", + "CREATE TABLE turn_realm_option (realm varchar(512) default '', opt varchar(32), value varchar(128), primary key (realm,opt))", + "CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256) default '',timestamp bigint default 0,lifetime integer default 0,hkdf_hash_func varchar(64) default '',as_rs_alg varchar(64) default '',as_rs_key varchar(256) default '',auth_alg varchar(64) default '',auth_key varchar(256) default '',primary key (kid))", + NULL + }; + + int i = 0; + while(statements[i]) { + sqlite3_stmt *statement = NULL; + int rc = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statements[i], -1, &statement, 0)) == SQLITE_OK) { + sqlite3_step(statement); + } + sqlite3_finalize(statement); + ++i; } - return pqdbconnection; +} + +static sqlite3 * get_sqlite_connection(void) { + + persistent_users_db_t *pud = get_persistent_users_db(); + + sqlite3 *sqliteconnection = (sqlite3 *)(pud->connection); + if(!sqliteconnection) { + fix_user_directory(pud->userdb); + sqlite_init_multithreaded(); + int rc = sqlite3_open(pud->userdb, &sqliteconnection); + if(!sqliteconnection || (rc != SQLITE_OK)) { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open SQLite DB connection: <%s>, runtime error: %s\n",pud->userdb,errmsg); + } else if(!donot_print_connection_success){ + init_sqlite_database(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite DB connection success: %s\n",pud->userdb); + } + pud->connection = sqliteconnection; + } + return sqliteconnection; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int pgsql_get_auth_secrets(secrets_list_t *sl, u08bits *realm) { - int ret = -1; - PGconn * pqc = get_pqdb_connection(); - if(pqc) { +static int sqlite_get_auth_secrets(secrets_list_t *sl, u08bits *realm) +{ + int ret = -1; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { 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); + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement) - 1, "select value from turn_secret where realm='%s'", realm); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - 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 0) { + + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + int type = sqlite3_column_type(st, 0); + if (type != SQLITE_NULL) + add_to_secrets_list(sl, (const char*) sqlite3_column_text(st, 0)); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } + } + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } - return ret; + 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]; - 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) { +static int sqlite_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) +{ + int ret = -1; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + snprintf(statement, sizeof(statement), "select hmackey from turnusers_lt where name='%s' and realm='%s'", usname, realm); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + char *kval = turn_strdup((const char*) sqlite3_column_text(st, 0)); size_t sz = get_hmackey_size(turn_params.shatype); - if(((size_t)lenikm_key,sqlite3_column_text(st, 0)); + key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10); + key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10); + STRCPY((char*)key->hkdf_hash_func,sqlite3_column_text(st, 3)); + STRCPY((char*)key->as_rs_alg,sqlite3_column_text(st, 4)); + STRCPY((char*)key->as_rs_key,sqlite3_column_text(st, 5)); + STRCPY((char*)key->auth_alg,sqlite3_column_text(st, 6)); + STRCPY((char*)key->auth_key,sqlite3_column_text(st, 7)); + STRCPY((char*)key->kid,kid); + ret = 0; + } } else { - STRCPY((char*)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((char*)key->hkdf_hash_func,PQgetvalue(res,0,3)); - STRCPY((char*)key->as_rs_alg,PQgetvalue(res,0,4)); - STRCPY((char*)key->as_rs_key,PQgetvalue(res,0,5)); - STRCPY((char*)key->auth_alg,PQgetvalue(res,0,6)); - STRCPY((char*)key->auth_key,PQgetvalue(res,0,7)); - STRCPY((char*)key->kid,kid); - ret = 0; + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } - if(res) { - PQclear(res); - } + sqlite3_finalize(st); } return ret; } -static int pgsql_list_oauth_keys(void) { +static int sqlite_list_oauth_keys(void) { oauth_key_data_raw key_; oauth_key_data_raw *key=&key_; @@ -238,505 +288,543 @@ static int pgsql_list_oauth_keys(void) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key,kid from oauth_key order by kid"); - PGconn * pqc = get_pqdb_connection(); - if(pqc) { - PGresult *res = PQexec(pqc, statement); + sqlite3 *sqliteconnection = get_sqlite_connection(); + if(sqliteconnection) { - 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;iikm_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((char*)key->hkdf_hash_func,PQgetvalue(res,i,3)); - STRCPY((char*)key->as_rs_alg,PQgetvalue(res,i,4)); - STRCPY((char*)key->as_rs_key,PQgetvalue(res,i,5)); - STRCPY((char*)key->auth_alg,PQgetvalue(res,i,6)); - STRCPY((char*)key->auth_key,PQgetvalue(res,i,7)); - STRCPY((char*)key->kid,PQgetvalue(res,i,8)); - - printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n", + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + STRCPY((char*)key->ikm_key,sqlite3_column_text(st, 0)); + key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10); + key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10); + STRCPY((char*)key->hkdf_hash_func,sqlite3_column_text(st, 3)); + STRCPY((char*)key->as_rs_alg,sqlite3_column_text(st, 4)); + STRCPY((char*)key->as_rs_key,sqlite3_column_text(st, 5)); + STRCPY((char*)key->auth_alg,sqlite3_column_text(st, 6)); + STRCPY((char*)key->auth_key,sqlite3_column_text(st, 7)); + STRCPY((char*)key->kid,sqlite3_column_text(st, 7)); + + printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n", key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func, key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key); - ret = 0; + } else if (res == SQLITE_DONE) { + break; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; + } } + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } - if(res) { - PQclear(res); - } + sqlite3_finalize(st); } return ret; } - -static int pgsql_set_user_key(u08bits *usname, u08bits *realm, const char *key) { - int ret = -1; + +static int sqlite_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); + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + + snprintf(statement, sizeof(statement), "insert or replace into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')", realm, usname, key); + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } - return ret; + 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,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')", - key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime, - key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key); - - 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, hkdf_hash_func = '%s', as_rs_alg='%s',as_rs_key='%s',auth_alg='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime, - key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key,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; - } - } - if(res) { - PQclear(res); - } - } - return ret; -} +static int sqlite_set_oauth_key(oauth_key_data_raw *key) +{ -static int pgsql_set_user_pwd(u08bits *usname, st_password_t pwd) { - int ret = -1; + int ret = -1; char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"insert into turnusers_st values('%s','%s')",usname,pwd); - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - if(res) { - PQclear(res); - } - snprintf(statement,sizeof(statement),"update turnusers_st set password='%s' where name='%s'",pwd,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; - } + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf( + statement, + sizeof(statement), + "insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')", + key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->hkdf_hash_func, key->as_rs_alg, key->as_rs_key, key->auth_alg, + key->auth_key); + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } - if(res) { - PQclear(res); + sqlite3_finalize(st); + } + return ret; +} + +static int sqlite_set_user_pwd(u08bits *usname, st_password_t pwd) +{ + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "insert or replace into turnusers_st values('%s','%s')", usname, pwd); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } - return ret; + return ret; } - -static int pgsql_del_user(u08bits *usname, int is_st, u08bits *realm) { - int ret = -1; + +static int sqlite_del_user(u08bits *usname, int is_st, u08bits *realm) +{ + int ret = -1; char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - if(is_st) { - snprintf(statement,sizeof(statement),"delete from turnusers_st where name='%s'",usname); + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (is_st) { + snprintf(statement, sizeof(statement), "delete from turnusers_st where name='%s'", usname); } else { - snprintf(statement,sizeof(statement),"delete from turnusers_lt where name='%s' and realm='%s'",usname,realm); + snprintf(statement, sizeof(statement), "delete from turnusers_lt where name='%s' and realm='%s'", usname, realm); } - PGresult *res = PQexec(pqc, statement); - if(res) { - PQclear(res); - ret = 0; + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } - return ret; + return ret; } -static int pgsql_del_oauth_key(const u08bits *kid) { - - int ret = -1; - char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - snprintf(statement,sizeof(statement),"delete from oauth_key where kid = '%s'",(const char*)kid); - - PGresult *res = PQexec(pqc, statement); - if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth_key information: %s\n",PQerrorMessage(pqc)); - } else { - ret = 0; - } - if(res) { - PQclear(res); - } - } - return ret; -} - -static int pgsql_list_users(int is_st, u08bits *realm) { - int ret = -1; +static int sqlite_del_oauth_key(const u08bits *kid) +{ + int ret = -1; char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - if(is_st) { - snprintf(statement,sizeof(statement),"select name,'' from turnusers_st order by name"); - } else if(realm && realm[0]) { - snprintf(statement,sizeof(statement),"select name,realm from turnusers_lt where realm='%s' order by name",realm); + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + snprintf(statement, sizeof(statement), "delete from oauth_key where kid = '%s'", (const char*) kid); + + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; } else { - snprintf(statement,sizeof(statement),"select name,realm from turnusers_lt order by name"); + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } - 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)); + sqlite3_finalize(st); + } + return ret; +} + + +static int sqlite_list_users(int is_st, u08bits *realm) +{ + int ret = -1; + char statement[TURN_LONG_STRING_SIZE]; + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (is_st) { + snprintf(statement, sizeof(statement), "select name,'' from turnusers_st order by name"); + } else if (realm && realm[0]) { + snprintf(statement, sizeof(statement), "select name,realm from turnusers_lt where realm='%s' order by name", realm); } else { - int i = 0; - for(i=0;i> %s\n",oval,rval); - } + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + + ret = 0; + while (1) { + int res = sqlite3_step(st); + if (res == SQLITE_ROW) { + + const char* kval = (const char*) sqlite3_column_text(st, 0); + const char* rval = (const char*) sqlite3_column_text(st, 1); + + printf("%s ==>> %s\n",kval,rval); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; } } - ret = 0; - } - if(res) { - PQclear(res); + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } - return ret; + return ret; } -static int pgsql_set_realm_option_one(u08bits *realm, unsigned long value, const char* opt) { - int ret = -1; +static int sqlite_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); - } - } + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if(sqliteconnection) { 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)); + snprintf(statement,sizeof(statement),"insert or replace into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value); + if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { + sqlite3_step(st); + ret = 0; } else { - ret = 0; - } - if(res) { - PQclear(res); + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } + sqlite3_finalize(st); } } - return ret; + return ret; } -static int pgsql_list_realm_options(u08bits *realm) { - int ret = -1; +static int sqlite_list_realm_options(u08bits *realm) +{ + int ret = -1; donot_print_connection_success = 1; char statement[TURN_LONG_STRING_SIZE]; - PGconn *pqc = get_pqdb_connection(); - if(pqc) { - if(realm && realm[0]) { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt",realm); + sqlite3_stmt *st = NULL; + int rc = 0; + sqlite3 *sqliteconnection = get_sqlite_connection(); + if (sqliteconnection) { + if (realm && realm[0]) { + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt", realm); } else { - snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option order by realm,opt"); + snprintf(statement, sizeof(statement), "select realm,opt,value from turn_realm_option order by realm,opt"); } - 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;ioptions.perf_options.max_bps = (band_limit_t)atol(vval); @@ -790,13 +878,22 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) { else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval); } + + turn_free(rval,strlen(rval)+1); + + } else if (res == SQLITE_DONE) { + break; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + break; } } + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } - - if(res) { - PQclear(res); - } + sqlite3_finalize(st); } } } @@ -804,35 +901,32 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) { /////////////////////////////////////////////////////////////////////////////////////////////////////////// static turn_dbdriver_t driver = { - &pgsql_get_auth_secrets, - &pgsql_get_user_key, - &pgsql_get_user_pwd, - &pgsql_set_user_key, - &pgsql_set_user_pwd, - &pgsql_del_user, - &pgsql_list_users, - &pgsql_show_secret, - &pgsql_del_secret, - &pgsql_set_secret, - &pgsql_add_origin, - &pgsql_del_origin, - &pgsql_list_origins, - &pgsql_set_realm_option_one, - &pgsql_list_realm_options, - &pgsql_auth_ping, - &pgsql_get_ip_list, - &pgsql_reread_realms, - &pgsql_set_oauth_key, - &pgsql_get_oauth_key, - &pgsql_del_oauth_key, - &pgsql_list_oauth_keys + &sqlite_get_auth_secrets, + &sqlite_get_user_key, + &sqlite_get_user_pwd, + &sqlite_set_user_key, + &sqlite_set_user_pwd, + &sqlite_del_user, + &sqlite_list_users, + &sqlite_show_secret, + &sqlite_del_secret, + &sqlite_set_secret, + &sqlite_add_origin, + &sqlite_del_origin, + &sqlite_list_origins, + &sqlite_set_realm_option_one, + &sqlite_list_realm_options, + &sqlite_auth_ping, + &sqlite_get_ip_list, + &sqlite_reread_realms, + &sqlite_set_oauth_key, + &sqlite_get_oauth_key, + &sqlite_del_oauth_key, + &sqlite_list_oauth_keys }; /////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif - turn_dbdriver_t * get_sqlite_dbdriver(void) { - //TODO - return NULL; + return &driver; } diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 164fdaa6..ca7201ba 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -137,9 +137,9 @@ static char Usage[] = " -I Do not set permissions on TURN relay endpoints\n" " (for testing the non-standard server relay functionality).\n" " -G Generate extra requests (create permissions, channel bind).\n" - " -B Random disconnect after a few initial packets.\n" - " -Z Dual allocation.\n" - " -J Use oAuth with default test key kid='north'.\n" + " -B Random disconnect after a few initial packets.\n" + " -Z Dual allocation.\n" + " -J Use oAuth with default test key kid='north'.\n" "Options:\n" " -l Message length (Default: 100 Bytes).\n" " -i Certificate file (for secure connections only, optional).\n"