Skip to content

Commit b9e5547

Browse files
bpo-38686: fix HTTP Digest handling in request.py (GH-17045)
* fix HTTP Digest handling in request.py There is a bug triggered when server replies to a request with `WWW-Authenticate: Digest` where `qop="auth,auth-int"` rather than mere `qop="auth"`. Having both `auth` and `auth-int` is legitimate according to the `qop-options` rule in §3.2.1 of [[https://www.ietf.org/rfc/rfc2617.txt|RFC 2617]]: > qop-options = "qop" "=" <"> 1GH-qop-value <"> > qop-value = "auth" | "auth-int" | token > **qop-options**: [...] If present, it is a quoted string **of one or more** tokens indicating the "quality of protection" values supported by the server. The value `"auth"` indicates authentication; the value `"auth-int"` indicates authentication with integrity protection This is description confirmed by the definition of the [//n//]`GH-`[//m//]//rule// extended-BNF pattern defined in §2.1 of [[https://www.ietf.org/rfc/rfc2616.txt|RFC 2616]] as 'a comma-separated list of //rule// with at least //n// and at most //m// items'. When this reply is parsed by `get_authorization`, request.py only tests for identity with `'auth'`, failing to recognize it as one of the supported modes the server announced, and claims that `"qop 'auth,auth-int' is not supported"`. * 📜🤖 Added by blurb_it. * bpo-38686 review fix: remember why. * fix trailing space in Lib/urllib/request.py Co-Authored-By: Brandt Bucher <[email protected]> (cherry picked from commit 14a89c4) Co-authored-by: PypeBros <[email protected]>
1 parent ca5fafc commit b9e5547

File tree

2 files changed

+5
-2
lines changed

2 files changed

+5
-2
lines changed

Lib/urllib/request.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,15 +1144,17 @@ def get_authorization(self, req, chal):
11441144
A2 = "%s:%s" % (req.get_method(),
11451145
# XXX selector: what about proxies and full urls
11461146
req.selector)
1147-
if qop == 'auth':
1147+
# NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth`
1148+
# or `auth-int` to the response back. we use `auth` to send the response back.
1149+
if 'auth' in qop.split(','):
11481150
if nonce == self.last_nonce:
11491151
self.nonce_count += 1
11501152
else:
11511153
self.nonce_count = 1
11521154
self.last_nonce = nonce
11531155
ncvalue = '%08x' % self.nonce_count
11541156
cnonce = self.get_cnonce(nonce)
1155-
noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
1157+
noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2))
11561158
respdig = KD(H(A1), noncebit)
11571159
elif qop is None:
11581160
respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added support for multiple ``qop`` values in :class:`urllib.request.AbstractDigestAuthHandler`.

0 commit comments

Comments
 (0)