[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Duplicity-talk] Unnecessarily asking for passphrase on incremental
From: |
Kenneth Loafman |
Subject: |
Re: [Duplicity-talk] Unnecessarily asking for passphrase on incremental backup |
Date: |
Wed, 15 Apr 2009 09:47:31 -0500 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090318) |
Kenneth Loafman wrote:
> Georg Lutz wrote:
>> On 2009-04-07 15:55, Kenneth Loafman wrote:
>>> Duplicity needs the key to decrypt the remote manifest file, which it
>>> then compares to the local manifest to guarantee that the two are in
>>> sync. If you are running a recent release of duplicity, --use-agent is
>>> available to allow gpg to query a gpg-agent instead of the user.
>>>
>> Hi Ken,
>>
>> Ok, I understand that this make the data handling much more robust and
>> probably fixes another severe bug.
>>
>> However this breaks the nice feature that duplicity didn't need access
>> to a secret key just for doing backups up to version 0.5.12 . I liked
>> it, because the backup should work fully unattended - the concerning
>> workstations/servers just had to be switched on at a certain time. Now I
>> have to make sure to manually unlock the secret key on every machine to
>> let the backup happen. The same issue was recently reported as bug
>> #26112.
>>
>> Couldn't the data integrity check been done without decrypting the
>> remote manifest? The archive-dir could hold e.g. an additional file with
>> a checksum for the encrypted remote manifest. What do you think? Would
>> this be feasible?
>
> This is a good idea. If the archive dir had the name and a hash of the
> latest manifest gpg file that could be checked and all would be OK.
>
> Taking it a step further, hashes for all of the remote files could be
> saved in the archive. During a restore, it would be nice to know that
> the downloaded file had been corrupted.
>
> I'll keep this in mind and get it fixed, at least the first part.
It's going to be a while before the fix for this is available, so I put
together a patch that restores the old behavior. This will still allow
you to "screw up" the archive if you forget to use the --archive-dir
option every time, but my tests show that duplicity will complain enough
that you'll be able to spot the problem if you do. The worst case is
that an incremental will be repeated because we just threw away the now
extra copy on the remote.
I had to edit the patch file to remove some other changes, so there may
be some fuzz warnings when you apply the patch.
...Ken
Index: duplicity-bin
===================================================================
RCS file: /sources/duplicity/duplicity/duplicity-bin,v
retrieving revision 1.71
diff -u -r1.71 duplicity-bin
--- duplicity-bin 9 Apr 2009 16:32:15 -0000 1.71
+++ duplicity-bin 15 Apr 2009 14:35:21 -0000
@@ -109,6 +109,15 @@
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
+ # and there is an archive-dir specified
+ elif (action == "inc"
+ and globals.gpg_profile.recipients
+ and not globals.gpg_profile.sign_key
+ and globals.archive_dir):
+ return ""
+
# Finally, ask the user for the passphrase
else:
log.Info("PASSPHRASE variable not set, asking user.")
@@ -695,6 +710,7 @@
log.Notice(_("Last full backup date:") + " " +
dup_time.timetopretty(last_full_time))
else:
log.Notice(_("Last full backup date: none"))
+ action = "full"
if action == "inc" and last_full_time < globals.full_force_time:
log.Notice(_("Last full backup is too old, forcing full backup"))
action = "full"
@@ -765,6 +781,15 @@
# No traceback, just get out
sys.exit(e)
+ except gpg.GPGError, e:
+ # For user errors, don't show an ugly stack trace by
+ # default. But do with sufficient verbosity.
+ log.Info(_("GPG error detail: %s")
+ % (''.join(traceback.format_exception(*sys.exc_info()))))
+ log.FatalError("%s: %s" % (e.__class__.__name__, e.args[0]),
+ log.ErrorCode.gpg_failed,
+ e.__class__.__name__)
+
except duplicity.errors.UserError, e:
# For user errors, don't show an ugly stack trace by
# default. But do with sufficient verbosity.
Index: duplicity/collections.py
===================================================================
RCS file: /sources/duplicity/duplicity/duplicity/collections.py,v
retrieving revision 1.41
diff -u -r1.41 collections.py
--- duplicity/collections.py 2 Apr 2009 14:47:16 -0000 1.41
+++ duplicity/collections.py 15 Apr 2009 14:35:22 -0000
@@ -30,6 +30,7 @@
from duplicity import dup_time
from duplicity import globals
from duplicity import manifest
+from duplicity.gpg import GPGError
class CollectionsError(Exception):
pass
@@ -164,8 +165,8 @@
# public key w/o secret key
try:
manifest_buffer = self.backend.get_data(self.remote_manifest_name)
- except IOError, message:
- if message.args[0] == "GnuPG exited non-zero, with code 2":
+ except GPGError, message:
+ if "secret key not available" in message.args[0]:
return None
else:
raise
Index: duplicity/gpg.py
===================================================================
RCS file: /sources/duplicity/duplicity/duplicity/gpg.py,v
retrieving revision 1.28
diff -u -r1.28 gpg.py
--- duplicity/gpg.py 2 Apr 2009 14:47:15 -0000 1.28
+++ duplicity/gpg.py 15 Apr 2009 14:35:22 -0000
@@ -147,15 +147,13 @@
return res
def gpg_failed(self):
- self.print_log(0)
- log.FatalError("GPG Failed, see log above", log.ErrorCode.gpg_failed)
-
- def print_log(self, level):
- log.Log("===== Begin GnuPG log =====", level)
+ msg = "GPG Failed, see log below:\n"
+ msg += "===== Begin GnuPG log =====\n"
self.logger_fp.seek(0)
for line in self.logger_fp:
- log.Log(line.strip(), level)
- log.Log("===== End GnuPG log =====", level)
+ msg += line.strip() + "\n"
+ msg += "===== End GnuPG log =====\n"
+ raise GPGError, msg
def close(self):
if self.encrypt:
@@ -187,7 +185,6 @@
self.gpg_process.wait()
except:
self.gpg_failed()
- self.print_log(5)
self.logger_fp.close()
self.closed = 1
signature.asc
Description: OpenPGP digital signature