[svn-commits] trunk r34951 - /trunk/channels/chan_sip.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Jun 19 14:09:24 MST 2006


Author: oej
Date: Mon Jun 19 16:09:24 2006
New Revision: 34951

URL: http://svn.digium.com/view/asterisk?rev=34951&view=rev
Log:
- Formatting 
- Create larger buffer for managing long auth headers from clients (adviced by SNOM)

Modified:
    trunk/channels/chan_sip.c

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?rev=34951&r1=34950&r2=34951&view=diff
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Mon Jun 19 16:09:24 2006
@@ -7604,6 +7604,26 @@
 	const char *reqheader = "Proxy-Authorization";
 	const char *respheader = "Proxy-Authenticate";
 	const char *authtoken;
+	char a1_hash[256];
+	char resp_hash[256]="";
+	char tmp[BUFSIZ * 2];                /* Make a large enough buffer */
+	char *c;
+	int  wrongnonce = FALSE;
+	int  good_response;
+	const char *usednonce = p->randdata;
+
+	/* table of recognised keywords, and their value in the digest */
+	enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
+	struct x {
+		const char *key;
+		const char *s;
+	} *i, keys[] = {
+		[K_RESP] = { "response=", "" },
+		[K_URI] = { "uri=", "" },
+		[K_USER] = { "username=", "" },
+		[K_NONCE] = { "nonce=", "" },
+		[K_LAST] = { NULL, NULL}
+	};
 
 	/* Always OK if no secret */
 	if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
@@ -7635,120 +7655,102 @@
 		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
 		return AUTH_CHALLENGE_SENT;
-	} else {	/* We have auth, so check it */
-
-		/* XXX reduce nesting here */
-
-		/* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
-	   	an example in the spec of just what it is you're doing a hash on. */
-		char a1_hash[256];
-		char resp_hash[256]="";
-		char tmp[256];
-		char *c;
-		int  wrongnonce = FALSE;
-		int  good_response;
-		const char *usednonce = p->randdata; /* XXX check */
-
-		/* table of recognised keywords, and their value in the digest */
-		enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
-		struct x {
-			const char *key;
-			const char *s;
-		} *i, keys[] = {
-			[K_RESP] = { "response=", "" },
-			[K_URI] = { "uri=", "" },
-			[K_USER] = { "username=", "" },
-			[K_NONCE] = { "nonce=", "" },
-			[K_LAST] = { NULL, NULL}
-		};
-
-		/* Make a copy of the response and parse it */
-		ast_copy_string(tmp, authtoken, sizeof(tmp));
-		c = tmp;
-
-		while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
-			for (i = keys; i->key != NULL; i++) {
-				const char *separator = ",";	/* default */
-
-				if (strncasecmp(c, i->key, strlen(i->key)) != 0)
-					continue;
-				/* Found. Skip keyword, take text in quotes or up to the separator. */
-				c += strlen(i->key);
-				if (*c == '"') { /* in quotes. Skip first and look for last */
-					c++;
-					separator = "\"";
-				}
-				i->s = c;
-				strsep(&c, separator);
-				break;
+	} 
+
+	/* --- We have auth, so check it */
+
+	/* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
+   	   an example in the spec of just what it is you're doing a hash on. */
+
+
+	/* Make a copy of the response and parse it */
+	ast_copy_string(tmp, authtoken, sizeof(tmp));
+	c = tmp;
+
+	while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
+		for (i = keys; i->key != NULL; i++) {
+			const char *separator = ",";	/* default */
+
+			if (strncasecmp(c, i->key, strlen(i->key)) != 0)
+				continue;
+			/* Found. Skip keyword, take text in quotes or up to the separator. */
+			c += strlen(i->key);
+			if (*c == '"') { /* in quotes. Skip first and look for last */
+				c++;
+				separator = "\"";
 			}
-			if (i->key == NULL) /* not found, jump after space or comma */
-				strsep(&c, " ,");
-		}
-		/* Verify that digest username matches  the username we auth as */
-		if (strcmp(username, keys[K_USER].s)) {
-			ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
-				username, keys[K_USER].s);
-			/* Oops, we're trying something here */
-			return AUTH_USERNAME_MISMATCH;
-		}
-
-		/* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
-		if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
-			wrongnonce = TRUE;
-			usednonce = keys[K_NONCE].s;
-		}
-
-		if (!ast_strlen_zero(md5secret))
-			ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
-		else {
-			char a1[256];
-			snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
-			ast_md5_hash(a1_hash, a1);
-		}
-
-		/* compute the expected response to compare with what we received */
-		{
-			char a2[256];
-			char a2_hash[256];
-			char resp[256];
-
-			snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
-					S_OR(keys[K_URI].s, uri));
-			ast_md5_hash(a2_hash, a2);
-			snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
-			ast_md5_hash(resp_hash, resp);
-		}
-
-		good_response = keys[K_RESP].s &&
-				!strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
-		if (wrongnonce) {
-			ast_string_field_build(p, randdata, "%08lx", ast_random());
-			if (good_response) {
-				if (sipdebug)
-					ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
-				/* We got working auth token, based on stale nonce . */
-				transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 1);
-			} else {
-				/* Everything was wrong, so give the device one more try with a new challenge */
-				if (sipdebug)
-					ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
-				transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
-			}
-
-			/* Schedule auto destroy in 32 seconds */
-			sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
-			return AUTH_CHALLENGE_SENT;
-		} 
-		if (good_response)
-			return AUTH_SUCCESSFUL;
-
-		/* Ok, we have a bad username/secret pair */
-		/* Challenge again, and again, and again */
-		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+			i->s = c;
+			strsep(&c, separator);
+			break;
+		}
+		if (i->key == NULL) /* not found, jump after space or comma */
+			strsep(&c, " ,");
+	}
+
+	/* Verify that digest username matches  the username we auth as */
+	if (strcmp(username, keys[K_USER].s)) {
+		ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
+			username, keys[K_USER].s);
+		/* Oops, we're trying something here */
+		return AUTH_USERNAME_MISMATCH;
+	}
+
+	/* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
+	if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
+		wrongnonce = TRUE;
+		usednonce = keys[K_NONCE].s;
+	}
+
+	if (!ast_strlen_zero(md5secret))
+		ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
+	else {
+		char a1[256];
+		snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
+		ast_md5_hash(a1_hash, a1);
+	}
+
+	/* compute the expected response to compare with what we received */
+	{
+		char a2[256];
+		char a2_hash[256];
+		char resp[256];
+
+		snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
+				S_OR(keys[K_URI].s, uri));
+		ast_md5_hash(a2_hash, a2);
+		snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
+		ast_md5_hash(resp_hash, resp);
+	}
+
+	good_response = keys[K_RESP].s &&
+			!strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
+	if (wrongnonce) {
+		ast_string_field_build(p, randdata, "%08lx", ast_random());
+		if (good_response) {
+			if (sipdebug)
+				ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
+			/* We got working auth token, based on stale nonce . */
+			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 1);
+		} else {
+			/* Everything was wrong, so give the device one more try with a new challenge */
+			if (sipdebug)
+				ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
+			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+		}
+
+		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
 		return AUTH_CHALLENGE_SENT;
-	}
+	} 
+	if (good_response)
+		return AUTH_SUCCESSFUL;
+
+	/* Ok, we have a bad username/secret pair */
+	/* Challenge again, and again, and again */
+	transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+	sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
+
+	return AUTH_CHALLENGE_SENT;
 }
 
 /*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem



More information about the svn-commits mailing list