commit 22448bed9d0781b173cf652caa11b529fa50780e Author: deronnax Date: Sun Feb 28 19:47:40 2016 +0800 WIP_md5_sess diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index c8b37ee..8892d54 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -199,6 +199,23 @@ class DigestAuthHandler: return True +class MD5SessDigestAuthHandler(DigestAuthHandler): + def _return_auth_challenge(self, request_handler): + request_handler.send_response(401) + request_handler.send_header("Content-Type", "text/html") + request_handler.send_header( + 'Www-Authenticate', 'Digest realm="%s", ' + 'qop="%s",' + 'algorithm=md5-sess,' + 'nonce="%s", ' % \ + (self._realm_name, self._qop, self._generate_nonce())) + # XXX: Not sure if we're supposed to add this next header or + # not. + #request_handler.send_header('Connection', 'close') + request_handler.end_headers() + request_handler.wfile.write(b"Proxy Authentication Required.") + return False + class BasicAuthHandler(http.server.BaseHTTPRequestHandler): """Handler for performing basic authentication.""" # Server side values @@ -383,6 +400,39 @@ class ProxyAuthTests(unittest.TestCase): result.close() +@unittest.skipUnless(threading, "Threading required for this test.") +class DigestAuthTests(unittest.TestCase): + USER = "tester" + PASSWD = "test123" + REALM = "TestRealm" + + def setUp(self): + super(DigestAuthTests, self).setUp() + self.md5sess_digest_auth_handler = MD5SessDigestAuthHandler() + self.md5sess_digest_auth_handler.set_users({self.USER: self.PASSWD}) + self.md5sess_digest_auth_handler.set_realm(self.REALM) + # With Digest Authentication. + def create_digest_auth_handler(*args, **kwargs): + return FakeProxyHandler(self.md5sess_digest_auth_handler, *args, **kwargs) + + self.server = LoopbackHttpServerThread(create_digest_auth_handler) + self.server.start() + self.server.ready.wait() + self.server_url = 'http://127.0.0.1:%s' % self.server.port + self.digest_handler = urllib.request.HTTPDigestAuthHandler() + self.opener = urllib.request.build_opener(self.digest_handler) + + def tearDown(self): + self.server.stop() + + def test_digest_with_unsupported_digest_algorithm(self): + self.digest_handler.add_password(self.REALM, self.server_url, + self.USER, self.PASSWD) + self.assertRaises(ValueError, + self.opener.open, + self.server_url) + + def GetRequestHandler(responses): class FakeHTTPRequestHandler(http.server.BaseHTTPRequestHandler): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index e3eed16..ab843c3 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1170,7 +1170,8 @@ class AbstractDigestAuthHandler: H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest() elif algorithm == 'SHA': H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest() - # XXX MD5-sess + else: # XXX MD5-sess + raise ValueError("Unsupported Digest Authentication Algorithm %r" % algorithm) KD = lambda s, d: H("%s:%s" % (s, d)) return H, KD