Skip to content

Commit 14a89c4

Browse files
PypeBrosbrandtbucher
authored andcommitted
bpo-38686: fix HTTP Digest handling in request.py (#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" "=" <"> 1#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//]`#`[//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]>
1 parent 3ae38cc commit 14a89c4

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
@@ -1136,15 +1136,17 @@ def get_authorization(self, req, chal):
11361136
A2 = "%s:%s" % (req.get_method(),
11371137
# XXX selector: what about proxies and full urls
11381138
req.selector)
1139-
if qop == 'auth':
1139+
# NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth`
1140+
# or `auth-int` to the response back. we use `auth` to send the response back.
1141+
if 'auth' in qop.split(','):
11401142
if nonce == self.last_nonce:
11411143
self.nonce_count += 1
11421144
else:
11431145
self.nonce_count = 1
11441146
self.last_nonce = nonce
11451147
ncvalue = '%08x' % self.nonce_count
11461148
cnonce = self.get_cnonce(nonce)
1147-
noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
1149+
noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2))
11481150
respdig = KD(H(A1), noncebit)
11491151
elif qop is None:
11501152
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)