summaryrefslogtreecommitdiff
path: root/swiftclient
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2022-06-08 09:30:17 -0700
committerTim Burke <tim.burke@gmail.com>2022-06-08 09:30:21 -0700
commit9eee29d2e46e774eb08acb76c3317a58856f3f71 (patch)
treea1d6942f1b03a5487b81cd98b180af0047e3aa30 /swiftclient
parent1dc635a32c30d4e6c823b8367247f4554365c456 (diff)
downloadpython-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-xswiftclient/shell.py11
-rw-r--r--swiftclient/utils.py22
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(