summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-08-22 13:00:09 +0200
committerRuben Pollan <meskio@sindominio.net>2017-08-25 10:29:22 +0200
commit5292016becad94bfe603cdb7c4833b82ac07723a (patch)
tree832a48eee35bd00399811b832f7d8db457336652
parent7179ed5829a879c88292a8a57b59ad108a74af67 (diff)
[bug] replace content-type after removing the signature
- Resolves: #9003
-rw-r--r--src/leap/bitmask/mail/incoming/service.py9
-rw-r--r--tests/integration/mail/incoming/test_incoming_mail.py46
2 files changed, 52 insertions, 3 deletions
diff --git a/src/leap/bitmask/mail/incoming/service.py b/src/leap/bitmask/mail/incoming/service.py
index 00e7ee4f..a68adc22 100644
--- a/src/leap/bitmask/mail/incoming/service.py
+++ b/src/leap/bitmask/mail/incoming/service.py
@@ -614,6 +614,14 @@ class IncomingMail(Service):
return buf.getvalue()
def _extract_signature(self, msg):
+ """
+ Extract and return the signature from msg.
+
+ Remove the signature part from msg. For that we modify the content type
+ from multipart/signed to multipart/mixed. Even for single part messages
+ we do multipart/signed, other options will require modifying the part
+ to extract it's MIME headers and promote them into the main headers.
+ """
body = msg.get_payload(0).get_payload()
if isinstance(body, str):
@@ -621,6 +629,7 @@ class IncomingMail(Service):
detached_sig = msg.get_payload(1).get_payload()
msg.set_payload(body)
+ msg.set_type('multipart/mixed')
return detached_sig
def _decryption_error(self, failure, msg):
diff --git a/tests/integration/mail/incoming/test_incoming_mail.py b/tests/integration/mail/incoming/test_incoming_mail.py
index 3b5727e3..3dc7ca71 100644
--- a/tests/integration/mail/incoming/test_incoming_mail.py
+++ b/tests/integration/mail/incoming/test_incoming_mail.py
@@ -29,12 +29,11 @@ import uuid
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.parser import Parser
-from mock import Mock, patch, MagicMock, ANY
+from mock import Mock, patch
from twisted.internet import defer
from twisted.python import log
from twisted.logger import Logger
-from twisted.python.failure import Failure
from leap.bitmask.keymanager.errors import KeyAddressMismatch
from leap.bitmask.mail.adaptors import soledad_indexes as fields
@@ -45,7 +44,12 @@ from leap.bitmask.mail.mailbox_indexer import MailboxIndexer
from leap.bitmask.mail import utils
from leap.bitmask.mail.incoming.service import IncomingMail
-from leap.bitmask.mail.rfc3156 import MultipartEncrypted, PGPEncrypted
+from leap.bitmask.mail.rfc3156 import (
+ MultipartEncrypted,
+ PGPEncrypted,
+ MultipartSigned,
+ PGPSignature
+)
from leap.bitmask.mail.testing import KeyManagerWithSoledadTestCase
from leap.bitmask.mail.testing import ADDRESS, ADDRESS_2
from leap.soledad.common.document import SoledadDocument
@@ -323,6 +327,42 @@ subject: independence of cyberspace
d.addCallback(add_decrypted_header_called)
return d
+ def testVerifyEmail(self):
+
+ self.fetcher._add_message_locally = Mock()
+ self.fetcher._add_verified_signature_header = Mock()
+
+ def create_signed_message(sigstr):
+ message = Parser().parsestr(self.EMAIL)
+ newmsg = MultipartSigned('application/pgp-signature', 'pgp-sha512')
+ for hkey, hval in message.items():
+ newmsg.add_header(hkey, hval)
+
+ sigmsg = PGPSignature(sigstr)
+ newmsg.attach(message)
+ newmsg.attach(sigmsg)
+ return newmsg
+
+ def add_verified_signature_header_called(_):
+ self.assertTrue(self.fetcher._add_verified_signature_header.called,
+ "There were some errors with verification")
+
+ def message_added(_):
+ self.assertTrue(self.fetcher._add_message_locally.called,
+ "The message was not added to soledad")
+ _, data = self.fetcher._add_message_locally.call_args[0][0]
+ msg = Parser().parsestr(data)
+ self.assertEqual(msg.get_content_type(), 'multipart/mixed')
+
+ d = self.km.sign(self.EMAIL, ADDRESS_2)
+ d.addCallback(create_signed_message)
+ d.addCallback(
+ lambda message:
+ self._do_fetch(message.as_string()))
+ d.addCallback(add_verified_signature_header_called)
+ d.addCallback(message_added)
+ return d
+
def testLogErrorIfDecryptFails(self):
def assert_failure(_):