Pārlūkot izejas kodu

Imported Upstream version 4.1.2.1

Oleg Moskalenko 11 gadi atpakaļ
vecāks
revīzija
f746731b8d

+ 10 - 1
ChangeLog

@@ -1,6 +1,15 @@
+08/14/2014 Oleg Moskalenko <[email protected]>
+Version 4.1.2.1 'Vitari':
+	- The origin attribute is verified in the subsequent 
+	session messages (server flag --check-origin-consistency).
+	- MySQL SSL connection support.
+	- Crash fixed when the DB connection string is incorrect.
+	- Minor docs fixes.
+	
 07/29/2014 Oleg Moskalenko <[email protected]>
 07/29/2014 Oleg Moskalenko <[email protected]>
 Version 4.1.1.1 'Vitari':
 Version 4.1.1.1 'Vitari':
-	- Forceful session concellation (TODO).
+	- Forceful server-side session cancellation implemented
+	(in telnet console).
 	
 	
 07/22/2014 Oleg Moskalenko <[email protected]>
 07/22/2014 Oleg Moskalenko <[email protected]>
 Version 4.1.0.2 'Vitari':
 Version 4.1.0.2 'Vitari':

+ 7 - 2
INSTALL

@@ -232,8 +232,7 @@ The following platforms have been used in the development:
 	- FreeBSD 8.x, i386
 	- FreeBSD 8.x, i386
 	- PC-BSD 9.x, x86_64
 	- PC-BSD 9.x, x86_64
 	- Solaris 11, x86_64
 	- Solaris 11, x86_64
-	- Linux CentOS / Red Hat Enterprise Edition 6.3, x86_64 (amd64)
-	- Linux CentOS / Red Hat Enterprise Edition 6.4, x86_32 (i386)
+	- Linux CentOS / Red Hat Enterprise Edition 6.x-7.0, x86_64 (i386 & amd64)
 	- Linux Debian 'Squeeze', i386
 	- Linux Debian 'Squeeze', i386
 	- Linux Mint 14.1 'Nadia', i386
 	- Linux Mint 14.1 'Nadia', i386
 	- Linux Mint 16 'Petra', i386
 	- Linux Mint 16 'Petra', i386
@@ -898,6 +897,12 @@ Or in the turnserver.conf file:
 
 
 mysql-userdb="host=localhost dbname=turn user=turn password=turn connect_timeout=30"
 mysql-userdb="host=localhost dbname=turn user=turn password=turn connect_timeout=30"
 
 
+If you have to use a secure MySQL connection (SSL) then you have to use also
+the optional connection string parameters for the secure communications:
+ca, capath, cert, key, cipher (see 
+http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the 
+command options description).
+
 XVI. MongoDB setup
 XVI. MongoDB setup
 
 
 The MongoDB setup is well documented on their site http://docs.mongodb.org/manual/. 
 The MongoDB setup is well documented on their site http://docs.mongodb.org/manual/. 

+ 17 - 6
README.turnserver

@@ -118,6 +118,11 @@ User database settings:
 		Also, see http://www.mysql.org or http://mariadb.org 
 		Also, see http://www.mysql.org or http://mariadb.org 
 		for full MySQL documentation.
 		for full MySQL documentation.
 		
 		
+		Optional connection string parameters for the secure communications (SSL): 
+		ca, capath, cert, key, cipher 
+		(see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the 
+		command options description).
+		
 -J, --mongo-userdb	User database connection string for MongoDB. 
 -J, --mongo-userdb	User database connection string for MongoDB. 
 		This database can be used for long-term and short-term 
 		This database can be used for long-term and short-term 
 		credentials mechanisms, and it can store the secret value 
 		credentials mechanisms, and it can store the secret value 
@@ -222,8 +227,9 @@ Flags:
 			
 			
 --syslog		With this flag, all log will be redirected to the system log (syslog).
 --syslog		With this flag, all log will be redirected to the system log (syslog).
 
 
---simple-log	This flag means that no log file rollover will be used, and the log file
-				name will be constructed as-is, without PID and date appendage.
+--simple-log		This flag means that no log file rollover will be used, and the log file
+			name will be constructed as-is, without PID and date appendage.
+			This option can be used, for example, together with the logrotate tool.
 				
 				
 --secure-stun		Require authentication of the STUN Binding request.
 --secure-stun		Require authentication of the STUN Binding request.
 			By default, the clients are allowed anonymous access to the STUN Binding functionality.
 			By default, the clients are allowed anonymous access to the STUN Binding functionality.
@@ -263,6 +269,11 @@ Flags:
 			(if configured). The load balancing is using the 
 			(if configured). The load balancing is using the 
 			ALTERNATE-SERVER mechanism. The TURN client must support 
 			ALTERNATE-SERVER mechanism. The TURN client must support 
 			300 ALTERNATE-SERVER response for this functionality.
 			300 ALTERNATE-SERVER response for this functionality.
+			
+--check-origin-consistency	The flag that sets the origin consistency 
+			check: across the session, all requests must have the same
+			main ORIGIN attribute value (if the ORIGIN was
+			initially used by the session).
 
 
 -h			Help.
 -h			Help.
     
     
@@ -305,7 +316,7 @@ Options with required values:
 			on that endpoint only for "symmetry".
 			on that endpoint only for "symmetry".
 
 
 --alt-tls-listening-port	Alternative listening port for TLS and DTLS protocols.
 --alt-tls-listening-port	Alternative listening port for TLS and DTLS protocols.
-				Default (or zero) value means "TLS listening port plus one".
+			Default (or zero) value means "TLS listening port plus one".
 				
 				
 --aux-server		Auxiliary STUN/TURN server listening endpoint.
 --aux-server		Auxiliary STUN/TURN server listening endpoint.
 			Aux servers have almost full TURN and STUN functionality.
 			Aux servers have almost full TURN and STUN functionality.
@@ -382,8 +393,8 @@ Options with required values:
 			and the userdb file). Must be used with long-term credentials 
 			and the userdb file). Must be used with long-term credentials 
 			mechanism or with TURN REST API.
 			mechanism or with TURN REST API.
 
 
--C, --rest-api-separator	This is the timestamp/username separator symbol (character) in TURN REST API.
-				The default value is :.
+-C, --rest-api-separator	This is the timestamp/username separator symbol 
+			(character) in TURN REST API. The default value is :.
 
 
 -q, --user-quota	Per-user allocations quota: how many concurrent 
 -q, --user-quota	Per-user allocations quota: how many concurrent 
 			allocations a user can create. This option can also be set 
 			allocations a user can create. This option can also be set 
@@ -527,7 +538,7 @@ Options with required values:
 --cli-max-output-sessions	Maximum number of output sessions in ps CLI command.
 --cli-max-output-sessions	Maximum number of output sessions in ps CLI command.
 			This value can be changed on-the-fly in CLI. The default value is 256.
 			This value can be changed on-the-fly in CLI. The default value is 256.
 
 
---ne=[1|2|3]			Set network engine type for the process (for internal purposes).
+--ne=[1|2|3]		Set network engine type for the process (for internal purposes).
 
 
 ==================================
 ==================================
 
 

+ 2 - 0
STATUS

@@ -102,6 +102,8 @@ compatibility.
 43) MongoDB support added.
 43) MongoDB support added.
 
 
 44) Double (dual) allocation added (SSODA draft).
 44) Double (dual) allocation added (SSODA draft).
+
+45) Secure MySQL connection implemented.
  
  
 Things to be implemented in future (the development roadmap) 
 Things to be implemented in future (the development roadmap) 
 are described in the TODO file.
 are described in the TODO file.

+ 2 - 4
TODO

@@ -47,7 +47,7 @@
 
 
 ==================================================================
 ==================================================================
 
 
-1) RADIUS integration ?
+1) New security oAuth draft.
 
 
 ==================================================================
 ==================================================================
 
 
@@ -63,9 +63,7 @@
 
 
 4) Redirect draft.
 4) Redirect draft.
 
 
-5) New security oAuth draft.
-
-6) DTLS 1.2 (when available).
+5) DTLS 1.2 (when available).
 
 
 ==================================================================
 ==================================================================
 
 

+ 16 - 1
examples/etc/turnserver.conf

@@ -263,7 +263,13 @@
 # MySQL database connection string in the case that we are using MySQL
 # MySQL database connection string in the case that we are using MySQL
 # as the user database.
 # as the user database.
 # This database can be used for long-term and short-term credential mechanisms
 # This database can be used for long-term and short-term credential mechanisms
-# and it can store the secret value for secret-based timed authentication in TURN RESP API. 
+# and it can store the secret value for secret-based timed authentication in TURN RESP API.
+#
+# Optional connection string parameters for the secure communications (SSL): 
+# ca, capath, cert, key, cipher 
+# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the 
+# command options description).
+#
 # Use string format as below (space separated parameters, all optional):
 # Use string format as below (space separated parameters, all optional):
 #
 #
 #mysql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds>"
 #mysql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds>"
@@ -300,6 +306,13 @@
 #
 #
 #realm=mycompany.org
 #realm=mycompany.org
 
 
+# The flag that sets the origin consistency 
+# check: across the session, all requests must have the same
+# main ORIGIN attribute value (if the ORIGIN was
+# initially used by the session).
+#
+#check-origin-consistency
+
 # Per-user allocation quota.
 # Per-user allocation quota.
 # default value is 0 (no quota, unlimited number of sessions per user).
 # default value is 0 (no quota, unlimited number of sessions per user).
 # This option can also be set through the database, for a particular realm.
 # This option can also be set through the database, for a particular realm.
@@ -441,6 +454,8 @@
 
 
 # This flag means that no log file rollover will be used, and the log file
 # This flag means that no log file rollover will be used, and the log file
 # name will be constructed as-is, without PID and date appendage.
 # name will be constructed as-is, without PID and date appendage.
+# This option can be used, for example, together with the logrotate tool.
+#
 #simple-log
 #simple-log
 
 
 # Option to set the "redirection" mode. The value of this option
 # Option to set the "redirection" mode. The value of this option

+ 35 - 0
examples/scripts/longtermsecuredb/secure_relay_with_db_mysql_ssl.sh

@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# This is an example how to start a TURN Server in
+# secure mode with SSL connection to a MySQL 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) --mysql-userdb="host=localhost dbname=coturn user=turn password=turn cipher=DHE-RSA-AES256-SHA connect_timeout=30" 
+# means that local MySQL database "coturn" will be used, with database user "turn" and 
+# database user password "turn", and with SSL connection with cipher DHE-RSA-AES256-SHA, 
+# and connection timeout 30 seconds.
+# 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
+# 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 -r north.gov --mysql-userdb="host=localhost dbname=turn user=turn password=turn cipher=DHE-RSA-AES256-SHA connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

+ 1 - 1
man/man1/turnadmin.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "22 July 2014" "" ""
+.TH TURN 1 "18 August 2014" "" ""
 .SH GENERAL INFORMATION
 .SH GENERAL INFORMATION
 
 
 \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage 
 \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage 

+ 16 - 3
man/man1/turnserver.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "22 July 2014" "" ""
+.TH TURN 1 "18 August 2014" "" ""
 .SH GENERAL INFORMATION
 .SH GENERAL INFORMATION
 
 
 The \fBTURN Server\fP project contains the source code of a TURN server and TURN client 
 The \fBTURN Server\fP project contains the source code of a TURN server and TURN client 
@@ -175,6 +175,11 @@ See the INSTALL file for more explanations and examples.
 .PP
 .PP
 Also, see http://www.mysql.org or http://mariadb.org 
 Also, see http://www.mysql.org or http://mariadb.org 
 for full MySQL documentation.
 for full MySQL documentation.
+.PP
+Optional connection string parameters for the secure communications (SSL): 
+ca, capath, cert, key, cipher 
+(see http://dev.mysql.com/doc/refman/5.1/en/ssl\-options.html for the 
+command \fIoptions\fP description).
 .RE
 .RE
 .TP
 .TP
 .B
 .B
@@ -343,6 +348,7 @@ With this flag, all log will be redirected to the system log (syslog).
 \fB\-\-simple\-log\fP
 \fB\-\-simple\-log\fP
 This flag means that no log file rollover will be used, and the log file
 This flag means that no log file rollover will be used, and the log file
 name will be constructed as\-is, without PID and date appendage.
 name will be constructed as\-is, without PID and date appendage.
+This option can be used, for example, together with the logrotate tool.
 .TP
 .TP
 .B
 .B
 \fB\-\-secure\-stun\fP
 \fB\-\-secure\-stun\fP
@@ -404,6 +410,13 @@ ALTERNATE\-SERVER mechanism. The TURN client must support
 300 ALTERNATE\-SERVER response for this functionality.
 300 ALTERNATE\-SERVER response for this functionality.
 .TP
 .TP
 .B
 .B
+\fB\-\-check\-origin\-consistency\fP
+The flag that sets the origin consistency 
+check: across the session, all requests must have the same
+main ORIGIN attribute value (if the ORIGIN was
+initially used by the session).
+.TP
+.B
 \fB\-h\fP
 \fB\-h\fP
 Help.
 Help.
 .TP
 .TP
@@ -560,8 +573,8 @@ mechanism or with TURN REST API.
 .TP
 .TP
 .B
 .B
 \fB\-C\fP, \fB\-\-rest\-api\-separator\fP
 \fB\-C\fP, \fB\-\-rest\-api\-separator\fP
-This is the timestamp/username separator symbol (character) in TURN REST API.
-The default value is :.
+This is the timestamp/username separator symbol 
+(character) in TURN REST API. The default value is :.
 .TP
 .TP
 .B
 .B
 \fB\-q\fP, \fB\-\-user\-quota\fP
 \fB\-q\fP, \fB\-\-user\-quota\fP

+ 1 - 1
man/man1/turnutils.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "22 July 2014" "" ""
+.TH TURN 1 "18 August 2014" "" ""
 .SH GENERAL INFORMATION
 .SH GENERAL INFORMATION
 
 
 A set of turnutils_* programs provides some utility functionality to be used
 A set of turnutils_* programs provides some utility functionality to be used

+ 1 - 1
rpm/build.settings.sh

@@ -2,7 +2,7 @@
 
 
 # Common settings script.
 # Common settings script.
 
 
-TURNVERSION=4.1.1.1
+TURNVERSION=4.1.2.1
 BUILDDIR=~/rpmbuild
 BUILDDIR=~/rpmbuild
 ARCH=`uname -p`
 ARCH=`uname -p`
 TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn
 TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn

+ 4 - 1
rpm/turnserver.spec

@@ -1,5 +1,5 @@
 Name:		turnserver
 Name:		turnserver
-Version:	4.1.1.1
+Version:	4.1.2.1
 Release:	0%{dist}
 Release:	0%{dist}
 Summary:	Coturn TURN Server
 Summary:	Coturn TURN Server
 
 
@@ -235,6 +235,7 @@ fi
 %{_datadir}/%{name}/scripts/longtermsecure/secure_udp_client.sh
 %{_datadir}/%{name}/scripts/longtermsecure/secure_udp_client.sh
 %dir %{_datadir}/%{name}/scripts/longtermsecuredb
 %dir %{_datadir}/%{name}/scripts/longtermsecuredb
 %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mysql.sh
 %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mysql.sh
+%{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mysql_ssl.sh
 %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mongo.sh
 %{_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_psql.sh
 %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_redis.sh
 %{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_redis.sh
@@ -293,6 +294,8 @@ fi
 %{_includedir}/turn/client/TurnMsgLib.h
 %{_includedir}/turn/client/TurnMsgLib.h
 
 
 %changelog
 %changelog
+* Thu Aug 14 2014 Oleg Moskalenko <[email protected]>
+  - Sync to 4.1.2.1
 * Tue Jul 29 2014 Oleg Moskalenko <[email protected]>
 * Tue Jul 29 2014 Oleg Moskalenko <[email protected]>
   - Sync to 4.1.1.1
   - Sync to 4.1.1.1
 * Tue Jul 22 2014 Oleg Moskalenko <[email protected]>
 * Tue Jul 22 2014 Oleg Moskalenko <[email protected]>

+ 1 - 1
src/apps/relay/dbdrivers/dbd_mongo.c

@@ -124,7 +124,7 @@ static mongoc_collection_t * mongo_get_collection(const char * name) {
 	MONGO * mc = get_mongodb_connection();
 	MONGO * mc = get_mongodb_connection();
 
 
 	if(!mc) {
 	if(!mc) {
-		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error gettting a connection to MongoDB\n");
+		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error getting a connection to MongoDB\n");
 		return NULL;
 		return NULL;
 	}
 	}
     
     

+ 45 - 8
src/apps/relay/dbdrivers/dbd_mysql.c

@@ -46,6 +46,13 @@ struct _Myconninfo {
 	char *password;
 	char *password;
 	unsigned int port;
 	unsigned int port;
 	unsigned int connect_timeout;
 	unsigned int connect_timeout;
+	/* SSL ==>> */
+	char *key;
+	char *ca;
+	char *cert;
+	char *capath;
+	char *cipher;
+	/* <<== SSL : see http://dev.mysql.com/doc/refman/5.0/en/mysql-ssl-set.html */
 };
 };
 
 
 typedef struct _Myconninfo Myconninfo;
 typedef struct _Myconninfo Myconninfo;
@@ -56,6 +63,11 @@ static void MyconninfoFree(Myconninfo *co) {
 		if(co->dbname) turn_free(co->dbname, strlen(co->dbname)+1);
 		if(co->dbname) turn_free(co->dbname, strlen(co->dbname)+1);
 		if(co->user) turn_free(co->user, strlen(co->user)+1);
 		if(co->user) turn_free(co->user, strlen(co->user)+1);
 		if(co->password) turn_free(co->password, strlen(co->password)+1);
 		if(co->password) turn_free(co->password, strlen(co->password)+1);
+		if(co->key) turn_free(co->key, strlen(co->key)+1);
+		if(co->ca) turn_free(co->ca, strlen(co->ca)+1);
+		if(co->cert) turn_free(co->cert, strlen(co->cert)+1);
+		if(co->capath) turn_free(co->capath, strlen(co->capath)+1);
+		if(co->cipher) turn_free(co->cipher, strlen(co->cipher)+1);
 		ns_bzero(co,sizeof(Myconninfo));
 		ns_bzero(co,sizeof(Myconninfo));
 	}
 	}
 }
 }
@@ -127,6 +139,26 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
 				co->connect_timeout = (unsigned int)atoi(seq+1);
 				co->connect_timeout = (unsigned int)atoi(seq+1);
 			else if(!strcmp(s,"timeout"))
 			else if(!strcmp(s,"timeout"))
 				co->connect_timeout = (unsigned int)atoi(seq+1);
 				co->connect_timeout = (unsigned int)atoi(seq+1);
+			else if(!strcmp(s,"key"))
+				co->key = strdup(seq+1);
+			else if(!strcmp(s,"ssl-key"))
+				co->key = strdup(seq+1);
+			else if(!strcmp(s,"ca"))
+				co->ca = strdup(seq+1);
+			else if(!strcmp(s,"ssl-ca"))
+				co->ca = strdup(seq+1);
+			else if(!strcmp(s,"capath"))
+				co->capath = strdup(seq+1);
+			else if(!strcmp(s,"ssl-capath"))
+				co->capath = strdup(seq+1);
+			else if(!strcmp(s,"cert"))
+				co->cert = strdup(seq+1);
+			else if(!strcmp(s,"ssl-cert"))
+				co->cert = strdup(seq+1);
+			else if(!strcmp(s,"cipher"))
+				co->cipher = strdup(seq+1);
+			else if(!strcmp(s,"ssl-cipher"))
+				co->cipher = strdup(seq+1);
 			else {
 			else {
 				MyconninfoFree(co);
 				MyconninfoFree(co);
 				co = NULL;
 				co = NULL;
@@ -142,14 +174,16 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
 		turn_free(s0, strlen(s0)+1);
 		turn_free(s0, strlen(s0)+1);
 	}
 	}
 
 
-	if(!(co->dbname))
-		co->dbname=strdup("0");
-	if(!(co->host))
-		co->host=strdup("127.0.0.1");
-	if(!(co->user))
-		co->user=strdup("");
-	if(!(co->password))
-		co->password=strdup("");
+	if(co) {
+		if(!(co->dbname))
+			co->dbname=strdup("0");
+		if(!(co->host))
+			co->host=strdup("127.0.0.1");
+		if(!(co->user))
+			co->user=strdup("");
+		if(!(co->password))
+			co->password=strdup("");
+	}
 
 
 	return co;
 	return co;
 }
 }
@@ -190,6 +224,9 @@ static MYSQL *get_mydb_connection(void) {
 			} else {
 			} else {
 				if(co->connect_timeout)
 				if(co->connect_timeout)
 					mysql_options(mydbconnection,MYSQL_OPT_CONNECT_TIMEOUT,&(co->connect_timeout));
 					mysql_options(mydbconnection,MYSQL_OPT_CONNECT_TIMEOUT,&(co->connect_timeout));
+				if(co->ca || co->capath || co->cert || co->cipher || co->key) {
+					mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher);
+				}
 				MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, CLIENT_IGNORE_SIGPIPE);
 				MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, CLIENT_IGNORE_SIGPIPE);
 				if(!conn) {
 				if(!conn) {
 					TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n",pud->userdb);
 					TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n",pud->userdb);

+ 8 - 6
src/apps/relay/dbdrivers/dbd_redis.c

@@ -148,12 +148,14 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
 		turn_free(s0, strlen(s0)+1);
 		turn_free(s0, strlen(s0)+1);
 	}
 	}
 
 
-	if(!(co->dbname))
-		co->dbname=strdup("0");
-	if(!(co->host))
-		co->host=strdup("127.0.0.1");
-	if(!(co->password))
-		co->password=strdup("");
+	if(co) {
+		if(!(co->dbname))
+			co->dbname=strdup("0");
+		if(!(co->host))
+			co->host=strdup("127.0.0.1");
+		if(!(co->password))
+			co->password=strdup("");
+	}
 
 
 	return co;
 	return co;
 }
 }

+ 21 - 6
src/apps/relay/mainrelay.c

@@ -81,7 +81,7 @@ DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,1,
 NEV_UNKNOWN, 
 NEV_UNKNOWN, 
 { "Unknown", "UDP listening socket per session", "UDP thread per network endpoint", "UDP thread per CPU core" },
 { "Unknown", "UDP listening socket per session", "UDP thread per network endpoint", "UDP thread per CPU core" },
 //////////////// Relay servers //////////////////////////////////
 //////////////// Relay servers //////////////////////////////////
-LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,"",
+LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"",
 0,NULL,0,NULL,DEFAULT_GENERAL_RELAY_SERVERS_NUMBER,0,
 0,NULL,0,NULL,DEFAULT_GENERAL_RELAY_SERVERS_NUMBER,0,
 ////////////// Auth server /////////////////////////////////////
 ////////////// Auth server /////////////////////////////////////
 {NULL,NULL,NULL,0,NULL},
 {NULL,NULL,NULL,0,NULL},
@@ -361,7 +361,8 @@ static char Usage[] = "Usage: turnserver [options]\n"
 " -X, --external-ip  <public-ip[/private-ip]>	TURN Server public/private address mapping, if the server is behind NAT.\n"
 " -X, --external-ip  <public-ip[/private-ip]>	TURN Server public/private address mapping, if the server is behind NAT.\n"
 "						In that situation, if a -X is used in form \"-X ip\" then that ip will be reported\n"
 "						In that situation, if a -X is used in form \"-X ip\" then that ip will be reported\n"
 "						as relay IP address of all allocations. This scenario works only in a simple case\n"
 "						as relay IP address of all allocations. This scenario works only in a simple case\n"
-"						when one single relay address is be used, and no STUN CHANGE_REQUEST functionality is required.\n"
+"						when one single relay address is be used, and no STUN CHANGE_REQUEST\n"
+"						functionality is required.\n"
 "						That single relay address must be mapped by NAT to the 'external' IP.\n"
 "						That single relay address must be mapped by NAT to the 'external' IP.\n"
 "						For that 'external' IP, NAT must forward ports directly (relayed port 12345\n"
 "						For that 'external' IP, NAT must forward ports directly (relayed port 12345\n"
 "						must be always mapped to the same 'external' port 12345).\n"
 "						must be always mapped to the same 'external' port 12345).\n"
@@ -396,6 +397,10 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "						server is not using any database (just the commands-line settings\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"
 "						and the userdb file). Must be used with long-term credentials \n"
 "						mechanism or with TURN REST API.\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"
+"						main ORIGIN attribute value (if the ORIGIN was\n"
+"						initially used by the session).\n"
 " -q, --user-quota		<number>	Per-user allocation quota: how many concurrent allocations a user can create.\n"
 " -q, --user-quota		<number>	Per-user allocation quota: how many concurrent allocations a user can create.\n"
 "						This option can also be set through the database, for a particular realm.\n"
 "						This option can also be set through the database, for a particular realm.\n"
 " -Q, --total-quota		<number>	Total allocations quota: global limit on concurrent allocations.\n"
 " -Q, --total-quota		<number>	Total allocations quota: global limit on concurrent allocations.\n"
@@ -424,8 +429,12 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "	                                	This database can be used for long-term and short-term credentials mechanisms,\n"
 "	                                	This database can be used for long-term and short-term credentials mechanisms,\n"
 "		                                and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
 "		                                and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
 "						The connection string my be space-separated list of parameters:\n"
 "						The connection string my be space-separated list of parameters:\n"
-"	        	          		\"host=<ip-addr> dbname=<database-name> user=<database-user> \\\n								password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n"
-"	        	          		All parameters are optional.\n"
+"	        	          		\"host=<ip-addr> dbname=<database-name> user=<database-user> \\\n								password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n\n"
+"						The connection string parameters for the secure communications (SSL):\n"
+"						ca, capath, cert, key, cipher\n"
+"						(see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the\n"
+"						command options description).\n\n"
+"	        	          		All connection-string parameters are optional.\n\n"
 #endif
 #endif
 #if !defined(TURN_NO_MONGO)
 #if !defined(TURN_NO_MONGO)
 " -J, --mongo-userdb	<connection-string>	MongoDB connection string, if used (default - empty, no MongoDB used).\n"
 " -J, --mongo-userdb	<connection-string>	MongoDB connection string, if used (default - empty, no MongoDB used).\n"
@@ -437,8 +446,8 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "	                                	This database can be used for long-term and short-term credentials mechanisms,\n"
 "	                                	This database can be used for long-term and short-term credentials mechanisms,\n"
 "		                                and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
 "		                                and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
 "						The connection string my be space-separated list of parameters:\n"
 "						The connection string my be space-separated list of parameters:\n"
-"	        	          		\"host=<ip-addr> dbname=<db-number> \\\n								password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n"
-"	        	          		All parameters are optional.\n"
+"	        	          		\"host=<ip-addr> dbname=<db-number> \\\n								password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n\n"
+"	        	          		All connection-string parameters are optional.\n\n"
 " -O, --redis-statsdb	<connection-string>	Redis status and statistics database connection string, if used \n"
 " -O, --redis-statsdb	<connection-string>	Redis status and statistics database connection string, if used \n"
 "						(default - empty, no Redis stats DB used).\n"
 "						(default - empty, no Redis stats DB used).\n"
 "	                                	This database keeps allocations status information, and it can be also used for publishing\n"
 "	                                	This database keeps allocations status information, and it can be also used for publishing\n"
@@ -499,6 +508,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
 " --syslog					Output all log information into the system log (syslog), do not use the file output.\n"
 " --syslog					Output all log information into the system log (syslog), do not use the file output.\n"
 " --simple-log					This flag means that no log file rollover will be used, and the log file\n"
 " --simple-log					This flag means that no log file rollover will be used, and the log file\n"
 "						name will be constructed as-is, without PID and date appendage.\n"
 "						name will be constructed as-is, without PID and date appendage.\n"
+"						This option can be used, for example, together with the logrotate tool.\n"
 " --stale-nonce					Use extra security with nonce value having limited lifetime (600 secs).\n"
 " --stale-nonce					Use extra security with nonce value having limited lifetime (600 secs).\n"
 " -S, --stun-only				Option to set standalone STUN operation only, all TURN requests will be ignored.\n"
 " -S, --stun-only				Option to set standalone STUN operation only, all TURN requests will be ignored.\n"
 "     --no-stun					Option to suppress STUN functionality, only TURN requests will be processed.\n"
 "     --no-stun					Option to suppress STUN functionality, only TURN requests will be processed.\n"
@@ -664,6 +674,7 @@ enum EXTRA_OPTS {
 	NO_TLSV1_OPT,
 	NO_TLSV1_OPT,
 	NO_TLSV1_1_OPT,
 	NO_TLSV1_1_OPT,
 	NO_TLSV1_2_OPT,
 	NO_TLSV1_2_OPT,
+	CHECK_ORIGIN_CONSISTENCY_OPT,
 	ADMIN_MAX_BPS_OPT,
 	ADMIN_MAX_BPS_OPT,
 	ADMIN_TOTAL_QUOTA_OPT,
 	ADMIN_TOTAL_QUOTA_OPT,
 	ADMIN_USER_QUOTA_OPT
 	ADMIN_USER_QUOTA_OPT
@@ -728,6 +739,7 @@ static const struct myoption long_options[] = {
 				{ "Verbose", optional_argument, NULL, 'V' },
 				{ "Verbose", optional_argument, NULL, 'V' },
 				{ "daemon", optional_argument, NULL, 'o' },
 				{ "daemon", optional_argument, NULL, 'o' },
 				{ "fingerprint", optional_argument, NULL, 'f' },
 				{ "fingerprint", optional_argument, NULL, 'f' },
+				{ "check-origin-consistency", optional_argument, NULL, CHECK_ORIGIN_CONSISTENCY_OPT },
 				{ "no-udp", optional_argument, NULL, NO_UDP_OPT },
 				{ "no-udp", optional_argument, NULL, NO_UDP_OPT },
 				{ "no-tcp", optional_argument, NULL, NO_TCP_OPT },
 				{ "no-tcp", optional_argument, NULL, NO_TCP_OPT },
 				{ "no-tls", optional_argument, NULL, NO_TLS_OPT },
 				{ "no-tls", optional_argument, NULL, NO_TLS_OPT },
@@ -1146,6 +1158,9 @@ static void set_option(int c, char *value)
 		turn_params.bps_capacity = (band_limit_t)atoi(value);
 		turn_params.bps_capacity = (band_limit_t)atoi(value);
 		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed, combined server capacity\n",(unsigned long)turn_params.bps_capacity);
 		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed, combined server capacity\n",(unsigned long)turn_params.bps_capacity);
 		break;
 		break;
+	case CHECK_ORIGIN_CONSISTENCY_OPT:
+		turn_params.check_origin = get_bool_value(value);
+		break;
 	case NO_UDP_OPT:
 	case NO_UDP_OPT:
 		turn_params.no_udp = get_bool_value(value);
 		turn_params.no_udp = get_bool_value(value);
 		break;
 		break;

+ 2 - 0
src/apps/relay/mainrelay.h

@@ -250,6 +250,8 @@ typedef struct _turn_params_ {
   u16bits min_port;
   u16bits min_port;
   u16bits max_port;
   u16bits max_port;
 
 
+  vint check_origin;
+
   vint no_multicast_peers;
   vint no_multicast_peers;
   vint no_loopback_peers;
   vint no_loopback_peers;
 
 

+ 1 - 0
src/apps/relay/netengine.c

@@ -1574,6 +1574,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
 			 check_new_allocation_quota,
 			 check_new_allocation_quota,
 			 release_allocation_quota,
 			 release_allocation_quota,
 			 turn_params.external_ip,
 			 turn_params.external_ip,
+			 &turn_params.check_origin,
 			 &turn_params.no_tcp_relay,
 			 &turn_params.no_tcp_relay,
 			 &turn_params.no_udp_relay,
 			 &turn_params.no_udp_relay,
 			 &turn_params.stale_nonce,
 			 &turn_params.stale_nonce,

+ 22 - 7
src/apps/uclient/startuclient.c

@@ -302,6 +302,17 @@ int read_mobility_ticket(app_ur_conn_info *clnet_info, stun_buffer *message)
 	return ret;
 	return ret;
 }
 }
 
 
+void add_origin(stun_buffer *message)
+{
+	if(message && origin[0]) {
+		const char* some_origin = "https://carleon.gov:443";
+		stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin));
+		stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, origin, strlen(origin));
+		some_origin = "ftp://uffrith.net";
+		stun_attr_add(message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin));
+	}
+}
+
 static int clnet_allocate(int verbose,
 static int clnet_allocate(int verbose,
 		app_ur_conn_info *clnet_info,
 		app_ur_conn_info *clnet_info,
 		ioa_addr *relay_addr,
 		ioa_addr *relay_addr,
@@ -372,13 +383,7 @@ static int clnet_allocate(int verbose,
 		  }
 		  }
 		}
 		}
 
 
-		if(origin[0]) {
-			const char* some_origin = "https://carleon.gov:443";
-			stun_attr_add(&message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin));
-			stun_attr_add(&message, STUN_ATTRIBUTE_ORIGIN, origin, strlen(origin));
-			some_origin = "ftp://uffrith.net";
-			stun_attr_add(&message, STUN_ATTRIBUTE_ORIGIN, some_origin, strlen(some_origin));
-		}
+		add_origin(&message);
 
 
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 
@@ -645,6 +650,8 @@ static int clnet_allocate(int verbose,
 				stun_attr_add(&message, STUN_ATTRIBUTE_MOBILITY_TICKET, (const char*)clnet_info->s_mobile_id, strlen(clnet_info->s_mobile_id));
 				stun_attr_add(&message, STUN_ATTRIBUTE_MOBILITY_TICKET, (const char*)clnet_info->s_mobile_id, strlen(clnet_info->s_mobile_id));
 			}
 			}
 
 
+			add_origin(&message);
+
 			if(add_integrity(clnet_info, &message)<0) return -1;
 			if(add_integrity(clnet_info, &message)<0) return -1;
 
 
 			stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
 			stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
@@ -734,6 +741,8 @@ static int turn_channel_bind(int verbose, uint16_t *chn,
 			*chn = stun_set_channel_bind_request(&message, peer_addr, *chn);
 			*chn = stun_set_channel_bind_request(&message, peer_addr, *chn);
 		}
 		}
 
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
@@ -845,6 +854,8 @@ static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info,
 			}
 			}
 		}
 		}
 
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
@@ -1388,6 +1399,8 @@ int turn_tcp_connect(int verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_a
 		stun_init_request(STUN_METHOD_CONNECT, &message);
 		stun_init_request(STUN_METHOD_CONNECT, &message);
 		stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr);
 		stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr);
 
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
@@ -1427,6 +1440,8 @@ static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, a
 
 
 		stun_attr_add(&message, STUN_ATTRIBUTE_CONNECTION_ID, (const s08bits*)&cid,4);
 		stun_attr_add(&message, STUN_ATTRIBUTE_CONNECTION_ID, (const s08bits*)&cid,4);
 
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));
 		stun_attr_add_fingerprint_str(message.buf,(size_t*)&(message.len));

+ 2 - 0
src/apps/uclient/startuclient.h

@@ -43,6 +43,8 @@ extern "C" {
 int rare_event(void);
 int rare_event(void);
 int not_rare_event(void);
 int not_rare_event(void);
 
 
+void add_origin(stun_buffer *message);
+
 int start_c2c_connection(uint16_t clnet_remote_port,
 int start_c2c_connection(uint16_t clnet_remote_port,
 			 const char *remote_address, 
 			 const char *remote_address, 
 			 const unsigned char* ifname, const char *local_address,
 			 const unsigned char* ifname, const char *local_address,

+ 3 - 0
src/apps/uclient/uclient.c

@@ -1083,6 +1083,7 @@ static int refresh_channel(app_ur_session* elem, u16bits method, uint32_t lt)
 		stun_init_request(STUN_METHOD_REFRESH, &message);
 		stun_init_request(STUN_METHOD_REFRESH, &message);
 		lt = htonl(lt);
 		lt = htonl(lt);
 		stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char*) &lt, 4);
 		stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char*) &lt, 4);
+		add_origin(&message);
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(use_fingerprints)
 		if(use_fingerprints)
 			    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));
 			    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));
@@ -1095,6 +1096,7 @@ static int refresh_channel(app_ur_session* elem, u16bits method, uint32_t lt)
 			if (!method || (method == STUN_METHOD_CREATE_PERMISSION)) {
 			if (!method || (method == STUN_METHOD_CREATE_PERMISSION)) {
 				stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message);
 				stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message);
 				stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr));
 				stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr));
+				add_origin(&message);
 				if(add_integrity(clnet_info, &message)<0) return -1;
 				if(add_integrity(clnet_info, &message)<0) return -1;
 				if(use_fingerprints)
 				if(use_fingerprints)
 				    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));
 				    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));
@@ -1105,6 +1107,7 @@ static int refresh_channel(app_ur_session* elem, u16bits method, uint32_t lt)
 		if (!method || (method == STUN_METHOD_CHANNEL_BIND)) {
 		if (!method || (method == STUN_METHOD_CHANNEL_BIND)) {
 			if (STUN_VALID_CHANNEL(elem->chnum)) {
 			if (STUN_VALID_CHANNEL(elem->chnum)) {
 				stun_set_channel_bind_request(&message, &(elem->pinfo.peer_addr), elem->chnum);
 				stun_set_channel_bind_request(&message, &(elem->pinfo.peer_addr), elem->chnum);
+				add_origin(&message);
 				if(add_integrity(clnet_info, &message)<0) return -1;
 				if(add_integrity(clnet_info, &message)<0) return -1;
 				if(use_fingerprints)
 				if(use_fingerprints)
 					    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));
 					    stun_attr_add_fingerprint_str(message.buf, (size_t*) &(message.len));

+ 48 - 0
src/client/ns_turn_msg.c

@@ -43,6 +43,54 @@
 
 
 ///////////
 ///////////
 
 
+int stun_method_str(u16bits method, char *smethod)
+{
+	int ret = 0;
+
+	const char* s = "UNKNOWN";
+
+	switch(method) {
+	case STUN_METHOD_BINDING:
+		s = "BINDING";
+		break;
+	case STUN_METHOD_ALLOCATE:
+		s = "ALLOCATE";
+		break;
+	case STUN_METHOD_REFRESH:
+		s = "REFRESH";
+		break;
+	case STUN_METHOD_SEND:
+		s = "SEND";
+		break;
+	case STUN_METHOD_DATA:
+		s = "DATA";
+		break;
+	case STUN_METHOD_CREATE_PERMISSION:
+		s = "CREATE_PERMISSION";
+		break;
+	case STUN_METHOD_CHANNEL_BIND:
+		s = "CHANNEL_BIND";
+		break;
+	case STUN_METHOD_CONNECT:
+		s = "CONNECT";
+		break;
+	case STUN_METHOD_CONNECTION_BIND:
+		s = "CONNECTION_BIND";
+		break;
+	case STUN_METHOD_CONNECTION_ATTEMPT:
+		s = "CONNECTION_ATTEMPT";
+		break;
+	default:
+		ret = -1;
+	};
+
+	if(smethod) {
+		STRCPY(smethod,s);
+	}
+
+	return ret;
+}
+
 long turn_random(void)
 long turn_random(void)
 {
 {
 	long ret = 0;
 	long ret = 0;

+ 2 - 0
src/client/ns_turn_msg.h

@@ -94,6 +94,8 @@ u32bits stun_adjust_allocate_lifetime(u32bits lifetime);
 
 
 ///////////// STR ////////////////////////////////////////////////
 ///////////// STR ////////////////////////////////////////////////
 
 
+int stun_method_str(u16bits method, char *smethod);
+
 int stun_get_message_len_str(u08bits *buf, size_t len, int padding, size_t *app_len);
 int stun_get_message_len_str(u08bits *buf, size_t len, int padding, size_t *app_len);
 
 
 void stun_init_buffer_str(u08bits *buf, size_t *len);
 void stun_init_buffer_str(u08bits *buf, size_t *len);

+ 1 - 1
src/ns_turn_defs.h

@@ -31,7 +31,7 @@
 #ifndef __IOADEFS__
 #ifndef __IOADEFS__
 #define __IOADEFS__
 #define __IOADEFS__
 
 
-#define TURN_SERVER_VERSION "4.1.1.1"
+#define TURN_SERVER_VERSION "4.1.2.1"
 #define TURN_SERVER_VERSION_NAME "Vitari"
 #define TURN_SERVER_VERSION_NAME "Vitari"
 #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
 #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
 
 

+ 61 - 1
src/server/ns_turn_server.c

@@ -3472,7 +3472,65 @@ static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss,
 				}
 				}
 			}
 			}
 
 
-			if(!(ss->realm_set) && (method == STUN_METHOD_ALLOCATE)) {
+			/* check that the realm is the same as in the original request */
+			if(ss->realm_set) {
+				stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh),
+					ioa_network_buffer_get_size(in_buffer->nbh));
+
+				int origin_found = 0;
+				int norigins = 0;
+
+				while(sar && !origin_found) {
+					if(stun_attr_get_type(sar) == STUN_ATTRIBUTE_ORIGIN) {
+						int sarlen = stun_attr_get_len(sar);
+						if(sarlen>0) {
+							++norigins;
+							char *o = (char*)turn_malloc(sarlen+1);
+							ns_bcopy(stun_attr_get_value(sar),o,sarlen);
+							o[sarlen]=0;
+							char *corigin = (char*)turn_malloc(STUN_MAX_ORIGIN_SIZE+1);
+							corigin[0]=0;
+							if(get_canonic_origin(o,corigin,STUN_MAX_ORIGIN_SIZE)<0) {
+								TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
+									"%s: Wrong origin format: %s\n",
+									__FUNCTION__, o);
+							}
+							if(!strncmp(ss->origin,corigin,STUN_MAX_ORIGIN_SIZE)) {
+								origin_found = 1;
+							}
+							turn_free(corigin,sarlen+1);
+							turn_free(o,sarlen+1);
+						}
+					}
+					sar = stun_attr_get_next_str(ioa_network_buffer_data(in_buffer->nbh),
+							ioa_network_buffer_get_size(in_buffer->nbh), sar);
+				}
+
+				if(server->check_origin && *(server->check_origin)) {
+					if(ss->origin[0]) {
+						if(!origin_found) {
+							err_code = 441;
+							reason = (const u08bits *)"The origin attribute does not match the initial session origin value";
+							if(server->verbose) {
+								char smethod[129];
+								stun_method_str(method,smethod);
+								log_method(ss, smethod, err_code, reason);
+							}
+						}
+					} else if(norigins > 0){
+						err_code = 441;
+						reason = (const u08bits *)"The origin attribute is empty, does not match the initial session origin value";
+						if(server->verbose) {
+							char smethod[129];
+							stun_method_str(method,smethod);
+							log_method(ss, smethod, err_code, reason);
+						}
+					}
+				}
+			}
+
+			/* get the initial origin value */
+			if(!err_code && !(ss->realm_set) && (method == STUN_METHOD_ALLOCATE)) {
 
 
 				stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh),
 				stun_attr_ref sar = stun_attr_get_first_str(ioa_network_buffer_data(in_buffer->nbh),
 					ioa_network_buffer_get_size(in_buffer->nbh));
 					ioa_network_buffer_get_size(in_buffer->nbh));
@@ -4619,6 +4677,7 @@ void init_turn_server(turn_turnserver* server,
 		check_new_allocation_quota_cb chquotacb,
 		check_new_allocation_quota_cb chquotacb,
 		release_allocation_quota_cb raqcb,
 		release_allocation_quota_cb raqcb,
 		ioa_addr *external_ip,
 		ioa_addr *external_ip,
+		vintp check_origin,
 		vintp no_tcp_relay,
 		vintp no_tcp_relay,
 		vintp no_udp_relay,
 		vintp no_udp_relay,
 		vintp stale_nonce,
 		vintp stale_nonce,
@@ -4662,6 +4721,7 @@ void init_turn_server(turn_turnserver* server,
 
 
 	TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id);
 	TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id);
 
 
+	server->check_origin = check_origin;
 	server->no_tcp_relay = no_tcp_relay;
 	server->no_tcp_relay = no_tcp_relay;
 	server->no_udp_relay = no_udp_relay;
 	server->no_udp_relay = no_udp_relay;
 
 

+ 2 - 0
src/server/ns_turn_server.h

@@ -112,6 +112,7 @@ struct _turn_turnserver {
 	int verbose;
 	int verbose;
 	int fingerprint;
 	int fingerprint;
 	int rfc5780;
 	int rfc5780;
+	vintp check_origin;
 	vintp stale_nonce;
 	vintp stale_nonce;
 	vintp stun_only;
 	vintp stun_only;
 	vintp no_stun;
 	vintp no_stun;
@@ -174,6 +175,7 @@ void init_turn_server(turn_turnserver* server,
 				    check_new_allocation_quota_cb chquotacb,
 				    check_new_allocation_quota_cb chquotacb,
 				    release_allocation_quota_cb raqcb,
 				    release_allocation_quota_cb raqcb,
 				    ioa_addr *external_addr,
 				    ioa_addr *external_addr,
+				    vintp check_origin,
 				    vintp no_tcp_relay,
 				    vintp no_tcp_relay,
 				    vintp no_udp_relay,
 				    vintp no_udp_relay,
 				    vintp stale_nonce,
 				    vintp stale_nonce,