Deliver cleartext if Unicode encoding or message serialisation fail

This commit is contained in:
Piotr F. Mieszkowski 2024-03-02 18:36:41 +01:00
parent 3138864d32
commit 110ea885f2
Signed by: pfm
GPG Key ID: BDE5BC1FA5DC53D5
4 changed files with 17 additions and 6 deletions

View File

@ -40,7 +40,7 @@ import lacre.keyring as kcache
import lacre.recipients as recpt
import lacre.smime as smime
from lacre.transport import send_msg, register_sender, SendFrom
from lacre.mailop import KeepIntact, InlineOpenPGPEncrypt, MimeOpenPGPEncrypt
from lacre.mailop import KeepIntact, InlineOpenPGPEncrypt, MimeOpenPGPEncrypt, MailSerialisationException
LOG = logging.getLogger(__name__)
@ -127,7 +127,10 @@ def _gpg_encrypt_copy(message: EmailMessage, keys, recipients, encrypt_f):
def _gpg_encrypt_to_bytes(message: EmailMessage, keys, recipients, encrypt_f) -> bytes:
msg_copy = _gpg_encrypt_copy(message, keys, recipients, encrypt_f)
return msg_copy.as_bytes(policy=SMTPUTF8)
try:
return msg_copy.as_bytes(policy=SMTPUTF8)
except IndexError:
raise MailSerialisationException()
def _gpg_encrypt_to_str(message: EmailMessage, keys, recipients, encrypt_f) -> str:

View File

@ -22,7 +22,7 @@ from GnuPG import EncryptionException
import lacre.core as gate
import lacre.keyring as kcache
import lacre.transport as xport
from lacre.mailop import KeepIntact
from lacre.mailop import KeepIntact, MailSerialisationException
class MailEncryptionProxy:
@ -48,7 +48,7 @@ class MailEncryptionProxy:
try:
new_message = operation.perform(message)
send(new_message, operation.recipients())
except EncryptionException as e:
except (EncryptionException, MailSerialisationException, UnicodeEncodeError) as e:
# If the message can't be encrypted, deliver cleartext.
LOG.error('Unable to encrypt message, delivering in cleartext: %s', e)
if not isinstance(operation, KeepIntact):

View File

@ -22,6 +22,11 @@ from email.policy import SMTP, SMTPUTF8
LOG = logging.getLogger(__name__)
class MailSerialisationException(BaseException):
"""We can't turn an EmailMessage into sequence of bytes."""
pass
class MailOperation:
"""Contract for an operation to be performed on a message."""
@ -124,7 +129,10 @@ class KeepIntact(MailOperation):
def perform(self, message: Message) -> bytes:
"""Return MESSAGE unmodified."""
return message.as_bytes(policy=SMTPUTF8)
try:
return message.as_bytes(policy=SMTPUTF8)
except IndexError as e:
raise MailSerialisationException(e)
def __repr__(self):
"""Return representation with just method and email."""

View File

@ -33,6 +33,6 @@ class ExecutionTimeLoggerTest(unittest.TestCase):
self.assertEqual(handler.logged_records[1], 'Doing something')
# Exception record should include the timing result and the traceback...
self.assertRegex(handler.logged_records[2], '^Just a test took 0 ms, raised exception\nTraceback.*')
self.assertRegex(handler.logged_records[2], '^Just a test took \\d ms, raised exception\nTraceback.*')
# ...as well as the original exception
self.assertRegex(handler.logged_records[2], 'Exception: this is a test$')