summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Boeckel <mathstuf@gmail.com>2015-09-25 01:37:54 -0400
committerLars Wirzenius <liw@liw.fi>2015-10-11 11:42:02 +0300
commit8cbd118637941e9d2621cb248ffd1ed3f7905413 (patch)
tree7b2a0c4e51b0d6d10962afab656ac1f17281c26b
parent88363ebc8e1f01c7179811da7a11b8ff2b5cd9bb (diff)
downloadobnam-8cbd118637941e9d2621cb248ffd1ed3f7905413.tar.gz
encryption_plugin: add a gnupghome configuration option
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
-rw-r--r--obnam.1.in5
-rw-r--r--obnamlib/plugins/encryption_plugin.py27
-rw-r--r--yarns/0060-encryption.yarn16
-rw-r--r--yarns/9000-implements.yarn26
4 files changed, 68 insertions, 6 deletions
diff --git a/obnam.1.in b/obnam.1.in
index 08ca79a8..8a2de45f 100644
--- a/obnam.1.in
+++ b/obnam.1.in
@@ -426,6 +426,11 @@ and then tell
about it using the
.B \-\-encrypt\-with
option.
+You may optionally use a separate home directory using the
+.B \-\-gnupghome
+option. By default, the default directory for
+.BR gpg(1)
+will be used.
.SS "Configuration files"
.B obnam
will look for configuration files in a number of locations.
diff --git a/obnamlib/plugins/encryption_plugin.py b/obnamlib/plugins/encryption_plugin.py
index ec3bccab..8c8eecf3 100644
--- a/obnamlib/plugins/encryption_plugin.py
+++ b/obnamlib/plugins/encryption_plugin.py
@@ -49,6 +49,12 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
'size of symmetric key, in bits',
metavar='BITS',
group=encryption_group)
+ self.app.settings.string(
+ ['gnupghome'],
+ 'home directory for GPG',
+ metavar='HOMEDIR',
+ group=encryption_group,
+ default=None)
self.tag = "encrypt1"
@@ -87,7 +93,8 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
@property
def pubkey(self):
if self._pubkey is None:
- self._pubkey = obnamlib.get_public_key(self.keyid)
+ self._pubkey = obnamlib.get_public_key(self.keyid,
+ gpghome=self.gnupghome)
return self._pubkey
@property
@@ -98,6 +105,10 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
return '/dev/random'
@property
+ def gnupghome(self):
+ return self.app.settings['gnupghome']
+
+ @property
def symmetric_key_bits(self):
return int(self.app.settings['symmetric-key-bits'] or '256')
@@ -127,19 +138,22 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
def filter_read(self, encrypted, repo, toplevel):
symmetric_key = self.get_symmetric_key(repo, toplevel)
- return obnamlib.decrypt_symmetric(encrypted, symmetric_key)
+ return obnamlib.decrypt_symmetric(encrypted, symmetric_key,
+ gpghome=self.gnupghome)
def filter_write(self, cleartext, repo, toplevel):
if not self.keyid:
return cleartext
symmetric_key = self.get_symmetric_key(repo, toplevel)
- return obnamlib.encrypt_symmetric(cleartext, symmetric_key)
+ return obnamlib.encrypt_symmetric(cleartext, symmetric_key,
+ gpghome=self.gnupghome)
def get_symmetric_key(self, repo, toplevel):
key = self._symkeys.get(repo, toplevel)
if key is None:
encoded = repo.get_fs().cat(os.path.join(toplevel, 'key'))
- key = obnamlib.decrypt_with_secret_keys(encoded)
+ key = obnamlib.decrypt_with_secret_keys(encoded,
+ gpghome=self.gnupghome)
self._symkeys.put(repo, toplevel, key)
return key
@@ -222,7 +236,8 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
def _get_key_string(self, keyid):
verbose = self.app.settings['key-details']
if verbose:
- user_ids = obnamlib.get_public_key_user_ids(keyid)
+ user_ids = obnamlib.get_public_key_user_ids(keyid,
+ gpghome=self.gnupghome)
if user_ids:
return "%s (%s)" % (keyid, ", ".join(user_ids))
return str(keyid)
@@ -260,7 +275,7 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
self.app.settings.require('keyid')
repo = self.app.get_repository_object()
keyid = self.app.settings['keyid']
- key = obnamlib.get_public_key(keyid)
+ key = obnamlib.get_public_key(keyid, gpghome=self.gnupghome)
clients = self._find_clientdirs(repo, args)
for toplevel in repo.get_shared_directories() + clients:
self.add_to_userkeys(repo, toplevel, key)
diff --git a/yarns/0060-encryption.yarn b/yarns/0060-encryption.yarn
index acbade88..6985f1ff 100644
--- a/yarns/0060-encryption.yarn
+++ b/yarns/0060-encryption.yarn
@@ -46,6 +46,22 @@ that encryption is done at the I/O abstraction level.
AND user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M
+Keys provided by a custom directory
+-----------------------------------
+
+We'll make a simple backup and restore using encryption. If this
+works, we can probably assume that any other normal repository
+operations (those not part of encryption management) also work, given
+that encryption is done at the I/O abstraction level.
+
+ SCENARIO encrypted backup and restore with a separate keyring
+ GIVEN user U separately uses encryption key "Test Key One" from test-data/keyring-1
+ AND 128kB of new data in directory L
+ AND a manifest of L in M
+ WHEN user U backs up directory L to repository R
+ AND user U restores their latest generation in repository R into X
+ THEN L, restored to X, matches manifest M
+
Adding and removing keys to clients
-----------------------------------
diff --git a/yarns/9000-implements.yarn b/yarns/9000-implements.yarn
index 204611cf..4a03f3d8 100644
--- a/yarns/9000-implements.yarn
+++ b/yarns/9000-implements.yarn
@@ -231,6 +231,32 @@ use. We store that.
add_to_config "$MATCH_1" encrypt-with "$MATCH_2"
+Scenarios involving encryption may also use a private keyring directory.
+
+ IMPLEMENTS GIVEN user (\S+) separately uses encryption key "(.*)" from (\S+)
+ if [ ! -e "$DATADIR/$MATCH_1.gnupg" ]
+ then
+ mkdir "$DATADIR/$MATCH_1.gnupg"
+ cp -a "$SRCDIR/$MATCH_3/." "$DATADIR/$MATCH_1.gnupg/."
+ add_to_config "$MATCH_1" gnupghome "$DATADIR/$MATCH_1.gnupg"
+ else
+ # Export public and secret keys from new keyring.
+ export GNUPGHOME="$SRCDIR/$MATCH_3"
+ gpg --export "$MATCH_2" > "$DATADIR/public.key"
+ gpg --export-secret-keys "$MATCH_2" > "$DATADIR/secret.key"
+
+ # Import into the keyring uses for tests.
+ export GNUPGHOME="$DATADIR/$MATCH_1.gnupg"
+ gpg --import "$DATADIR/public.key"
+ gpg --import "$DATADIR/secret.key"
+
+ # Use the configuration rather than the environment.
+ add_to_config "$MATCH_1" gnupghome "$GNUPGHOME"
+ unset GNUPGHOME
+ fi
+
+ add_to_config "$MATCH_1" encrypt-with "$MATCH_2"
+
Encryption scenarions, at least, also need users that pretend to be
someone else.