Browse Source

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.
Jon Griffiths 8 years ago
parent
commit
63407b689e
2 changed files with 39 additions and 20 deletions
  1. 21 14
      qvm-tools/qvm-backup
  2. 18 6
      qvm-tools/qvm-backup-restore

+ 21 - 14
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)
+
+        if getpass.getpass("Enter again for verification: ") != passphrase:
+            print >>sys.stderr, "ERROR: Password mismatch"
+            exit(1)
 
-    passphrase = passphrase.decode(sys.stdin.encoding)
+    encoding = sys.stdin.encoding or getpreferredencoding()
+    passphrase = passphrase.decode(encoding)
 
     kwargs = {}
     if options.hmac_algorithm:

+ 18 - 6
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-<current-time>' 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,