← Back to team overview

duplicity-team team mailing list archive

[Merge] lp:~lenharo-h/duplicity/duplicity into lp:duplicity

 

Marcos Lenharo has proposed merging lp:~lenharo-h/duplicity/duplicity into lp:duplicity.

Requested reviews:
  duplicity-team (duplicity-team)

For more details, see:
https://code.launchpad.net/~lenharo-h/duplicity/duplicity/+merge/135300

Hi,

I thought that we could also generate encrypted backups without revealing the user's key id.
So I created a new switch (--hidden-encrypt-key) that will act like --encrypt-key but will use gpg's --hidden-recipient switch instead of --recipient.

Please, let me know if you need more info.

Thanks,
Marcos
-- 
https://code.launchpad.net/~lenharo-h/duplicity/duplicity/+merge/135300
Your team duplicity-team is requested to review the proposed merge of lp:~lenharo-h/duplicity/duplicity into lp:duplicity.
=== modified file 'bin/duplicity'
--- bin/duplicity	2012-11-13 21:53:24 +0000
+++ bin/duplicity	2012-11-21 01:36:22 +0000
@@ -93,13 +93,15 @@
     # check if we can reuse an already set (signing_)passphrase
     ## if signing key is also an encryption key assume that the passphrase is identical
     if ( for_signing
-         and globals.gpg_profile.sign_key in globals.gpg_profile.recipients
+         and (globals.gpg_profile.sign_key in globals.gpg_profile.recipients
+         or globals.gpg_profile.sign_key in globals.gpg_profile.hidden_recipients)
          and 'PASSPHRASE' in os.environ ):
         log.Notice(_("Reuse configured PASSPHRASE as SIGN_PASSPHRASE"))
         return os.environ['PASSPHRASE']
     ## if one encryption key is also the signing key assume that the passphrase is identical
     if ( not for_signing
-         and globals.gpg_profile.sign_key in globals.gpg_profile.recipients
+         and (globals.gpg_profile.sign_key in globals.gpg_profile.recipients
+         or globals.gpg_profile.sign_key in globals.gpg_profile.hidden_recipients)
          and 'SIGN_PASSPHRASE' in os.environ ):
         log.Notice(_("Reuse configured SIGN_PASSPHRASE as PASSPHRASE"))
         return os.environ['SIGN_PASSPHRASE']
@@ -127,14 +129,14 @@
     # for a full backup, we don't need a password if
     # there is no sign_key and there are recipients
     elif (action == "full"
-          and globals.gpg_profile.recipients
+          and (globals.gpg_profile.recipients or globals.gpg_profile.hidden_recipients)
           and not globals.gpg_profile.sign_key):
         return ""
 
     # for an inc backup, we don't need a password if
     # there is no sign_key and there are recipients
     elif (action == "inc"
-          and globals.gpg_profile.recipients
+          and (globals.gpg_profile.recipients or globals.gpg_profile.hidden_recipients)
           and not globals.gpg_profile.sign_key):
         return ""
 
@@ -174,7 +176,7 @@
                 use_cache = False
                 continue
 
-            if not pass1 and not globals.gpg_profile.recipients and not for_signing:
+            if not pass1 and not (globals.gpg_profile.recipients or globals.gpg_profile.hidden_recipients) and not for_signing:
                 print _("Cannot use empty passphrase with symmetric encryption!  Please try again.")
                 use_cache = False
                 continue
@@ -1350,7 +1352,7 @@
 
         # if there are no recipients (no --encrypt-key), it must be a
         # symmetric key. Therefore, confirm the passphrase
-        if not globals.gpg_profile.recipients:
+        if not (globals.gpg_profile.recipients or globals.gpg_profile.hidden_recipients):
             globals.gpg_profile.passphrase = get_passphrase(2, action)
             # a limitation in the GPG implementation does not allow for
             # inputting different passphrases, this affects symmetric+sign.

=== modified file 'bin/duplicity.1'
--- bin/duplicity.1	2012-11-03 14:10:38 +0000
+++ bin/duplicity.1	2012-11-21 01:36:22 +0000
@@ -478,6 +478,12 @@
 Use the GIO backend and interpret any URLs as GIO would.
 
 .TP
+.BI "--hidden-encrypt-key " key-id
+Same as
+.B --encrypy-key
+, but it hides user's key id from encrypted file.
+
+.TP
 .B --ignore-errors
 Try to ignore certain errors if they happen. This option is only
 intended to allow the restoration of a backup in the face of certain

=== modified file 'duplicity/commandline.py'
--- duplicity/commandline.py	2012-10-29 10:01:25 +0000
+++ duplicity/commandline.py	2012-11-21 01:36:22 +0000
@@ -350,6 +350,12 @@
 
     parser.add_option("--gpg-options", action="extend", metavar=_("options"))
 
+    # TRANSL: Used in usage help to represent an ID for a hidden GnuPG key. Example:
+    # --hidden-encrypt-key <gpg_key_id>
+    parser.add_option("--hidden-encrypt-key", type="string", metavar=_("gpg-key-id"),
+                      dest="", action="callback",
+                      callback=lambda o, s, v, p: globals.gpg_profile.hidden_recipients.append(v)) #@UndefinedVariable
+
     # ignore (some) errors during operations; supposed to make it more
     # likely that you are able to restore data under problematic
     # circumstances. the default should absolutely always be False unless

=== modified file 'duplicity/gpg.py'
--- duplicity/gpg.py	2012-10-15 17:13:08 +0000
+++ duplicity/gpg.py	2012-11-21 01:36:22 +0000
@@ -54,7 +54,7 @@
     Just hold some GPG settings, avoid passing tons of arguments
     """
     def __init__(self, passphrase = None, sign_key = None,
-                 recipients = None):
+                 recipients = None, hidden_recipients = None):
         """
         Set all data with initializer
 
@@ -76,6 +76,12 @@
         else:
             self.recipients = []
 
+        if hidden_recipients is not None:
+            assert type(hidden_recipients) is types.ListType # must be list, not tuple
+            self.hidden_recipients = hidden_recipients
+        else:
+            self.hidden_recipients = []
+
 
 class GPGFile:
     """
@@ -131,7 +137,10 @@
             if profile.recipients:
                 gnupg.options.recipients = profile.recipients
                 cmdlist.append('--encrypt')
-            else:
+            if profile.hidden_recipients:
+                gnupg.options.hidden_recipients = profile.hidden_recipients
+                cmdlist.append('--encrypt')
+            if not (profile.recipients or profile.hidden_recipients):
                 cmdlist.append('--symmetric')
                 # use integrity protection
                 gnupg.options.extra_args.append('--force-mdc')
@@ -149,7 +158,7 @@
                 p1.handles['passphrase'].close()
             self.gpg_input = p1.handles['stdin']
         else:
-            if profile.recipients and profile.encrypt_secring:
+            if (profile.recipients or profile.hidden_recipients) and profile.encrypt_secring:
                 cmdlist.append('--secret-keyring')
                 cmdlist.append(profile.encrypt_secring)
             self.status_fp = tempfile.TemporaryFile( dir=tempdir.default().dir() )

=== modified file 'duplicity/gpginterface.py'
--- duplicity/gpginterface.py	2012-10-15 17:13:08 +0000
+++ duplicity/gpginterface.py	2012-11-21 01:36:22 +0000
@@ -570,6 +570,7 @@
         # lists
         self.encrypt_to = []
         self.recipients = []
+        self.hidden_recipients = []
 
         # miscellaneous arguments
         self.extra_args = []
@@ -602,6 +603,7 @@
         if self.openpgp: args.append( '--openpgp' )
 
         for r in self.recipients: args.extend( [ '--recipient',  r ] )
+        for r in self.hidden_recipients: args.extend( [ '--hidden-recipient',  r ] )
         for r in self.encrypt_to: args.extend( [ '--encrypt-to', r ] )
 
         return args