Browse Source

working on per-realm white/black lists

mom040267 11 years ago
parent
commit
13b8ac9e74

+ 4 - 2
ChangeLog

@@ -1,5 +1,7 @@
-10/16/2014 Oleg Moskalenko <[email protected]>
-Version 4.2.1.4 'Monza':
+10/26/2014 Oleg Moskalenko <[email protected]>
+Version 4.2.2.1 'Monza':
+	- black- and white- IP lists are divided per realm
+		(the DB schema changed);
 	- TCP/TLS tests extended.
 	- relay RTCP sockets ports allocation fixed.
 	- list of libraries cleaned.

+ 1 - 1
rpm/build.settings.sh

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

+ 3 - 3
rpm/turnserver.spec

@@ -1,5 +1,5 @@
 Name:		turnserver
-Version:	4.2.1.4
+Version:	4.2.2.1
 Release:	0%{dist}
 Summary:	Coturn TURN Server
 
@@ -294,8 +294,8 @@ fi
 %{_includedir}/turn/client/TurnMsgLib.h
 
 %changelog
-* Thu Oct 16 2014 Oleg Moskalenko <[email protected]>
-  - Sync to 4.2.1.4
+* Sun Oct 26 2014 Oleg Moskalenko <[email protected]>
+  - Sync to 4.2.2.1
 * Sun Oct 05 2014 Oleg Moskalenko <[email protected]>
   - Sync to 4.2.1.2
 * Thu Aug 14 2014 Oleg Moskalenko <[email protected]>

+ 18 - 3
src/apps/relay/dbdrivers/dbd_mysql.c

@@ -896,11 +896,22 @@ static int mysql_get_ip_list(const char *kind, ip_range_list_t * list) {
 	MYSQL * myc = get_mydb_connection();
 	if(myc) {
 		char statement[TURN_LONG_STRING_SIZE];
-		snprintf(statement,sizeof(statement),"select ip_range from %s_peer_ip",kind);
+		snprintf(statement,sizeof(statement),"select ip_range,realm from %s_peer_ip",kind);
 		int res = mysql_query(myc, statement);
+
+		if(res) {
+			static int wrong_table_reported = 0;
+			if(!wrong_table_reported) {
+				wrong_table_reported = 1;
+				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information; probably, the tables 'allowed_peer_ip' and/or 'denied_peer_ip' have to be upgraded to include the realm column.\n");
+			}
+			snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind);
+			res = mysql_query(myc, statement);
+		}
+
 		if(res == 0) {
 			MYSQL_RES *mres = mysql_store_result(myc);
-			if(mres && mysql_field_count(myc)==1) {
+			if(mres && mysql_field_count(myc)==2) {
 				for(;;) {
 					MYSQL_ROW row = mysql_fetch_row(mres);
 					if(!row) {
@@ -913,7 +924,11 @@ static int mysql_get_ip_list(const char *kind, ip_range_list_t * list) {
 								char kval[TURN_LONG_STRING_SIZE];
 								ns_bcopy(row[0],kval,sz);
 								kval[sz]=0;
-								add_ip_list_range(kval,NULL,list);
+								sz = lengths[1];
+								char rval[TURN_LONG_STRING_SIZE];
+								ns_bcopy(row[1],rval,sz);
+								rval[sz]=0;
+								add_ip_list_range(kval,rval,list);
 							}
 						}
 					}

+ 25 - 12
src/apps/relay/dbdrivers/dbd_pgsql.c

@@ -645,30 +645,43 @@ static void pgsql_auth_ping(void * rch) {
 	}
 }
   
-static int pgsql_get_ip_list(const char *kind, ip_range_list_t * list) {
-  int ret = -1;
+
+static int pgsql_get_ip_list(const char *kind, ip_range_list_t * list)
+{
+	int ret = -1;
 	PGconn * pqc = get_pqdb_connection();
-	if(pqc) {
+	if (pqc) {
 		char statement[TURN_LONG_STRING_SIZE];
-		snprintf(statement,sizeof(statement),"select ip_range from %s_peer_ip",kind);
+		snprintf(statement, sizeof(statement), "select ip_range,realm from %s_peer_ip", kind);
 		PGresult *res = PQexec(pqc, statement);
 
-		if(res && (PQresultStatus(res) == PGRES_TUPLES_OK)) {
+		if (!res || (PQresultStatus(res) != PGRES_TUPLES_OK)) {
+			static int wrong_table_reported = 0;
+			if(!wrong_table_reported) {
+				wrong_table_reported = 1;
+				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s; probably, the tables 'allowed_peer_ip' and/or 'denied_peer_ip' have to be upgraded to include the realm column.\n",PQerrorMessage(pqc));
+			}
+			snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind);
+			res = PQexec(pqc, statement);
+		}
+
+		if (res && (PQresultStatus(res) == PGRES_TUPLES_OK)) {
 			int i = 0;
-			for(i=0;i<PQntuples(res);i++) {
-				char *kval = PQgetvalue(res,i,0);
-				if(kval) {
-					add_ip_list_range(kval,NULL,list);
+			for (i = 0; i < PQntuples(res); i++) {
+				char *kval = PQgetvalue(res, i, 0);
+				char *rval = PQgetvalue(res, i, 1);
+				if (kval) {
+					add_ip_list_range(kval, rval, list);
 				}
 			}
-      ret = 0;
+			ret = 0;
 		}
 
-		if(res) {
+		if (res) {
 			PQclear(res);
 		}
 	}
-  return ret;
+	return ret;
 }
   
 static void pgsql_reread_realms(secrets_list_t * realms_list) {

+ 30 - 14
src/apps/relay/dbdrivers/dbd_redis.c

@@ -1094,14 +1094,20 @@ static void redis_auth_ping(void * rch) {
 		send_message_to_redis((redis_context_handle)rch, "publish", "__XXX__", "__YYY__");
 }
   
-static int redis_get_ip_list(const char *kind, ip_range_list_t * list) {
-  int ret = -1;
+
+
+static int redis_get_ip_list(const char *kind, ip_range_list_t * list)
+{
+	int ret = -1;
 	redisContext *rc = get_redis_connection();
-	if(rc) {
+	if (rc) {
+		char header[TURN_LONG_STRING_SIZE];
 		char statement[TURN_LONG_STRING_SIZE];
-		snprintf(statement,sizeof(statement),"keys turn/%s-peer-ip/*", kind);
-		redisReply *reply = (redisReply*)redisCommand(rc, statement);
-		if(reply) {
+		snprintf(header, sizeof(header), "turn/%s-peer-ip/", kind);
+		size_t header_len = strlen(header);
+		snprintf(statement, sizeof(statement), "keys %s*", header);
+		redisReply *reply = (redisReply*) redisCommand(rc, statement);
+		if (reply) {
 			secrets_list_t keys;
 			size_t isz = 0;
 			char s[257];
@@ -1116,21 +1122,31 @@ static int redis_get_ip_list(const char *kind, ip_range_list_t * list) {
 			} else {
 				size_t i;
 				for (i = 0; i < reply->elements; ++i) {
-					add_to_secrets_list(&keys,reply->element[i]->str);
+					add_to_secrets_list(&keys, reply->element[i]->str);
 				}
 			}
 
-			for(isz=0;isz<keys.sz;++isz) {
-				snprintf(s,sizeof(s),"get %s", keys.secrets[isz]);
-				redisReply *rget = (redisReply *)redisCommand(rc, s);
-				if(rget) {
+			for (isz = 0; isz < keys.sz; ++isz) {
+				char *realm = NULL;
+				snprintf(s, sizeof(s), "get %s", keys.secrets[isz]);
+				redisReply *rget = (redisReply *) redisCommand(rc, s);
+				if (rget) {
 					if (rget->type == REDIS_REPLY_ERROR)
 						TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str);
 					else if (rget->type != REDIS_REPLY_STRING) {
 						if (rget->type != REDIS_REPLY_NIL)
 							TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
 					} else {
-						add_ip_list_range(rget->str,NULL,list);
+						char *ptr = ((char*)keys.secrets[isz])+header_len;
+						char *sep = strstr(ptr, "/");
+						if (sep) {
+							*sep = 0;
+							realm = ptr;
+						}
+						add_ip_list_range(rget->str, realm, list);
+						if(sep) {
+							*sep='/';
+						}
 					}
 					turnFreeRedisReply(rget);
 				}
@@ -1139,10 +1155,10 @@ static int redis_get_ip_list(const char *kind, ip_range_list_t * list) {
 			clean_secrets_list(&keys);
 
 			turnFreeRedisReply(reply);
-      ret = 0;
+			ret = 0;
 		}
 	}
-  return ret;
+	return ret;
 }
   
 static void redis_reread_realms(secrets_list_t * realms_list) {

+ 1 - 1
src/ns_turn_defs.h

@@ -31,7 +31,7 @@
 #ifndef __IOADEFS__
 #define __IOADEFS__
 
-#define TURN_SERVER_VERSION "4.2.1.4"
+#define TURN_SERVER_VERSION "4.2.2.1"
 #define TURN_SERVER_VERSION_NAME "Monza"
 #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
 

+ 7 - 5
turndb/schema.sql

@@ -1,6 +1,6 @@
 
 CREATE TABLE turnusers_lt (
-    realm varchar(512),
+    realm varchar(512) default '',
     name varchar(512),
     hmackey char(128),
     PRIMARY KEY (realm,name)
@@ -12,19 +12,21 @@ CREATE TABLE turnusers_st (
 );
 
 CREATE TABLE turn_secret (
-	realm varchar(512),
+	realm varchar(512) default '',
     value varchar(512),
 	primary key (realm,value)
 );
 
 CREATE TABLE allowed_peer_ip (
+	realm varchar(512) default '',
 	ip_range varchar(256),
-	primary key (ip_range)
+	primary key (realm,ip_range)
 );
 
 CREATE TABLE denied_peer_ip (
+	realm varchar(512) default '',
 	ip_range varchar(256),
-	primary key (ip_range)
+	primary key (realm,ip_range)
 );
 
 CREATE TABLE turn_origin_to_realm (
@@ -34,7 +36,7 @@ CREATE TABLE turn_origin_to_realm (
 );
 
 CREATE TABLE turn_realm_option (
-	realm varchar(512),
+	realm varchar(512) default '',
 	opt varchar(32),
 	value varchar(128),
 	primary key (realm,opt)

+ 14 - 5
turndb/schema.userdb.redis

@@ -28,13 +28,17 @@ issue command "keys turn/realm/north.gov/secret/*" it it will try to use the
 obtained keys in arbitrary order.
 
 4) The "white" and "black" peer IP ranges are stored as keys of the
-following form: "turn/allowed-peer-ip/<arbitrary>" or 
-"turn/denied-peer-ip/<arbitrary>"
+following form: 
+"turn/allowed-peer-ip/<arbitrary-unique-id>" or 
+"turn/allowed-peer-ip/<realm>/<arbitrary-unique-id>" or 
+"turn/denied-peer-ip/<arbitrary-unique-id>" or
+"turn/denied-peer-ip/<realm>/<arbitrary-unique-id>".
 
 The meaning of the keys is the same as the meaning of allowed-peer-ip and
-denied-peer-ip turnserver command-line option. The only difference is that 
-the option values are "static" (they remain the same for the lifetime of 
-the turnserver process) but the database records can be dynamically changed 
+denied-peer-ip turnserver command-line option (with the addition of the realm option).
+The only difference is that the turnserver option values are "static" 
+(they remain the same for the lifetime of the turnserver process) but 
+the database records can be dynamically changed 
 and they will be almost immediately "seen" by the turnserver process.
 
 5) For the oAuth authentication, there is a hash structure with the key 
@@ -143,7 +147,12 @@ set turn/origin/https://bligh.edu:443 crinna.org
 set turn/denied-peer-ip/123456 "172.17.13.133-172.17.14.56"
 set turn/denied-peer-ip/234567 "123::45"
 
+set turn/denied-peer-ip/north.gov/1234567 "172.17.17.133-172.17.19.56"
+set turn/denied-peer-ip/crinna.org/2345678 "123::77"
+
 set turn/allowed-peer-ip/345678 "172.17.13.200"
+set turn/allowed-peer-ip/north.gov/345679 "172.17.13.201"
+set turn/allowed-peer-ip/crinna.org/3456710 "172.17.13.202"
 
 hmset turn/oauth/kid/north ikm_key Y2FybGVvbg== hkdf_hash_func 'SHA-256' as_rs_alg 'AES-128-CBC' auth_alg 'HMAC-SHA-256-128'
 

+ 5 - 0
turndb/testredisdbsetup.sh

@@ -45,7 +45,12 @@ set turn/origin/https://bligh.edu:443 crinna.org
 set turn/denied-peer-ip/123456 "172.17.13.133-172.17.14.56"
 set turn/denied-peer-ip/234567 "123::45"
 
+set turn/denied-peer-ip/north.gov/1234567 "172.17.17.133-172.17.19.56"
+set turn/denied-peer-ip/crinna.org/2345678 "123::77"
+
 set turn/allowed-peer-ip/345678 "172.17.13.200"
+set turn/allowed-peer-ip/north.gov/345679 "172.17.13.201"
+set turn/allowed-peer-ip/crinna.org/3456710 "172.17.13.202"
 
 hmset turn/oauth/kid/north ikm_key Y2FybGVvbg== hkdf_hash_func 'SHA-256' as_rs_alg 'AES-256-CBC' auth_alg 'HMAC-SHA-256-128'
 hmset turn/oauth/kid/oldempire ikm_key YXVsY3Vz hkdf_hash_func 'SHA-256' as_rs_alg 'AEAD-AES-256-GCM'

+ 4 - 0
turndb/testsqldbsetup.sql

@@ -23,9 +23,13 @@ insert into turn_realm_option (realm,opt,value) values('north.gov','user-quota',
 insert into turn_realm_option (realm,opt,value) values('crinna.org','user-quota','8000');
 
 insert into allowed_peer_ip (ip_range) values('172.17.13.200');
+insert into allowed_peer_ip (realm,ip_range) values('north.gov','172.17.13.201');
+insert into allowed_peer_ip (realm,ip_range) values('crinna.org','172.17.13.202');
 
 insert into denied_peer_ip (ip_range) values('172.17.13.133-172.17.14.56');
 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('crinna.org','123::77');
 
 insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('north','Y2FybGVvbg==',0,0,'SHA-256','AES-256-CBC','','HMAC-SHA-256-128','');
 insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('oldempire','YXVsY3Vz',0,0,'SHA-256','AEAD-AES-256-GCM','','','');