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
This commit is contained in:
Tim Burke 2017-12-05 21:52:51 +00:00 committed by Matthew Oliver
parent b621a6f932
commit 118cf2ba8a
9 changed files with 188 additions and 130 deletions

View File

@ -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::

View File

@ -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]

View File

@ -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 ``"<digest name>:"``.
@ -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')

View File

@ -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()

View File

@ -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'

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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_<thing> is passed in, it takes precedence.
opts = utils.parse_override_options(