diff options
author | Ruben Pollan <meskio@sindominio.net> | 2017-08-22 13:00:09 +0200 |
---|---|---|
committer | Ruben Pollan <meskio@sindominio.net> | 2017-08-25 10:29:22 +0200 |
commit | 5292016becad94bfe603cdb7c4833b82ac07723a (patch) | |
tree | 832a48eee35bd00399811b832f7d8db457336652 | |
parent | 7179ed5829a879c88292a8a57b59ad108a74af67 (diff) |
[bug] replace content-type after removing the signature
- Resolves: #9003
-rw-r--r-- | src/leap/bitmask/mail/incoming/service.py | 9 | ||||
-rw-r--r-- | tests/integration/mail/incoming/test_incoming_mail.py | 46 |
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(_): |