[Freeswitch-svn] [commit] r5648 - freeswitch/trunk/src/mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Tue Aug 21 10:48:17 EDT 2007


Author: anthm
Date: Tue Aug 21 10:48:16 2007
New Revision: 5648

Modified:
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c

Log:
add NDLB-broken-auth-hash option for interop with eyebeam and zoiper

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	Tue Aug 21 10:48:16 2007
@@ -117,7 +117,8 @@
 
 
 typedef enum {
-	PFLAG_NDLB_TO_IN_200_CONTACT = (1 << 1)
+	PFLAG_NDLB_TO_IN_200_CONTACT = (1 << 0),
+	PFLAG_NDLB_BROKEN_AUTH_HASH = (1 << 1)
 } sofia_NDLB_t;
 
 typedef enum {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	Tue Aug 21 10:48:16 2007
@@ -793,6 +793,10 @@
 						if (switch_true(val)) {
 							profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
 						}
+					} else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
+						if (switch_true(val)) {
+							profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
+						}
 					} else if (!strcasecmp(var, "pass-rfc2833")) {
 						if (switch_true(val)) {
 							profile->pflags |= PFLAG_PASS_RFC2833;

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	Tue Aug 21 10:48:16 2007
@@ -725,8 +725,11 @@
 	char bigdigest[2 * SU_MD5_DIGEST_SIZE + 1];
 	char *username, *realm, *nonce, *uri, *qop, *cnonce, *nc, *response, *input = NULL, *input2 = NULL;
 	auth_res_t ret = AUTH_FORBIDDEN;
-	char *npassword = NULL;
-	int cnt = 0;
+	int cnt = 0, first = 0;
+	const char *passwd = NULL;
+	const char *a1_hash = NULL;
+	char *sql;
+	switch_xml_t domain, xml, user, param, xparams;	
 
 	username = realm = nonce = uri = qop = cnonce = nc = response = NULL;
 	
@@ -783,11 +786,7 @@
 	}
 
 	if (switch_strlen_zero(np)) {
-		switch_xml_t domain, xml, user, param, xparams;
-		const char *passwd = NULL;
-		const char *a1_hash = NULL;
-		char *sql;
-
+		first = 1;
 		sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
 		assert(sql != NULL);
 		if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
@@ -796,72 +795,72 @@
 			goto end;
 		}
 		free(sql);
-
-		if (switch_xml_locate_user(username, realm, ip, &xml, &domain, &user) != SWITCH_STATUS_SUCCESS) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", username, realm);
-			ret = AUTH_FORBIDDEN;
-			goto end;
-		}
+	} 
+	
+	if (switch_xml_locate_user(username, realm, ip, &xml, &domain, &user) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", username, realm);
+		ret = AUTH_FORBIDDEN;
+		goto end;
+	}
 		
-		if (!(xparams = switch_xml_child(user, "params"))) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find params for user [%s@%s]\n", username, realm);
-			ret = AUTH_FORBIDDEN;
-			goto end;
+	if (!(xparams = switch_xml_child(user, "params"))) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find params for user [%s@%s]\n", username, realm);
+		switch_xml_free(xml);
+		ret = AUTH_FORBIDDEN;
+		goto end;
+	}
+		
+	for (param = switch_xml_child(xparams, "param"); param; param = param->next) {
+		const char *var = switch_xml_attr_soft(param, "name");
+		const char *val = switch_xml_attr_soft(param, "value");
+				
+		if (!strcasecmp(var, "password")) {
+			passwd = val;
 		}
 		
-		for (param = switch_xml_child(xparams, "param"); param; param = param->next) {
-			const char *var = switch_xml_attr_soft(param, "name");
-			const char *val = switch_xml_attr_soft(param, "value");
-
-			if (!strcasecmp(var, "password")) {
-				passwd = val;
-			}
-
-			if (!strcasecmp(var, "a1-hash")) {
-				a1_hash = val;
-			}
+		if (!strcasecmp(var, "a1-hash")) {
+			a1_hash = val;
 		}
+	}
 
+	if (first) {
 		if (v_event && (xparams = switch_xml_child(user, "variables"))) {
 			if (switch_event_create(v_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
 				for (param = switch_xml_child(xparams, "variable"); param; param = param->next) {
 					const char *var = switch_xml_attr_soft(param, "name");
 					const char *val = switch_xml_attr_soft(param, "value");
-
+					
 					if (!switch_strlen_zero(var) && !switch_strlen_zero(val)) {
 						switch_event_add_header(*v_event, SWITCH_STACK_BOTTOM, var, "%s", val);
 					}
 				}
 			}
 		}
+	}
 
+	switch_xml_free(xml);
 
-		if (switch_strlen_zero(passwd) && switch_strlen_zero(a1_hash)) {
-			ret = AUTH_OK;
-			goto end;
-		}
-
-		if (!a1_hash) {
-			su_md5_t ctx;
-			char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1];
-			char *input;
-
-			input = switch_mprintf("%s:%s:%s", username, realm, passwd);
-			su_md5_init(&ctx);
-			su_md5_strupdate(&ctx, input);
-			su_md5_hexdigest(&ctx, hexdigest);
-			su_md5_deinit(&ctx);
-			switch_safe_free(input);
-			a1_hash = hexdigest;
-			
-		}
+	if (switch_strlen_zero(passwd) && switch_strlen_zero(a1_hash)) {
+		ret = AUTH_OK;
+		goto end;
+	}
 
-		np = strdup(a1_hash);
+	if (!a1_hash) {
+		su_md5_t ctx;
+		char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1];
+		char *input;
 
-		switch_xml_free(xml);
+		input = switch_mprintf("%s:%s:%s", username, realm, passwd);
+		su_md5_init(&ctx);
+		su_md5_strupdate(&ctx, input);
+		su_md5_hexdigest(&ctx, hexdigest);
+		su_md5_deinit(&ctx);
+		switch_safe_free(input);
+		a1_hash = hexdigest;
+			
 	}
 
-	npassword = np;
+ for_the_sake_of_interop:
 
 	if ((input = switch_mprintf("%s:%q", regstr, uri))) {
 		su_md5_init(&ctx);
@@ -870,7 +869,7 @@
 		su_md5_deinit(&ctx);
 	}
 
-	if ((input2 = switch_mprintf("%q:%q:%q:%q:%q:%q", npassword, nonce, nc, cnonce, qop, uridigest))) {
+	if ((input2 = switch_mprintf("%q:%q:%q:%q:%q:%q", a1_hash, nonce, nc, cnonce, qop, uridigest))) {
 		memset(&ctx, 0, sizeof(ctx));
 		su_md5_init(&ctx);
 		su_md5_strupdate(&ctx, input2);
@@ -880,6 +879,16 @@
 		if (!strcasecmp(bigdigest, response)) {
 			ret = AUTH_OK;
 		} else {
+			if ((profile->ndlb & PFLAG_NDLB_BROKEN_AUTH_HASH) && strcasecmp(regstr, "REGISTER") && strcasecmp(regstr, "INVITE")) {
+				/* some clients send an ACK with the method 'INVITE' in the hash which will break auth so we will
+				   try again with INVITE so we don't get people complaining to us when someone else's client has a bug......
+				 */
+				switch_safe_free(input);
+				switch_safe_free(input2);
+				regstr = "INVITE";
+				goto for_the_sake_of_interop;
+			}
+
 			ret = AUTH_FORBIDDEN;
 		}
 	}



More information about the Freeswitch-svn mailing list