diff options
author | Johannes Kulick <kulick@hildensia.de> | 2012-12-13 12:16:18 +0100 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2013-02-19 10:10:07 +0000 |
commit | 8448de9d8a81225ac43f625c4bd99358e4329546 (patch) | |
tree | 46f778d0db1b6bcae9de551a828244efd118d6f4 | |
parent | 88e73d066982018fdd666e49ec33c3f81419098c (diff) |
support multiple recipients in encryption
Multiple recipient-keys can be specified. They are shown in the envelope buffer.
A new command is introduced: 'rmencrypt' do remove a key from the encryption
lsit. Unfortunately pygpgme doesn't implement __cmp__() so we have to either
write something similar on our own or use this solution (index of the key in
encryption list)
-rw-r--r-- | alot/buffers.py | 17 | ||||
-rw-r--r-- | alot/commands/envelope.py | 41 | ||||
-rw-r--r-- | alot/crypto.py | 4 | ||||
-rw-r--r-- | alot/db/envelope.py | 4 |
4 files changed, 53 insertions, 13 deletions
diff --git a/alot/buffers.py b/alot/buffers.py index 117eecce..8f344081 100644 --- a/alot/buffers.py +++ b/alot/buffers.py @@ -154,9 +154,20 @@ class EnvelopeBuffer(Buffer): if self.envelope.encrypt: description = 'Yes' - encrypt_key = self.envelope.encrypt_key - if encrypt_key is not None and len(encrypt_key.subkeys) > 0: - description += ', with key ' + encrypt_key.subkeys[0].keyid + encrypt_keys = self.envelope.encrypt_keys + if len(encrypt_keys) == 1: + description += ', with key ' + elif len(encrypt_keys) > 1: + description += ', with keys ' + first_key = True + for key in encrypt_keys: + if key is not None: + if first_key: + first_key = False + else: + description += ', ' + if len(key.subkeys) > 0: + description += key.subkeys[0].keyid lines.append(('GPG encrypt', description)) # add header list widget iff header values exists diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py index 618bdc10..af0705bc 100644 --- a/alot/commands/envelope.py +++ b/alot/commands/envelope.py @@ -453,13 +453,19 @@ class SignCommand(Command): @registerCommand(MODE, 'encrypt', forced={'action': 'encrypt'}, arguments=[ - (['keyid'], {'help': 'keyid of the key to encrypt with'})]) + (['keyids'], {'nargs':argparse.REMAINDER, + 'help': 'keyid of the key to encrypt with'})]) @registerCommand(MODE, 'unencrypt', forced={'action': 'unencrypt'}) @registerCommand(MODE, 'toggleencrypt', forced={'action': 'toggleencrypt'}, arguments=[ - (['keyid'], {'help':'keyid of the key to encrypt with'})]) + (['keyids'], {'nargs': argparse.REMAINDER, + 'help':'keyid of the key to encrypt with'})]) +@registerCommand(MODE, 'rmencrypt', forced={'action': 'rmencrypt'}, + arguments=[ + (['keyids'], {'nargs': argparse.REMAINDER, + 'help':'keyid of the key to encrypt with'})]) class EncryptCommand(Command): - def __init__(self, action=None, keyid=None, **kwargs): + def __init__(self, action=None, keyids=None, **kwargs): """ :param action: wether to encrypt/unencrypt/toggleencrypt :type action: str @@ -467,13 +473,30 @@ class EncryptCommand(Command): :type keyid: str """ - self.encrypt_key = keyid + self.encrypt_keys = keyids self.action = action Command.__init__(self, **kwargs) def apply(self, ui): envelope = ui.current_buffer.envelope - if self.action == 'encrypt': + if self.action == 'rmencrypt': + try: + for keyid in self.encrypt_keys: + # this is not so nice, but pygpgme doesn't supply a + # __cmp__() operator so list.remove(x) doesn't work + del envelope.encrypt_keys[int(keyid) - 1] + except gpgme.GpgmeError as e: + if e.code == gpgme.ERR_INV_VALUE: + raise GPGProblem("Can not find key to encrypt.") + raise GPGProblem(str(e)) + except ValueError as e: + raise Warning("Enter a the index of the key as argument to " + + "rmencrypt.") + except IndexError as e: + raise Warning("There are not so many encryption keys.") + ui.current_buffer.rebuild() + return + elif self.action == 'encrypt': encrypt = True elif self.action == 'unencrypt': encrypt = False @@ -482,7 +505,13 @@ class EncryptCommand(Command): envelope.encrypt = encrypt if encrypt: try: - envelope.encrypt_key = crypto.get_key(self.encrypt_key) + # cache all keys before appending to envelope, since otherwise + # we get an error message but all earlier keys are added, but + # not shown + keys = [] + for keyid in self.encrypt_keys: + keys.append(crypto.get_key(keyid)) + envelope.encrypt_keys.extend(keys) except gpgme.GpgmeError as e: if e.code == gpgme.ERR_INV_VALUE: raise GPGProblem("Can not find key to encrypt.") diff --git a/alot/crypto.py b/alot/crypto.py index dfa8491f..be7e83e2 100644 --- a/alot/crypto.py +++ b/alot/crypto.py @@ -153,7 +153,7 @@ def detached_signature_for(plaintext_str, key=None): return sigs, signature -def encrypt(plaintext_str, key=None): +def encrypt(plaintext_str, keys=None): """ Encrypts the given plaintext string and returns a PGP/MIME compatible string @@ -166,7 +166,7 @@ def encrypt(plaintext_str, key=None): encrypted_data = StringIO() ctx = gpgme.Context() ctx.armor = True - ctx.encrypt([key], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext_data, + ctx.encrypt(keys, gpgme.ENCRYPT_ALWAYS_TRUST, plaintext_data, encrypted_data) encrypted_data.seek(0, 0) encrypted = encrypted_data.read() diff --git a/alot/db/envelope.py b/alot/db/envelope.py index 83050d03..00f7a22f 100644 --- a/alot/db/envelope.py +++ b/alot/db/envelope.py @@ -58,7 +58,7 @@ class Envelope(object): self.sign = sign self.sign_key = sign_key self.encrypt = encrypt - self.encrypt_key = None + self.encrypt_keys = [] self.tags = tags # tags to add after successful sendout self.sent_time = None self.modified_since_sent = False @@ -214,7 +214,7 @@ class Envelope(object): try: - encrypted_str = crypto.encrypt(plaintext, self.encrypt_key) + encrypted_str = crypto.encrypt(plaintext, self.encrypt_keys) except gpgme.GpgmeError as e: raise GPGProblem(str(e)) |