Ver Fonte

origin is checked in subsequent session messages

mom040267 há 11 anos atrás
pai
commit
2ebb02b647

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+08/03/2014 Oleg Moskalenko <[email protected]>
+Version 4.1.1.2 'Vitari':
+	- The origin attribute is verified in the subsequent 
+	session messages.
+	
 07/29/2014 Oleg Moskalenko <[email protected]>
 Version 4.1.1.1 'Vitari':
 	- Forceful server-side session cancellation implemented

+ 1 - 1
rpm/build.settings.sh

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

+ 3 - 1
rpm/turnserver.spec

@@ -1,5 +1,5 @@
 Name:		turnserver
-Version:	4.1.1.1
+Version:	4.1.1.2
 Release:	0%{dist}
 Summary:	Coturn TURN Server
 
@@ -293,6 +293,8 @@ fi
 %{_includedir}/turn/client/TurnMsgLib.h
 
 %changelog
+* Sun Aug 03 2014 Oleg Moskalenko <[email protected]>
+  - Sync to 4.1.1.2
 * Tue Jul 29 2014 Oleg Moskalenko <[email protected]>
   - Sync to 4.1.1.1
 * Tue Jul 22 2014 Oleg Moskalenko <[email protected]>

+ 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;
 }
 
+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,
 		app_ur_conn_info *clnet_info,
 		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;
 
@@ -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));
 			}
 
+			add_origin(&message);
+
 			if(add_integrity(clnet_info, &message)<0) return -1;
 
 			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);
 		}
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 		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;
 
 		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_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr);
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 		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);
 
+		add_origin(&message);
+
 		if(add_integrity(clnet_info, &message)<0) return -1;
 
 		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 not_rare_event(void);
 
+void add_origin(stun_buffer *message);
+
 int start_c2c_connection(uint16_t clnet_remote_port,
 			 const char *remote_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);
 		lt = htonl(lt);
 		stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char*) &lt, 4);
+		add_origin(&message);
 		if(add_integrity(clnet_info, &message)<0) return -1;
 		if(use_fingerprints)
 			    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)) {
 				stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message);
 				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(use_fingerprints)
 				    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 (STUN_VALID_CHANNEL(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(use_fingerprints)
 					    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 ret = 0;

+ 2 - 0
src/client/ns_turn_msg.h

@@ -94,6 +94,8 @@ u32bits stun_adjust_allocate_lifetime(u32bits lifetime);
 
 ///////////// 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);
 
 void stun_init_buffer_str(u08bits *buf, size_t *len);

+ 1 - 1
src/ns_turn_defs.h

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

+ 57 - 1
src/server/ns_turn_server.c

@@ -3472,7 +3472,63 @@ 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(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),
 					ioa_network_buffer_get_size(in_buffer->nbh));