summaryrefslogtreecommitdiff
path: root/obnamlib/encryption.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2011-03-27 13:29:35 +0100
committerLars Wirzenius <liw@liw.fi>2011-03-27 13:29:35 +0100
commit3215d90e59b2a99f53a11e4f6b9614d6a63c2326 (patch)
treef30126a2afd499a0e4d96e9cbc38695c1441d557 /obnamlib/encryption.py
parentf4b6df3ec38a428e4320139c681e3b2e08cab347 (diff)
downloadobnam-3215d90e59b2a99f53a11e4f6b9614d6a63c2326.tar.gz
Add a Keyring class.
Diffstat (limited to 'obnamlib/encryption.py')
-rw-r--r--obnamlib/encryption.py70
1 files changed, 67 insertions, 3 deletions
diff --git a/obnamlib/encryption.py b/obnamlib/encryption.py
index 7ddc9760..8adc26de 100644
--- a/obnamlib/encryption.py
+++ b/obnamlib/encryption.py
@@ -15,6 +15,7 @@
import os
+import shutil
import subprocess
import tempfile
@@ -90,7 +91,7 @@ def decrypt_with_symmetric_key(encrypted, key):
return _gpg_pipe(['-d'], encrypted, key)
-def _gpg(args, gpghome=None):
+def _gpg(args, stdin='', gpghome=None):
'''Run gpg and return its output.'''
env = dict()
@@ -98,10 +99,10 @@ def _gpg(args, gpghome=None):
if gpghome is not None:
env['GNUPGHOME'] = gpghome
- argv = ['gpg', '-q', '--batch'] + args
+ argv = ['gpg', '-q', '--no-tty', '--batch'] + args
p = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env)
- out, err = p.communicate('')
+ out, err = p.communicate(stdin)
# Return output data, or deal with errors.
if p.returncode: # pragma: no cover
@@ -114,3 +115,66 @@ def get_public_key(keyid, gpghome=None):
'''Return the ASCII armored export form of a given public key.'''
return _gpg(['--export', '--armor', keyid], gpghome=gpghome)
+
+
+class Keyring(object):
+
+ '''A simplistic representation of GnuPG keyrings.
+
+ Just enough functionality for obnam's purposes.
+
+ '''
+
+ def __init__(self, encoded=''):
+ self._encoded = encoded
+ self._gpghome = None
+
+ def _setup(self):
+ self._gpghome = tempfile.mkdtemp()
+ f = open(self._pubring, 'wb')
+ f.write(self._encoded)
+ f.close()
+
+ def _cleanup(self):
+ shutil.rmtree(self._gpghome)
+ self._gpghome = None
+
+ @property
+ def _pubring(self):
+ return os.path.join(self._gpghome, 'pubring.gpg')
+
+ def keyids(self):
+ self._setup()
+ output = _gpg(['--list-keys', '--with-colons'], gpghome=self._gpghome)
+ self._cleanup()
+
+ keyids = []
+ for line in output.splitlines():
+ fields = line.split(':')
+ if len(fields) >= 5 and fields[0] == 'pub':
+ keyids.append(fields[4])
+ return keyids
+
+ def __str__(self):
+ return self._encoded
+
+ def __contains__(self, keyid):
+ return keyid in self.keyids()
+
+ def _reread_pubring(self):
+ f = open(self._pubring, 'rb')
+ self._encoded = f.read()
+ f.close()
+
+ def add(self, key):
+ self._setup()
+ _gpg(['--import'], stdin=key, gpghome=self._gpghome)
+ self._reread_pubring()
+ self._cleanup()
+
+ def remove(self, keyid):
+ self._setup()
+ _gpg(['--delete-key', '--yes', keyid], gpghome=self._gpghome)
+ self._reread_pubring()
+ self._cleanup()
+