From 118cf2ba8af97dbbd78271126e22cb80f18f9adc Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 5 Dec 2017 21:52:51 +0000 Subject: [PATCH] tempurl: Deprecate sha1 signatures We've known this would eventually be necessary for a while [1], and way back in 2017 we started seeing SHA-1 collisions [2]. [1] https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html [2] https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html UpgradeImpact: ============== "sha1" has been removed from the default set of `allowed_digests` in the tempurl middleware config. If your cluster still has clients requiring the use of SHA-1, - explicitly configure `allowed_digests` to include "sha1" and - encourage your clients to move to more-secure algorithms. Depends-On: https://review.opendev.org/c/openstack/tempest/+/832771 Change-Id: I6e6fa76671c860191a2ce921cb6caddc859b1066 Related-Change: Ia9dd1a91cc3c9c946f5f029cdefc9e66bcf01046 Closes-Bug: #1733634 --- doc/source/api/temporary_url_middleware.rst | 37 +++-- etc/proxy-server.conf-sample | 2 +- swift/common/middleware/tempurl.py | 83 ++++++----- swift/common/utils.py | 9 +- test/functional/test_object_versioning.py | 4 +- test/functional/test_symlink.py | 4 +- test/functional/test_tempurl.py | 8 +- test/unit/common/middleware/test_tempurl.py | 152 +++++++++++--------- test/unit/common/test_utils.py | 19 +++ 9 files changed, 188 insertions(+), 130 deletions(-) diff --git a/doc/source/api/temporary_url_middleware.rst b/doc/source/api/temporary_url_middleware.rst index 4e6216115b..7dea043ff5 100644 --- a/doc/source/api/temporary_url_middleware.rst +++ b/doc/source/api/temporary_url_middleware.rst @@ -38,7 +38,7 @@ parameters: .. code:: https://swift-cluster.example.com/v1/my_account/container/object - ?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709 + ?temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b &temp_url_expires=1323479485 &filename=My+Test+File.pdf @@ -47,9 +47,11 @@ The example shows these elements: **Object URL**: Required. The full path URL to the object. -**temp\_url\_sig**: Required. An HMAC-SHA1 cryptographic signature that defines +**temp\_url\_sig**: Required. An HMAC cryptographic signature that defines the allowed HTTP method, expiration date, full path to the object, and the -secret key for the temporary URL. +secret key for the temporary URL. The digest used (for example, SHA-256 or +SHA-512) must be supported by the cluster; supported digests will be listed +in the ``tempurl.allowed_digests`` key in the cluster's capabilities. **temp\_url\_expires**: Required. An expiration date as a UNIX Epoch timestamp or ISO 8601 UTC timestamp. For example, ``1390852007`` or @@ -72,7 +74,7 @@ by all object names for which the URL is valid. .. code:: https://swift-cluster.example.com/v1/my_account/container/my_prefix/object - ?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709 + ?temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b &temp_url_expires=2011-12-10T01:11:25Z &temp_url_prefix=my_prefix @@ -117,15 +119,15 @@ Note Changing these headers invalidates any previously generated temporary URLs within 60 seconds, which is the memcache time for the key. -HMAC-SHA1 signature for temporary URLs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +HMAC signature for temporary URLs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Temporary URL middleware uses an HMAC-SHA1 cryptographic signature. This +Temporary URL middleware uses an HMAC cryptographic signature. This signature includes these elements: - The allowed method. Typically, **GET** or **PUT**. -- Expiry time. In the example for the HMAC-SHA1 signature for temporary +- Expiry time. In the example for the HMAC-SHA256 signature for temporary URLs below, the expiry time is set to ``86400`` seconds (or 1 day) into the future. Please be aware that you have to use a UNIX timestamp for generating the signature (in the API request it is also allowed to @@ -141,12 +143,12 @@ signature includes these elements: These sample Python codes show how to compute a signature for use with temporary URLs: -**Example HMAC-SHA1 signature for object-based temporary URLs** +**Example HMAC-SHA256 signature for object-based temporary URLs** .. code:: import hmac - from hashlib import sha1 + from hashlib import sha256 from time import time method = 'GET' duration_in_seconds = 60*60*24 @@ -154,14 +156,14 @@ temporary URLs: path = '/v1/my_account/container/object' key = 'MYKEY' hmac_body = '%s\n%s\n%s' % (method, expires, path) - signature = hmac.new(key, hmac_body, sha1).hexdigest() + signature = hmac.new(key, hmac_body, sha256).hexdigest() -**Example HMAC-SHA1 signature for prefix-based temporary URLs** +**Example HMAC-SHA512 signature for prefix-based temporary URLs** .. code:: import hmac - from hashlib import sha1 + from hashlib import sha512 from time import time method = 'GET' duration_in_seconds = 60*60*24 @@ -169,9 +171,9 @@ temporary URLs: path = 'prefix:/v1/my_account/container/my_prefix' key = 'MYKEY' hmac_body = '%s\n%s\n%s' % (method, expires, path) - signature = hmac.new(key, hmac_body, sha1).hexdigest() + signature = hmac.new(key, hmac_body, sha512).hexdigest() -Do not URL-encode the path when you generate the HMAC-SHA1 signature. +Do not URL-encode the path when you generate the HMAC signature. However, when you make the actual HTTP request, you should properly URL-encode the URL. @@ -200,6 +202,11 @@ parameters. For example, you might run this command: $ swift tempurl GET 3600 /v1/my_account/container/object MYKEY +.. note:: + + The ``swift`` tool is not yet updated and continues to use the + deprecated cipher SHA1. + This command returns the path: .. code:: diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index ef49c430f7..63f53dc53c 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -944,7 +944,7 @@ use = egg:swift#tempurl # # The digest algorithm(s) supported for generating signatures; # whitespace-delimited. -# allowed_digests = sha1 sha256 sha512 +# allowed_digests = sha256 sha512 # Note: Put formpost just before your auth filter(s) in the pipeline [filter:formpost] diff --git a/swift/common/middleware/tempurl.py b/swift/common/middleware/tempurl.py index 86a6e91b3b..1385900201 100644 --- a/swift/common/middleware/tempurl.py +++ b/swift/common/middleware/tempurl.py @@ -64,7 +64,7 @@ signature is generated using the HTTP method to allow (``GET``, ``PUT``, the full path to the object, and the key set on the account. The digest algorithm to be used may be configured by the operator. By default, -HMAC-SHA1, HMAC-SHA256, and HMAC-SHA512 are supported. Check the +HMAC-SHA256 and HMAC-SHA512 are supported. Check the ``tempurl.allowed_digests`` entry in the cluster's capabilities response to see which algorithms are supported by your deployment; see :doc:`api/discoverability` for more information. On older clusters, @@ -75,24 +75,25 @@ For example, here is code generating the signature for a ``GET`` for 60 seconds on ``/v1/AUTH_account/container/object``:: import hmac - from hashlib import sha1 + from hashlib import sha256 from time import time method = 'GET' expires = int(time() + 60) path = '/v1/AUTH_account/container/object' key = 'mykey' hmac_body = '%s\n%s\n%s' % (method, expires, path) - sig = hmac.new(key, hmac_body, sha1).hexdigest() + sig = hmac.new(key, hmac_body, sha256).hexdigest() Be certain to use the full path, from the ``/v1/`` onward. Let's say ``sig`` ends up equaling -``da39a3ee5e6b4b0d3255bfef95601890afd80709`` and ``expires`` ends up -``1323479485``. Then, for example, the website could provide a link to:: +``732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b`` and +``expires`` ends up ``1512508563``. Then, for example, the website could +provide a link to:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485 + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563 For longer hashes, a hex encoding becomes unwieldy. Base64 encoding is also supported, and indicated by prefixing the signature with ``":"``. @@ -124,11 +125,11 @@ Supposing that ``sig`` ends up equaling You may also use ISO 8601 UTC timestamps with the format ``"%Y-%m-%dT%H:%M:%SZ"`` instead of UNIX timestamps in the URL (but NOT in the code above for generating the signature!). -So, the above HMAC-SHA1 URL could also be formulated as:: +So, the above HMAC-SHA246 URL could also be formulated as:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=2011-12-10T01:11:25Z + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=2017-12-05T21:16:03Z If a prefix-based signature with the prefix ``pre`` is desired, set path to:: @@ -140,31 +141,31 @@ a query parameter called ``temp_url_prefix``. So, if ``sig`` and ``expires`` would end up like above, following URL would be valid:: https://swift-cluster.example.com/v1/AUTH_account/container/pre/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485& + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563& temp_url_prefix=pre Another valid URL:: https://swift-cluster.example.com/v1/AUTH_account/container/pre/ subfolder/another_object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485& + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563& temp_url_prefix=pre If you wish to lock down the ip ranges from where the resource can be accessed to the ip ``1.2.3.4``:: import hmac - from hashlib import sha1 + from hashlib import sha256 from time import time method = 'GET' expires = int(time() + 60) path = '/v1/AUTH_account/container/object' ip_range = '1.2.3.4' - key = 'mykey' + key = b'mykey' hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path) - sig = hmac.new(key, hmac_body, sha1).hexdigest() + sig = hmac.new(key, hmac_body.encode('ascii'), sha256).hexdigest() The generated signature would only be valid from the ip ``1.2.3.4``. The middleware detects an ip-based temporary URL by a query parameter called @@ -172,29 +173,29 @@ middleware detects an ip-based temporary URL by a query parameter called above, following URL would be valid:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485& + temp_url_sig=3f48476acaf5ec272acd8e99f7b5bad96c52ddba53ed27c60613711774a06f0c& + temp_url_expires=1648082711& temp_url_ip_range=1.2.3.4 Similarly to lock down the ip to a range of ``1.2.3.X`` so starting from the ip ``1.2.3.0`` to ``1.2.3.255``:: import hmac - from hashlib import sha1 + from hashlib import sha256 from time import time method = 'GET' expires = int(time() + 60) path = '/v1/AUTH_account/container/object' ip_range = '1.2.3.0/24' - key = 'mykey' + key = b'mykey' hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path) - sig = hmac.new(key, hmac_body, sha1).hexdigest() + sig = hmac.new(key, hmac_body.encode('ascii'), sha256).hexdigest() Then the following url would be valid:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485& + temp_url_sig=6ff81256b8a3ba11d239da51a703b9c06a56ffddeb8caab74ca83af8f73c9c83& + temp_url_expires=1648082711& temp_url_ip_range=1.2.3.0/24 @@ -222,16 +223,16 @@ can override this with a filename query parameter. Modifying the above example:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485&filename=My+Test+File.pdf + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563&filename=My+Test+File.pdf If you do not want the object to be downloaded, you can cause ``Content-Disposition: inline`` to be set on the response by adding the ``inline`` parameter to the query string, like so:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485&inline + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563&inline In some cases, the client might not able to present the content of the object, but you still want the content able to save to local with the specific @@ -240,8 +241,8 @@ set on the response by adding the ``inline&filename=...`` parameter to the query string, like so:: https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485&inline&filename=My+Test+File.pdf + temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b& + temp_url_expires=1512508563&inline&filename=My+Test+File.pdf --------------------- Cluster Configuration @@ -288,7 +289,7 @@ This middleware understands the following configuration settings: A whitespace delimited list of digest algorithms that are allowed to be used when calculating the signature for a temporary URL. - Default: ``sha1 sha256 sha512`` + Default: ``sha256 sha512`` """ __all__ = ['TempURL', 'filter_factory', @@ -299,7 +300,6 @@ __all__ = ['TempURL', 'filter_factory', import binascii from calendar import timegm -import hashlib import six from os.path import basename from time import time, strftime, strptime, gmtime @@ -341,8 +341,9 @@ DEFAULT_OUTGOING_REMOVE_HEADERS = 'x-object-meta-*' #: '*' to indicate a prefix match. DEFAULT_OUTGOING_ALLOW_HEADERS = 'x-object-meta-public-*' -DEFAULT_ALLOWED_DIGESTS = 'sha1 sha256 sha512' -SUPPORTED_DIGESTS = set(DEFAULT_ALLOWED_DIGESTS.split()) +DEFAULT_ALLOWED_DIGESTS = 'sha256 sha512' +DEPRECATED_DIGESTS = {'sha1'} +SUPPORTED_DIGESTS = set(DEFAULT_ALLOWED_DIGESTS.split()) | DEPRECATED_DIGESTS CONTAINER_SCOPE = 'container' ACCOUNT_SCOPE = 'account' @@ -749,12 +750,10 @@ class TempURL(object): if not request_method: request_method = env['REQUEST_METHOD'] - digest = getattr(hashlib, hash_algorithm) - return [ (get_hmac( request_method, path, expires, key, - digest=digest, ip_range=ip_range + digest=hash_algorithm, ip_range=ip_range ), scope) for (key, scope) in scoped_keys] @@ -846,6 +845,8 @@ def filter_factory(global_conf, **local_conf): conf = global_conf.copy() conf.update(local_conf) + logger = get_logger(conf, log_route='tempurl') + defaults = { 'methods': 'GET HEAD PUT POST DELETE', 'incoming_remove_headers': DEFAULT_INCOMING_REMOVE_HEADERS, @@ -860,10 +861,16 @@ def filter_factory(global_conf, **local_conf): for digest in info_conf['allowed_digests']) not_supported = allowed_digests - SUPPORTED_DIGESTS if not_supported: - logger = get_logger(conf, log_route='tempurl') logger.warning('The following digest algorithms are configured but ' 'not supported: %s', ', '.join(not_supported)) allowed_digests -= not_supported + + deprecated = allowed_digests & DEPRECATED_DIGESTS + if deprecated: + logger.warning('The following digest algorithms are configured but ' + 'deprecated: %s. Support will be removed in a future ' + 'release.', ', '.join(deprecated)) + if not allowed_digests: raise ValueError('No valid digest algorithms are configured ' 'for tempurls') diff --git a/swift/common/utils.py b/swift/common/utils.py index 06c9ded308..826a5b1056 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -40,7 +40,6 @@ import uuid import functools import platform import email.parser -from hashlib import sha1 from random import random, shuffle from contextlib import contextmanager, closing import ctypes @@ -283,7 +282,7 @@ except (InvalidHashPathConfigError, IOError): pass -def get_hmac(request_method, path, expires, key, digest=sha1, +def get_hmac(request_method, path, expires, key, digest="sha1", ip_range=None): """ Returns the hexdigest string of the HMAC (see RFC 2104) for @@ -294,7 +293,8 @@ def get_hmac(request_method, path, expires, key, digest=sha1, :param expires: Unix timestamp as an int for when the URL expires. :param key: HMAC shared secret. - :param digest: constructor for the digest to use in calculating the HMAC + :param digest: constructor or the string name for the digest to use in + calculating the HMAC Defaults to SHA1 :param ip_range: The ip range from which the resource is allowed to be accessed. We need to put the ip_range as the @@ -320,6 +320,9 @@ def get_hmac(request_method, path, expires, key, digest=sha1, else part.encode("utf-8")) for fmt, part in zip(formats, parts)) + if six.PY2 and isinstance(digest, six.string_types): + digest = getattr(hashlib, digest) + return hmac.new(key, message, digest).hexdigest() diff --git a/test/functional/test_object_versioning.py b/test/functional/test_object_versioning.py index a6ac9027d4..32eb092c82 100644 --- a/test/functional/test_object_versioning.py +++ b/test/functional/test_object_versioning.py @@ -2578,7 +2578,7 @@ class TestHistoryLocationWithVersioning(TestVersionsLocationWithVersioning): class TestVersioningAccountTempurl(TestObjectVersioningBase): env = TestTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): self.env.versions_header_key = 'X-Versions-Enabled' @@ -2689,7 +2689,7 @@ class TestVersioningAccountTempurl(TestObjectVersioningBase): class TestVersioningContainerTempurl(TestObjectVersioningBase): env = TestContainerTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): self.env.versions_header_key = 'X-Versions-Enabled' diff --git a/test/functional/test_symlink.py b/test/functional/test_symlink.py index 372d2b3a83..eee6465761 100755 --- a/test/functional/test_symlink.py +++ b/test/functional/test_symlink.py @@ -2268,7 +2268,7 @@ class TestSymlinkComparison(TestSymlinkTargetObjectComparison): class TestSymlinkAccountTempurl(Base): env = TestTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): super(TestSymlinkAccountTempurl, self).setUp() @@ -2364,7 +2364,7 @@ class TestSymlinkAccountTempurl(Base): class TestSymlinkContainerTempurl(Base): env = TestContainerTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): super(TestSymlinkContainerTempurl, self).setUp() diff --git a/test/functional/test_tempurl.py b/test/functional/test_tempurl.py index 54659bc319..48b3bc753a 100644 --- a/test/functional/test_tempurl.py +++ b/test/functional/test_tempurl.py @@ -90,7 +90,7 @@ class TestTempurlEnv(TestTempurlBaseEnv): class TestTempurl(Base): env = TestTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): super(TestTempurl, self).setUp() @@ -102,6 +102,8 @@ class TestTempurl(Base): "Expected tempurl_enabled to be True/False, got %r" % (self.env.tempurl_enabled,)) + # N.B. The default to 'sha1' in case the info has nothing is for + # extremely old clusters, which presumably use SHA1. if self.digest_name not in cluster_info['tempurl'].get( 'allowed_digests', ['sha1']): raise SkipTest("tempurl does not support %s signatures" % @@ -461,7 +463,7 @@ class TestContainerTempurlEnv(BaseEnv): class TestContainerTempurl(Base): env = TestContainerTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): super(TestContainerTempurl, self).setUp() @@ -736,7 +738,7 @@ class TestSloTempurlEnv(TestTempurlBaseEnv): class TestSloTempurl(Base): env = TestSloTempurlEnv - digest_name = 'sha1' + digest_name = 'sha256' def setUp(self): super(TestSloTempurl, self).setUp() diff --git a/test/unit/common/middleware/test_tempurl.py b/test/unit/common/middleware/test_tempurl.py index 115f0e5255..24f3512b42 100644 --- a/test/unit/common/middleware/test_tempurl.py +++ b/test/unit/common/middleware/test_tempurl.py @@ -130,9 +130,11 @@ class TestTempURL(unittest.TestCase): self.assertEqual(resp.status_int, 200) def assert_valid_sig(self, expires, path, keys, sig, environ=None, - prefix=None): + prefix=None, tempurl=None): if not environ: environ = {} + if tempurl is None: + tempurl = self.tempurl if six.PY3 and isinstance(sig, six.binary_type): sig = sig.decode('utf-8') environ['QUERY_STRING'] = 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -140,8 +142,8 @@ class TestTempURL(unittest.TestCase): if prefix is not None: environ['QUERY_STRING'] += '&temp_url_prefix=%s' % prefix req = self._make_request(path, keys=keys, environ=environ) - self.tempurl.app = FakeApp(iter([('200 Ok', (), '123')])) - resp = req.get_response(self.tempurl) + tempurl.app = FakeApp(iter([('200 Ok', (), '123')])) + resp = req.get_response(tempurl) self.assertEqual(resp.status_int, 200) self.assertEqual(resp.headers['content-disposition'], 'attachment; filename="o"; ' + "filename*=UTF-8''o") @@ -157,8 +159,11 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') + + tempurl1 = tempurl.filter_factory({ + 'allowed_digests': 'sha1'})(self.auth) sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() - self.assert_valid_sig(expires, path, [key], sig) + self.assert_valid_sig(expires, path, [key], sig, tempurl=tempurl1) sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() self.assert_valid_sig(expires, path, [key], sig) @@ -178,8 +183,8 @@ class TestTempURL(unittest.TestCase): key1 = b'abc123' key2 = b'def456' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig1 = hmac.new(key1, hmac_body, hashlib.sha1).hexdigest() - sig2 = hmac.new(key2, hmac_body, hashlib.sha1).hexdigest() + sig1 = hmac.new(key1, hmac_body, hashlib.sha256).hexdigest() + sig2 = hmac.new(key2, hmac_body, hashlib.sha256).hexdigest() for sig in (sig1, sig2): self.assert_valid_sig(expires, path, [key1, key2], sig) @@ -201,8 +206,8 @@ class TestTempURL(unittest.TestCase): key1 = b'me' key2 = b'other' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig1 = hmac.new(key1, hmac_body, hashlib.sha1).hexdigest() - sig2 = hmac.new(key2, hmac_body, hashlib.sha1).hexdigest() + sig1 = hmac.new(key1, hmac_body, hashlib.sha256).hexdigest() + sig2 = hmac.new(key2, hmac_body, hashlib.sha256).hexdigest() account_keys = [] for sig in (sig1, sig2): self.assert_valid_sig(expires, path, account_keys, sig, environ) @@ -210,9 +215,10 @@ class TestTempURL(unittest.TestCase): def test_signature_trim(self): # Insert proxy logging into the pipeline p_logging = proxy_logging.filter_factory({})(self.app) - self.auth = tempauth.filter_factory({'reseller_prefix': ''})( - p_logging) - self.tempurl = tempurl.filter_factory({})(self.auth) + self.auth = tempauth.filter_factory({ + 'reseller_prefix': ''})(p_logging) + self.tempurl = tempurl.filter_factory({ + 'allowed_digests': 'sha1'})(self.auth) sig = 'valid_sigs_will_be_exactly_40_characters' expires = int(time() + 1000) @@ -239,7 +245,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'filename=bob%%20%%22killer%%22.txt' % (sig, expires)}) @@ -261,7 +267,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'REQUEST_METHOD': 'HEAD', 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' @@ -279,7 +285,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'REQUEST_METHOD': 'HEAD', 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' @@ -290,7 +296,7 @@ class TestTempURL(unittest.TestCase): get_method = 'GET' get_hmac_body = ('%s\n%i\n%s' % (get_method, expires, path)).encode('utf-8') - get_sig = hmac.new(key, get_hmac_body, hashlib.sha1).hexdigest() + get_sig = hmac.new(key, get_hmac_body, hashlib.sha256).hexdigest() get_req = self._make_request(path, keys=[key], environ={ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' @@ -306,7 +312,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'filename=bob%%20%%22killer%%22.txt&inline=' % (sig, expires)}) @@ -328,7 +334,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'inline=' % (sig, expires)}) @@ -349,14 +355,14 @@ class TestTempURL(unittest.TestCase): key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, sig_path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix) query_path = query_path[:-1] + 'p3/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, sig_path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix) def test_get_valid_with_prefix_empty(self): @@ -367,7 +373,7 @@ class TestTempURL(unittest.TestCase): key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, sig_path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() self.assert_valid_sig(expires, query_path, [key], sig, prefix='') def test_obj_odd_chars(self): @@ -376,7 +382,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/a\r\nb' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(quote(path), keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( sig, expires)}) @@ -396,7 +402,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( sig, expires)}) @@ -416,7 +422,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o/' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( sig, expires)}) @@ -436,7 +442,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'filename=/i/want/this/just/as/it/is/' % (sig, expires)}) @@ -457,7 +463,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -475,7 +481,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'PUT', @@ -492,7 +498,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'PUT', @@ -526,7 +532,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'PUT', @@ -545,7 +551,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -561,7 +567,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_expires=%s' % expires}) @@ -576,7 +582,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s' % sig}) @@ -591,7 +597,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -607,7 +613,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -623,7 +629,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'HEAD', @@ -640,7 +646,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'HEAD', @@ -657,7 +663,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'HEAD', @@ -674,7 +680,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() # Deliberately fudge expires to show HEADs aren't just automatically # allowed. expires += 1 @@ -694,7 +700,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'POST', @@ -712,7 +718,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'DELETE', @@ -729,7 +735,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'DELETE', @@ -744,7 +750,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'REQUEST_METHOD': 'UNKNOWN', @@ -772,7 +778,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(b'account-key', hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(b'account-key', hmac_body, hashlib.sha256).hexdigest() qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) # make request will setup the environ cache for us @@ -794,7 +800,7 @@ class TestTempURL(unittest.TestCase): # the container level; a different container in the same account is # out of scope and thus forbidden. hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(b'container-key', hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(b'container-key', hmac_body, hashlib.sha256).hexdigest() qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) req = self._make_request(path + qs, **key_kwargs) @@ -815,7 +821,7 @@ class TestTempURL(unittest.TestCase): # account-level tempurls by reusing one of the account's keys on a # container. hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(b'shared-key', hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(b'shared-key', hmac_body, hashlib.sha256).hexdigest() qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) req = self._make_request(path + qs, **key_kwargs) @@ -836,7 +842,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path + '2', keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -852,7 +858,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() if sig[-1] != '0': sig = sig[:-1] + '0' else: @@ -872,7 +878,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -936,7 +942,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key + b'2'], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -954,7 +960,7 @@ class TestTempURL(unittest.TestCase): key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, sig_path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( query_path, keys=[key], environ={'QUERY_STRING': @@ -972,7 +978,7 @@ class TestTempURL(unittest.TestCase): key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': @@ -993,7 +999,7 @@ class TestTempURL(unittest.TestCase): ('X-Symlink-Target', 'cont/symlink')]: hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, method=method, keys=[key], headers={hdr: value}, @@ -1014,7 +1020,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={'x-remove-this': 'value'}, @@ -1033,7 +1039,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={'x-remove-this-one': 'value1', @@ -1055,7 +1061,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={'x-conflict-header': 'value'}, @@ -1074,7 +1080,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={'x-conflict-header-test': 'value'}, @@ -1092,7 +1098,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -1111,7 +1117,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( @@ -1131,7 +1137,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={}, @@ -1153,7 +1159,7 @@ class TestTempURL(unittest.TestCase): path = '/v1/a/c/o' key = b'abc' hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request( path, keys=[key], headers={}, @@ -1467,7 +1473,7 @@ class TestTempURL(unittest.TestCase): ip_range = '127.0.0.0/29' hmac_body = ('ip=%s\n%s\n%i\n%s' % (ip_range, method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'temp_url_ip_range=%s' % (sig, expires, ip_range), @@ -1491,7 +1497,7 @@ class TestTempURL(unittest.TestCase): ip = '127.0.0.1' hmac_body = ('ip=%s\n%s\n%i\n%s' % (ip, method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'temp_url_ip_range=%s' % (sig, expires, ip), @@ -1536,7 +1542,7 @@ class TestTempURL(unittest.TestCase): ip = '2001:db8::' hmac_body = ('ip=%s\n%s\n%i\n%s' % (ip, method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'temp_url_ip_range=%s' % (sig, expires, ip), @@ -1560,7 +1566,7 @@ class TestTempURL(unittest.TestCase): ip_range = '2001:db8::/127' hmac_body = ('ip=%s\n%s\n%i\n%s' % (ip_range, method, expires, path)).encode('utf-8') - sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() + sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() req = self._make_request(path, keys=[key], environ={ 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'temp_url_ip_range=%s' % (sig, expires, ip_range), @@ -1614,7 +1620,7 @@ class TestSwiftInfo(unittest.TestCase): set(('x-object-meta-*',))) self.assertEqual(set(info['outgoing_allow_headers']), set(('x-object-meta-public-*',))) - self.assertEqual(info['allowed_digests'], ['sha1', 'sha256', 'sha512']) + self.assertEqual(info['allowed_digests'], ['sha256', 'sha512']) def test_non_default_methods(self): tempurl.filter_factory({ @@ -1623,7 +1629,7 @@ class TestSwiftInfo(unittest.TestCase): 'incoming_allow_headers': 'x-timestamp x-versions-location', 'outgoing_remove_headers': 'x-*', 'outgoing_allow_headers': 'x-object-meta-* content-type', - 'allowed_digests': 'sha512 md5 not-a-valid-digest', + 'allowed_digests': 'sha1 sha512 md5 not-a-valid-digest', }) swift_info = registry.get_swift_info() self.assertIn('tempurl', swift_info) @@ -1636,7 +1642,7 @@ class TestSwiftInfo(unittest.TestCase): self.assertEqual(set(info['outgoing_remove_headers']), set(('x-*', ))) self.assertEqual(set(info['outgoing_allow_headers']), set(('x-object-meta-*', 'content-type'))) - self.assertEqual(info['allowed_digests'], ['sha512']) + self.assertEqual(info['allowed_digests'], ['sha1', 'sha512']) def test_bad_config(self): with self.assertRaises(ValueError): @@ -1645,5 +1651,19 @@ class TestSwiftInfo(unittest.TestCase): }) +class TestTempurlWarning(unittest.TestCase): + + def test_deprecation_warning(self): + logger = debug_logger() + with mock.patch('swift.common.middleware.tempurl.get_logger', + lambda *a, **kw: logger): + tempurl.filter_factory({'allowed_digests': 'sha1'}) + log_lines = logger.get_lines_for_level('warning') + self.assertIn( + 'The following digest algorithms are configured but deprecated:' + ' sha1. Support will be removed in a future release.', + log_lines) + + if __name__ == '__main__': unittest.main() diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py index 3f14fdcdda..62ff27d3be 100644 --- a/test/unit/common/test_utils.py +++ b/test/unit/common/test_utils.py @@ -3828,6 +3828,25 @@ cluster_dfw1 = http://dfw1.host/v1/ utils.get_hmac(u'GET', u'/path', 1, u'abc', ip_range=u'127.0.0.1'), 'b30dde4d2b8562b8496466c3b46b2b9ac5054461') + def test_get_hmac_digest(self): + self.assertEqual( + utils.get_hmac(u'GET', u'/path', 1, u'abc', digest='sha256'), + '64c5558394f86b042ce1e929b34907abd9d0a57f3e20cd3f93cffd83de0206a7') + self.assertEqual( + utils.get_hmac(u'GET', u'/path', 1, u'abc', digest=hashlib.sha256), + '64c5558394f86b042ce1e929b34907abd9d0a57f3e20cd3f93cffd83de0206a7') + + self.assertEqual( + utils.get_hmac(u'GET', u'/path', 1, u'abc', digest='sha512'), + '7e95af818aec1b69b53fc2cb6d69456ec64ebda6c17b8fc8b7303b78acc8ca' + '14fc4aed96c1614a8e9d6ff45a6237711d8be294cda679624825d79aa6959b' + '5229') + self.assertEqual( + utils.get_hmac(u'GET', u'/path', 1, u'abc', digest=hashlib.sha512), + '7e95af818aec1b69b53fc2cb6d69456ec64ebda6c17b8fc8b7303b78acc8ca' + '14fc4aed96c1614a8e9d6ff45a6237711d8be294cda679624825d79aa6959b' + '5229') + def test_parse_override_options(self): # When override_ is passed in, it takes precedence. opts = utils.parse_override_options(