diff options
author | Tim Burke <tim.burke@gmail.com> | 2022-06-08 09:30:17 -0700 |
---|---|---|
committer | Tim Burke <tim.burke@gmail.com> | 2022-06-08 09:30:21 -0700 |
commit | 9eee29d2e46e774eb08acb76c3317a58856f3f71 (patch) | |
tree | a1d6942f1b03a5487b81cd98b180af0047e3aa30 /swiftclient | |
parent | 1dc635a32c30d4e6c823b8367247f4554365c456 (diff) | |
download | python-swiftclient-9eee29d2e46e774eb08acb76c3317a58856f3f71.tar.gz |
tempurl: Support sha256 and sha512 signatures4.0.1
Up the default to sha256 since
* the proxy has supported (and defaulted to allowing) it for four years
now, and
* Rackspace has supported it for even longer.
Include a note in the --help about older clusters likely requiring sha1.
Change-Id: Ibac2bb7e2e4c9946c7384f0aab8e43d0d79ba645
Related-Change: Ia9dd1a91cc3c9c946f5f029cdefc9e66bcf01046
Related-Bug: #1733634
Closes-Bug: #1977867
Diffstat (limited to 'swiftclient')
-rwxr-xr-x | swiftclient/shell.py | 11 | ||||
-rw-r--r-- | swiftclient/utils.py | 22 |
2 files changed, 29 insertions, 4 deletions
diff --git a/swiftclient/shell.py b/swiftclient/shell.py index df7c511..b4721fe 100755 --- a/swiftclient/shell.py +++ b/swiftclient/shell.py @@ -1427,6 +1427,8 @@ Optional arguments: ISO 8601 UTC timestamp instead of a Unix timestamp. --ip-range If present, the temporary URL will be restricted to the given ip or ip range. + --digest The digest algorithm to use. Defaults to sha256, but + older clusters may only support sha1. '''.strip('\n') @@ -1456,6 +1458,12 @@ def st_tempurl(parser, args, thread_manager, return_parser=False): help=("If present, the temporary URL will be restricted to the " "given ip or ip range."), ) + parser.add_argument( + '--digest', choices=('sha1', 'sha256', 'sha512'), + default='sha256', + help=("The digest algorithm to use. Defaults to sha256, but " + "older clusters may only support sha1."), + ) # We return the parser to build up the bash_completion if return_parser: @@ -1480,7 +1488,8 @@ def st_tempurl(parser, args, thread_manager, return_parser=False): absolute=options['absolute_expiry'], iso8601=options['iso8601'], prefix=options['prefix_based'], - ip_range=options['ip_range']) + ip_range=options['ip_range'], + digest=options['digest']) except ValueError as err: thread_manager.error(err) return diff --git a/swiftclient/utils.py b/swiftclient/utils.py index 860d8bf..c865d27 100644 --- a/swiftclient/utils.py +++ b/swiftclient/utils.py @@ -14,6 +14,7 @@ # limitations under the License. """Miscellaneous utility functions for use with Swift.""" +import base64 from calendar import timegm from collections.abc import Mapping import gzip @@ -70,7 +71,8 @@ def prt_bytes(num_bytes, human_flag): def generate_temp_url(path, seconds, key, method, absolute=False, - prefix=False, iso8601=False, ip_range=None): + prefix=False, iso8601=False, ip_range=None, + digest='sha256'): """Generates a temporary URL that gives unauthenticated access to the Swift object. @@ -95,7 +97,11 @@ def generate_temp_url(path, seconds, key, method, absolute=False, instead of a UNIX timestamp will be created. :param ip_range: if a valid ip range, restricts the temporary URL to the range of ips. - :raises ValueError: if timestamp or path is not in valid format. + :param digest: digest algorithm to use. Must be one of ``sha1``, + ``sha256``, or ``sha512``. + :raises ValueError: if timestamp or path is not in valid format, + or if digest is not one of ``sha1``, ``sha256``, or + ``sha512``. :return: the path portion of a temporary URL """ try: @@ -140,6 +146,11 @@ def generate_temp_url(path, seconds, key, method, absolute=False, else: path_for_body = path + if isinstance(digest, str) and digest in ('sha1', 'sha256', 'sha512'): + digest = getattr(hashlib, digest) + if digest not in (hashlib.sha1, hashlib.sha256, hashlib.sha512): + raise ValueError('digest must be one of sha1, sha256, or sha512') + parts = path_for_body.split('/', 4) if len(parts) != 5 or parts[0] or not all(parts[1:(4 if prefix else 5)]): if prefix: @@ -177,7 +188,12 @@ def generate_temp_url(path, seconds, key, method, absolute=False, # Encode to UTF-8 for py3 compatibility if not isinstance(key, bytes): key = key.encode('utf-8') - sig = hmac.new(key, hmac_body.encode('utf-8'), hashlib.sha1).hexdigest() + mac = hmac.new(key, hmac_body.encode('utf-8'), digest) + if digest == hashlib.sha512: + sig = 'sha512:' + base64.urlsafe_b64encode( + mac.digest()).decode('ascii').strip('=') + else: + sig = mac.hexdigest() if iso8601: expiration = time.strftime( |