Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2007-06-17 Michal Ludvig <michal@logix.cz>

	* s3cmd: Added encryption key support to --configure



git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@125 830e0280-6d2a-0410-9c65-932aecc39d9d
  • Loading branch information...
commit 49731b402071abd6d020ca7e9f7bc8d1b709a3a4 1 parent b7bdf45
@mludvig mludvig authored
Showing with 54 additions and 8 deletions.
  1. +1 −0  ChangeLog
  2. +4 −0 NEWS
  3. +1 −1  S3/Config.py
  4. +8 −0 S3/Utils.py
  5. +40 −7 s3cmd
View
1  ChangeLog
@@ -1,5 +1,6 @@
2007-06-17 Michal Ludvig <michal@logix.cz>
+ * s3cmd: Added encryption key support to --configure
* S3/PkgInfo.py: Bump up version to 0.9.4-pre
* setup.py: Cleaned up some rpm-specific stuff that
caused problems to Debian packager Mikhail Gusarov
View
4 NEWS
@@ -1,3 +1,7 @@
+s3cmd 0.9.4 - ...
+===========
+* Support for transparent GPG encryption of uploaded files.
+
s3cmd 0.9.3 - 2007-05-26
===========
* New command "du" for displaying size of your data in S3.
View
2  S3/Config.py
@@ -21,7 +21,7 @@ class Config(object):
acl_public = False
encrypt = False
gpg_passphrase = ""
- gpg_command = "/usr/bin/gpg"
+ gpg_command = ""
gpg_encrypt = "%(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s"
gpg_decrypt = "%(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s"
View
8 S3/Utils.py
@@ -9,6 +9,7 @@
import elementtree.ElementTree as ET
import string
import random
+import md5
def parseNodes(nodes, xmlns = ""):
retval = []
@@ -104,3 +105,10 @@ def mktmpdir(prefix = "/tmp/tmpdir-", randchars = 10):
def mktmpfile(prefix = "/tmp/tmpfile-", randchars = 20):
createfunc = lambda filename : os.close(os.open(filename, os.O_CREAT | os.O_EXCL))
return mktmpsomething(prefix, randchars, createfunc)
+
+def hash_file_md5(filename):
+ h = md5.new()
+ f = open(filename, "r")
+ h.update(f.read())
+ f.close()
+ return h.hexdigest()
View
47 s3cmd
@@ -13,6 +13,7 @@ from copy import copy
from optparse import OptionParser, Option, OptionValueError, IndentedHelpFormatter
from logging import debug, info, warning, error
import elementtree.ElementTree as ET
+from distutils.spawn import find_executable
## Our modules
from S3 import PkgInfo
@@ -250,7 +251,7 @@ def gpg_encrypt(filename):
code = gpg_command(command, cfg.gpg_passphrase)
return (code, tmp_filename, "gpg")
-def gpg_decrypt(filename, gpgenc_header = ""):
+def gpg_decrypt(filename, gpgenc_header = "", in_place = True):
tmp_filename = Utils.mktmpfile(filename)
args = {
"gpg_command" : cfg.gpg_command,
@@ -261,22 +262,28 @@ def gpg_decrypt(filename, gpgenc_header = ""):
info("Decrypting file %(input_file)s to %(output_file)s..." % args)
command = resolve_list(cfg.gpg_decrypt.split(" "), args)
code = gpg_command(command, cfg.gpg_passphrase)
- if code == 0:
+ if code == 0 and in_place:
debug("Renaming %s to %s" % (tmp_filename, filename))
os.unlink(filename)
os.rename(tmp_filename, filename)
- return (code)
+ tmp_filename = filename
+ return (code, tmp_filename)
def run_configure(config_file):
cfg = Config()
options = [
("access_key", "Access Key", "Access key and Secret key are your identifiers for Amazon S3"),
("secret_key", "Secret Key"),
+ ("gpg_passphrase", "Encryption password", "Encryption password is used to protect your files from reading\nby unauthorized persons while in transfer to S3"),
+ ("gpg_command", "Path to GPG program"),
]
+ if getattr(cfg, "gpg_command") == "":
+ setattr(cfg, "gpg_command", find_executable("gpg"))
+
try:
while 1:
output("\nEnter new values or accept defaults in brackets with Enter.")
- output("Refer to user manual for detailed description of all options.\n")
+ output("Refer to user manual for detailed description of all options.")
for option in options:
prompt = option[1]
try:
@@ -287,7 +294,7 @@ def run_configure(config_file):
pass
if len(option) >= 3:
- output("%s" % option[2])
+ output("\n%s" % option[2])
val = raw_input(prompt + ": ")
if val != "":
@@ -300,12 +307,38 @@ def run_configure(config_file):
try:
output("Please wait...")
S3(Config()).bucket_list("", "")
- output("\nSuccess. Your access key and secret key worked fine :-)")
- except S3Error, e:
+ output("Success. Your access key and secret key worked fine :-)")
+
+ output("\nNow verifying that encryption works...")
+ if not getattr(cfg, "gpg_command"):
+ raise Exception("Path to GPG program not set")
+ if not os.path.isfile(getattr(cfg, "gpg_command")):
+ raise Exception("GPG program not found")
+ filename = Utils.mktmpfile()
+ f = open(filename, "w")
+ f.write(os.sys.copyright)
+ f.close()
+ ret_enc = gpg_encrypt(filename)
+ ret_dec = gpg_decrypt(ret_enc[1], ret_enc[2], False)
+ hash = [
+ Utils.hash_file_md5(filename),
+ Utils.hash_file_md5(ret_enc[1]),
+ Utils.hash_file_md5(ret_dec[1]),
+ ]
+ os.unlink(filename)
+ os.unlink(ret_enc[1])
+ os.unlink(ret_dec[1])
+ if hash[0] == hash[2] and hash[0] != hash[1]:
+ output ("Success. Encryption and decryption worked fine :-)")
+ else:
+ raise Exception("Encryption verification error.")
+
+ except Exception, e:
error("Test failed: %s" % (e))
val = raw_input("\nRetry configuration? [Y/n] ")
if val.lower().startswith("y") or val == "":
continue
+
val = raw_input("\nSave settings? [y/N] ")
if val.lower().startswith("y"):
Please sign in to comment.
Something went wrong with that request. Please try again.