Browse code

* 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

Michal Ludvig authored on 2009/02/24 10:01:01
Showing 6 changed files
... ...
@@ -1,3 +1,10 @@
1
+2009-02-24  Michal Ludvig  <michal@logix.cz>
2
+
3
+	* s3cmd: New command [sign]
4
+	* S3/Utils.py: New function sign_string()
5
+	* S3/S3.py, S3/CloudFront.py: Use sign_string().
6
+	* NEWS: Updated.
7
+
1 8
 2009-02-17  Michal Ludvig  <michal@logix.cz>
2 9
 
3 10
 	* Released version 0.9.9
... ...
@@ -1,3 +1,8 @@
1
+s3cmd 1.0.0
2
+===========
3
+* New command 'sign' for signing for instance
4
+  the POST upload policies.
5
+
1 6
 s3cmd 0.9.9   -   2009-02-17
2 7
 ===========
3 8
 New commands:
... ...
@@ -4,26 +4,18 @@
4 4
 ## License: GPL Version 2
5 5
 
6 6
 import sys
7
-import base64
8 7
 import time
9 8
 import httplib
10 9
 from logging import debug, info, warning, error
11 10
 
12 11
 try:
13
-	from hashlib import md5, sha1
14
-except ImportError:
15
-	from md5 import md5
16
-	import sha as sha1
17
-import hmac
18
-
19
-try:
20 12
 	import xml.etree.ElementTree as ET
21 13
 except ImportError:
22 14
 	import elementtree.ElementTree as ET
23 15
 
24 16
 from Config import Config
25 17
 from Exceptions import *
26
-from Utils import getTreeFromXml, appendXmlTextNode, getDictFromTree, dateS3toPython
18
+from Utils import getTreeFromXml, appendXmlTextNode, getDictFromTree, dateS3toPython, sign_string
27 19
 from S3Uri import S3Uri, S3UriS3
28 20
 
29 21
 def output(message):
... ...
@@ -349,7 +341,7 @@ class CloudFront(object):
349 349
 
350 350
 	def sign_request(self, headers):
351 351
 		string_to_sign = headers['x-amz-date']
352
-		signature = base64.encodestring(hmac.new(self.config.secret_key, string_to_sign, sha1).digest()).strip()
352
+		signature = sign_string(string_to_sign)
353 353
 		debug(u"CloudFront.sign_request('%s') = %s" % (string_to_sign, signature))
354 354
 		return signature
355 355
 
... ...
@@ -5,7 +5,6 @@
5 5
 
6 6
 import sys
7 7
 import os, os.path
8
-import base64
9 8
 import time
10 9
 import httplib
11 10
 import logging
... ...
@@ -14,11 +13,9 @@ from logging import debug, info, warning, error
14 14
 from stat import ST_SIZE
15 15
 
16 16
 try:
17
-	from hashlib import md5, sha1
17
+	from hashlib import md5
18 18
 except ImportError:
19 19
 	from md5 import md5
20
-	import sha as sha1
21
-import hmac
22 20
 
23 21
 from Utils import *
24 22
 from SortedDict import SortedDict
... ...
@@ -649,7 +646,7 @@ class S3(object):
649 649
 			h += "/" + resource['bucket']
650 650
 		h += resource['uri']
651 651
 		debug("SignHeaders: " + repr(h))
652
-		return base64.encodestring(hmac.new(self.config.secret_key, h, sha1).digest()).strip()
652
+		return sign_string(h)
653 653
 
654 654
 	@staticmethod
655 655
 	def check_bucket_name(bucket, dns_strict = True):
... ...
@@ -10,9 +10,12 @@ import string
10 10
 import random
11 11
 import rfc822
12 12
 try:
13
-	from hashlib import md5
13
+	from hashlib import md5, sha1
14 14
 except ImportError:
15 15
 	from md5 import md5
16
+	import sha as sha1
17
+import hmac
18
+import base64
16 19
 import errno
17 20
 
18 21
 from logging import debug, info, warning, error
... ...
@@ -253,3 +256,8 @@ def unicodise_safe(string, encoding = None):
253 253
 
254 254
 	return unicodise(deunicodise(string, encoding), encoding).replace(u'\ufffd', '?')
255 255
 
256
+def sign_string(string_to_sign):
257
+	#debug("string_to_sign: %s" % string_to_sign)
258
+	signature = base64.encodestring(hmac.new(Config.Config().secret_key, string_to_sign, sha1).digest()).strip()
259
+	#debug("signature: %s" % signature)
260
+	return signature
... ...
@@ -1048,6 +1048,12 @@ def cmd_setacl(args):
1048 1048
 		if retsponse['status'] == 200:
1049 1049
 			output(u"%s: ACL set to %s  %s" % (uri, set_to_acl, seq_label))
1050 1050
 
1051
+def cmd_sign(args):
1052
+	string_to_sign = args.pop()
1053
+	debug("string-to-sign: %r" % string_to_sign)
1054
+	signature = Utils.sign_string(string_to_sign)
1055
+	output("Signature: %s" % signature)
1056
+
1051 1057
 def resolve_list(lst, args):
1052 1058
 	retval = []
1053 1059
 	for item in lst:
... ...
@@ -1281,6 +1287,8 @@ def get_commands_list():
1281 1281
 	{"cmd":"cp", "label":"Copy object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_cp, "argc":2},
1282 1282
 	{"cmd":"mv", "label":"Move object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_mv, "argc":2},
1283 1283
 	{"cmd":"setacl", "label":"Modify Access control list for Bucket or Files", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1},
1284
+	{"cmd":"sign", "label":"Sign arbitrary string using the secret key", "param":"STRING-TO-SIGN", "func":cmd_sign, "argc":1},
1285
+
1284 1286
 	## CloudFront commands
1285 1287
 	{"cmd":"cflist", "label":"List CloudFront distribution points", "param":"", "func":CfCmd.info, "argc":0},
1286 1288
 	{"cmd":"cfinfo", "label":"Display CloudFront distribution point parameters", "param":"[cf://DIST_ID]", "func":CfCmd.info, "argc":0},