blob: c779f67285b4c07d1aca4fe562532ca153a6daa1 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001
2From: sauwming <ming@teluu.com>
3Date: Thu, 22 Apr 2021 14:03:28 +0800
4Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408)
5
6Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
7---
8 pjsip/src/pjsip/sip_auth_client.c | 32 +++++--
9 tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++
10 .../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++
11 3 files changed, 117 insertions(+), 5 deletions(-)
12 create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py
13 create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
14
15--- a/pjsip/src/pjsip/sip_auth_client.c
16+++ b/pjsip/src/pjsip/sip_auth_client.c
17@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool
18 pjsip_hdr *hdr;
19 pj_status_t status;
20
21- /* See if we have sent authorization header for this realm */
22+ /* See if we have sent authorization header for this realm (and scheme) */
23 hdr = tdata->msg->hdr.next;
24 while (hdr != &tdata->msg->hdr) {
25 if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&
26@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool
27 {
28 sent_auth = (pjsip_authorization_hdr*) hdr;
29 if (pj_stricmp(&hchal->challenge.common.realm,
30- &sent_auth->credential.common.realm )==0)
31+ &sent_auth->credential.common.realm)==0 &&
32+ pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0)
33 {
34 /* If this authorization has empty response, remove it. */
35 if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
36@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool
37 hdr = hdr->next;
38 pj_list_erase(sent_auth);
39 continue;
40+ } else
41+ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
42+ pj_stricmp(&sent_auth->credential.digest.algorithm,
43+ &hchal->challenge.digest.algorithm)!=0)
44+ {
45+ /* Same 'digest' scheme but different algo */
46+ hdr = hdr->next;
47+ continue;
48 } else {
49 /* Found previous authorization attempt */
50 break;
51@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
52 {
53 pjsip_tx_data *tdata;
54 const pjsip_hdr *hdr;
55- unsigned chal_cnt;
56+ unsigned chal_cnt, auth_cnt;
57 pjsip_via_hdr *via;
58 pj_status_t status;
59+ pj_status_t last_auth_err;
60
61 PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,
62 PJ_EINVAL);
63@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
64 */
65 hdr = rdata->msg_info.msg->hdr.next;
66 chal_cnt = 0;
67+ auth_cnt = 0;
68+ last_auth_err = PJSIP_EAUTHNOAUTH;
69 while (hdr != &rdata->msg_info.msg->hdr) {
70 pjsip_cached_auth *cached_auth;
71 const pjsip_www_authenticate_hdr *hchal;
72@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
73 */
74 status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
75 tdata, sess, cached_auth, &hauth);
76- if (status != PJ_SUCCESS)
77- return status;
78+ if (status != PJ_SUCCESS) {
79+ last_auth_err = status;
80+
81+ /* Process next header. */
82+ hdr = hdr->next;
83+ continue;
84+ }
85
86 if (pj_pool_get_used_size(cached_auth->pool) >
87 PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
88@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
89
90 /* Process next header. */
91 hdr = hdr->next;
92+ auth_cnt++;
93 }
94
95 /* Check if challenge is present */
96 if (chal_cnt == 0)
97 return PJSIP_EAUTHNOCHAL;
98
99+ /* Check if any authorization header has been created */
100+ if (auth_cnt == 0)
101+ return last_auth_err;
102+
103 /* Remove branch param in Via header. */
104 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
105 via->branch_param.slen = 0;
106--- /dev/null
107+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
108@@ -0,0 +1,7 @@
109+# $Id$
110+#
111+import inc_const as const
112+
113+PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"]
114+
115+PJSUA_EXPECTS = [[0, "registration success", ""]]
116--- /dev/null
117+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
118@@ -0,0 +1,83 @@
119+<?xml version="1.0" encoding="ISO-8859-1" ?>
120+<!DOCTYPE scenario SYSTEM "sipp.dtd">
121+
122+<scenario name="Basic UAS responder">
123+ <recv request="REGISTER" crlf="true">
124+ </recv>
125+
126+ <send>
127+ <![CDATA[
128+ SIP/2.0 100 Trying
129+ [last_Via:];received=1.1.1.1;rport=1111
130+ [last_From:]
131+ [last_To:];tag=[call_number]
132+ [last_Call-ID:]
133+ [last_CSeq:]
134+ Content-Length: 0
135+ ]]>
136+ </send>
137+
138+ <send>
139+ <![CDATA[
140+ SIP/2.0 401 Unauthorized
141+ [last_Via:];received=1.1.1.1;rport=1111
142+ [last_From:]
143+ [last_To:];tag=[call_number]
144+ [last_Call-ID:]
145+ [last_CSeq:]
146+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"
147+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"
148+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD2, qop="auth"
149+ Content-Length: 0
150+ ]]>
151+ </send>
152+
153+ <recv request="REGISTER" crlf="true">
154+ <action>
155+ <ereg regexp=".*"
156+ search_in="hdr"
157+ header="Authorization:"
158+ assign_to="have_auth" />
159+ </action>
160+ </recv>
161+
162+ <nop next="resp_okay" test="have_auth" />
163+
164+ <send next="end">
165+ <![CDATA[
166+ SIP/2.0 403 no auth
167+ [last_Via:];received=1.1.1.1;rport=1111
168+ [last_From:]
169+ [last_To:];tag=[call_number]
170+ [last_Call-ID:]
171+ [last_CSeq:]
172+ [last_Contact:]
173+ Content-Length: 0
174+ ]]>
175+ </send>
176+
177+ <label id="resp_okay" />
178+
179+ <send>
180+ <![CDATA[
181+ SIP/2.0 200 OK
182+ [last_Via:];received=1.1.1.1;rport=1111
183+ [last_From:]
184+ [last_To:];tag=[call_number]
185+ [last_Call-ID:]
186+ [last_CSeq:]
187+ [last_Contact:]
188+ Content-Length: 0
189+ ]]>
190+ </send>
191+
192+ <label id="end" />
193+
194+ <!-- definition of the response time repartition table (unit is ms) -->
195+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
196+
197+ <!-- definition of the call length repartition table (unit is ms) -->
198+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
199+
200+</scenario>
201+