From eb7fe230528e4eb0ee0a057b7199926531291caa Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Mon, 23 Dec 2024 22:09:33 +1100 Subject: [PATCH 01/14] support sha-256 digest authentication --- Lib/urllib/request.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index c5a6a18a32bba1..69b414ac03749d 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1182,6 +1182,8 @@ def get_algorithm_impls(self, algorithm): elif algorithm == 'SHA': H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest() # XXX MD5-sess + elif algorithm == 'SHA-256': + H = lambda x: hashlib.sha256(x.encode("ascii")).hexdigest() else: raise ValueError("Unsupported digest authentication " "algorithm %r" % algorithm) From 06cd409a2b3164f917365213233f3995c7a5fadb Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:14:08 +0000 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst new file mode 100644 index 00000000000000..f1c6afc4bb28d0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst @@ -0,0 +1 @@ +Support digest authentication algorithm SHA-256 From 1d9d1afb98c23266faf9e8896cf233611a0cd75f Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Tue, 24 Dec 2024 00:57:38 +1100 Subject: [PATCH 03/14] Update Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst Co-authored-by: Peter Bierma --- .../2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst index f1c6afc4bb28d0..275579761abff2 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst @@ -1 +1 @@ -Support digest authentication algorithm SHA-256 +Support digest authentication algorithm SHA-256 in :mod:`urllib.request`. From aea1b4ec777ddde9cc8ecfdc99e4f3762313c08d Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 02:30:19 +1100 Subject: [PATCH 04/14] comments regarding rfc7616 --- Lib/urllib/request.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 69b414ac03749d..8b18726b693167 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1048,7 +1048,7 @@ def http_error_407(self, req, fp, code, msg, headers): class AbstractDigestAuthHandler: - # Digest authentication is specified in RFC 2617. + # Digest authentication is specified in RFC 2617/7616. # XXX The client does not inspect the Authentication-Info header # in a successful response. @@ -1176,6 +1176,7 @@ def get_authorization(self, req, chal): return base def get_algorithm_impls(self, algorithm): + # algorithm names taken from RFC 7616 Section 6.1 # lambdas assume digest modules are imported at the top level if algorithm == 'MD5': H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest() From 5c214022d6aff41069b65a587cd2632777e158cd Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 02:30:35 +1100 Subject: [PATCH 05/14] move md5-sess comment --- Lib/urllib/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 8b18726b693167..38ede13b934291 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1182,9 +1182,9 @@ def get_algorithm_impls(self, algorithm): H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest() elif algorithm == 'SHA': H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest() - # XXX MD5-sess elif algorithm == 'SHA-256': H = lambda x: hashlib.sha256(x.encode("ascii")).hexdigest() + # XXX MD5-sess else: raise ValueError("Unsupported digest authentication " "algorithm %r" % algorithm) From 10b25ade5e402c4a6e816d0f9c9c1677b712408e Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:13:37 +1100 Subject: [PATCH 06/14] tests --- Lib/test/test_urllib2.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 4a9e653515be5b..2767c4a1d79882 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1962,10 +1962,28 @@ def test_parse_proxy(self): self.assertRaises(ValueError, _parse_proxy, 'file:/ftp.example.com'), - def test_unsupported_algorithm(self): - handler = AbstractDigestAuthHandler() +class TestDigestAlgorithms(unittest.TestCase): + def setUp(self): + self.handler = AbstractDigestAuthHandler() + + def test_md5_algorithm(self): + H, KD = self.handler.get_algorithm_impls('MD5') + self.assertEqual(H("foo"), "acbd18db4cc2f85cedef654fccc4a4d8") + self.assertEqual(KD("foo", "bar"), "4e99e8c12de7e01535248d2bac85e732") + + def test_sha_algorithm(self): + H, KD = self.handler.get_algorithm_impls('SHA') + self.assertEqual(H("foo"), "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") + self.assertEqual(KD("foo", "bar"), "54dcbe67d21d5eb39493d46d89ae1f412d3bd6de") + + def test_sha256_algorithm(self): + H, KD = self.handler.get_algorithm_impls('SHA-256') + self.assertEqual(H("foo"), "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") + self.assertEqual(KD("foo", "bar"), "a765a8beaa9d561d4c5cbed29d8f4e30870297fdfa9cb7d6e9848a95fec9f937") + + def test_invalid_algorithm(self): with self.assertRaises(ValueError) as exc: - handler.get_algorithm_impls('invalid') + self.handler.get_algorithm_impls('invalid') self.assertEqual( str(exc.exception), "Unsupported digest authentication algorithm 'invalid'" From fa80be1b851d30415d5a2a0fac08cbc336561a85 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:15:14 +1100 Subject: [PATCH 07/14] fix lint --- Lib/test/test_urllib2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 2767c4a1d79882..94a48d76020a58 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1970,17 +1970,17 @@ def test_md5_algorithm(self): H, KD = self.handler.get_algorithm_impls('MD5') self.assertEqual(H("foo"), "acbd18db4cc2f85cedef654fccc4a4d8") self.assertEqual(KD("foo", "bar"), "4e99e8c12de7e01535248d2bac85e732") - + def test_sha_algorithm(self): H, KD = self.handler.get_algorithm_impls('SHA') self.assertEqual(H("foo"), "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") self.assertEqual(KD("foo", "bar"), "54dcbe67d21d5eb39493d46d89ae1f412d3bd6de") - + def test_sha256_algorithm(self): H, KD = self.handler.get_algorithm_impls('SHA-256') self.assertEqual(H("foo"), "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") self.assertEqual(KD("foo", "bar"), "a765a8beaa9d561d4c5cbed29d8f4e30870297fdfa9cb7d6e9848a95fec9f937") - + def test_invalid_algorithm(self): with self.assertRaises(ValueError) as exc: self.handler.get_algorithm_impls('invalid') From 3c2ac12f57b1406769570f928c8f7c5798bc5d54 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:20:32 +1100 Subject: [PATCH 08/14] Add name in ACKS --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 086930666822ad..c6e53317b37d78 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -258,6 +258,7 @@ Colm Buckley Erik de Bueger Jan-Hein Bührman Marc Bürg +Calvin Bui Lars Buitinck Artem Bulgakov Dick Bulterman From d9e3c44607f687c3c7b18527cd9bc75d608876e1 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:56:20 +1100 Subject: [PATCH 09/14] Update Lib/test/test_urllib2.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_urllib2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 94a48d76020a58..96d91c1f1c2f8a 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1962,6 +1962,7 @@ def test_parse_proxy(self): self.assertRaises(ValueError, _parse_proxy, 'file:/ftp.example.com'), + class TestDigestAlgorithms(unittest.TestCase): def setUp(self): self.handler = AbstractDigestAuthHandler() From 47c0148be1aa05620002a5bfce171f8d5fa4b2df Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 21:12:14 +1100 Subject: [PATCH 10/14] Update Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- .../2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst index 275579761abff2..b80ab715ffc7db 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-23-11-14-07.gh-issue-128192.02mEhD.rst @@ -1 +1,2 @@ -Support digest authentication algorithm SHA-256 in :mod:`urllib.request`. +Upgrade HTTP digest authentication algorithm for :mod:`urllib.request` by +supporting SHA-256 digest authentication as specified in :rfc:`7616`. From 28866f9c8e93288b5d96d0a11894740799b8c796 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sat, 28 Dec 2024 21:19:13 +1100 Subject: [PATCH 11/14] update what's new --- Doc/whatsnew/3.14.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 97a37a82f76b9b..86a95393ca4e6a 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -638,6 +638,13 @@ unittest (Contributed by Jacob Walls in :gh:`80958`.) +urllib +------ + +* Upgrade HTTP digest authentication algorithm for :mod:`urllib.request` by + supporting SHA-256 digest authentication as specified in :rfc:`7616`. + (Contributed by Calvin Bui in :gh:`128193`) + uuid ---- From 7f9dc2fd4012bf0530d421685fffcc76ef929b02 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sun, 29 Dec 2024 02:39:25 +1100 Subject: [PATCH 12/14] update docs --- Doc/library/urllib.request.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 3c07dc4adf434a..b3efde3f189566 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -411,6 +411,9 @@ The following classes are provided: :ref:`http-password-mgr` for information on the interface that must be supported. + .. versionchanged:: 3.14 + Added support for HTTP digest authentication algorithm ``SHA-256``. + .. class:: HTTPDigestAuthHandler(password_mgr=None) From 9292180e11b97d7ee0418b48ecab88c701d43e83 Mon Sep 17 00:00:00 2001 From: Calvin Bui <3604363+calvinbui@users.noreply.github.com> Date: Sun, 29 Dec 2024 02:39:31 +1100 Subject: [PATCH 13/14] Update Doc/whatsnew/3.14.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/whatsnew/3.14.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 86a95393ca4e6a..a7d937d7dc0ef2 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -643,7 +643,8 @@ urllib * Upgrade HTTP digest authentication algorithm for :mod:`urllib.request` by supporting SHA-256 digest authentication as specified in :rfc:`7616`. - (Contributed by Calvin Bui in :gh:`128193`) + (Contributed by Calvin Bui in :gh:`128193`.) + uuid ---- From 5381ff4407e45dd0e713819ccb809dbebda20800 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 28 Dec 2024 12:42:10 -0800 Subject: [PATCH 14/14] mention --- Lib/urllib/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 38ede13b934291..0d1b594b8cf20b 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1180,7 +1180,7 @@ def get_algorithm_impls(self, algorithm): # lambdas assume digest modules are imported at the top level if algorithm == 'MD5': H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest() - elif algorithm == 'SHA': + elif algorithm == 'SHA': # non-standard, retained for compatibility. H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest() elif algorithm == 'SHA-256': H = lambda x: hashlib.sha256(x.encode("ascii")).hexdigest()