summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Kulick <kulick@hildensia.de>2012-12-13 12:16:18 +0100
committerPatrick Totzke <patricktotzke@gmail.com>2013-02-19 10:10:07 +0000
commit8448de9d8a81225ac43f625c4bd99358e4329546 (patch)
tree46f778d0db1b6bcae9de551a828244efd118d6f4
parent88e73d066982018fdd666e49ec33c3f81419098c (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.py17
-rw-r--r--alot/commands/envelope.py41
-rw-r--r--alot/crypto.py4
-rw-r--r--alot/db/envelope.py4
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))