浏览代码

Imported Upstream version 4.5.0.1

Oleg Moskalenko 10 年之前
父节点
当前提交
d4bc5ecf23

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+9/13/2015 Oleg Moskalenko <[email protected]>
+Version 4.5.0.1 'dan Eider':
+	- multiple realms based on oAuth (third-party authorization);
+	- STUN attributes conflict resolution;
+	- SIGHUP handler fixed;
+	- error message logging improved;
+	- mongo test db files fixed.
+	
 7/18/2015 Oleg Moskalenko <[email protected]>
 7/18/2015 Oleg Moskalenko <[email protected]>
 Version 4.4.5.4 'Ardee West':
 Version 4.4.5.4 'Ardee West':
 	- moved to github.
 	- moved to github.

+ 27 - 10
INSTALL

@@ -744,6 +744,7 @@ CREATE TABLE oauth_key (
 	timestamp bigint default 0,
 	timestamp bigint default 0,
 	lifetime integer default 0,
 	lifetime integer default 0,
 	as_rs_alg varchar(64) default '',
 	as_rs_alg varchar(64) default '',
+	realm varchar(127) default '',
 	primary key (kid)
 	primary key (kid)
 ); 
 ); 
 
 
@@ -763,6 +764,8 @@ The oauth_key table fields meanings are:
 		"A256GCM", "A128GCM" (see 
 		"A256GCM", "A128GCM" (see 
 		http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-5.1).
 		http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-5.1).
 		The default value is "A256GCM";
 		The default value is "A256GCM";
+	
+	realm - (optional) can be used to set the user realm (if the field is not empty).
 
 
 # Https access admin users.
 # Https access admin users.
 # Leave this table empty if you do not want 
 # Leave this table empty if you do not want 
@@ -852,6 +855,9 @@ may be located in different places.
 
 
   $ sudo /etc/init.d/postgresql stop
   $ sudo /etc/init.d/postgresql stop
   $ sudo /etc/init.d/postgresql start
   $ sudo /etc/init.d/postgresql start
+  
+  The scripts may also be in /usr/local/etc/init.d, or in /etc/rc.d/, or
+  in /usr/local/etc/rc.d/ .
 
 
 5) Check /etc/passwd file to find out which user account is used for the 
 5) Check /etc/passwd file to find out which user account is used for the 
 PostgreSQL admin access on your system (it may be "pgsql", or "postgres", 
 PostgreSQL admin access on your system (it may be "pgsql", or "postgres", 
@@ -859,10 +865,10 @@ or "postgresql"). Let's assume that this is "postgres" account.
 
 
 6) Create a database for the TURN purposes, with name, say, "turn":
 6) Create a database for the TURN purposes, with name, say, "turn":
 
 
-   $ createdb -U postgres turn
+   $ createdb -U postgres coturn
 
 
 7) Create a user for the TURN with name, say, "turn":
 7) Create a user for the TURN with name, say, "turn":
-   $ psql -U postgres turn
+   $ psql -U postgres coturn
      turn=# create user turn with password 'turn';
      turn=# create user turn with password 'turn';
      turn=# 
      turn=# 
      Ctrl-D
      Ctrl-D
@@ -873,13 +879,17 @@ The database schema for the TURN server is very minimalistic and is located
 in project's turndb/schema.sql file, or in the system's 
 in project's turndb/schema.sql file, or in the system's 
 PREFIX/share/turnserver/schema.sql file after the turnserver installation:
 PREFIX/share/turnserver/schema.sql file after the turnserver installation:
 
 
-$ cat turndb/schema.sql | psql -U turn -d turn
+$ cat turndb/schema.sql | psql -U turn -d coturn
 	NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "turnusers_lt_pkey" for table "turnusers_lt"
 	NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "turnusers_lt_pkey" for table "turnusers_lt"
 	CREATE TABLE
 	CREATE TABLE
 	CREATE TABLE
 	CREATE TABLE
 
 
 See the SQLite section for the detailed database schema explanation.
 See the SQLite section for the detailed database schema explanation.
 
 
+To fill the database with test data:
+
+cat turndb/testsqldbsetup.sql | psql -U turn -d coturn
+
 You can use turnadmin program to manage the database - you can either use 
 You can use turnadmin program to manage the database - you can either use 
 turnadmin to add/modify/delete users, or you can use turnadmin to produce 
 turnadmin to add/modify/delete users, or you can use turnadmin to produce 
 the hmac keys and modify the database with your favorite tools.
 the hmac keys and modify the database with your favorite tools.
@@ -930,13 +940,13 @@ Fill in users, for example:
 
 
 XVII. MySQL (MariaDB) setup
 XVII. MySQL (MariaDB) setup
 
 
-The MySQL setup is similar to PostgreSQL (same idea), and is well documented 
+The MySQL setup is similar to PostgreSQL (the same idea), and is well documented 
 on their site http://www.mysql.org. The TURN Server database schema is the 
 on their site http://www.mysql.org. The TURN Server database schema is the 
 same as for PostgreSQL and you can find it in turndb/schema.sql file, or 
 same as for PostgreSQL and you can find it in turndb/schema.sql file, or 
 in the system's PREFIX/share/turnserver/schema.sql file after the turnserver 
 in the system's PREFIX/share/turnserver/schema.sql file after the turnserver 
 installation.
 installation.
 
 
-The general setup idea is the same as for PostgreSQL:
+The general setup is similar to PostgreSQL setup procedure:
 
 
 1) Check that the mysql server access is OK. Immediately after the MySQL server 
 1) Check that the mysql server access is OK. Immediately after the MySQL server 
 installation, it must be accessible, at the very minimum, at the localhost with
 installation, it must be accessible, at the very minimum, at the localhost with
@@ -945,25 +955,32 @@ the root account.
 2) Login into mysql console from root account:
 2) Login into mysql console from root account:
 
 
   $ sudo bash
   $ sudo bash
-  # mysql -p mysql
+  # mysql mysql
+  
+(or mysql -p mysql if mysql account password set)
   
   
 3) Add 'turn' user with 'turn' password (for example):
 3) Add 'turn' user with 'turn' password (for example):
 
 
   > create user 'turn'@'localhost' identified by 'turn';
   > create user 'turn'@'localhost' identified by 'turn';
   
   
-4) Create database 'turn' (for example) and grant privileges to user 'turn':
+4) Create database 'coturn' (for example) and grant privileges to user 'turn':
 
 
-  > create database turn;
-  > grant all on turn.* to 'turn'@'localhost';
+  > create database coturn;
+  > grant all on coturn.* to 'turn'@'localhost';
   > flush privileges;
   > flush privileges;
   Ctrl-D
   Ctrl-D
   
   
 5) Create database schema:
 5) Create database schema:
 
 
-  $ mysql -p -u turn turn < turndb/schema.sql
+  $ mysql -p -u turn coturn < turndb/schema.sql
   Enter password: turn
   Enter password: turn
   $
   $
   
   
+  Fill in test database data, if this is a test database
+  (not a production database):
+  
+  $ mysql -p -u turn coturn < turndb/testsqldbsetup.sql
+  
 6) Fill in users, for example:
 6) Fill in users, for example:
 
 
   Shared secret for the TURN REST API (realm north.gov):
   Shared secret for the TURN REST API (realm north.gov):

+ 8 - 3
README.md

@@ -1,5 +1,9 @@
 **_This project evolved from rfc5766-turn-server project (https://code.google.com/p/rfc5766-turn-server/). There are many new advanced TURN specs which are going far beyond the original RFC 5766 document. This project takes the code of rfc5766-turn-server as the starter, and adds new advanced features to it._**
 **_This project evolved from rfc5766-turn-server project (https://code.google.com/p/rfc5766-turn-server/). There are many new advanced TURN specs which are going far beyond the original RFC 5766 document. This project takes the code of rfc5766-turn-server as the starter, and adds new advanced features to it._**
 
 
+[Downloads page](https://github.com/coturn/coturn/wiki/Downloads)
+
+[Wiki pages](https://github.com/coturn/coturn/wiki/)
+
 # Free open source implementation of TURN and STUN Server #
 # Free open source implementation of TURN and STUN Server #
 
 
 The TURN Server is a VoIP media traffic NAT traversal server and gateway. It can be used as a general-purpose network traffic TURN server and gateway, too.
 The TURN Server is a VoIP media traffic NAT traversal server and gateway. It can be used as a general-purpose network traffic TURN server and gateway, too.
@@ -16,13 +20,13 @@ TURN specs:
   * RFC 6062 - TCP relaying TURN extension
   * RFC 6062 - TCP relaying TURN extension
   * RFC 6156 - IPv6 extension for TURN
   * RFC 6156 - IPv6 extension for TURN
   * RFC 7443 - ALPN support for STUN & TURN
   * RFC 7443 - ALPN support for STUN & TURN
+  * RFC 7635 - oAuth third-party TURN/STUN authorization
   * DTLS support (http://tools.ietf.org/html/draft-petithuguenin-tram-turn-dtls-00).
   * DTLS support (http://tools.ietf.org/html/draft-petithuguenin-tram-turn-dtls-00).
   * Mobile ICE (MICE) support (http://tools.ietf.org/html/draft-wing-tram-turn-mobility-02).
   * Mobile ICE (MICE) support (http://tools.ietf.org/html/draft-wing-tram-turn-mobility-02).
   * TURN REST API (http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00)
   * TURN REST API (http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00)
   * Origin field in TURN (Multi-tenant TURN Server) (https://tools.ietf.org/html/draft-ietf-tram-stun-origin-05)
   * Origin field in TURN (Multi-tenant TURN Server) (https://tools.ietf.org/html/draft-ietf-tram-stun-origin-05)
   * TURN Bandwidth draft specs (http://tools.ietf.org/html/draft-thomson-tram-turn-bandwidth-01)
   * TURN Bandwidth draft specs (http://tools.ietf.org/html/draft-thomson-tram-turn-bandwidth-01)
-  * TURN-bis (with dual allocation) draft specs (http://tools.ietf.org/html/draft-ietf-tram-turnbis-04)
-  * Third-party authorization support (http://tools.ietf.org/html/draft-ietf-tram-turn-third-party-authz-16).
+  * TURN-bis (with dual allocation) draft specs (http://tools.ietf.org/html/draft-ietf-tram-turnbis-04).
 
 
 STUN specs:
 STUN specs:
 
 
@@ -31,6 +35,7 @@ STUN specs:
   * RFC 5769 - test vectors for STUN protocol testing
   * RFC 5769 - test vectors for STUN protocol testing
   * RFC 5780 - NAT behavior discovery support
   * RFC 5780 - NAT behavior discovery support
   * RFC 7443 - ALPN support for STUN & TURN
   * RFC 7443 - ALPN support for STUN & TURN
+  * RFC 7635 - oAuth third-party TURN/STUN authorization
 
 
 Supported ICE and related specs:
 Supported ICE and related specs:
 
 
@@ -116,4 +121,4 @@ email:[email protected]
 
 
 ### Feedback is very welcome (bugs, issues, suggestions, stories, questions). ###
 ### Feedback is very welcome (bugs, issues, suggestions, stories, questions). ###
 
 
-### Volunteers are welcome, too. ###
+### Volunteers are welcome, too. ###

+ 1 - 1
README.turnserver

@@ -181,7 +181,7 @@ Flags:
 			The actual value of the secret is defined either by option static-auth-secret,
 			The actual value of the secret is defined either by option static-auth-secret,
 			or can be found in the turn_secret table in the database.
 			or can be found in the turn_secret table in the database.
 			
 			
---oauth			Support oAuth authentication, as in the third-party TURN specs document.
+--oauth			Support oAuth authentication, as in the third-party STUN/TURN RFC 7635.
 			
 			
 --dh566			Use 566 bits predefined DH TLS key. Default size of the key is 1066.
 --dh566			Use 566 bits predefined DH TLS key. Default size of the key is 1066.
 
 

+ 3 - 0
STATUS

@@ -123,6 +123,9 @@ supported in the client library).
 53) SHA384 and SHA512 support added (experimental).
 53) SHA384 and SHA512 support added (experimental).
 
 
 54) native SCTP experimental support.
 54) native SCTP experimental support.
+
+55) Multi-tenant implementation based upon third-party authorization
+(oAuth).
  
  
 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.

二进制
examples/var/db/turndb


+ 1 - 1
man/man1/turnadmin.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "19 July 2015" "" ""
+.TH TURN 1 "13 September 2015" "" ""
 .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 

+ 2 - 2
man/man1/turnserver.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "19 July 2015" "" ""
+.TH TURN 1 "13 September 2015" "" ""
 .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 
@@ -265,7 +265,7 @@ or can be found in the turn_secret table in the database.
 .TP
 .TP
 .B
 .B
 \fB\-\-oauth\fP
 \fB\-\-oauth\fP
-Support oAuth authentication, as in the third\-party TURN specs document.
+Support oAuth authentication, as in the third\-party STUN/TURN RFC 7635.
 .TP
 .TP
 .B
 .B
 \fB\-\-dh566\fP
 \fB\-\-dh566\fP

+ 1 - 1
man/man1/turnutils.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
 .\" Text automatically generated by txt2man
-.TH TURN 1 "19 July 2015" "" ""
+.TH TURN 1 "13 September 2015" "" ""
 .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.4.5.4
+TURNVERSION=4.5.0.1
 BUILDDIR=~/rpmbuild
 BUILDDIR=~/rpmbuild
 ARCH=`uname -p`
 ARCH=`uname -p`
 TURNSERVER_GIT_URL=https://github.com/coturn/coturn.git
 TURNSERVER_GIT_URL=https://github.com/coturn/coturn.git

+ 3 - 1
rpm/turnserver.spec

@@ -1,5 +1,5 @@
 Name:		turnserver
 Name:		turnserver
-Version:	4.4.5.4
+Version:	4.5.0.1
 Release:	0%{dist}
 Release:	0%{dist}
 Summary:	Coturn TURN Server
 Summary:	Coturn TURN Server
 
 
@@ -289,6 +289,8 @@ fi
 %{_includedir}/turn/client/TurnMsgLib.h
 %{_includedir}/turn/client/TurnMsgLib.h
 
 
 %changelog
 %changelog
+* Sun Sep 13 2015 Oleg Moskalenko <[email protected]>
+  - Sync to 4.5.0.1
 * Sat Jul 18 2015 Oleg Moskalenko <[email protected]>
 * Sat Jul 18 2015 Oleg Moskalenko <[email protected]>
   - Sync to 4.4.5.4
   - Sync to 4.4.5.4
 * Sat Jun 20 2015 Oleg Moskalenko <[email protected]>
 * Sat Jun 20 2015 Oleg Moskalenko <[email protected]>

+ 1 - 0
src/apps/common/apputils.h

@@ -142,6 +142,7 @@ struct _oauth_key_data_raw {
 	u64bits timestamp;
 	u64bits timestamp;
 	u32bits lifetime;
 	u32bits lifetime;
 	char as_rs_alg[OAUTH_ALG_SIZE+1];
 	char as_rs_alg[OAUTH_ALG_SIZE+1];
+	char realm[STUN_MAX_REALM_SIZE+1];
 };
 };
 
 
 typedef struct _oauth_key_data_raw oauth_key_data_raw;
 typedef struct _oauth_key_data_raw oauth_key_data_raw;

+ 8 - 2
src/apps/common/ns_turn_utils.c

@@ -236,6 +236,7 @@ static int to_syslog = 0;
 static int simple_log = 0;
 static int simple_log = 0;
 static char log_fn[FILE_STR_LEN]="\0";
 static char log_fn[FILE_STR_LEN]="\0";
 static char log_fn_base[FILE_STR_LEN]="\0";
 static char log_fn_base[FILE_STR_LEN]="\0";
+static volatile int to_reset_log_file = 0;
 
 
 static turn_mutex log_mutex;
 static turn_mutex log_mutex;
 static int log_mutex_inited = 0;
 static int log_mutex_inited = 0;
@@ -344,13 +345,18 @@ static void set_log_file_name_func(char *base, char *f, size_t fsz)
 static void sighup_callback_handler(int signum)
 static void sighup_callback_handler(int signum)
 {
 {
 	if(signum == SIGHUP) {
 	if(signum == SIGHUP) {
-		printf("%s: resetting the log file\n",__FUNCTION__);
-		reset_rtpprintf();
+		to_reset_log_file = 1;
 	}
 	}
 }
 }
 
 
 static void set_rtpfile(void)
 static void set_rtpfile(void)
 {
 {
+	if(to_reset_log_file) {
+		printf("%s: resetting the log file\n",__FUNCTION__);
+		reset_rtpprintf();
+		to_reset_log_file = 0;
+	}
+
 	if(to_syslog) {
 	if(to_syslog) {
 		return;
 		return;
 	} else if (!_rtpfile) {
 	} else if (!_rtpfile) {

+ 13 - 3
src/apps/relay/dbdrivers/dbd_mongo.c

@@ -255,6 +255,7 @@ static int mongo_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	BSON_APPEND_INT32(&fields, "lifetime", 1);
 	BSON_APPEND_INT32(&fields, "lifetime", 1);
 	BSON_APPEND_INT32(&fields, "timestamp", 1);
 	BSON_APPEND_INT32(&fields, "timestamp", 1);
 	BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
 	BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
+	BSON_APPEND_INT32(&fields, "realm", 1);
 	BSON_APPEND_INT32(&fields, "ikm_key", 1);
 	BSON_APPEND_INT32(&fields, "ikm_key", 1);
 
 
 	mongoc_cursor_t * cursor;
 	mongoc_cursor_t * cursor;
@@ -277,6 +278,9 @@ static int mongo_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 			if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
 			if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
 				STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length));
 				STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length));
 			}
 			}
+			if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) {
+				STRCPY(key->realm,bson_iter_utf8(&iter, &length));
+			}
 			if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
 			if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
 				STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
 				STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
 			}
 			}
@@ -341,6 +345,7 @@ static int mongo_set_oauth_key(oauth_key_data_raw *key) {
   bson_init(&doc);
   bson_init(&doc);
   BSON_APPEND_UTF8(&doc, "kid", (const char *)key->kid);
   BSON_APPEND_UTF8(&doc, "kid", (const char *)key->kid);
   BSON_APPEND_UTF8(&doc, "as_rs_alg", (const char *)key->as_rs_alg);
   BSON_APPEND_UTF8(&doc, "as_rs_alg", (const char *)key->as_rs_alg);
+  BSON_APPEND_UTF8(&doc, "realm", (const char *)key->realm);
   BSON_APPEND_UTF8(&doc, "ikm_key", (const char *)key->ikm_key);
   BSON_APPEND_UTF8(&doc, "ikm_key", (const char *)key->ikm_key);
   BSON_APPEND_INT64(&doc, "timestamp", (int64_t)key->timestamp);
   BSON_APPEND_INT64(&doc, "timestamp", (int64_t)key->timestamp);
   BSON_APPEND_INT32(&doc, "lifetime", (int32_t)key->lifetime);
   BSON_APPEND_INT32(&doc, "lifetime", (int32_t)key->lifetime);
@@ -477,7 +482,7 @@ static int mongo_list_users(u08bits *realm, secrets_list_t *users, secrets_list_
   return ret;
   return ret;
 }
 }
 
 
-static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
+static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) {
 
 
   const char * collection_name = "oauth_key";
   const char * collection_name = "oauth_key";
   mongoc_collection_t * collection = mongo_get_collection(collection_name);
   mongoc_collection_t * collection = mongo_get_collection(collection_name);
@@ -501,6 +506,7 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
   BSON_APPEND_INT32(&fields, "lifetime", 1);
   BSON_APPEND_INT32(&fields, "lifetime", 1);
   BSON_APPEND_INT32(&fields, "timestamp", 1);
   BSON_APPEND_INT32(&fields, "timestamp", 1);
   BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
   BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
+  BSON_APPEND_INT32(&fields, "realm", 1);
   BSON_APPEND_INT32(&fields, "ikm_key", 1);
   BSON_APPEND_INT32(&fields, "ikm_key", 1);
 
 
   mongoc_cursor_t * cursor;
   mongoc_cursor_t * cursor;
@@ -525,6 +531,9 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
     	if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
     	if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
     	    STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length));
     	    STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length));
     	}
     	}
+    	if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) {
+    	    STRCPY(key->realm,bson_iter_utf8(&iter, &length));
+    	}
     	if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
     	if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
     		STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
     		STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
     	}
     	}
@@ -537,6 +546,7 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
     	if(kids) {
     	if(kids) {
     		add_to_secrets_list(kids,key->kid);
     		add_to_secrets_list(kids,key->kid);
     		add_to_secrets_list(teas,key->as_rs_alg);
     		add_to_secrets_list(teas,key->as_rs_alg);
+    		add_to_secrets_list(realms,key->realm);
 			{
 			{
 				char ts[256];
 				char ts[256];
 				snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
 				snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@@ -548,9 +558,9 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 				add_to_secrets_list(lts,lt);
 				add_to_secrets_list(lts,lt);
 			}
 			}
     	} else {
     	} else {
-    		printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
+    		printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n",
     						key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
     						key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
-    						key->as_rs_alg);
+    						key->as_rs_alg, key->realm);
     	}
     	}
     }
     }
     mongoc_cursor_destroy(cursor);
     mongoc_cursor_destroy(cursor);

+ 20 - 13
src/apps/relay/dbdrivers/dbd_mysql.c

@@ -345,7 +345,7 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	int ret = -1;
 	int ret = -1;
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg from oauth_key where kid='%s'",(const char*)kid);
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'",(const char*)kid);
 
 
 	MYSQL * myc = get_mydb_connection();
 	MYSQL * myc = get_mydb_connection();
 	if(myc) {
 	if(myc) {
@@ -356,7 +356,7 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 			MYSQL_RES *mres = mysql_store_result(myc);
 			MYSQL_RES *mres = mysql_store_result(myc);
 			if(!mres) {
 			if(!mres) {
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
-			} else if(mysql_field_count(myc)!=4) {
+			} else if(mysql_field_count(myc)!=5) {
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
 			} else {
 			} else {
 				MYSQL_ROW row = mysql_fetch_row(mres);
 				MYSQL_ROW row = mysql_fetch_row(mres);
@@ -380,6 +380,9 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 						ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
 						ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
 						key->as_rs_alg[lengths[3]]=0;
 						key->as_rs_alg[lengths[3]]=0;
 
 
+						ns_bcopy(row[4],key->realm,lengths[4]);
+						key->realm[lengths[4]]=0;
+
 						ret = 0;
 						ret = 0;
 					}
 					}
 				}
 				}
@@ -392,13 +395,13 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	return ret;
 	return ret;
 }
 }
 
 
-static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
+static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) {
 
 
 	oauth_key_data_raw key_;
 	oauth_key_data_raw key_;
 	oauth_key_data_raw *key=&key_;
 	oauth_key_data_raw *key=&key_;
 	int ret = -1;
 	int ret = -1;
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,kid from oauth_key order by kid");
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid");
 
 
 	MYSQL * myc = get_mydb_connection();
 	MYSQL * myc = get_mydb_connection();
 	if(myc) {
 	if(myc) {
@@ -409,7 +412,7 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 			MYSQL_RES *mres = mysql_store_result(myc);
 			MYSQL_RES *mres = mysql_store_result(myc);
 			if(!mres) {
 			if(!mres) {
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
-			} else if(mysql_field_count(myc)!=5) {
+			} else if(mysql_field_count(myc)!=6) {
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
 			} else {
 			} else {
 				MYSQL_ROW row = mysql_fetch_row(mres);
 				MYSQL_ROW row = mysql_fetch_row(mres);
@@ -433,12 +436,16 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 						ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
 						ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
 						key->as_rs_alg[lengths[3]]=0;
 						key->as_rs_alg[lengths[3]]=0;
 
 
-						ns_bcopy(row[4],key->kid,lengths[4]);
-						key->kid[lengths[4]]=0;
+						ns_bcopy(row[4],key->realm,lengths[4]);
+						key->realm[lengths[4]]=0;
+
+						ns_bcopy(row[5],key->kid,lengths[5]);
+						key->kid[lengths[5]]=0;
 
 
 						if(kids) {
 						if(kids) {
 							add_to_secrets_list(kids,key->kid);
 							add_to_secrets_list(kids,key->kid);
 							add_to_secrets_list(teas,key->as_rs_alg);
 							add_to_secrets_list(teas,key->as_rs_alg);
+							add_to_secrets_list(realms,key->realm);
 							{
 							{
 								char ts[256];
 								char ts[256];
 								snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
 								snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@@ -450,9 +457,9 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 								add_to_secrets_list(lts,lt);
 								add_to_secrets_list(lts,lt);
 							}
 							}
 						} else {
 						} else {
-							printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
+							printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n",
 								key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
 								key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
-								key->as_rs_alg);
+								key->as_rs_alg,key->realm);
 						}
 						}
 					}
 					}
 					row = mysql_fetch_row(mres);
 					row = mysql_fetch_row(mres);
@@ -496,13 +503,13 @@ static int mysql_set_oauth_key(oauth_key_data_raw *key)
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
 	MYSQL * myc = get_mydb_connection();
 	MYSQL * myc = get_mydb_connection();
 	if(myc) {
 	if(myc) {
-		snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('%s','%s',%llu,%lu,'%s')",
+		snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')",
 					  key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
 					  key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
-					  key->as_rs_alg);
+					  key->as_rs_alg,key->realm);
 		int res = mysql_query(myc, statement);
 		int res = mysql_query(myc, statement);
 		if(res) {
 		if(res) {
-			snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
-							  key->as_rs_alg,key->kid);
+			snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
+							  key->as_rs_alg,key->realm,key->kid);
 			res = mysql_query(myc, statement);
 			res = mysql_query(myc, statement);
 			if(res) {
 			if(res) {
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n",mysql_error(myc));
 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n",mysql_error(myc));

+ 13 - 10
src/apps/relay/dbdrivers/dbd_pgsql.c

@@ -160,7 +160,7 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 
 
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg from oauth_key where kid='%s'",(const char*)kid);
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'",(const char*)kid);
 
 
 	PGconn * pqc = get_pqdb_connection();
 	PGconn * pqc = get_pqdb_connection();
 	if(pqc) {
 	if(pqc) {
@@ -173,6 +173,7 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 			key->timestamp = (u64bits)strtoll(PQgetvalue(res,0,1),NULL,10);
 			key->timestamp = (u64bits)strtoll(PQgetvalue(res,0,1),NULL,10);
 			key->lifetime = (u32bits)strtol(PQgetvalue(res,0,2),NULL,10);
 			key->lifetime = (u32bits)strtol(PQgetvalue(res,0,2),NULL,10);
 			STRCPY(key->as_rs_alg,PQgetvalue(res,0,3));
 			STRCPY(key->as_rs_alg,PQgetvalue(res,0,3));
+			STRCPY(key->realm,PQgetvalue(res,0,4));
 			STRCPY(key->kid,kid);
 			STRCPY(key->kid,kid);
 			ret = 0;
 			ret = 0;
 		}
 		}
@@ -185,7 +186,7 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	return ret;
 	return ret;
 }
 }
 
 
-static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
+static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) {
 
 
 	oauth_key_data_raw key_;
 	oauth_key_data_raw key_;
 	oauth_key_data_raw *key=&key_;
 	oauth_key_data_raw *key=&key_;
@@ -193,7 +194,7 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 	int ret = -1;
 	int ret = -1;
 
 
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,kid from oauth_key order by kid");
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid");
 
 
 	PGconn * pqc = get_pqdb_connection();
 	PGconn * pqc = get_pqdb_connection();
 	if(pqc) {
 	if(pqc) {
@@ -209,11 +210,13 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 				key->timestamp = (u64bits)strtoll(PQgetvalue(res,i,1),NULL,10);
 				key->timestamp = (u64bits)strtoll(PQgetvalue(res,i,1),NULL,10);
 				key->lifetime = (u32bits)strtol(PQgetvalue(res,i,2),NULL,10);
 				key->lifetime = (u32bits)strtol(PQgetvalue(res,i,2),NULL,10);
 				STRCPY(key->as_rs_alg,PQgetvalue(res,i,3));
 				STRCPY(key->as_rs_alg,PQgetvalue(res,i,3));
-				STRCPY(key->kid,PQgetvalue(res,i,4));
+				STRCPY(key->realm,PQgetvalue(res,i,4));
+				STRCPY(key->kid,PQgetvalue(res,i,5));
 
 
 				if(kids) {
 				if(kids) {
 					add_to_secrets_list(kids,key->kid);
 					add_to_secrets_list(kids,key->kid);
 					add_to_secrets_list(teas,key->as_rs_alg);
 					add_to_secrets_list(teas,key->as_rs_alg);
+					add_to_secrets_list(realms,key->realm);
 					{
 					{
 						char ts[256];
 						char ts[256];
 						snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
 						snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@@ -225,9 +228,9 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 						add_to_secrets_list(lts,lt);
 						add_to_secrets_list(lts,lt);
 					}
 					}
 				} else {
 				} else {
-					printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
+					printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n",
 						key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
 						key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
-						key->as_rs_alg);
+						key->as_rs_alg,key->realm);
 				}
 				}
 
 
 				ret = 0;
 				ret = 0;
@@ -275,17 +278,17 @@ static int pgsql_set_oauth_key(oauth_key_data_raw *key) {
   char statement[TURN_LONG_STRING_SIZE];
   char statement[TURN_LONG_STRING_SIZE];
   PGconn *pqc = get_pqdb_connection();
   PGconn *pqc = get_pqdb_connection();
   if(pqc) {
   if(pqc) {
-	  snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('%s','%s',%llu,%lu,'%s')",
+	  snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')",
 			  key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
 			  key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
-			  key->as_rs_alg);
+			  key->as_rs_alg,key->realm);
 
 
 	  PGresult *res = PQexec(pqc, statement);
 	  PGresult *res = PQexec(pqc, statement);
 	  if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
 	  if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
 		  if(res) {
 		  if(res) {
 			PQclear(res);
 			PQclear(res);
 		  }
 		  }
-		  snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
-				  key->as_rs_alg,key->kid);
+		  snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s', realm='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
+				  key->as_rs_alg,key->realm,key->kid);
 		  res = PQexec(pqc, statement);
 		  res = PQexec(pqc, statement);
 		  if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
 		  if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
 			  TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n",PQerrorMessage(pqc));
 			  TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n",PQerrorMessage(pqc));

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

@@ -477,6 +477,8 @@ static int redis_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 				if(kw) {
 				if(kw) {
 					if(!strcmp(kw,"as_rs_alg")) {
 					if(!strcmp(kw,"as_rs_alg")) {
 						STRCPY(key->as_rs_alg,val);
 						STRCPY(key->as_rs_alg,val);
+					} else if(!strcmp(kw,"realm")) {
+						STRCPY(key->realm,val);
 					} else if(!strcmp(kw,"ikm_key")) {
 					} else if(!strcmp(kw,"ikm_key")) {
 						STRCPY(key->ikm_key,val);
 						STRCPY(key->ikm_key,val);
 					} else if(!strcmp(kw,"timestamp")) {
 					} else if(!strcmp(kw,"timestamp")) {
@@ -512,8 +514,8 @@ static int redis_set_oauth_key(oauth_key_data_raw *key) {
   redisContext *rc = get_redis_connection();
   redisContext *rc = get_redis_connection();
   if(rc) {
   if(rc) {
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
-	snprintf(statement,sizeof(statement),"hmset turn/oauth/kid/%s ikm_key %s as_rs_alg %s timestamp %llu lifetime %lu",
-			key->kid,key->ikm_key,key->as_rs_alg,(unsigned long long)key->timestamp,(unsigned long)key->lifetime);
+	snprintf(statement,sizeof(statement),"hmset turn/oauth/kid/%s ikm_key %s as_rs_alg %s timestamp %llu lifetime %lu realm %s",
+			key->kid,key->ikm_key,key->as_rs_alg,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,key->realm);
 	turnFreeRedisReply(redisCommand(rc, statement));
 	turnFreeRedisReply(redisCommand(rc, statement));
 	turnFreeRedisReply(redisCommand(rc, "save"));
 	turnFreeRedisReply(redisCommand(rc, "save"));
     ret = 0;
     ret = 0;
@@ -629,7 +631,7 @@ static int redis_list_users(u08bits *realm, secrets_list_t *users, secrets_list_
 	return ret;
 	return ret;
 }
 }
 
 
-static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
+static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) {
   int ret = -1;
   int ret = -1;
   redisContext *rc = get_redis_connection();
   redisContext *rc = get_redis_connection();
   secrets_list_t keys;
   secrets_list_t keys;
@@ -668,6 +670,7 @@ static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 		if(kids) {
 		if(kids) {
 			add_to_secrets_list(kids,key->kid);
 			add_to_secrets_list(kids,key->kid);
 			add_to_secrets_list(teas,key->as_rs_alg);
 			add_to_secrets_list(teas,key->as_rs_alg);
+			add_to_secrets_list(realms,key->realm);
 			{
 			{
 				char ts[256];
 				char ts[256];
 				snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
 				snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@@ -679,9 +682,9 @@ static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secre
 				add_to_secrets_list(lts,lt);
 				add_to_secrets_list(lts,lt);
 			}
 			}
 		} else {
 		} else {
-			printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
+			printf("  kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, realm=%s\n",
 							key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
 							key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
-							key->as_rs_alg);
+							key->as_rs_alg,key->realm);
 		}
 		}
 	}
 	}
   }
   }

+ 10 - 7
src/apps/relay/dbdrivers/dbd_sqlite.c

@@ -157,7 +157,7 @@ static void init_sqlite_database(sqlite3 *sqliteconnection) {
 		"CREATE TABLE denied_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key (realm,ip_range))",
 		"CREATE TABLE denied_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key (realm,ip_range))",
 		"CREATE TABLE turn_origin_to_realm (origin varchar(127),realm varchar(127),primary key (origin))",
 		"CREATE TABLE turn_origin_to_realm (origin varchar(127),realm varchar(127),primary key (origin))",
 		"CREATE TABLE turn_realm_option (realm varchar(127) default '',	opt varchar(32),	value varchar(128),	primary key (realm,opt))",
 		"CREATE TABLE turn_realm_option (realm varchar(127) default '',	opt varchar(32),	value varchar(128),	primary key (realm,opt))",
-		"CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256),timestamp bigint default 0,lifetime integer default 0,as_rs_alg varchar(64) default '',primary key (kid))",
+		"CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256),timestamp bigint default 0,lifetime integer default 0,as_rs_alg varchar(64) default '',realm varchar(127) default '',primary key (kid))",
 		"CREATE TABLE admin_user (name varchar(32), realm varchar(127), password varchar(127), primary key (name))",
 		"CREATE TABLE admin_user (name varchar(32), realm varchar(127), password varchar(127), primary key (name))",
 		NULL
 		NULL
 	};
 	};
@@ -299,7 +299,7 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	int rc = 0;
 	int rc = 0;
 
 
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
 	/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg from oauth_key where kid='%s'",(const char*)kid);
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm from oauth_key where kid='%s'",(const char*)kid);
 
 
 	sqlite3 *sqliteconnection = get_sqlite_connection();
 	sqlite3 *sqliteconnection = get_sqlite_connection();
 	if(sqliteconnection) {
 	if(sqliteconnection) {
@@ -315,6 +315,7 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 				key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
 				key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
 				key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
 				key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
 				STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
 				STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
+				STRCPY(key->realm,sqlite3_column_text(st, 4));
 				STRCPY(key->kid,kid);
 				STRCPY(key->kid,kid);
 				ret = 0;
 				ret = 0;
 			}
 			}
@@ -331,7 +332,7 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
 	return ret;
 	return ret;
 }
 }
 
 
-static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
+static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms) {
 
 
 	oauth_key_data_raw key_;
 	oauth_key_data_raw key_;
 	oauth_key_data_raw *key=&key_;
 	oauth_key_data_raw *key=&key_;
@@ -343,7 +344,7 @@ static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secr
 	char statement[TURN_LONG_STRING_SIZE];
 	char statement[TURN_LONG_STRING_SIZE];
 	sqlite3_stmt *st = NULL;
 	sqlite3_stmt *st = NULL;
 	int rc = 0;
 	int rc = 0;
-	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,kid from oauth_key order by kid");
+	snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,realm,kid from oauth_key order by kid");
 
 
 	sqlite3 *sqliteconnection = get_sqlite_connection();
 	sqlite3 *sqliteconnection = get_sqlite_connection();
 	if(sqliteconnection) {
 	if(sqliteconnection) {
@@ -361,11 +362,13 @@ static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secr
 					key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
 					key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
 					key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
 					key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
 					STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
 					STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
-					STRCPY(key->kid,sqlite3_column_text(st, 4));
+					STRCPY(key->realm,sqlite3_column_text(st, 4));
+					STRCPY(key->kid,sqlite3_column_text(st, 5));
 
 
 					if(kids) {
 					if(kids) {
 						add_to_secrets_list(kids,key->kid);
 						add_to_secrets_list(kids,key->kid);
 						add_to_secrets_list(teas,key->as_rs_alg);
 						add_to_secrets_list(teas,key->as_rs_alg);
+						add_to_secrets_list(realms,key->realm);
 						{
 						{
 							char ts[256];
 							char ts[256];
 							snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
 							snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@@ -449,8 +452,8 @@ static int sqlite_set_oauth_key(oauth_key_data_raw *key)
 		snprintf(
 		snprintf(
 						statement,
 						statement,
 						sizeof(statement),
 						sizeof(statement),
-						"insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('%s','%s',%llu,%lu,'%s')",
-						key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->as_rs_alg);
+						"insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('%s','%s',%llu,%lu,'%s','%s')",
+						key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->as_rs_alg, key->realm);
 
 
 		sqlite_lock(1);
 		sqlite_lock(1);
 
 

+ 1 - 1
src/apps/relay/dbdrivers/dbdriver.h

@@ -68,7 +68,7 @@ typedef struct _turn_dbdriver_t {
   int (*set_oauth_key)(oauth_key_data_raw *key);
   int (*set_oauth_key)(oauth_key_data_raw *key);
   int (*get_oauth_key)(const u08bits *kid, oauth_key_data_raw *key);
   int (*get_oauth_key)(const u08bits *kid, oauth_key_data_raw *key);
   int (*del_oauth_key)(const u08bits *kid);
   int (*del_oauth_key)(const u08bits *kid);
-  int (*list_oauth_keys)(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts);
+  int (*list_oauth_keys)(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts,secrets_list_t *realms);
   int (*get_admin_user)(const u08bits *usname, u08bits *realm, password_t pwd);
   int (*get_admin_user)(const u08bits *usname, u08bits *realm, password_t pwd);
   int (*set_admin_user)(const u08bits *usname, const u08bits *realm, const password_t pwd);
   int (*set_admin_user)(const u08bits *usname, const u08bits *realm, const password_t pwd);
   int (*del_admin_user)(const u08bits *usname);
   int (*del_admin_user)(const u08bits *usname);

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

@@ -805,7 +805,7 @@ static int handle_relay_message(relay_server_handle rs, struct message_to_relay
 static void handle_relay_auth_message(struct relay_server *rs, struct auth_message *am)
 static void handle_relay_auth_message(struct relay_server *rs, struct auth_message *am)
 {
 {
 	am->resume_func(am->success, am->out_oauth, am->max_session_time, am->key, am->pwd,
 	am->resume_func(am->success, am->out_oauth, am->max_session_time, am->key, am->pwd,
-				&(rs->server), am->ctxkey, &(am->in_buffer));
+				&(rs->server), am->ctxkey, &(am->in_buffer), am->realm);
 	if (am->in_buffer.nbh) {
 	if (am->in_buffer.nbh) {
 		ioa_network_buffer_delete(rs->ioa_eng, am->in_buffer.nbh);
 		ioa_network_buffer_delete(rs->ioa_eng, am->in_buffer.nbh);
 		am->in_buffer.nbh = NULL;
 		am->in_buffer.nbh = NULL;

+ 2 - 36
src/apps/relay/ns_ioalib_engine_impl.c

@@ -708,10 +708,10 @@ int ioa_socket_check_bandwidth(ioa_socket_handle s, ioa_network_buffer_handle nb
 	return 1;
 	return 1;
 }
 }
 
 
-int get_ioa_socket_from_reservation(ioa_engine_handle e, u64bits in_reservation_token, ioa_socket_handle *s, u08bits *realm)
+int get_ioa_socket_from_reservation(ioa_engine_handle e, u64bits in_reservation_token, ioa_socket_handle *s)
 {
 {
   if (e && in_reservation_token && s) {
   if (e && in_reservation_token && s) {
-    *s = rtcp_map_get(e->map_rtcp, in_reservation_token, realm);
+    *s = rtcp_map_get(e->map_rtcp, in_reservation_token);
     if (*s) {
     if (*s) {
       return 0;
       return 0;
     }
     }
@@ -1652,8 +1652,6 @@ ioa_socket_handle detach_ioa_socket(ioa_socket_handle s)
 
 
 		ret->magic = SOCKET_MAGIC;
 		ret->magic = SOCKET_MAGIC;
 
 
-		ret->realm_hash = s->realm_hash;
-
 		SSL* ssl = s->ssl;
 		SSL* ssl = s->ssl;
 		set_socket_ssl(s,NULL);
 		set_socket_ssl(s,NULL);
 		set_socket_ssl(ret,ssl);
 		set_socket_ssl(ret,ssl);
@@ -3417,38 +3415,6 @@ void set_ioa_socket_tobeclosed(ioa_socket_handle s)
 		s->tobeclosed = 1;
 		s->tobeclosed = 1;
 }
 }
 
 
-static u32bits string_hash(const u08bits *str) {
-
-  u32bits hash = 0;
-  int c = 0;
-
-  while ((c = *str++))
-    hash = c + (hash << 6) + (hash << 16) - hash;
-
-  return hash;
-}
-
-int check_realm_hash(ioa_socket_handle s, u08bits *realm)
-{
-	if(s) {
-		if(realm && realm[0]) {
-			if(s->realm_hash != string_hash(realm)) {
-				return 0;
-			}
-		}
-	}
-	return 1;
-}
-
-void set_realm_hash(ioa_socket_handle s, u08bits *realm)
-{
-	if(s) {
-		if(realm && realm[0]) {
-			s->realm_hash = string_hash(realm);
-		}
-	}
-}
-
 /*
 /*
  * Network buffer functions
  * Network buffer functions
  */
  */

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

@@ -221,8 +221,6 @@ struct _ioa_socket
 	struct bufferevent *conn_bev;
 	struct bufferevent *conn_bev;
 	connect_cb conn_cb;
 	connect_cb conn_cb;
 	void *conn_arg;
 	void *conn_arg;
-	//Transferable sockets user data
-	u32bits realm_hash;
 	//Accept:
 	//Accept:
 	struct evconnlistener *list_ev;
 	struct evconnlistener *list_ev;
 	accept_cb acb;
 	accept_cb acb;

+ 37 - 7
src/apps/relay/turn_admin_server.c

@@ -1369,6 +1369,7 @@ typedef enum _AS_FORM AS_FORM;
 #define HR_ADD_IP_KIND "aipk"
 #define HR_ADD_IP_KIND "aipk"
 #define HR_UPDATE_PARAMETER "togglepar"
 #define HR_UPDATE_PARAMETER "togglepar"
 #define HR_ADD_OAUTH_KID "oauth_kid"
 #define HR_ADD_OAUTH_KID "oauth_kid"
+#define HR_ADD_OAUTH_REALM "oauth_realm"
 #define HR_ADD_OAUTH_TS "oauth_ts"
 #define HR_ADD_OAUTH_TS "oauth_ts"
 #define HR_ADD_OAUTH_LT "oauth_lt"
 #define HR_ADD_OAUTH_LT "oauth_lt"
 #define HR_ADD_OAUTH_IKM "oauth_ikm"
 #define HR_ADD_OAUTH_IKM "oauth_ikm"
@@ -2773,12 +2774,13 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
 	size_t ret = 0;
 	size_t ret = 0;
 	const turn_dbdriver_t * dbd = get_dbdriver();
 	const turn_dbdriver_t * dbd = get_dbdriver();
 	if (dbd && dbd->list_oauth_keys) {
 	if (dbd && dbd->list_oauth_keys) {
-		secrets_list_t kids,teas,tss,lts;
+		secrets_list_t kids,teas,tss,lts,realms;
 		init_secrets_list(&kids);
 		init_secrets_list(&kids);
 		init_secrets_list(&teas);
 		init_secrets_list(&teas);
 		init_secrets_list(&tss);
 		init_secrets_list(&tss);
 		init_secrets_list(&lts);
 		init_secrets_list(&lts);
-		dbd->list_oauth_keys(&kids,&teas,&tss,&lts);
+		init_secrets_list(&realms);
+		dbd->list_oauth_keys(&kids,&teas,&tss,&lts,&realms);
 
 
 		size_t sz = get_secrets_list_size(&kids);
 		size_t sz = get_secrets_list_size(&kids);
 		size_t i;
 		size_t i;
@@ -2807,6 +2809,9 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
 			str_buffer_append(sb,"<td>");
 			str_buffer_append(sb,"<td>");
 			str_buffer_append(sb,get_secrets_list_elem(&teas,i));
 			str_buffer_append(sb,get_secrets_list_elem(&teas,i));
 			str_buffer_append(sb,"</td>");
 			str_buffer_append(sb,"</td>");
+			str_buffer_append(sb,"<td>");
+			str_buffer_append(sb,get_secrets_list_elem(&realms,i));
+			str_buffer_append(sb,"</td>");
 
 
 			{
 			{
 				str_buffer_append(sb,"<td> <a href=\"");
 				str_buffer_append(sb,"<td> <a href=\"");
@@ -2824,6 +2829,9 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
 
 
 		clean_secrets_list(&kids);
 		clean_secrets_list(&kids);
 		clean_secrets_list(&teas);
 		clean_secrets_list(&teas);
+		clean_secrets_list(&tss);
+		clean_secrets_list(&lts);
+		clean_secrets_list(&realms);
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -2889,9 +2897,13 @@ static void write_https_oauth_show_keys(ioa_socket_handle s, const char* kid)
 	}
 	}
 }
 }
 
 
-static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, const char* add_ikm,
+static void write_https_oauth_page(ioa_socket_handle s,
+				const char* add_kid,
+				const char* add_ikm,
 				const char* add_tea,
 				const char* add_tea,
-				const char *add_ts, const char* add_lt,
+				const char *add_ts,
+				const char* add_lt,
+				const char* add_realm,
 				const char* msg)
 				const char* msg)
 {
 {
 	if(s && !ioa_socket_tobeclosed(s)) {
 	if(s && !ioa_socket_tobeclosed(s)) {
@@ -2956,12 +2968,12 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
 
 
 				str_buffer_append(sb,"</td></tr>\r\n");
 				str_buffer_append(sb,"</td></tr>\r\n");
 
 
-				str_buffer_append(sb,"<tr><td colspan=\"2\">");
+				str_buffer_append(sb,"<tr><td colspan=\"1\">");
 
 
 				{
 				{
 					if(!add_ikm) add_ikm = "";
 					if(!add_ikm) add_ikm = "";
 
 
-					str_buffer_append(sb,"  <br>Base64-encoded input keying material (required):<br><textarea wrap=\"soft\" cols=70 rows=4 name=\"");
+					str_buffer_append(sb,"  <br>Base64-encoded input keying material (required):<br><textarea wrap=\"soft\" cols=40 rows=4 name=\"");
 					str_buffer_append(sb,HR_ADD_OAUTH_IKM);
 					str_buffer_append(sb,HR_ADD_OAUTH_IKM);
 					str_buffer_append(sb,"\" maxLength=256 >");
 					str_buffer_append(sb,"\" maxLength=256 >");
 					str_buffer_append(sb,(const char*)add_ikm);
 					str_buffer_append(sb,(const char*)add_ikm);
@@ -2971,6 +2983,18 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
 
 
 				str_buffer_append(sb,"</td><td>");
 				str_buffer_append(sb,"</td><td>");
 
 
+				{
+					if(!add_realm) add_realm = "";
+
+					str_buffer_append(sb,"  <br>Realm (optional): <input type=\"text\" name=\"");
+					str_buffer_append(sb,HR_ADD_OAUTH_REALM);
+					str_buffer_append(sb,"\" value=\"");
+					str_buffer_append(sb,(const char*)add_realm);
+					str_buffer_append(sb,"\"><br>\r\n");
+				}
+
+				str_buffer_append(sb,"</td><td>");
+
 				{
 				{
 					str_buffer_append(sb,"<br>Token encryption algorithm (required):<br>\r\n");
 					str_buffer_append(sb,"<br>Token encryption algorithm (required):<br>\r\n");
 
 
@@ -3008,6 +3032,7 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
 			str_buffer_append(sb,"<th>Timestamp, secs</th>");
 			str_buffer_append(sb,"<th>Timestamp, secs</th>");
 			str_buffer_append(sb,"<th>Lifetime,secs</th>");
 			str_buffer_append(sb,"<th>Lifetime,secs</th>");
 			str_buffer_append(sb,"<th>Token encryption algorithm</th>");
 			str_buffer_append(sb,"<th>Token encryption algorithm</th>");
+			str_buffer_append(sb,"<th>Realm</th>");
 			str_buffer_append(sb,"<th> </th>");
 			str_buffer_append(sb,"<th> </th>");
 			str_buffer_append(sb,"</tr>\r\n");
 			str_buffer_append(sb,"</tr>\r\n");
 
 
@@ -3495,6 +3520,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
 					const char* add_lt = "0";
 					const char* add_lt = "0";
 					const char* add_ikm = "";
 					const char* add_ikm = "";
 					const char* add_tea = "";
 					const char* add_tea = "";
+					const char* add_realm = "";
 					const char* msg = "";
 					const char* msg = "";
 
 
 					add_kid = get_http_header_value(hr,HR_ADD_OAUTH_KID,"");
 					add_kid = get_http_header_value(hr,HR_ADD_OAUTH_KID,"");
@@ -3503,6 +3529,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
 						add_ts = get_http_header_value(hr,HR_ADD_OAUTH_TS,"");
 						add_ts = get_http_header_value(hr,HR_ADD_OAUTH_TS,"");
 						add_lt = get_http_header_value(hr,HR_ADD_OAUTH_LT,"");
 						add_lt = get_http_header_value(hr,HR_ADD_OAUTH_LT,"");
 						add_tea = get_http_header_value(hr,HR_ADD_OAUTH_TEA,"");
 						add_tea = get_http_header_value(hr,HR_ADD_OAUTH_TEA,"");
+						add_realm = get_http_header_value(hr,HR_ADD_OAUTH_REALM,"");
 
 
 						int keys_ok = (add_ikm[0] != 0);
 						int keys_ok = (add_ikm[0] != 0);
 						if(!keys_ok) {
 						if(!keys_ok) {
@@ -3526,6 +3553,8 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
 								key.timestamp = (u64bits)strtoull(add_ts,NULL,10);
 								key.timestamp = (u64bits)strtoull(add_ts,NULL,10);
 							}
 							}
 
 
+							if(add_realm && add_realm[0]) STRCPY(key.realm,add_realm);
+
 							STRCPY(key.ikm_key,add_ikm);
 							STRCPY(key.ikm_key,add_ikm);
 							STRCPY(key.as_rs_alg,add_tea);
 							STRCPY(key.as_rs_alg,add_tea);
 
 
@@ -3539,12 +3568,13 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
 									add_lt = "0";
 									add_lt = "0";
 									add_ikm = "";
 									add_ikm = "";
 									add_tea = "";
 									add_tea = "";
+									add_realm = "";
 								}
 								}
 							}
 							}
 						}
 						}
 					}
 					}
 
 
-					write_https_oauth_page(s,add_kid,add_ikm,add_tea,add_ts,add_lt,msg);
+					write_https_oauth_page(s,add_kid,add_ikm,add_tea,add_ts,add_lt,add_realm,msg);
 				}
 				}
 				break;
 				break;
 			}
 			}

+ 4 - 0
src/apps/relay/userdb.c

@@ -517,6 +517,10 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u
 
 
 						ns_bcopy(dot.enc_block.mac_key,key,dot.enc_block.key_length);
 						ns_bcopy(dot.enc_block.mac_key,key,dot.enc_block.key_length);
 
 
+						if(rawKey.realm[0]) {
+							ns_bcopy(rawKey.realm,realm,sizeof(rawKey.realm));
+						}
+
 						ret = 0;
 						ret = 0;
 					}
 					}
 				}
 				}

+ 4 - 4
src/apps/uclient/mainuclient.c

@@ -102,9 +102,9 @@ int oauth = 0;
 oauth_key okey_array[3];
 oauth_key okey_array[3];
 
 
 static oauth_key_data_raw okdr_array[3] = {
 static oauth_key_data_raw okdr_array[3] = {
-		{"north","MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK",0,0,"A256GCM"},
-		{"union","MTIzNDU2Nzg5MDEyMzQ1Ngo=",0,0,"A128GCM"},
-		{"oldempire","MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK",0,0,"A256GCM"}
+		{"north","MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK",0,0,"A256GCM","crinna.org"},
+		{"union","MTIzNDU2Nzg5MDEyMzQ1Ngo=",0,0,"A128GCM","north.gov"},
+		{"oldempire","MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK",0,0,"A256GCM",""}
 };
 };
 
 
 //////////////// local definitions /////////////////
 //////////////// local definitions /////////////////
@@ -137,7 +137,7 @@ static char Usage[] =
   "	-G	Generate extra requests (create permissions, channel bind).\n"
   "	-G	Generate extra requests (create permissions, channel bind).\n"
   "	-B	Random disconnect after a few initial packets.\n"
   "	-B	Random disconnect after a few initial packets.\n"
   "	-Z	Dual allocation (implies -c).\n"
   "	-Z	Dual allocation (implies -c).\n"
-  "	-J	Use oAuth with default test key kid='north' or 'oldempire'.\n"
+  "	-J	Use oAuth with default test keys kid='north', 'union' or 'oldempire'.\n"
   "Options:\n"
   "Options:\n"
   "	-l	Message length (Default: 100 Bytes).\n"
   "	-l	Message length (Default: 100 Bytes).\n"
   "	-i	Certificate file (for secure connections only, optional).\n"
   "	-i	Certificate file (for secure connections only, optional).\n"

+ 0 - 6
src/client/ns_turn_msg_defs.h

@@ -148,12 +148,6 @@
 #define STUN_ATTRIBUTE_TRANSPORT_DTLS_VALUE (250)
 #define STUN_ATTRIBUTE_TRANSPORT_DTLS_VALUE (250)
 /* <<== RFC 6062 */
 /* <<== RFC 6062 */
 
 
-/* Mobility ==>> */
-#define STUN_ATTRIBUTE_MOBILITY_TICKET (0x802E)
-#define STUN_ATTRIBUTE_MOBILITY_EVENT (0x802)
-#define STUN_ATTRIBUTE_MOBILITY_SUPPORT (0x8000)
-/* <<== Mobility */
-
 /* SHA ==>> */
 /* SHA ==>> */
 
 
 #define SHA1SIZEBYTES (20)
 #define SHA1SIZEBYTES (20)

+ 5 - 0
src/client/ns_turn_msg_defs_experimental.h

@@ -38,6 +38,11 @@
 #define STUN_ATTRIBUTE_ORIGIN (0x802F)
 #define STUN_ATTRIBUTE_ORIGIN (0x802F)
 /* <<== Origin */
 /* <<== Origin */
 
 
+/* Mobility ==>> */
+/* conflicts with third-party authorization ! 0x802E is used for third-party authorization now */
+#define STUN_ATTRIBUTE_MOBILITY_TICKET (0x8030)
+/* <<== Mobility */
+
 /* Bandwidth */
 /* Bandwidth */
 
 
 #define STUN_ATTRIBUTE_NEW_BANDWIDTH (0x8000 + STUN_ATTRIBUTE_BANDWIDTH)
 #define STUN_ATTRIBUTE_NEW_BANDWIDTH (0x8000 + STUN_ATTRIBUTE_BANDWIDTH)

+ 2 - 2
src/ns_turn_defs.h

@@ -31,8 +31,8 @@
 #ifndef __IOADEFS__
 #ifndef __IOADEFS__
 #define __IOADEFS__
 #define __IOADEFS__
 
 
-#define TURN_SERVER_VERSION "4.4.5.4"
-#define TURN_SERVER_VERSION_NAME "Ardee West"
+#define TURN_SERVER_VERSION "4.5.0.1"
+#define TURN_SERVER_VERSION_NAME "dan Eider"
 #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
 #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
 
 
 #if (defined(__unix__) || defined(unix)) && !defined(USG)
 #if (defined(__unix__) || defined(unix)) && !defined(USG)

+ 1 - 3
src/server/ns_turn_ioalib.h

@@ -227,7 +227,7 @@ int create_relay_ioa_sockets(ioa_engine_handle e, ioa_socket_handle client_s,
 
 
 ioa_socket_handle  ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, void *arg);
 ioa_socket_handle  ioa_create_connecting_tcp_relay_socket(ioa_socket_handle s, ioa_addr *peer_addr, connect_cb cb, void *arg);
 
 
-int get_ioa_socket_from_reservation(ioa_engine_handle e, u64bits in_reservation_token, ioa_socket_handle *s, u08bits *realm);
+int get_ioa_socket_from_reservation(ioa_engine_handle e, u64bits in_reservation_token, ioa_socket_handle *s);
 
 
 int get_ioa_socket_address_family(ioa_socket_handle s);
 int get_ioa_socket_address_family(ioa_socket_handle s);
 int is_stream_socket(int st);
 int is_stream_socket(int st);
@@ -260,8 +260,6 @@ void set_do_not_use_df(ioa_socket_handle s);
 int ioa_socket_tobeclosed(ioa_socket_handle s);
 int ioa_socket_tobeclosed(ioa_socket_handle s);
 void set_ioa_socket_tobeclosed(ioa_socket_handle s);
 void set_ioa_socket_tobeclosed(ioa_socket_handle s);
 void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s);
 void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s);
-int check_realm_hash(ioa_socket_handle s, u08bits *realm);
-void set_realm_hash(ioa_socket_handle s, u08bits *realm);
 
 
 ////////////////// Base64 /////////////////////////////
 ////////////////// Base64 /////////////////////////////
 
 

+ 2 - 2
src/server/ns_turn_maps.c

@@ -1029,11 +1029,11 @@ struct _ur_string_map {
   TURN_MUTEX_DECLARE(mutex)
   TURN_MUTEX_DECLARE(mutex)
 };
 };
 
 
-static unsigned long string_hash(const ur_string_map_key_type key) {
+static u32bits string_hash(const ur_string_map_key_type key) {
 
 
   u08bits *str=(u08bits*)key;
   u08bits *str=(u08bits*)key;
 
 
-  unsigned long hash = 0;
+  u32bits hash = 0;
   int c = 0;
   int c = 0;
 
 
   while ((c = *str++))
   while ((c = *str++))

+ 2 - 6
src/server/ns_turn_maps_rtcp.c

@@ -214,7 +214,7 @@ int rtcp_map_put(rtcp_map* map, rtcp_token_type token, ioa_socket_handle s) {
  * >=0 - success
  * >=0 - success
  * <0 - not found
  * <0 - not found
  */
  */
-ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token, u08bits *realm) {
+ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token) {
 	ioa_socket_handle s = NULL;
 	ioa_socket_handle s = NULL;
 	if (rtcp_map_valid(map)) {
 	if (rtcp_map_valid(map)) {
 		ur_map_value_type value;
 		ur_map_value_type value;
@@ -224,11 +224,7 @@ ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token, u08bits *re
 			rtcp_alloc_type* rval = (rtcp_alloc_type*) value;
 			rtcp_alloc_type* rval = (rtcp_alloc_type*) value;
 			if (rval) {
 			if (rval) {
 				s = rval->s;
 				s = rval->s;
-				if(!check_realm_hash(s,realm)) {
-					s = NULL;
-				} else {
-					rtcp_map_del_savefd(map, token);
-				}
+				rtcp_map_del_savefd(map, token);
 			}
 			}
 		}
 		}
 		TURN_MUTEX_UNLOCK(&map->mutex);
 		TURN_MUTEX_UNLOCK(&map->mutex);

+ 1 - 1
src/server/ns_turn_maps_rtcp.h

@@ -61,7 +61,7 @@ int rtcp_map_put(rtcp_map* map, rtcp_token_type key, ioa_socket_handle s);
  * >=0 - success
  * >=0 - success
  * <0 - not found
  * <0 - not found
  */
  */
-ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token, u08bits *realm);
+ioa_socket_handle rtcp_map_get(rtcp_map* map, rtcp_token_type token);
 
 
 /**
 /**
  * @ret:
  * @ret:

+ 18 - 13
src/server/ns_turn_server.c

@@ -77,7 +77,7 @@ static inline void log_method(ts_ur_super_session* ss, const char *method, int e
 				(unsigned long long)(ss->id), (const char*)(ss->realm_options.name),(const char*)(ss->username),method);
 				(unsigned long long)(ss->id), (const char*)(ss->realm_options.name),(const char*)(ss->username),method);
 		}
 		}
 	  } else {
 	  } else {
-		  if(!reason) reason=(const u08bits*)"Unknown error";
+		  if(!reason) reason=get_default_reason(err_code);
 		  if(ss->origin[0]) {
 		  if(ss->origin[0]) {
 			  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
 			  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
 					  "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n",
 					  "session %018llu: origin <%s> realm <%s> user <%s>: incoming packet %s processed, error %d: %s\n",
@@ -3191,7 +3191,7 @@ static int create_challenge_response(ts_ur_super_session *ss, stun_tid *tid, int
 #define min(a,b) ((a)<=(b) ? (a) : (b))
 #define min(a,b) ((a)<=(b) ? (a) : (b))
 #endif
 #endif
 
 
-static void resume_processing_after_username_check(int success,  int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, u64bits ctxkey, ioa_net_data *in_buffer)
+static void resume_processing_after_username_check(int success,  int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, u64bits ctxkey, ioa_net_data *in_buffer, u08bits *realm)
 {
 {
 
 
 	if(server && in_buffer && in_buffer->nbh) {
 	if(server && in_buffer && in_buffer->nbh) {
@@ -3206,6 +3206,11 @@ static void resume_processing_after_username_check(int success,  int oauth, int
 				ss->oauth = oauth;
 				ss->oauth = oauth;
 				ss->max_session_time_auth = (turn_time_t)max_session_time;
 				ss->max_session_time_auth = (turn_time_t)max_session_time;
 				ns_bcopy(pwd,ss->pwd,sizeof(password_t));
 				ns_bcopy(pwd,ss->pwd,sizeof(password_t));
+				if(realm && realm[0] && strcmp((char*)realm,ss->realm_options.name)) {
+					dec_quota(ss);
+					get_realm_options_by_name((char*)realm, &(ss->realm_options));
+					inc_quota(ss,ss->username);
+				}
 			}
 			}
 
 
 			read_client_connection(server,ss,in_buffer,0,0);
 			read_client_connection(server,ss,in_buffer,0,0);
@@ -3318,14 +3323,18 @@ static int check_stun_auth(turn_turnserver *server,
 			get_realm_options_by_name((char *)realm, &(ss->realm_options));
 			get_realm_options_by_name((char *)realm, &(ss->realm_options));
 
 
 		} else if(strcmp((char*)realm, (char*)(ss->realm_options.name))) {
 		} else if(strcmp((char*)realm, (char*)(ss->realm_options.name))) {
-			if(method == STUN_METHOD_ALLOCATE) {
-				*err_code = 437;
-				*reason = (const u08bits*)"Allocation mismatch: wrong credentials: the realm value is incorrect";
+			if(!(ss->oauth)){
+				if(method == STUN_METHOD_ALLOCATE) {
+					*err_code = 437;
+					*reason = (const u08bits*)"Allocation mismatch: wrong credentials: the realm value is incorrect";
+				} else {
+					*err_code = 441;
+					*reason = (const u08bits*)"Wrong credentials: the realm value is incorrect";
+				}
+				return -1;
 			} else {
 			} else {
-				*err_code = 441;
-				*reason = (const u08bits*)"Wrong credentials: the realm value is incorrect";
+				ns_bcopy(ss->realm_options.name,realm,sizeof(ss->realm_options.name));
 			}
 			}
-			return -1;
 		}
 		}
 	}
 	}
 
 
@@ -3366,7 +3375,6 @@ static int check_stun_auth(turn_turnserver *server,
 		}
 		}
 	} else {
 	} else {
 		STRCPY(ss->username,usname);
 		STRCPY(ss->username,usname);
-		set_realm_hash(ss->client_socket,(u08bits*)ss->realm_options.name);
 	}
 	}
 
 
 	{
 	{
@@ -4261,7 +4269,7 @@ static int create_relay_connection(turn_turnserver* server,
 
 
 			ioa_socket_handle s = NULL;
 			ioa_socket_handle s = NULL;
 
 
-			if ((get_ioa_socket_from_reservation(server->e, in_reservation_token,&s,(u08bits*)ss->realm_options.name) < 0)||
+			if ((get_ioa_socket_from_reservation(server->e, in_reservation_token,&s) < 0)||
 				!s ||
 				!s ||
 				ioa_socket_tobeclosed(s)) {
 				ioa_socket_tobeclosed(s)) {
 
 
@@ -4317,11 +4325,8 @@ static int create_relay_connection(turn_turnserver* server,
 			return -1;
 			return -1;
 		}
 		}
 
 
-		set_realm_hash(newelem->s,(u08bits*)ss->realm_options.name);
-
 		if (rtcp_s) {
 		if (rtcp_s) {
 			if (out_reservation_token && *out_reservation_token) {
 			if (out_reservation_token && *out_reservation_token) {
-				set_realm_hash(rtcp_s,(u08bits*)ss->realm_options.name);
 				/* OK */
 				/* OK */
 			} else {
 			} else {
 				IOA_CLOSE_SOCKET(newelem->s);
 				IOA_CLOSE_SOCKET(newelem->s);

+ 1 - 1
src/server/ns_turn_server.h

@@ -90,7 +90,7 @@ typedef enum {
 struct _turn_turnserver;
 struct _turn_turnserver;
 typedef struct _turn_turnserver turn_turnserver;
 typedef struct _turn_turnserver turn_turnserver;
 
 
-typedef void (*get_username_resume_cb)(int success, int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, u64bits ctxkey, ioa_net_data *in_buffer);
+typedef void (*get_username_resume_cb)(int success, int oauth, int max_session_time, hmackey_t hmackey, password_t pwd, turn_turnserver *server, u64bits ctxkey, ioa_net_data *in_buffer, u08bits* realm);
 typedef u08bits *(*get_user_key_cb)(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, u08bits *uname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply);
 typedef u08bits *(*get_user_key_cb)(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, u08bits *uname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply);
 typedef int (*check_new_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm);
 typedef int (*check_new_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm);
 typedef void (*release_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm);
 typedef void (*release_allocation_quota_cb)(u08bits *username, int oauth, u08bits *realm);

+ 1 - 0
turndb/schema.sql

@@ -43,6 +43,7 @@ CREATE TABLE oauth_key (
 	timestamp bigint default 0,
 	timestamp bigint default 0,
 	lifetime integer default 0,
 	lifetime integer default 0,
 	as_rs_alg varchar(64) default '',
 	as_rs_alg varchar(64) default '',
+	realm varchar(127),
 	primary key (kid)
 	primary key (kid)
 );
 );
 
 

+ 18 - 9
turndb/schema.userdb.redis

@@ -46,6 +46,9 @@ and they will be almost immediately "seen" by the turnserver process.
 		"A256GCM", "A128GCM" (see 
 		"A256GCM", "A128GCM" (see 
 		http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-5.1).
 		http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-5.1).
 		The default value is "A256GCM".
 		The default value is "A256GCM".
+
+	realm - optionally, a kid can be assigned to a realm that is different
+		from the default realm.
 		
 		
 5) admin users (over https interface) are maintained as keys of form:
 5) admin users (over https interface) are maintained as keys of form:
 "turn/admin_user/<username> with hash members "password" and,
 "turn/admin_user/<username> with hash members "password" and,
@@ -54,15 +57,21 @@ optionally, "realm".
 II. Extra realms data in the database
 II. Extra realms data in the database
 
 
 We can use more than one realm with the same instance of the TURN server.
 We can use more than one realm with the same instance of the TURN server.
-This is done through the ORIGIN mechanism - users with different ORIGINS
-are placed into different realms. The database includes information about the
-relationships between the ORIGIN and realms, and about the extra realms
-database numbers.
+This is done in two ways:
+
+  1) through the third-party authentication option. An oAuth kid can be optionally
+  assigned to a realm. When the user provides kid, and the database record
+  for that kid contains a non-empty non-default realm, then the user is treated
+  as belonging to that realm.
+  2) the ORIGIN mechanism - users with different ORIGINS
+  are placed into different realms. The database includes information about the
+  relationships between the ORIGIN and realms, and about the extra realms
+  database numbers.
 	The relationship between ORIGIN and realm is set as keys of form:
 	The relationship between ORIGIN and realm is set as keys of form:
-"turn/origin/<origin>" with the realm-names as the value. Many different
-ORIGIN keys may have the same realm. If the ORIGIN value is not found in 
-the database or the ORIGIN field is missed in the initial allocate 
-request, then the default realm is assumed.
+	"turn/origin/<origin>" with the realm-names as the value. Many different
+	ORIGIN keys may have the same realm. If the ORIGIN value is not found in 
+	the database or the ORIGIN field is missed in the initial allocate 
+	request, then the default realm is assumed.
 
 
 III) Example of a Redis default user database setup.
 III) Example of a Redis default user database setup.
 
 
@@ -82,7 +91,7 @@ This example sets user database for:
   	"total_quota" and "user_quota" (same names as the turnserver 
   	"total_quota" and "user_quota" (same names as the turnserver 
   	configuration options, with the same meanings).
   	configuration options, with the same meanings).
   * The oAuth data for the key with kid "oldempire" and key value
   * The oAuth data for the key with kid "oldempire" and key value
-  "12345678901234567890123456789012".
+  "12345678901234567890123456789012", and default realm.
   * The admin user 'skarling', realm 'north.gov', with password 'hoodless';
   * The admin user 'skarling', realm 'north.gov', with password 'hoodless';
   * The global admin user 'bayaz' with password 'magi';  
   * The global admin user 'bayaz' with password 'magi';  
   
   

+ 6 - 4
turndb/testmongosetup.sh

@@ -28,8 +28,8 @@ db.turn_secret.insert({ realm: 'north.gov', value: 'bloody9' });
 db.turn_secret.insert({ realm: 'crinna.org', value: 'north' });
 db.turn_secret.insert({ realm: 'crinna.org', value: 'north' });
 db.turn_secret.insert({ realm: 'crinna.org', value: 'library' });
 db.turn_secret.insert({ realm: 'crinna.org', value: 'library' });
 
 
-db.admin_user.insert({ name: 'skarling', realm: 'north.gov', password: '$5$6fc35c3b0c7d4633$27fca7574f9b79d0cb93ae03e45379470cbbdfcacdd6401f97ebc620f31f54f2' });
-db.admin_user.insert({ name: 'bayaz', realm: '', password: '$5$e018513e9de69e73$5cbdd2e29e04ca46aeb022268a7460d3a3468de193dcb2b95f064901769f455f' });
+db.admin_user.insert({ name: 'skarling', realm: 'north.gov', password: '\$5\$6fc35c3b0c7d4633\$27fca7574f9b79d0cb93ae03e45379470cbbdfcacdd6401f97ebc620f31f54f2' });
+db.admin_user.insert({ name: 'bayaz', realm: '', password: '\$5\$e018513e9de69e73\$5cbdd2e29e04ca46aeb022268a7460d3a3468de193dcb2b95f064901769f455f' });
 
 
 db.realm.insert({
 db.realm.insert({
   realm: 'north.gov',
   realm: 'north.gov',
@@ -56,10 +56,12 @@ db.realm.insert({
 
 
 db.oauth_key.insert({ kid: 'north', 
 db.oauth_key.insert({ kid: 'north', 
 					ikm_key: 'MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK', 
 					ikm_key: 'MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK', 
-					as_rs_alg: 'A256GCM'});
+					as_rs_alg: 'A256GCM',
+					realm: 'crinna.org'});
 db.oauth_key.insert({ kid: 'union', 
 db.oauth_key.insert({ kid: 'union', 
 					ikm_key: 'MTIzNDU2Nzg5MDEyMzQ1Ngo=', 
 					ikm_key: 'MTIzNDU2Nzg5MDEyMzQ1Ngo=', 
-					as_rs_alg: 'A128GCM'});
+					as_rs_alg: 'A128GCM',
+					realm: 'north.gov'});
 db.oauth_key.insert({ kid: 'oldempire', 
 db.oauth_key.insert({ kid: 'oldempire', 
 					ikm_key: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK', 
 					ikm_key: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK', 
 					as_rs_alg: 'A256GCM'});
 					as_rs_alg: 'A256GCM'});

+ 2 - 2
turndb/testredisdbsetup.sh

@@ -38,8 +38,8 @@ sadd turn/realm/crinna.org/allowed-peer-ip "172.17.13.202"
 sadd turn/realm/north.gov/denied-peer-ip "172.17.13.133-172.17.14.56" "172.17.17.133-172.17.19.56" "123::45"
 sadd turn/realm/north.gov/denied-peer-ip "172.17.13.133-172.17.14.56" "172.17.17.133-172.17.19.56" "123::45"
 sadd turn/realm/crinna.org/denied-peer-ip "123::77"
 sadd turn/realm/crinna.org/denied-peer-ip "123::77"
 
 
-hmset turn/oauth/kid/north ikm_key 'MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK' as_rs_alg 'A256GCM'
-hmset turn/oauth/kid/union ikm_key 'MTIzNDU2Nzg5MDEyMzQ1Ngo=' as_rs_alg 'A128GCM'
+hmset turn/oauth/kid/north ikm_key 'MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK' as_rs_alg 'A256GCM' realm 'crinna.org'
+hmset turn/oauth/kid/union ikm_key 'MTIzNDU2Nzg5MDEyMzQ1Ngo=' as_rs_alg 'A128GCM' realm 'north.gov'
 hmset turn/oauth/kid/oldempire ikm_key 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK' as_rs_alg 'A256GCM'
 hmset turn/oauth/kid/oldempire ikm_key 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK' as_rs_alg 'A256GCM'
 
 
 hmset turn/admin_user/skarling realm 'north.gov' password '\$5\$6fc35c3b0c7d4633\$27fca7574f9b79d0cb93ae03e45379470cbbdfcacdd6401f97ebc620f31f54f2'
 hmset turn/admin_user/skarling realm 'north.gov' password '\$5\$6fc35c3b0c7d4633\$27fca7574f9b79d0cb93ae03e45379470cbbdfcacdd6401f97ebc620f31f54f2'

+ 3 - 3
turndb/testsqldbsetup.sql

@@ -31,6 +31,6 @@ insert into denied_peer_ip (ip_range) values('123::45');
 insert into denied_peer_ip (realm,ip_range) values('north.gov','172.17.17.133-172.17.19.56');
 insert into denied_peer_ip (realm,ip_range) values('north.gov','172.17.17.133-172.17.19.56');
 insert into denied_peer_ip (realm,ip_range) values('crinna.org','123::77');
 insert into denied_peer_ip (realm,ip_range) values('crinna.org','123::77');
 
 
-insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('north','MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK',0,0,'A256GCM');
-insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('union','MTIzNDU2Nzg5MDEyMzQ1Ngo=',0,0,'A128GCM');
-insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg) values('oldempire','MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK',0,0,'A256GCM');
+insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('north','MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEK',0,0,'A256GCM','crinna.org');
+insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('union','MTIzNDU2Nzg5MDEyMzQ1Ngo=',0,0,'A128GCM','north.gov');
+insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,realm) values('oldempire','MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIK',0,0,'A256GCM','');