working on sqlite support
This commit is contained in:
parent
ef7f087359
commit
b9ef9f4c61
@ -1,6 +1,8 @@
|
||||
11/10/2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
Version 4.2.3.2 'Monza':
|
||||
Version 4.3.1.1 'Tolomei':
|
||||
- TLS connection procedure improved in uclient test program.
|
||||
- Flat-file user database is no longer supported.
|
||||
- SQLite supported as the default user database (TODO).
|
||||
|
||||
11/07/2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
Version 4.2.3.1 'Monza':
|
||||
|
||||
17
INSTALL
17
INSTALL
@ -211,7 +211,7 @@ If you do not want to use the rpath linking option, or you OS or compiler
|
||||
do not allows that, then after the installation, you may have to adjust the
|
||||
system-wide shared library search path by using "ldconfig -n <libdirname>"
|
||||
(Linux), "ldconfig -m <libdirname>" (BSD) or "crle -u -l <libdirname>"
|
||||
(Solaris). Your system must be able to find the libevent2, openssl and
|
||||
(Solaris). Your system must be able to find the sqlite, libevent2, openssl and
|
||||
(optionally) PostgreSQL and/or MySQL (MariaDB) and/or MongoDB and/or Redis
|
||||
shared libraries, either with the help of the system-wide library search
|
||||
configuration or by using LD_LIBRARY_PATH. "make install" will make a
|
||||
@ -274,8 +274,9 @@ The code is compatible with C++ compiler, and a C++ compiler
|
||||
VII. WHICH EXTRA LIBRARIES AND UTILITIES YOU NEED
|
||||
|
||||
In addition to common *NIX OS services and libraries, to compile this code,
|
||||
OpenSSL (version 1.0.0a or better recommended) and libevent2 (version 2.0.5
|
||||
or better) are required, the PostgreSQL C client development setup is
|
||||
OpenSSL (version 1.0.0a or better recommended), sqlite C development library,
|
||||
and libevent2 (version 2.0.5 or better) are required,
|
||||
the PostgreSQL C client development setup is
|
||||
optional, the MySQL (MariaDB) C client development setup is optional, the MongoDB
|
||||
C Driver and the Hiredis development files for Redis database access are optional.
|
||||
For fully functional build, the extra set of libraries must be installed
|
||||
@ -283,9 +284,10 @@ in full version (the development headers and the libraries to link with).
|
||||
For runtime, only runtime setup is required. If the build is modified for
|
||||
static linking, then even runtime installation is not needed.
|
||||
|
||||
OpenSSL, libevent2, PostgreSQL, MySQL (or MariaDB) and Hiredis
|
||||
OpenSSL, SQLite, libevent2, PostgreSQL, MySQL (or MariaDB) and Hiredis
|
||||
libraries can be downloaded from their web sites:
|
||||
- http://www.openssl.org (required);
|
||||
- http://www.sqlite.org (required);
|
||||
- http://www.libevent.org (required);
|
||||
- http://www.postgresql.org (optional);
|
||||
- http://www.mysql.org (or http://mariadb.org) (optional);
|
||||
@ -315,6 +317,8 @@ installation:
|
||||
|
||||
$ cd /usr/ports/security/openssl/
|
||||
$ sudo make install clean
|
||||
$ cd /usr/ports/databases/sqlite3/
|
||||
$ sudo make install clean
|
||||
$ cd /usr/ports/devel/libevent2/
|
||||
$ sudo make install clean
|
||||
$ cd /usr/ports/databases/postgresql84-client/ (or any other version)
|
||||
@ -327,6 +331,7 @@ installation:
|
||||
**) Linux Ubuntu 11.10+, Debian Wheezy, Mint 14+:
|
||||
|
||||
$ sudo apt-get install libssl-dev
|
||||
$ sudo apt-get install sqlite3-dev
|
||||
$ sudo apt-get install libevent-dev
|
||||
$ sudo apt-get install libpq-dev
|
||||
$ sudo apt-get install mysql-client
|
||||
@ -338,6 +343,8 @@ installation:
|
||||
***) Fedora:
|
||||
|
||||
$ sudo yum install openssl-devel
|
||||
$ sudo yum install sqlite
|
||||
$ sudo yum install sqlite-devel
|
||||
$ sudo yum install libevent
|
||||
$ sudo yum install libevent-devel
|
||||
$ sudo yum install postgresql-devel
|
||||
@ -446,6 +453,8 @@ If you have a system with older libevent, then you have to install the new
|
||||
libevent2 from their web site. It was tested with older *NIXes
|
||||
(like FreeBSD 6.x) and it works just fine.
|
||||
|
||||
NOTE: SQLite must be of version 3.x.
|
||||
|
||||
NOTE: For extra security features (DTLS and SHA256) support, OpenSSL version
|
||||
1.0.0a or newer is recommended. Older versions do not support DTLS, reliably,
|
||||
in some cases. For example, the Debian 'Squeeze' Linux supplies 0.9.8 version
|
||||
|
||||
@ -27,8 +27,8 @@ IMPL_DEPS = ${COMMON_DEPS} ${IMPL_HEADERS} ${IMPL_MODS}
|
||||
HIREDIS_HEADERS = src/apps/common/hiredis_libevent2.h
|
||||
HIREDIS_MODS = src/apps/common/hiredis_libevent2.c
|
||||
|
||||
USERDB_HEADERS = src/apps/relay/dbdrivers/dbdriver.h src/apps/relay/dbdrivers/dbd_pgsql.h src/apps/relay/dbdrivers/dbd_mysql.h src/apps/relay/dbdrivers/dbd_mongo.h src/apps/relay/dbdrivers/dbd_redis.h
|
||||
USERDB_MODS = src/apps/relay/dbdrivers/dbdriver.c src/apps/relay/dbdrivers/dbd_pgsql.c src/apps/relay/dbdrivers/dbd_mysql.c src/apps/relay/dbdrivers/dbd_mongo.c src/apps/relay/dbdrivers/dbd_redis.c
|
||||
USERDB_HEADERS = src/apps/relay/dbdrivers/dbdriver.h src/apps/relay/dbdrivers/dbd_sqlite.h src/apps/relay/dbdrivers/dbd_pgsql.h src/apps/relay/dbdrivers/dbd_mysql.h src/apps/relay/dbdrivers/dbd_mongo.h src/apps/relay/dbdrivers/dbd_redis.h
|
||||
USERDB_MODS = src/apps/relay/dbdrivers/dbdriver.c src/apps/relay/dbdrivers/dbd_sqlite.c src/apps/relay/dbdrivers/dbd_pgsql.c src/apps/relay/dbdrivers/dbd_mysql.c src/apps/relay/dbdrivers/dbd_mongo.c src/apps/relay/dbdrivers/dbd_redis.c
|
||||
|
||||
SERVERAPP_HEADERS = src/apps/relay/userdb.h src/apps/relay/tls_listener.h src/apps/relay/mainrelay.h src/apps/relay/turncli.h src/apps/relay/dtls_listener.h src/apps/relay/libtelnet.h ${HIREDIS_HEADERS} ${USERDB_HEADERS}
|
||||
SERVERAPP_MODS = src/apps/relay/mainrelay.c src/apps/relay/netengine.c src/apps/relay/libtelnet.c src/apps/relay/turncli.c src/apps/relay/userdb.c src/apps/relay/tls_listener.c src/apps/relay/dtls_listener.c ${HIREDIS_MODS} ${USERDB_MODS}
|
||||
@ -142,7 +142,7 @@ install: all ${MAKE_DEPS}
|
||||
${INSTALL_DATA} turndb/schema.stats.redis ${DESTDIR}${DOCSDIR}
|
||||
${INSTALL_DATA} turndb/schema.stats.redis ${DESTDIR}${SCHEMADIR}
|
||||
${INSTALL_DATA} examples/etc/turnserver.conf ${DESTDIR}${CONFDIR}/turnserver.conf.default
|
||||
${INSTALL_DATA} examples/etc/turnuserdb.conf ${DESTDIR}${CONFDIR}/turnuserdb.conf.default
|
||||
${INSTALL_DATA} examples/var/db/turdb ${DESTDIR}/var/db/turndb
|
||||
${INSTALL_DIR} examples/etc ${DESTDIR}${EXAMPLESDIR}
|
||||
${INSTALL_DIR} examples/scripts ${DESTDIR}${EXAMPLESDIR}
|
||||
${RMCMD} ${DESTDIR}${EXAMPLESDIR}/scripts/rfc5769.sh
|
||||
@ -169,7 +169,7 @@ deinstall: ${MAKE_DEPS}
|
||||
${RMCMD} ${DESTDIR}${LIBDIR}/libturnclient.a
|
||||
${RMCMD} ${DESTDIR}${EXAMPLESDIR}/
|
||||
${RMCMD} ${DESTDIR}${CONFDIR}/turnserver.conf.default
|
||||
${RMCMD} ${DESTDIR}${CONFDIR}/turnuserdb.conf.default
|
||||
${RMCMD} ${DESTDIR}/var/db/turndb
|
||||
${RMCMD} ${DESTDIR}${TURNINCLUDEDIR}
|
||||
|
||||
uninstall: deinstall
|
||||
|
||||
@ -77,17 +77,11 @@ Commands:
|
||||
-g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.
|
||||
|
||||
-G, --list-realm-options List realm params.
|
||||
|
||||
NOTE: if you are using the flat file for the user database, then you will have
|
||||
to use a text editor to set or show the shared secrets.
|
||||
|
||||
NOTE: the origin functionality is not supported with flat user db file,
|
||||
a "real" database must be used.
|
||||
|
||||
Options with required values:
|
||||
|
||||
-b, --userdb File-based user database file name (default - turnuserdb.conf).
|
||||
See the --userdb option in the turnserver section.
|
||||
-b, --db, --userdb SQLite user database file name (default - /var/db/turndb).
|
||||
See the same option in the turnserver section.
|
||||
-e, --psql-userdb PostgreSQL user database connection string.
|
||||
See the --psql-userdb option in the turnserver section.
|
||||
-M, --mysql-userdb MySQL user database connection string.
|
||||
@ -112,11 +106,11 @@ Generate a key:
|
||||
|
||||
$ turnadmin -k -u <username> -r <realm> -p <password>
|
||||
|
||||
Add/update a user in the userdb file or in the database:
|
||||
Add/update a user in the in the database:
|
||||
|
||||
$ turnadmin -a [-b <userdb-file> | -e <db-connection-string> | -M <db-connection-string> | -N <db-connection-string> ] -u <username> -r <realm> -p <password>
|
||||
|
||||
Delete a user from the userdb file or from the database:
|
||||
Delete a user from the database:
|
||||
|
||||
$ turnadmin -d [-b <userdb-file> | -e <db-connection-string> | -M <db-connection-string> | -N <db-connection-string> ] -u <username> -r <realm>
|
||||
|
||||
@ -176,12 +170,10 @@ to see the man page.
|
||||
|
||||
/etc/turnserver.conf
|
||||
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
|
||||
/usr/local/etc/turnserver.conf
|
||||
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
|
||||
=====================================
|
||||
|
||||
DIRECTORIES
|
||||
|
||||
@ -81,11 +81,7 @@ Config file settings:
|
||||
|
||||
User database settings:
|
||||
|
||||
-b, --userdb User database file name (default - turnuserdb.conf),
|
||||
for long-term credentials mechanism only.
|
||||
This user file database is being dynamically checked while the
|
||||
turnserver is working, and the user accounts can be changed
|
||||
dynamically by editing the database.
|
||||
-b, --db, --userdb SQLite user database file name (default - /var/db/turndb).
|
||||
|
||||
-e, --psql-userdb User database connection string for PostgreSQL.
|
||||
This database can be used for long-term and short-term
|
||||
@ -161,11 +157,9 @@ Flags:
|
||||
fingerprints to the messages in this session, regardless of the
|
||||
per-server setting.
|
||||
|
||||
-a, --lt-cred-mech Use long-term credentials mechanism (this one you need for WebRTC usage).
|
||||
This option can be used with either flat file user database or
|
||||
PostgreSQL DB or MySQL DB or MongoDB or Redis for user keys storage.
|
||||
-A, --st-cred-mech Use the short-term credentials mechanism. This option requires
|
||||
a PostgreSQL or MySQL or MongoDB or Redis DB for short term passwords storage.
|
||||
-a, --lt-cred-mech Use long-term credentials mechanism (this one you need for WebRTC usage).
|
||||
|
||||
-A, --st-cred-mech Use the short-term credentials mechanism.
|
||||
|
||||
-z, --no-auth Do not use any credentials mechanism, allow anonymous access.
|
||||
Opposite to -a and -A options. This is default option when no
|
||||
@ -568,16 +562,14 @@ for that you have a number of options:
|
||||
|
||||
a) command-line options (-u).
|
||||
|
||||
b) userdb config file.
|
||||
|
||||
c) a database table (PostgreSQL or MySQL or MongoDB). You will have to set keys with
|
||||
turnadmin utility (see docs and wiki for turnadmin). You cannot use open passwords
|
||||
in the database.
|
||||
b) a database table (SQLite or PostgreSQL or MySQL or MongoDB). You will have to
|
||||
set keys with turnadmin utility (see docs and wiki for turnadmin).
|
||||
You cannot use open passwords in the database.
|
||||
|
||||
d) Redis key/value pair(s), if Redis is used. You key use either keys or
|
||||
c) Redis key/value pair(s), if Redis is used. You key use either keys or
|
||||
open passwords with Redis; see turndb/testredisdbsetup.sh file.
|
||||
|
||||
e) You also can use the TURN REST API. You will need shared secret(s) set
|
||||
d) You also can use the TURN REST API. You will need shared secret(s) set
|
||||
either through the command line option, or through the config file, or through
|
||||
the database table or Redis key/value pairs.
|
||||
|
||||
@ -724,9 +716,7 @@ For the user database, the turnserver has the following options:
|
||||
Obviously, only a few users can be set that way, and their credentials are fixed
|
||||
for the turnserver process lifetime.
|
||||
|
||||
2) Users can be set in turnusers.conf flat file DB. The turnserver process periodically
|
||||
re-reads this file, so the user accounts may be changed while the turnserver is running.
|
||||
But still a relatively small (up to a hundred ?) number of users can be handled that way.
|
||||
2) Users can be stored in SQlite DB. The default SQLite database file is /var/db/turndb.
|
||||
|
||||
3) Users can be stored in PostgreSQL database, if the turnserver was compiled with PostgreSQL
|
||||
support. Each time turnserver checks user credentials, it reads the database (asynchronously,
|
||||
@ -851,12 +841,10 @@ FILES
|
||||
|
||||
/etc/turnserver.conf
|
||||
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
|
||||
/usr/local/etc/turnserver.conf
|
||||
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
|
||||
=================================
|
||||
|
||||
DIRECTORIES
|
||||
|
||||
@ -251,12 +251,10 @@ FILES
|
||||
|
||||
/etc/turnserver.conf
|
||||
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
|
||||
/usr/local/etc/turnserver.conf
|
||||
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
|
||||
=================================
|
||||
|
||||
DIRECTORIES
|
||||
|
||||
2
STATUS
2
STATUS
@ -106,6 +106,8 @@ compatibility.
|
||||
45) Secure MySQL connection implemented.
|
||||
|
||||
46) Third-party security mechanism (through oAuth) implemented.
|
||||
|
||||
47) SQLite support added as default database.
|
||||
|
||||
Things to be implemented in future (the development roadmap)
|
||||
are described in the TODO file.
|
||||
|
||||
53
configure
vendored
53
configure
vendored
@ -19,6 +19,8 @@ cleanup() {
|
||||
rm -rf ${MONGO_TMPCPROGB}
|
||||
rm -rf ${D_TMPCPROGC}
|
||||
rm -rf ${D_TMPCPROGB}
|
||||
rm -rf ${SQL_TMPCPROGC}
|
||||
rm -rf ${SQL_TMPCPROGO}
|
||||
rm -rf ${E_TMPCPROGC}
|
||||
rm -rf ${E_TMPCPROGO}
|
||||
rm -rf ${HR_TMPCPROGC}
|
||||
@ -38,6 +40,19 @@ testlibraw() {
|
||||
fi
|
||||
}
|
||||
|
||||
testsqlite_comp() {
|
||||
SQLITE_LIBS=-lsqlite3
|
||||
${CC} -c ${SQL_TMPCPROGC} -o ${SQL_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "SQLite development is not installed properly"
|
||||
return 0
|
||||
else
|
||||
DBLIBS="${DBLIBS} ${SQLITE_LIBS}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
testlibevent2_comp() {
|
||||
${CC} -c ${E_TMPCPROGC} -o ${E_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null
|
||||
ER=$?
|
||||
@ -683,6 +698,18 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
!
|
||||
|
||||
SQL_TMPCPROG=__test__ccomp__sqlite__$$
|
||||
SQL_TMPCPROGC=${TMPDIR}/${SQL_TMPCPROG}.c
|
||||
SQL_TMPCPROGO=${TMPDIR}/${SQL_TMPCPROG}.o
|
||||
|
||||
cat > ${SQL_TMPCPROGC} <<!
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
int main(int argc, char** argv) {
|
||||
return (int)(argv[argc][0]);
|
||||
}
|
||||
!
|
||||
|
||||
HR_TMPCPROG=__test__ccomp__hiredis__$$
|
||||
HR_TMPCPROGC=${TMPDIR}/${HR_TMPCPROG}.c
|
||||
HR_TMPCPROGB=${TMPDIR}/${HR_TMPCPROG}
|
||||
@ -932,6 +959,32 @@ else
|
||||
TURN_NO_GCM="-DTURN_NO_GCM"
|
||||
fi
|
||||
|
||||
###########################
|
||||
# Test SQLite setup
|
||||
###########################
|
||||
|
||||
testlib sqlite3
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "SQLite library found."
|
||||
else
|
||||
${ECHO_CMD} "ERROR: SQLite3 development library cannot be found."
|
||||
cleanup
|
||||
exit
|
||||
fi
|
||||
|
||||
testsqlite_comp
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "SQLite development found."
|
||||
else
|
||||
${ECHO_CMD} "ERROR: SQLite development libraries are not installed properly in required location."
|
||||
${ECHO_CMD} "See the INSTALL file."
|
||||
${ECHO_CMD} "Abort."
|
||||
cleanup
|
||||
exit
|
||||
fi
|
||||
|
||||
###########################
|
||||
# Test Libevent2 setup
|
||||
###########################
|
||||
|
||||
@ -248,16 +248,11 @@
|
||||
#user=ninefingers:youhavetoberealistic
|
||||
#
|
||||
|
||||
# 'Dynamic' user accounts database file name.
|
||||
# Only users for long-term mechanism can be stored in a flat file,
|
||||
# short-term mechanism will not work with option, the short-term
|
||||
# mechanism required PostgreSQL or MySQL or MongoDB or Redis database.
|
||||
# 'Dynamic' long-term user accounts are dynamically checked by the turnserver process,
|
||||
# so that they can be changed while the turnserver is running.
|
||||
# SQLite database file name.
|
||||
#
|
||||
# Default file name is turnuserdb.conf.
|
||||
# Default file name is /var/db/turndb
|
||||
#
|
||||
#userdb=/usr/local/etc/turnuserdb.conf
|
||||
#userdb=/var/db/turndb
|
||||
|
||||
# PostgreSQL database connection string in the case that we are using PostgreSQL
|
||||
# as the user database.
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
#This file can be used as user accounts storage for long-term credentials mechanism.
|
||||
#
|
||||
#username1:key1
|
||||
#username2:key2
|
||||
# OR:
|
||||
#username1:password1
|
||||
#username2:password2
|
||||
#
|
||||
# Keys must be generated by turnadmin utility. The key value depends
|
||||
# on user name, realm, and password:
|
||||
#
|
||||
# Example:
|
||||
# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic
|
||||
# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee
|
||||
# ('0x' in the beginning of the key is what differentiates the key from
|
||||
# password. If it has 0x then it is a key, otherwise it is a password).
|
||||
#
|
||||
# The corresponding user account entry in the userdb file will be:
|
||||
#
|
||||
#ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee
|
||||
# Or, equivalently (less secure):
|
||||
#ninefingers:youhavetoberealistic
|
||||
#
|
||||
BIN
examples/var/db/turndb
Normal file
BIN
examples/var/db/turndb
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
.\" Text automatically generated by txt2man
|
||||
.TH TURN 1 "09 November 2014" "" ""
|
||||
.TH TURN 1 "15 November 2014" "" ""
|
||||
.SH GENERAL INFORMATION
|
||||
|
||||
\fIturnadmin\fP is a TURN administration tool. This tool can be used to manage
|
||||
@ -126,20 +126,14 @@ Set realm params: max\-bps, total\-quota, user\-quota.
|
||||
.B
|
||||
\fB\-G\fP, \fB\-\-list\-realm\-options\fP
|
||||
List realm params.
|
||||
.PP
|
||||
NOTE: if you are using the flat file for the user database, then you will have
|
||||
to use a text editor to set or show the shared secrets.
|
||||
.PP
|
||||
NOTE: the origin functionality is not supported with flat user db file,
|
||||
a "real" database must be used.
|
||||
.TP
|
||||
.B
|
||||
Options with required values:
|
||||
.TP
|
||||
.B
|
||||
\fB\-b\fP, \fB\-\-userdb\fP
|
||||
File\-based user database file name (default \- turnuserdb.conf).
|
||||
See the \fB\-\-userdb\fP option in the \fIturnserver\fP section.
|
||||
\fB\-b\fP, \fB\-\-db\fP, \fB\-\-userdb\fP
|
||||
SQLite user database file name (default \- /var/db/turndb).
|
||||
See the same option in the \fIturnserver\fP section.
|
||||
.TP
|
||||
.B
|
||||
\fB\-e\fP, \fB\-\-psql\-userdb\fP
|
||||
@ -204,11 +198,11 @@ Generate a key:
|
||||
.PP
|
||||
$ \fIturnadmin\fP \fB\-k\fP \fB\-u\fP <username> \fB\-r\fP <realm> \fB\-p\fP <password>
|
||||
.PP
|
||||
Add/update a user in the userdb file or in the database:
|
||||
Add/update a user in the in the database:
|
||||
.PP
|
||||
$ \fIturnadmin\fP \fB\-a\fP [\fB\-b\fP <userdb\-file> | \fB\-e\fP <db\-connection\-string> | \fB\-M\fP <db\-connection\-string> | \fB\-N\fP <db\-connection\-string> ] \fB\-u\fP <username> \fB\-r\fP <realm> \fB\-p\fP <password>
|
||||
.PP
|
||||
Delete a user from the userdb file or from the database:
|
||||
Delete a user from the database:
|
||||
.PP
|
||||
$ \fIturnadmin\fP \fB\-d\fP [\fB\-b\fP <userdb\-file> | \fB\-e\fP <db\-connection\-string> | \fB\-M\fP <db\-connection\-string> | \fB\-N\fP <db\-connection\-string> ] \fB\-u\fP <username> \fB\-r\fP <realm>
|
||||
.PP
|
||||
@ -267,12 +261,10 @@ to see the man page.
|
||||
|
||||
/etc/turnserver.conf
|
||||
.PP
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
.PP
|
||||
/usr/local/etc/turnserver.conf
|
||||
.PP
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
.PP
|
||||
=====================================
|
||||
.SS DIRECTORIES
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.\" Text automatically generated by txt2man
|
||||
.TH TURN 1 "09 November 2014" "" ""
|
||||
.TH TURN 1 "15 November 2014" "" ""
|
||||
.SH GENERAL INFORMATION
|
||||
|
||||
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client
|
||||
@ -131,12 +131,8 @@ installation directory /etc
|
||||
User database settings:
|
||||
.TP
|
||||
.B
|
||||
\fB\-b\fP, \fB\-\-userdb\fP
|
||||
User database file name (default \- turnuserdb.conf),
|
||||
for long\-term credentials mechanism only.
|
||||
This user file database is being dynamically checked while the
|
||||
\fIturnserver\fP is working, and the user accounts can be changed
|
||||
dynamically by editing the database.
|
||||
\fB\-b\fP, \fB\-\-db\fP, \fB\-\-userdb\fP
|
||||
SQLite user database file name (default \- /var/db/turndb).
|
||||
.TP
|
||||
.B
|
||||
\fB\-e\fP, \fB\-\-psql\-userdb\fP
|
||||
@ -239,14 +235,11 @@ per\-server setting.
|
||||
.TP
|
||||
.B
|
||||
\fB\-a\fP, \fB\-\-lt\-cred\-mech\fP
|
||||
Use long\-term credentials mechanism (this one you need for WebRTC usage).
|
||||
This option can be used with either flat file user database or
|
||||
PostgreSQL DB or MySQL DB or MongoDB or Redis for user keys storage.
|
||||
Use long\-term credentials mechanism (this one you need for WebRTC usage).
|
||||
.TP
|
||||
.B
|
||||
\fB\-A\fP, \fB\-\-st\-cred\-mech\fP
|
||||
Use the short\-term credentials mechanism. This option requires
|
||||
a PostgreSQL or MySQL or MongoDB or Redis DB for short term passwords storage.
|
||||
Use the short\-term credentials mechanism.
|
||||
.TP
|
||||
.B
|
||||
\fB\-z\fP, \fB\-\-no\-auth\fP
|
||||
@ -807,16 +800,14 @@ for that you have a number of \fIoptions\fP:
|
||||
.fam C
|
||||
a) command\-line options (\-u).
|
||||
|
||||
b) userdb config file.
|
||||
b) a database table (SQLite or PostgreSQL or MySQL or MongoDB). You will have to
|
||||
set keys with turnadmin utility (see docs and wiki for turnadmin).
|
||||
You cannot use open passwords in the database.
|
||||
|
||||
c) a database table (PostgreSQL or MySQL or MongoDB). You will have to set keys with
|
||||
turnadmin utility (see docs and wiki for turnadmin). You cannot use open passwords
|
||||
in the database.
|
||||
|
||||
d) Redis key/value pair(s), if Redis is used. You key use either keys or
|
||||
c) Redis key/value pair(s), if Redis is used. You key use either keys or
|
||||
open passwords with Redis; see turndb/testredisdbsetup.sh file.
|
||||
|
||||
e) You also can use the TURN REST API. You will need shared secret(s) set
|
||||
d) You also can use the TURN REST API. You will need shared secret(s) set
|
||||
either through the command line option, or through the config file, or through
|
||||
the database table or Redis key/value pairs.
|
||||
|
||||
@ -980,9 +971,7 @@ Users can be set in the command line, with multiple \fB\-u\fP or \fB\-\-user\fP
|
||||
Obviously, only a few users can be set that way, and their credentials are fixed
|
||||
for the \fIturnserver\fP process lifetime.
|
||||
.IP 2) 4
|
||||
Users can be set in turnusers.conf flat file DB. The \fIturnserver\fP process periodically
|
||||
re\-reads this file, so the user accounts may be changed while the \fIturnserver\fP is running.
|
||||
But still a relatively small (up to a hundred ?) number of users can be handled that way.
|
||||
Users can be stored in SQlite DB. The default SQLite database file is /var/db/turndb.
|
||||
.IP 3) 4
|
||||
Users can be stored in PostgreSQL database, if the \fIturnserver\fP was compiled with PostgreSQL
|
||||
support. Each time \fIturnserver\fP checks user credentials, it reads the database (asynchronously,
|
||||
@ -1107,12 +1096,10 @@ it would affect the performance.
|
||||
|
||||
/etc/turnserver.conf
|
||||
.PP
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
.PP
|
||||
/usr/local/etc/turnserver.conf
|
||||
.PP
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
.PP
|
||||
=================================
|
||||
.SH DIRECTORIES
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.\" Text automatically generated by txt2man
|
||||
.TH TURN 1 "09 November 2014" "" ""
|
||||
.TH TURN 1 "15 November 2014" "" ""
|
||||
.SH GENERAL INFORMATION
|
||||
|
||||
A set of turnutils_* programs provides some utility functionality to be used
|
||||
@ -374,12 +374,10 @@ to see the man page.
|
||||
|
||||
/etc/turnserver.conf
|
||||
.PP
|
||||
/etc/turnuserdb.conf
|
||||
/var/db/turndb
|
||||
.PP
|
||||
/usr/local/etc/turnserver.conf
|
||||
.PP
|
||||
/usr/local/etc/turnuserdb.conf
|
||||
.PP
|
||||
=================================
|
||||
.SH DIRECTORIES
|
||||
|
||||
|
||||
@ -9,13 +9,15 @@ service, you have to:
|
||||
Use /usr/local/etc/turnserver.conf.default as an example.
|
||||
|
||||
b) For user accounts settings, if using the turnserver
|
||||
with authentication: create and edit /etc/turnuserdb.conf
|
||||
file, or set up PostgreSQL or MySQL or MongoDB or Redis database for user accounts.
|
||||
Use /usr/local/etc/turnuserdb.conf.default as example for flat file DB,
|
||||
or use /usr/local/share/turnserver/schema.sql as SQL database schema,
|
||||
with authentication: set up SQLite or PostgreSQL or MySQL or MongoDB or
|
||||
Redis database for user accounts.
|
||||
Use /usr/local/share/turnserver/schema.sql as SQL database schema,
|
||||
or use /usr/local/share/turnserver/schema.userdb.redis as Redis
|
||||
database schema description and/or /usr/local/share/turnserver/schema.stats.redis
|
||||
as Redis status & statistics database schema description.
|
||||
|
||||
The installation process automatically creates /var/db/turndb SQlite database file,
|
||||
with empty tables.
|
||||
|
||||
c) add whatever is necessary to enable start-up daemon for the /usr/local/bin/turnserver.
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
# Common settings script.
|
||||
|
||||
TURNVERSION=4.2.3.2
|
||||
TURNVERSION=4.3.1.1
|
||||
BUILDDIR=~/rpmbuild
|
||||
ARCH=`uname -p`
|
||||
TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Name: turnserver
|
||||
Version: 4.2.3.2
|
||||
Version: 4.3.1.1
|
||||
Release: 0%{dist}
|
||||
Summary: Coturn TURN Server
|
||||
|
||||
@ -112,8 +112,6 @@ DESTDIR=$RPM_BUILD_ROOT make install
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig
|
||||
install -m644 rpm/turnserver.sysconfig \
|
||||
$RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/turnserver
|
||||
mv $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnuserdb.conf.default \
|
||||
$RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnuserdb.conf
|
||||
%if 0%{?el6}
|
||||
cat $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf.default | \
|
||||
sed s/#syslog/syslog/g | \
|
||||
@ -169,12 +167,12 @@ fi
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/turnserver
|
||||
%{_bindir}/turnadmin
|
||||
%{_localstatedir}/db/turndb
|
||||
%{_mandir}/man1/coturn.1.gz
|
||||
%{_mandir}/man1/turnserver.1.gz
|
||||
%{_mandir}/man1/turnadmin.1.gz
|
||||
%dir %attr(-,turnserver,turnserver) %{_sysconfdir}/%{name}
|
||||
%config(noreplace) %attr(0644,turnserver,turnserver) %{_sysconfdir}/%{name}/turnserver.conf
|
||||
%config(noreplace) %attr(0644,turnserver,turnserver) %{_sysconfdir}/%{name}/turnuserdb.conf
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/turnserver
|
||||
%if 0%{?el6}
|
||||
%config %{_sysconfdir}/rc.d/init.d/turnserver
|
||||
@ -203,7 +201,6 @@ fi
|
||||
%{_datadir}/%{name}/etc/turn_server_cert.pem
|
||||
%{_datadir}/%{name}/etc/turn_server_pkey.pem
|
||||
%{_datadir}/%{name}/etc/turnserver.conf
|
||||
%{_datadir}/%{name}/etc/turnuserdb.conf
|
||||
%dir %{_datadir}/%{name}/scripts
|
||||
%{_datadir}/%{name}/scripts/peer.sh
|
||||
%{_datadir}/%{name}/scripts/readme.txt
|
||||
@ -295,7 +292,7 @@ fi
|
||||
|
||||
%changelog
|
||||
* Mon Nov 10 2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
- Sync to 4.2.3.2
|
||||
- Sync to 4.3.1.1
|
||||
* Thu Nov 07 2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
- Sync to 4.2.3.1
|
||||
* Sun Oct 26 2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
|
||||
818
src/apps/relay/dbdrivers/dbd_sqlite.c
Normal file
818
src/apps/relay/dbdrivers/dbd_sqlite.c
Normal file
@ -0,0 +1,818 @@
|
||||
/*
|
||||
* Copyright (C) 2011, 2012, 2013 Citrix Systems
|
||||
* Copyright (C) 2014 Vivocha S.p.A.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../mainrelay.h"
|
||||
#include "dbd_sqlite.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
pud->connection = pqdbconnection;
|
||||
}
|
||||
return pqdbconnection;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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_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) {
|
||||
size_t sz = get_hmackey_size(turn_params.shatype);
|
||||
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;
|
||||
}
|
||||
|
||||
static int pgsql_get_user_pwd(u08bits *usname, st_password_t pwd) {
|
||||
int ret = -1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
snprintf(statement,sizeof(statement),"select password from turnusers_st where name='%s'",usname);
|
||||
|
||||
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 {
|
||||
char *kval = PQgetvalue(res,0,0);
|
||||
if(kval) {
|
||||
strncpy((char*)pwd,kval,sizeof(st_password_t));
|
||||
ret = 0;
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password data for user %s: NULL\n",usname);
|
||||
}
|
||||
}
|
||||
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
|
||||
|
||||
int ret = -1;
|
||||
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key 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((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;
|
||||
}
|
||||
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_list_oauth_keys(void) {
|
||||
|
||||
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,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);
|
||||
|
||||
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((char*)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((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",
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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_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 pgsql_set_user_pwd(u08bits *usname, st_password_t pwd) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_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);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
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);
|
||||
} else {
|
||||
snprintf(statement,sizeof(statement),"select name,realm from turnusers_lt order by 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;
|
||||
for(i=0;i<PQntuples(res);i++) {
|
||||
char *kval = PQgetvalue(res,i,0);
|
||||
if(kval) {
|
||||
char *rval = PQgetvalue(res,i,1);
|
||||
if(rval && *rval) {
|
||||
printf("%s[%s]\n",kval,rval);
|
||||
} else {
|
||||
printf("%s\n",kval);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_show_secret(u08bits *realm) {
|
||||
int ret = -1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm);
|
||||
|
||||
donot_print_connection_success=1;
|
||||
|
||||
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++) {
|
||||
char *kval = PQgetvalue(res,i,0);
|
||||
if(kval) {
|
||||
printf("%s\n",kval);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_del_secret(u08bits *secret, u08bits *realm) {
|
||||
int ret = -1;
|
||||
donot_print_connection_success=1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if (pqc) {
|
||||
if(!secret || (secret[0]==0))
|
||||
snprintf(statement,sizeof(statement),"delete from turn_secret where realm='%s'",realm);
|
||||
else
|
||||
snprintf(statement,sizeof(statement),"delete from turn_secret where value='%s' and realm='%s'",secret,realm);
|
||||
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_set_secret(u08bits *secret, u08bits *realm) {
|
||||
int ret = -1;
|
||||
donot_print_connection_success = 1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if (pqc) {
|
||||
snprintf(statement,sizeof(statement),"insert into turn_secret (realm,value) values('%s','%s')",realm,secret);
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
|
||||
TURN_LOG_FUNC(
|
||||
TURN_LOG_LEVEL_ERROR,
|
||||
"Error inserting/updating secret key information: %s\n",
|
||||
PQerrorMessage(pqc));
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_add_origin(u08bits *origin, u08bits *realm) {
|
||||
int ret = -1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if(pqc) {
|
||||
snprintf(statement,sizeof(statement),"insert into turn_origin_to_realm (origin,realm) values('%s','%s')",origin,realm);
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting origin information: %s\n",PQerrorMessage(pqc));
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_del_origin(u08bits *origin) {
|
||||
int ret = -1;
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if(pqc) {
|
||||
snprintf(statement,sizeof(statement),"delete from turn_origin_to_realm where origin='%s'",origin);
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting origin information: %s\n",PQerrorMessage(pqc));
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pgsql_list_origins(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 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 origin,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 *oval = PQgetvalue(res,i,0);
|
||||
if(oval) {
|
||||
char *rval = PQgetvalue(res,i,1);
|
||||
if(rval) {
|
||||
printf("%s ==>> %s\n",oval,rval);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 pgsql_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);
|
||||
} else {
|
||||
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;i<PQntuples(res);i++) {
|
||||
char *rval = PQgetvalue(res,i,0);
|
||||
if(rval) {
|
||||
char *oval = PQgetvalue(res,i,1);
|
||||
if(oval) {
|
||||
char *vval = PQgetvalue(res,i,2);
|
||||
if(vval) {
|
||||
printf("%s[%s]=%s\n",oval,rval,vval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pgsql_auth_ping(void * rch) {
|
||||
UNUSED_ARG(rch);
|
||||
donot_print_connection_success = 1;
|
||||
PGconn * pqc = get_pqdb_connection();
|
||||
if(pqc) {
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
STRCPY(statement,"select value from turn_secret");
|
||||
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));
|
||||
}
|
||||
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int pgsql_get_ip_list(const char *kind, ip_range_list_t * list)
|
||||
{
|
||||
int ret = -1;
|
||||
PGconn * pqc = get_pqdb_connection();
|
||||
if (pqc) {
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind);
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
|
||||
if (!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) {
|
||||
static int wrong_table_reported = 0;
|
||||
if(!wrong_table_reported) {
|
||||
wrong_table_reported = 1;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s; probably, the tables 'allowed_peer_ip' and/or 'denied_peer_ip' have to be upgraded to include the realm column.\n",PQerrorMessage(pqc));
|
||||
}
|
||||
snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind);
|
||||
res = PQexec(pqc, statement);
|
||||
}
|
||||
|
||||
if (res && (PQresultStatus(res) == PGRES_TUPLES_OK)) {
|
||||
int i = 0;
|
||||
for (i = 0; i < PQntuples(res); i++) {
|
||||
char *kval = PQgetvalue(res, i, 0);
|
||||
char *rval = PQgetvalue(res, i, 1);
|
||||
if (kval) {
|
||||
add_ip_list_range(kval, rval, list);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pgsql_reread_realms(secrets_list_t * realms_list) {
|
||||
PGconn * pqc = get_pqdb_connection();
|
||||
if(pqc) {
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
|
||||
{
|
||||
snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm");
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
|
||||
if(res && (PQresultStatus(res) == PGRES_TUPLES_OK)) {
|
||||
|
||||
ur_string_map *o_to_realm_new = ur_string_map_create(turn_free_simple);
|
||||
|
||||
int i = 0;
|
||||
for(i=0;i<PQntuples(res);i++) {
|
||||
char *oval = PQgetvalue(res,i,0);
|
||||
if(oval) {
|
||||
char *rval = PQgetvalue(res,i,1);
|
||||
if(rval) {
|
||||
get_realm(rval);
|
||||
ur_string_map_value_type value = turn_strdup(rval);
|
||||
ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_o_to_realm(o_to_realm_new);
|
||||
}
|
||||
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t rlsz = 0;
|
||||
|
||||
lock_realms();
|
||||
rlsz = realms_list->sz;
|
||||
unlock_realms();
|
||||
|
||||
for (i = 0; i<rlsz; ++i) {
|
||||
|
||||
char *realm = realms_list->secrets[i];
|
||||
|
||||
realm_params_t* rp = get_realm(realm);
|
||||
|
||||
lock_realms();
|
||||
rp->options.perf_options.max_bps = turn_params.max_bps;
|
||||
unlock_realms();
|
||||
|
||||
lock_realms();
|
||||
rp->options.perf_options.total_quota = turn_params.total_quota;
|
||||
unlock_realms();
|
||||
|
||||
lock_realms();
|
||||
rp->options.perf_options.user_quota = turn_params.user_quota;
|
||||
unlock_realms();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option");
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
|
||||
if(res && (PQresultStatus(res) == PGRES_TUPLES_OK)) {
|
||||
|
||||
int i = 0;
|
||||
for(i=0;i<PQntuples(res);i++) {
|
||||
char *rval = PQgetvalue(res,i,0);
|
||||
char *oval = PQgetvalue(res,i,1);
|
||||
char *vval = PQgetvalue(res,i,2);
|
||||
if(rval && oval && vval) {
|
||||
realm_params_t* rp = get_realm(rval);
|
||||
if(!strcmp(oval,"max-bps"))
|
||||
rp->options.perf_options.max_bps = (band_limit_t)atol(vval);
|
||||
else if(!strcmp(oval,"total-quota"))
|
||||
rp->options.perf_options.total_quota = (vint)atoi(vval);
|
||||
else if(!strcmp(oval,"user-quota"))
|
||||
rp->options.perf_options.user_quota = (vint)atoi(vval);
|
||||
else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
turn_dbdriver_t * get_sqlite_dbdriver(void) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
49
src/apps/relay/dbdrivers/dbd_sqlite.h
Normal file
49
src/apps/relay/dbdrivers/dbd_sqlite.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2011, 2012, 2013 Citrix Systems
|
||||
* Copyright (C) 2014 Vivocha S.p.A.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __DBD_SQLITE__
|
||||
#define __DBD_SQLITE__
|
||||
|
||||
#include "dbdriver.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
turn_dbdriver_t * get_sqlite_dbdriver(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/// __DBD_SQLITE__///
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "apputils.h"
|
||||
|
||||
#include "dbdriver.h"
|
||||
#include "dbd_sqlite.h"
|
||||
#include "dbd_pgsql.h"
|
||||
#include "dbd_mysql.h"
|
||||
#include "dbd_mongo.h"
|
||||
@ -62,6 +63,9 @@ persistent_users_db_t * get_persistent_users_db(void) {
|
||||
turn_dbdriver_t * get_dbdriver() {
|
||||
if (!_driver) {
|
||||
switch(turn_params.default_users_db.userdb_type) {
|
||||
case TURN_USERDB_TYPE_SQLITE:
|
||||
_driver = get_sqlite_dbdriver();
|
||||
break;
|
||||
#if !defined(TURN_NO_PQ)
|
||||
case TURN_USERDB_TYPE_PQ:
|
||||
_driver = get_pgsql_dbdriver();
|
||||
|
||||
@ -95,7 +95,7 @@ LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"",
|
||||
/////////////// MISC PARAMS ////////////////
|
||||
0,0,0,0,0,SHATYPE_SHA1,':',0,0,TURN_CREDENTIALS_NONE,0,0,0,0,0,0,
|
||||
///////////// Users DB //////////////
|
||||
{ TURN_USERDB_TYPE_FILE, {"\0",NULL}, {0,NULL,NULL, {NULL,0}} }
|
||||
{ TURN_USERDB_TYPE_SQLITE, {"\0",NULL}, {0,NULL,NULL, {NULL,0}} }
|
||||
|
||||
};
|
||||
|
||||
@ -386,17 +386,14 @@ static char Usage[] = "Usage: turnserver [options]\n"
|
||||
" -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n"
|
||||
" -o, --daemon Start process as daemon (detach from current shell).\n"
|
||||
" -f, --fingerprint Use fingerprints in the TURN messages.\n"
|
||||
" -a, --lt-cred-mech Use the long-term credential mechanism. This option can be used with either\n"
|
||||
" flat file user database or PostgreSQL DB or MySQL DB for user keys storage.\n"
|
||||
" -A, --st-cred-mech Use the short-term credential mechanism. This option requires\n"
|
||||
" a PostgreSQL or MySQL DB for short term passwords storage.\n"
|
||||
" -a, --lt-cred-mech Use the long-term credential mechanism.\n"
|
||||
" -A, --st-cred-mech Use the short-term credential mechanism.\n"
|
||||
" -z, --no-auth Do not use any credential mechanism, allow anonymous access.\n"
|
||||
" -u, --user <user:pwd> User account, in form 'username:password', for long-term credentials.\n"
|
||||
" Cannot be used with TURN REST API or with short-term credentials.\n"
|
||||
" -r, --realm <realm> The default realm to be used for the users when no explicit\n"
|
||||
" origin/realm relationship was found in the database, or if the TURN\n"
|
||||
" server is not using any database (just the commands-line settings\n"
|
||||
" and the userdb file). Must be used with long-term credentials \n"
|
||||
" origin/realm relationship was found in the database.\n"
|
||||
" Must be used with long-term credentials \n"
|
||||
" mechanism or with TURN REST API.\n"
|
||||
" --check-origin-consistency The flag that sets the origin consistency check:\n"
|
||||
" across the session, all requests must have the same\n"
|
||||
@ -415,7 +412,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
|
||||
" Total bytes-per-second bandwidth the TURN server is allowed to allocate\n"
|
||||
" for the sessions, combined (input and output network streams are treated separately).\n"
|
||||
" -c <filename> Configuration file name (default - turnserver.conf).\n"
|
||||
" -b, --userdb <filename> User database file name (default - turnuserdb.conf) for long-term credentials only.\n"
|
||||
" -b, , --db, --userdb <filename> SQLite database file name (default - "DEFAULT_USERDB_FILE").\n"
|
||||
#if !defined(TURN_NO_PQ)
|
||||
" -e, --psql-userdb, --sql-userdb <conn-string> PostgreSQL database connection string, if used (default - empty, no PostreSQL DB used).\n"
|
||||
" This database can be used for long-term and short-term credentials mechanisms,\n"
|
||||
@ -569,7 +566,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
|
||||
"\n";
|
||||
|
||||
static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
|
||||
"Commands:\n"
|
||||
"\nCommands:\n\n"
|
||||
" -k, --key generate long-term credential mechanism key for a user\n"
|
||||
" -a, --add add/update a long-term mechanism user\n"
|
||||
" -A, --add-st add/update a short-term mechanism user\n"
|
||||
@ -577,7 +574,6 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
|
||||
" -D, --delete-st delete a short-term mechanism user\n"
|
||||
" -l, --list list all long-term mechanism users\n"
|
||||
" -L, --list-st list all short-term mechanism users\n"
|
||||
#if !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
|
||||
" -s, --set-secret=<value> Add shared secret for TURN RESP API\n"
|
||||
" -S, --show-secret Show stored shared secrets for TURN REST API\n"
|
||||
" -X, --delete-secret=<value> Delete a shared secret\n"
|
||||
@ -587,9 +583,8 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
|
||||
" -I, --list-origins List origin-to-realm relations.\n"
|
||||
" -g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.\n"
|
||||
" -G, --list-realm-options List realm params.\n"
|
||||
#endif
|
||||
"Options with mandatory values:\n"
|
||||
" -b, --userdb User database file, if flat DB file is used.\n"
|
||||
"\nOptions with mandatory values:\n\n"
|
||||
" -b, --db, --userdb SQLite database file, default value is "DEFAULT_USERDB_FILE".\n"
|
||||
#if !defined(TURN_NO_PQ)
|
||||
" -e, --psql-userdb, --sql-userdb PostgreSQL user database connection string, if PostgreSQL DB is used.\n"
|
||||
#endif
|
||||
@ -720,6 +715,7 @@ static const struct myoption long_options[] = {
|
||||
{ "no-auth", optional_argument, NULL, 'z' },
|
||||
{ "user", required_argument, NULL, 'u' },
|
||||
{ "userdb", required_argument, NULL, 'b' },
|
||||
{ "db", required_argument, NULL, 'b' },
|
||||
#if !defined(TURN_NO_PQ)
|
||||
{ "psql-userdb", required_argument, NULL, 'e' },
|
||||
{ "sql-userdb", required_argument, NULL, 'e' },
|
||||
@ -808,15 +804,14 @@ static const struct myoption admin_long_options[] = {
|
||||
{ "delete", no_argument, NULL, 'd' },
|
||||
{ "list", no_argument, NULL, 'l' },
|
||||
{ "list-st", no_argument, NULL, 'L' },
|
||||
#if !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
|
||||
{ "set-secret", required_argument, NULL, 's' },
|
||||
{ "show-secret", no_argument, NULL, 'S' },
|
||||
{ "delete-secret", required_argument, NULL, 'X' },
|
||||
{ "delete-all-secrets", no_argument, NULL, DEL_ALL_AUTH_SECRETS_OPT },
|
||||
#endif
|
||||
{ "add-st", no_argument, NULL, 'A' },
|
||||
{ "delete-st", no_argument, NULL, 'D' },
|
||||
{ "userdb", required_argument, NULL, 'b' },
|
||||
{ "db", required_argument, NULL, 'b' },
|
||||
#if !defined(TURN_NO_PQ)
|
||||
{ "psql-userdb", required_argument, NULL, 'e' },
|
||||
{ "sql-userdb", required_argument, NULL, 'e' },
|
||||
@ -834,7 +829,6 @@ static const struct myoption admin_long_options[] = {
|
||||
{ "realm", required_argument, NULL, 'r' },
|
||||
{ "password", required_argument, NULL, 'p' },
|
||||
{ "sha256", no_argument, NULL, 'H' },
|
||||
#if !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
|
||||
{ "add-origin", no_argument, NULL, 'O' },
|
||||
{ "del-origin", no_argument, NULL, 'R' },
|
||||
{ "list-origins", required_argument, NULL, 'I' },
|
||||
@ -844,7 +838,6 @@ static const struct myoption admin_long_options[] = {
|
||||
{ "user-quota", required_argument, NULL, ADMIN_USER_QUOTA_OPT },
|
||||
{ "total-quota", required_argument, NULL, ADMIN_TOTAL_QUOTA_OPT },
|
||||
{ "max-bps", required_argument, NULL, ADMIN_MAX_BPS_OPT },
|
||||
#endif
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
@ -1113,7 +1106,7 @@ static void set_option(int c, char *value)
|
||||
break;
|
||||
case 'b':
|
||||
STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
|
||||
turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_FILE;
|
||||
turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE;
|
||||
break;
|
||||
#if !defined(TURN_NO_PQ)
|
||||
case 'e':
|
||||
@ -1461,7 +1454,6 @@ static int adminmain(int argc, char **argv)
|
||||
ct = TA_LIST_USERS;
|
||||
is_st = 1;
|
||||
break;
|
||||
#if !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
|
||||
case 's':
|
||||
ct = TA_SET_SECRET;
|
||||
STRCPY(secret,optarg);
|
||||
@ -1477,10 +1469,9 @@ static int adminmain(int argc, char **argv)
|
||||
case DEL_ALL_AUTH_SECRETS_OPT:
|
||||
ct = TA_DEL_SECRET;
|
||||
break;
|
||||
#endif
|
||||
case 'b':
|
||||
STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
|
||||
turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_FILE;
|
||||
turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE;
|
||||
break;
|
||||
#if !defined(TURN_NO_PQ)
|
||||
case 'e':
|
||||
@ -1544,12 +1535,7 @@ static int adminmain(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if(is_st && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_FILE)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: you have to use a PostgreSQL or MySQL database with short-term credentials\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_FILE))
|
||||
if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE))
|
||||
STRCPY(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE);
|
||||
|
||||
if(ct == TA_COMMAND_UNKNOWN) {
|
||||
@ -1601,6 +1587,8 @@ static void print_features(unsigned long mfn)
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "AEAD supported\n");
|
||||
#endif
|
||||
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite supported\n");
|
||||
|
||||
#if !defined(TURN_NO_HIREDIS)
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis supported\n");
|
||||
#else
|
||||
@ -1851,10 +1839,9 @@ int main(int argc, char **argv)
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIG: WARNING: --server-relay: NON-STANDARD AND DANGEROUS OPTION.\n");
|
||||
}
|
||||
|
||||
if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_FILE))
|
||||
if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE))
|
||||
STRCPY(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE);
|
||||
|
||||
read_userdb_file(0);
|
||||
update_white_and_black_lists();
|
||||
|
||||
argc -= optind;
|
||||
@ -1891,9 +1878,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if(use_lt_credentials) {
|
||||
if(!turn_params.default_users_db.ram_db.users_number && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_FILE) && !turn_params.use_auth_secret_with_timestamp) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you did not specify any user account, (-u option) \n but you did specified a long-term credentials mechanism option (-a option).\n The TURN Server will be inaccessible.\n Check your configuration.\n");
|
||||
} else if(!get_realm(NULL)->options.name[0]) {
|
||||
if(!get_realm(NULL)->options.name[0]) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you did specify the long-term credentials usage\n but you did not specify the default realm option (-r option).\n Check your configuration.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1696,7 +1696,6 @@ static void* run_auth_server_thread(void *arg)
|
||||
while(run_auth_server_flag) {
|
||||
reread_realms();
|
||||
run_events(eb,NULL);
|
||||
read_userdb_file(0);
|
||||
update_white_and_black_lists();
|
||||
auth_ping(authserver->rch);
|
||||
#if defined(DB_TEST)
|
||||
|
||||
@ -781,8 +781,8 @@ static void cli_print_configuration(struct cli_session* cs)
|
||||
|
||||
if(turn_params.default_users_db.persistent_users_db.userdb[0]) {
|
||||
switch(turn_params.default_users_db.userdb_type) {
|
||||
case TURN_USERDB_TYPE_FILE:
|
||||
cli_print_str(cs,"file","DB type",0);
|
||||
case TURN_USERDB_TYPE_SQLITE:
|
||||
cli_print_str(cs,"SQLite","DB type",0);
|
||||
break;
|
||||
#if !defined(TURN_NO_PQ)
|
||||
case TURN_USERDB_TYPE_PQ:
|
||||
|
||||
@ -736,83 +736,6 @@ void release_allocation_quota(u08bits *user, int oauth, u08bits *realm)
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
void read_userdb_file(int to_print)
|
||||
{
|
||||
static char *full_path_to_userdb_file = NULL;
|
||||
static int first_read = 1;
|
||||
static turn_time_t mtime = 0;
|
||||
|
||||
if(turn_params.default_users_db.userdb_type != TURN_USERDB_TYPE_FILE)
|
||||
return;
|
||||
if(turn_params.use_auth_secret_with_timestamp)
|
||||
return;
|
||||
|
||||
FILE *f = NULL;
|
||||
|
||||
persistent_users_db_t *pud = get_persistent_users_db();
|
||||
|
||||
if(full_path_to_userdb_file) {
|
||||
struct stat sb;
|
||||
if(stat(full_path_to_userdb_file,&sb)<0) {
|
||||
perror("File statistics");
|
||||
} else {
|
||||
turn_time_t newmtime = (turn_time_t)(sb.st_mtime);
|
||||
if(mtime == newmtime)
|
||||
return;
|
||||
mtime = newmtime;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!full_path_to_userdb_file)
|
||||
full_path_to_userdb_file = find_config_file(pud->userdb, first_read);
|
||||
|
||||
if (full_path_to_userdb_file)
|
||||
f = fopen(full_path_to_userdb_file, "r");
|
||||
|
||||
if (f) {
|
||||
|
||||
char sbuf[TURN_LONG_STRING_SIZE];
|
||||
|
||||
ur_string_map_lock(turn_params.default_users_db.ram_db.dynamic_accounts);
|
||||
|
||||
ur_string_map_clean(turn_params.default_users_db.ram_db.dynamic_accounts);
|
||||
|
||||
for (;;) {
|
||||
char *s = fgets(sbuf, sizeof(sbuf) - 1, f);
|
||||
if (!s)
|
||||
break;
|
||||
s = skip_blanks(s);
|
||||
if (s[0] == '#')
|
||||
continue;
|
||||
if (!s[0])
|
||||
continue;
|
||||
size_t slen = strlen(s);
|
||||
while (slen && (s[slen - 1] == 10 || s[slen - 1] == 13))
|
||||
s[--slen] = 0;
|
||||
if (slen) {
|
||||
if(to_print) {
|
||||
char* sc=strstr(s,":");
|
||||
if(sc)
|
||||
sc[0]=0;
|
||||
printf("%s\n",s);
|
||||
} else {
|
||||
add_user_account(s,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ur_string_map_unlock(turn_params.default_users_db.ram_db.dynamic_accounts);
|
||||
|
||||
fclose(f);
|
||||
|
||||
} else if (first_read) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Cannot find userdb file: %s: going without flat file user database.\n", pud->userdb);
|
||||
}
|
||||
|
||||
first_read = 0;
|
||||
}
|
||||
|
||||
int add_user_account(char *user, int dynamic)
|
||||
{
|
||||
/* Realm is either default or empty for users taken from file or command-line */
|
||||
@ -872,11 +795,9 @@ static int list_users(int is_st, u08bits *realm)
|
||||
turn_dbdriver_t * dbd = get_dbdriver();
|
||||
if (dbd && dbd->list_users) {
|
||||
(*dbd->list_users)(is_st, realm);
|
||||
} else if(!is_st) {
|
||||
read_userdb_file(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_secret(u08bits *realm)
|
||||
@ -989,217 +910,107 @@ static int list_realm_options(u08bits *realm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08bits *origin,
|
||||
TURNADMIN_COMMAND_TYPE ct, int is_st,
|
||||
perf_options_t *po) {
|
||||
int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08bits *origin, TURNADMIN_COMMAND_TYPE ct, int is_st, perf_options_t *po)
|
||||
{
|
||||
hmackey_t key;
|
||||
char skey[sizeof(hmackey_t)*2+1];
|
||||
char skey[sizeof(hmackey_t) * 2 + 1];
|
||||
|
||||
st_password_t passwd;
|
||||
|
||||
if(ct == TA_LIST_USERS) {
|
||||
if (ct == TA_LIST_USERS) {
|
||||
return list_users(is_st, realm);
|
||||
}
|
||||
|
||||
if(ct == TA_LIST_ORIGINS) {
|
||||
if (ct == TA_LIST_ORIGINS) {
|
||||
return list_origins(realm);
|
||||
}
|
||||
|
||||
if(ct == TA_SHOW_SECRET) {
|
||||
if (ct == TA_SHOW_SECRET) {
|
||||
return show_secret(realm);
|
||||
}
|
||||
|
||||
if(ct == TA_SET_SECRET) {
|
||||
if (ct == TA_SET_SECRET) {
|
||||
return set_secret(secret, realm);
|
||||
}
|
||||
|
||||
if(ct == TA_DEL_SECRET) {
|
||||
if (ct == TA_DEL_SECRET) {
|
||||
return del_secret(secret, realm);
|
||||
}
|
||||
|
||||
if(ct == TA_ADD_ORIGIN) {
|
||||
if (ct == TA_ADD_ORIGIN) {
|
||||
must_set_admin_origin(origin);
|
||||
must_set_admin_realm(realm);
|
||||
return add_origin(origin,realm);
|
||||
return add_origin(origin, realm);
|
||||
}
|
||||
|
||||
if(ct == TA_DEL_ORIGIN) {
|
||||
if (ct == TA_DEL_ORIGIN) {
|
||||
must_set_admin_origin(origin);
|
||||
return del_origin(origin);
|
||||
}
|
||||
|
||||
if(ct == TA_SET_REALM_OPTION) {
|
||||
if (ct == TA_SET_REALM_OPTION) {
|
||||
must_set_admin_realm(realm);
|
||||
if(!(po && (po->max_bps!=((band_limit_t)-1) || po->total_quota>=0 || po->user_quota>=0))) {
|
||||
if (!(po && (po->max_bps != ((band_limit_t) -1) || po->total_quota >= 0 || po->user_quota >= 0))) {
|
||||
fprintf(stderr, "The operation cannot be completed: a realm option must be set.\n");
|
||||
exit(-1);
|
||||
}
|
||||
return set_realm_option(realm,po);
|
||||
return set_realm_option(realm, po);
|
||||
}
|
||||
|
||||
if(ct == TA_LIST_REALM_OPTIONS) {
|
||||
if (ct == TA_LIST_REALM_OPTIONS) {
|
||||
return list_realm_options(realm);
|
||||
}
|
||||
|
||||
must_set_admin_user(user);
|
||||
|
||||
if(ct != TA_DELETE_USER) {
|
||||
if (ct != TA_DELETE_USER) {
|
||||
|
||||
must_set_admin_pwd(pwd);
|
||||
|
||||
if(is_st) {
|
||||
strncpy((char*)passwd,(char*)pwd,sizeof(st_password_t));
|
||||
if (is_st) {
|
||||
strncpy((char*) passwd, (char*) pwd, sizeof(st_password_t));
|
||||
} else {
|
||||
stun_produce_integrity_key_str(user, realm, pwd, key, turn_params.shatype);
|
||||
size_t i = 0;
|
||||
size_t sz = get_hmackey_size(turn_params.shatype);
|
||||
int maxsz = (int)(sz*2)+1;
|
||||
char *s=skey;
|
||||
for(i=0;(i<sz) && (maxsz>2);i++) {
|
||||
snprintf(s,(size_t)(sz*2),"%02x",(unsigned int)key[i]);
|
||||
maxsz-=2;
|
||||
s+=2;
|
||||
int maxsz = (int) (sz * 2) + 1;
|
||||
char *s = skey;
|
||||
for (i = 0; (i < sz) && (maxsz > 2); i++) {
|
||||
snprintf(s, (size_t) (sz * 2), "%02x", (unsigned int) key[i]);
|
||||
maxsz -= 2;
|
||||
s += 2;
|
||||
}
|
||||
skey[sz*2]=0;
|
||||
skey[sz * 2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
turn_dbdriver_t * dbd = get_dbdriver();
|
||||
turn_dbdriver_t * dbd = get_dbdriver();
|
||||
|
||||
if(ct == TA_PRINT_KEY) {
|
||||
if (ct == TA_PRINT_KEY) {
|
||||
|
||||
if(!is_st) {
|
||||
printf("0x%s\n",skey);
|
||||
if (!is_st) {
|
||||
printf("0x%s\n", skey);
|
||||
}
|
||||
|
||||
} else if(dbd) {
|
||||
} else if (dbd) {
|
||||
|
||||
if(!is_st) {
|
||||
if (!is_st) {
|
||||
must_set_admin_realm(realm);
|
||||
}
|
||||
|
||||
if (ct == TA_DELETE_USER) {
|
||||
if (dbd->del_user)
|
||||
(*dbd->del_user)(user, is_st, realm);
|
||||
} else if (ct == TA_UPDATE_USER) {
|
||||
if (is_st) {
|
||||
if (dbd->set_user_pwd)
|
||||
(*dbd->set_user_pwd)(user, passwd);
|
||||
} else {
|
||||
if (dbd->set_user_key)
|
||||
(*dbd->set_user_key)(user, realm, skey);
|
||||
}
|
||||
}
|
||||
|
||||
} else if(!is_st) {
|
||||
|
||||
persistent_users_db_t *pud = get_persistent_users_db();
|
||||
char *full_path_to_userdb_file = find_config_file(pud->userdb, 1);
|
||||
FILE *f = full_path_to_userdb_file ? fopen(full_path_to_userdb_file,"r") : NULL;
|
||||
int found = 0;
|
||||
char us[TURN_LONG_STRING_SIZE];
|
||||
size_t i = 0;
|
||||
char **content = NULL;
|
||||
size_t csz = 0;
|
||||
|
||||
STRCPY(us, (char*) user);
|
||||
strncpy(us + strlen(us), ":", sizeof(us)-1-strlen(us));
|
||||
us[sizeof(us)-1]=0;
|
||||
|
||||
if (!f) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "File %s not found, will be created.\n",pud->userdb);
|
||||
} else {
|
||||
|
||||
char sarg[TURN_LONG_STRING_SIZE];
|
||||
char sbuf[TURN_LONG_STRING_SIZE];
|
||||
|
||||
for (;;) {
|
||||
char *s0 = fgets(sbuf, sizeof(sbuf) - 1, f);
|
||||
if (!s0)
|
||||
break;
|
||||
|
||||
size_t slen = strlen(s0);
|
||||
while (slen && (s0[slen - 1] == 10 || s0[slen - 1] == 13))
|
||||
s0[--slen] = 0;
|
||||
|
||||
char *s = skip_blanks(s0);
|
||||
|
||||
if (s[0] == '#')
|
||||
goto add_and_cont;
|
||||
if (!s[0])
|
||||
goto add_and_cont;
|
||||
|
||||
STRCPY(sarg, s);
|
||||
if (strstr(sarg, us) == sarg) {
|
||||
if (ct == TA_DELETE_USER)
|
||||
continue;
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
found = 1;
|
||||
STRCPY(us, (char*) user);
|
||||
strncpy(us + strlen(us), ":0x", sizeof(us)-1-strlen(us));
|
||||
us[sizeof(us)-1]=0;
|
||||
size_t sz = get_hmackey_size(turn_params.shatype);
|
||||
for (i = 0; i < sz; i++) {
|
||||
snprintf(
|
||||
us + strlen(us),
|
||||
sizeof(us)-strlen(us),
|
||||
"%02x",
|
||||
(unsigned int) key[i]);
|
||||
}
|
||||
|
||||
s0 = us;
|
||||
}
|
||||
|
||||
add_and_cont:
|
||||
content = (char**)turn_realloc(content, 0, sizeof(char*) * (++csz));
|
||||
content[csz - 1] = turn_strdup(s0);
|
||||
if (ct == TA_DELETE_USER) {
|
||||
if (dbd->del_user)
|
||||
(*dbd->del_user)(user, is_st, realm);
|
||||
} else if (ct == TA_UPDATE_USER) {
|
||||
if (is_st) {
|
||||
if (dbd->set_user_pwd)
|
||||
(*dbd->set_user_pwd)(user, passwd);
|
||||
} else {
|
||||
if (dbd->set_user_key)
|
||||
(*dbd->set_user_key)(user, realm, skey);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if(!found && (ct == TA_UPDATE_USER)) {
|
||||
STRCPY(us,(char*)user);
|
||||
strncpy(us+strlen(us),":0x",sizeof(us)-1-strlen(us));
|
||||
us[sizeof(us)-1]=0;
|
||||
size_t sz = get_hmackey_size(turn_params.shatype);
|
||||
for(i=0;i<sz;i++) {
|
||||
snprintf(us+strlen(us),sizeof(us)-strlen(us),"%02x",(unsigned int)key[i]);
|
||||
}
|
||||
content = (char**)turn_realloc(content,0,sizeof(char*)*(++csz));
|
||||
content[csz-1]=turn_strdup(us);
|
||||
}
|
||||
|
||||
if(!full_path_to_userdb_file)
|
||||
full_path_to_userdb_file=turn_strdup(pud->userdb);
|
||||
|
||||
size_t dirsz = strlen(full_path_to_userdb_file)+21;
|
||||
char *dir = (char*)turn_malloc(dirsz+1);
|
||||
strncpy(dir,full_path_to_userdb_file,dirsz);
|
||||
dir[dirsz]=0;
|
||||
size_t dlen = strlen(dir);
|
||||
while(dlen) {
|
||||
if(dir[dlen-1]=='/')
|
||||
break;
|
||||
dir[--dlen]=0;
|
||||
}
|
||||
strncpy(dir+strlen(dir),".tmp_userdb",dirsz-strlen(dir));
|
||||
|
||||
f = fopen(dir,"w");
|
||||
if(!f) {
|
||||
perror("file open");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for(i=0;i<csz;i++)
|
||||
fprintf(f,"%s\n",content[i]);
|
||||
|
||||
fclose(f);
|
||||
|
||||
rename(dir,full_path_to_userdb_file);
|
||||
turn_free(dir,dirsz+1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -48,7 +48,7 @@ extern "C" {
|
||||
|
||||
//////////// Defines //////////////////////////////
|
||||
|
||||
#define DEFAULT_USERDB_FILE "turnuserdb.conf"
|
||||
#define DEFAULT_USERDB_FILE "/var/db/turndb"
|
||||
|
||||
#define AUTH_SECRET_SIZE (512)
|
||||
|
||||
@ -100,7 +100,7 @@ struct auth_message {
|
||||
};
|
||||
|
||||
enum _TURN_USERDB_TYPE {
|
||||
TURN_USERDB_TYPE_FILE=0
|
||||
TURN_USERDB_TYPE_SQLITE=0
|
||||
#if !defined(TURN_NO_PQ)
|
||||
,TURN_USERDB_TYPE_PQ
|
||||
#endif
|
||||
@ -202,7 +202,6 @@ void release_allocation_quota(u08bits *username, int oauth, u08bits *realm);
|
||||
void run_db_test(void);
|
||||
#endif
|
||||
|
||||
void read_userdb_file(int to_print);
|
||||
void auth_ping(redis_context_handle rch);
|
||||
void reread_realms(void);
|
||||
int add_user_account(char *user, int dynamic);
|
||||
|
||||
@ -31,8 +31,8 @@
|
||||
#ifndef __IOADEFS__
|
||||
#define __IOADEFS__
|
||||
|
||||
#define TURN_SERVER_VERSION "4.2.3.2"
|
||||
#define TURN_SERVER_VERSION_NAME "Monza"
|
||||
#define TURN_SERVER_VERSION "4.3.1.1"
|
||||
#define TURN_SERVER_VERSION_NAME "Tolomei"
|
||||
#define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
|
||||
|
||||
#if (defined(__unix__) || defined(unix)) && !defined(USG)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user