Skip to content

Commit

Permalink
2007-06-17 Michal Ludvig <michal@logix.cz>
Browse files Browse the repository at this point in the history
	* 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
mludvig committed Jun 16, 2007
1 parent b7bdf45 commit 49731b4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 8 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion S3/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
8 changes: 8 additions & 0 deletions S3/Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import elementtree.ElementTree as ET
import string
import random
import md5

def parseNodes(nodes, xmlns = ""):
retval = []
Expand Down Expand Up @@ -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()
47 changes: 40 additions & 7 deletions s3cmd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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:
Expand All @@ -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 != "":
Expand All @@ -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"):
Expand Down

0 comments on commit 49731b4

Please sign in to comment.