From 0b8ea55951f8eecf5b9268b1f9ade841023fae8f Mon Sep 17 00:00:00 2001 From: Michal Ludvig Date: Tue, 24 Feb 2009 01:01:01 +0000 Subject: [PATCH] * s3cmd: New command [sign] * S3/Utils.py: New function sign_string() * S3/S3.py, S3/CloudFront.py: Use sign_string(). git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@378 830e0280-6d2a-0410-9c65-932aecc39d9d --- ChangeLog | 7 +++++++ NEWS | 5 +++++ S3/CloudFront.py | 12 ++---------- S3/S3.py | 7 ++----- S3/Utils.py | 10 +++++++++- s3cmd | 8 ++++++++ 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index bccda6cdb..a8bc16f8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-02-24 Michal Ludvig + + * s3cmd: New command [sign] + * S3/Utils.py: New function sign_string() + * S3/S3.py, S3/CloudFront.py: Use sign_string(). + * NEWS: Updated. + 2009-02-17 Michal Ludvig * Released version 0.9.9 diff --git a/NEWS b/NEWS index 9dc7d181c..3ad89ccfd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +s3cmd 1.0.0 +=========== +* New command 'sign' for signing for instance + the POST upload policies. + s3cmd 0.9.9 - 2009-02-17 =========== New commands: diff --git a/S3/CloudFront.py b/S3/CloudFront.py index 059468183..be4dae941 100644 --- a/S3/CloudFront.py +++ b/S3/CloudFront.py @@ -4,18 +4,10 @@ ## License: GPL Version 2 import sys -import base64 import time import httplib from logging import debug, info, warning, error -try: - from hashlib import md5, sha1 -except ImportError: - from md5 import md5 - import sha as sha1 -import hmac - try: import xml.etree.ElementTree as ET except ImportError: @@ -23,7 +15,7 @@ from Config import Config from Exceptions import * -from Utils import getTreeFromXml, appendXmlTextNode, getDictFromTree, dateS3toPython +from Utils import getTreeFromXml, appendXmlTextNode, getDictFromTree, dateS3toPython, sign_string from S3Uri import S3Uri, S3UriS3 def output(message): @@ -349,7 +341,7 @@ def create_request(self, operation, dist_id = None, headers = None): def sign_request(self, headers): string_to_sign = headers['x-amz-date'] - signature = base64.encodestring(hmac.new(self.config.secret_key, string_to_sign, sha1).digest()).strip() + signature = sign_string(string_to_sign) debug(u"CloudFront.sign_request('%s') = %s" % (string_to_sign, signature)) return signature diff --git a/S3/S3.py b/S3/S3.py index 09a7407d7..d591b3866 100644 --- a/S3/S3.py +++ b/S3/S3.py @@ -5,7 +5,6 @@ import sys import os, os.path -import base64 import time import httplib import logging @@ -14,11 +13,9 @@ from stat import ST_SIZE try: - from hashlib import md5, sha1 + from hashlib import md5 except ImportError: from md5 import md5 - import sha as sha1 -import hmac from Utils import * from SortedDict import SortedDict @@ -649,7 +646,7 @@ def sign_headers(self, method, resource, headers): h += "/" + resource['bucket'] h += resource['uri'] debug("SignHeaders: " + repr(h)) - return base64.encodestring(hmac.new(self.config.secret_key, h, sha1).digest()).strip() + return sign_string(h) @staticmethod def check_bucket_name(bucket, dns_strict = True): diff --git a/S3/Utils.py b/S3/Utils.py index fe3c149b2..820b98ee8 100644 --- a/S3/Utils.py +++ b/S3/Utils.py @@ -10,9 +10,12 @@ import random import rfc822 try: - from hashlib import md5 + from hashlib import md5, sha1 except ImportError: from md5 import md5 + import sha as sha1 +import hmac +import base64 import errno from logging import debug, info, warning, error @@ -253,3 +256,8 @@ def unicodise_safe(string, encoding = None): return unicodise(deunicodise(string, encoding), encoding).replace(u'\ufffd', '?') +def sign_string(string_to_sign): + #debug("string_to_sign: %s" % string_to_sign) + signature = base64.encodestring(hmac.new(Config.Config().secret_key, string_to_sign, sha1).digest()).strip() + #debug("signature: %s" % signature) + return signature diff --git a/s3cmd b/s3cmd index 22fe87417..e2c72f54a 100755 --- a/s3cmd +++ b/s3cmd @@ -1048,6 +1048,12 @@ def cmd_setacl(args): if retsponse['status'] == 200: output(u"%s: ACL set to %s %s" % (uri, set_to_acl, seq_label)) +def cmd_sign(args): + string_to_sign = args.pop() + debug("string-to-sign: %r" % string_to_sign) + signature = Utils.sign_string(string_to_sign) + output("Signature: %s" % signature) + def resolve_list(lst, args): retval = [] for item in lst: @@ -1281,6 +1287,8 @@ def get_commands_list(): {"cmd":"cp", "label":"Copy object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_cp, "argc":2}, {"cmd":"mv", "label":"Move object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_mv, "argc":2}, {"cmd":"setacl", "label":"Modify Access control list for Bucket or Files", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1}, + {"cmd":"sign", "label":"Sign arbitrary string using the secret key", "param":"STRING-TO-SIGN", "func":cmd_sign, "argc":1}, + ## CloudFront commands {"cmd":"cflist", "label":"List CloudFront distribution points", "param":"", "func":CfCmd.info, "argc":0}, {"cmd":"cfinfo", "label":"Display CloudFront distribution point parameters", "param":"[cf://DIST_ID]", "func":CfCmd.info, "argc":0},