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... | ... |
@@ -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 |
... | ... |
@@ -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}, |