From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001 From: sauwming Date: Thu, 22 Apr 2021 14:03:28 +0800 Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408) Co-authored-by: Nanang Izzuddin --- pjsip/src/pjsip/sip_auth_client.c | 32 +++++-- tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++ .../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++ 3 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml --- a/pjsip/src/pjsip/sip_auth_client.c +++ b/pjsip/src/pjsip/sip_auth_client.c @@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool pjsip_hdr *hdr; pj_status_t status; - /* See if we have sent authorization header for this realm */ + /* See if we have sent authorization header for this realm (and scheme) */ hdr = tdata->msg->hdr.next; while (hdr != &tdata->msg->hdr) { if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE && @@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool { sent_auth = (pjsip_authorization_hdr*) hdr; if (pj_stricmp(&hchal->challenge.common.realm, - &sent_auth->credential.common.realm )==0) + &sent_auth->credential.common.realm)==0 && + pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0) { /* If this authorization has empty response, remove it. */ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 && @@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool hdr = hdr->next; pj_list_erase(sent_auth); continue; + } else + if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 && + pj_stricmp(&sent_auth->credential.digest.algorithm, + &hchal->challenge.digest.algorithm)!=0) + { + /* Same 'digest' scheme but different algo */ + hdr = hdr->next; + continue; } else { /* Found previous authorization attempt */ break; @@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini { pjsip_tx_data *tdata; const pjsip_hdr *hdr; - unsigned chal_cnt; + unsigned chal_cnt, auth_cnt; pjsip_via_hdr *via; pj_status_t status; + pj_status_t last_auth_err; PJ_ASSERT_RETURN(sess && rdata && old_request && new_request, PJ_EINVAL); @@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini */ hdr = rdata->msg_info.msg->hdr.next; chal_cnt = 0; + auth_cnt = 0; + last_auth_err = PJSIP_EAUTHNOAUTH; while (hdr != &rdata->msg_info.msg->hdr) { pjsip_cached_auth *cached_auth; const pjsip_www_authenticate_hdr *hchal; @@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini */ status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri, tdata, sess, cached_auth, &hauth); - if (status != PJ_SUCCESS) - return status; + if (status != PJ_SUCCESS) { + last_auth_err = status; + + /* Process next header. */ + hdr = hdr->next; + continue; + } if (pj_pool_get_used_size(cached_auth->pool) > PJSIP_AUTH_CACHED_POOL_MAX_SIZE) @@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini /* Process next header. */ hdr = hdr->next; + auth_cnt++; } /* Check if challenge is present */ if (chal_cnt == 0) return PJSIP_EAUTHNOCHAL; + /* Check if any authorization header has been created */ + if (auth_cnt == 0) + return last_auth_err; + /* Remove branch param in Via header. */ via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); via->branch_param.slen = 0; --- /dev/null +++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py @@ -0,0 +1,7 @@ +# $Id$ +# +import inc_const as const + +PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"] + +PJSUA_EXPECTS = [[0, "registration success", ""]] --- /dev/null +++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +