From 320be7fff9dd2cde0a1a7fe23514396b613df45b Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Mon, 13 Jun 2005 20:35:15 +0000 Subject: [PATCH] handle stale authentication nonces more properly (bug #4451) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/v1-0@5902 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 64 ++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 1d8dd05b02..f255cdd4c7 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -4776,8 +4776,9 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata char tmp[256] = ""; char *c; char *z; - char *response =""; + char *ua_hash =""; char *resp_uri =""; + char *nonce = ""; /* Find their response among the mess that we'r sent for comparison */ strncpy(tmp, authtoken, sizeof(tmp) - 1); @@ -4790,12 +4791,12 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata if (!strncasecmp(c, "response=", strlen("response="))) { c+= strlen("response="); if ((*c == '\"')) { - response=++c; + ua_hash=++c; if((c = strchr(c,'\"'))) *c = '\0'; } else { - response=c; + ua_hash=c; if((c = strchr(c,','))) *c = '\0'; } @@ -4812,31 +4813,52 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata *c = '\0'; } + } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) +{ + c+= strlen("nonce="); + if ((*c == '\"')) { + nonce=++c; + if ((c = strchr(c,'\"'))) + *c = '\0'; + } else { + nonce=c; + if ((c = strchr(c,','))) + *c = '\0'; + } } else if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; if (c) c++; } - snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); - if(!ast_strlen_zero(resp_uri)) - snprintf(a2, sizeof(a2), "%s:%s", method, resp_uri); - else - snprintf(a2, sizeof(a2), "%s:%s", method, uri); - if (!ast_strlen_zero(md5secret)) - snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); - else - md5_hash(a1_hash, a1); - md5_hash(a2_hash, a2); - snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, randdata, a2_hash); - md5_hash(resp_hash, resp); - - /* resp_hash now has the expected response, compare the two */ + /* Check if the nonce the client sends is the same as we are testing authentication with */ + if (strncasecmp(randdata, nonce, randlen)) { + ast_log(LOG_WARNING, "Stale nonce received from '%s'\n", get_header(req, "To")); + snprintf(randdata, randlen, "%08x", rand()); + transmit_response_with_auth(p, response, req, randdata, reliable, respheader); + /* Schedule auto destroy in 15 seconds */ + sip_scheddestroy(p, 15000); + return 1; + } else { + snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); + if(!ast_strlen_zero(resp_uri)) + snprintf(a2, sizeof(a2), "%s:%s", method, resp_uri); + else + snprintf(a2, sizeof(a2), "%s:%s", method, uri); + if (!ast_strlen_zero(md5secret)) + snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); + else + md5_hash(a1_hash, a1); + md5_hash(a2_hash, a2); + snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, randdata, a2_hash); + md5_hash(resp_hash, resp); + + /* resp_hash now has the expected response, compare the two */ - if (response && !strncasecmp(response, resp_hash, strlen(resp_hash))) { - /* Auth is OK */ - res = 0; + if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { + /* Auth is OK */ + return 0; + } } - /* Assume success ;-) */ } return res; } -- 2.47.2