From 63407b689ed87e4d517b4e62c7c5f8a811170847 Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Wed, 9 Mar 2016 00:50:06 +1300 Subject: [PATCH] qvm-backup/qvm-backup-restore: Allow reading pass phrase from file or stdin Passing -p/--passphrase-file uses the first line of the file passed, or stdin if '-' is given. This works with piped input too. --- qvm-tools/qvm-backup | 35 +++++++++++++++++++++-------------- qvm-tools/qvm-backup-restore | 24 ++++++++++++++++++------ 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/qvm-tools/qvm-backup b/qvm-tools/qvm-backup index aa69f9c6..854b7e31 100755 --- a/qvm-tools/qvm-backup +++ b/qvm-tools/qvm-backup @@ -30,6 +30,7 @@ import qubes.backup import os import sys import getpass +from locale import getpreferredencoding def print_progress(progress): print >> sys.stderr, "\r-> Backing up files: {0}%...".format (progress), @@ -51,6 +52,10 @@ def main(): parser.add_option ("--no-encrypt", action="store_true", dest="no_encrypt", default=False, help="Skip encryption even if sending the backup to VM") + parser.add_option ("-p", "--passphrase-file", action="store", + dest="pass_file", default=None, + help="File containing the pass phrase to use, or '-' " + "to read it from stdin") parser.add_option ("-E", "--enc-algo", action="store", dest="crypto_algorithm", default=None, help="Specify non-default encryption algorithm. For " @@ -156,24 +161,26 @@ def main(): if not options.encrypt: print >>sys.stderr, "WARNING: encryption will not be used" - prompt = raw_input ("Do you want to proceed? [y/N] ") - if not (prompt == "y" or prompt == "Y"): - exit (0) + if options.pass_file is not None: + f = open(options.pass_file) if options.pass_file != "-" else sys.stdin + passphrase = f.readline().rstrip() + if f is not sys.stdin: + f.close() - if options.encrypt: - passphrase = getpass.getpass("Please enter the pass phrase that will " - "be used to encrypt and verify the " - "backup: ") else: - passphrase = getpass.getpass("Please enter the pass phrase that will " - "be used to verify the backup: ") + if raw_input("Do you want to proceed? [y/N] ").upper() != "Y": + exit(0) - passphrase2 = getpass.getpass("Enter again for verification: ") - if passphrase != passphrase2: - print >>sys.stderr, "ERROR: Password mismatch" - exit(1) + s = ("Please enter the pass phrase that will be used to {}verify " + "the backup: ").format('encrypt and ' if options.encrypt else '') + passphrase = getpass.getpass(s) - passphrase = passphrase.decode(sys.stdin.encoding) + if getpass.getpass("Enter again for verification: ") != passphrase: + print >>sys.stderr, "ERROR: Password mismatch" + exit(1) + + encoding = sys.stdin.encoding or getpreferredencoding() + passphrase = passphrase.decode(encoding) kwargs = {} if options.hmac_algorithm: diff --git a/qvm-tools/qvm-backup-restore b/qvm-tools/qvm-backup-restore index bcfdfad0..d3ff527c 100755 --- a/qvm-tools/qvm-backup-restore +++ b/qvm-tools/qvm-backup-restore @@ -31,6 +31,7 @@ from qubes.backup import backup_restore_do import qubes.backup import sys from optparse import OptionParser +from locale import getpreferredencoding import os import sys @@ -81,6 +82,10 @@ def main(): parser.add_option ("-e", "--encrypted", action="store_true", dest="decrypt", default=False, help="The backup is encrypted") + parser.add_option ("-p", "--passphrase-file", action="store", + dest="pass_file", default=None, + help="File containing the pass phrase to use, or '-' to read it from stdin") + parser.add_option ("-z", "--compressed", action="store_true", dest="compressed", default=False, help="The backup is compressed") @@ -128,8 +133,16 @@ def main(): print >>sys.stderr, "ERROR: VM {0} does not exist".format(options.appvm) exit(1) - passphrase = getpass.getpass("Please enter the pass phrase that will be used to decrypt/verify the backup: ") - passphrase = passphrase.decode(sys.stdin.encoding) + if options.pass_file is not None: + f = open(options.pass_file) if options.pass_file != "-" else sys.stdin + passphrase = f.readline().rstrip() + if f is not sys.stdin: + f.close() + else: + passphrase = getpass.getpass("Please enter the pass phrase to decrypt/verify the backup: ") + + encoding = sys.stdin.encoding or getpreferredencoding() + passphrase = passphrase.decode(encoding) print >> sys.stderr, "Checking backup content..." @@ -244,10 +257,9 @@ def main(): print >> sys.stderr, "Continuing as directed" print >> sys.stderr, "While restoring user homedir, existing files/dirs will be backed up in 'home-pre-restore-' dir" - prompt = raw_input ("Do you want to proceed? [y/N] ") - if not (prompt == "y" or prompt == "Y"): - exit (0) - + if options.pass_file is None: + if raw_input("Do you want to proceed? [y/N] ").upper() != "Y": + exit(0) try: backup_restore_do(restore_info,