Merge pull request 'Fix unencrypted delivery' (#144) from v0.2_unencrypted-delivery-fix into main
Reviewed-on: #144
This commit is contained in:
commit
ccfaa39501
3 changed files with 36 additions and 17 deletions
|
@ -143,6 +143,11 @@ def strict_mode():
|
|||
return ("default" in cfg and cfg["default"]["enc_keymap_only"] == "yes")
|
||||
|
||||
|
||||
def should_log_headers() -> bool:
|
||||
"""Check if Lacre should log message headers."""
|
||||
return flag_enabled('daemon', 'log_headers')
|
||||
|
||||
|
||||
class FromStrMixin:
|
||||
"""Additional operations for configuration enums."""
|
||||
|
||||
|
|
|
@ -42,9 +42,6 @@ class MailEncryptionProxy:
|
|||
if message.defects:
|
||||
LOG.warning("Issues found: %d; %s", len(message.defects), repr(message.defects))
|
||||
|
||||
if conf.flag_enabled('daemon', 'log_headers'):
|
||||
LOG.info('Message headers: %s', self._extract_headers(message))
|
||||
|
||||
send = xport.SendFrom(envelope.mail_from)
|
||||
for operation in gate.delivery_plan(envelope.rcpt_tos, message, keys):
|
||||
LOG.debug(f"Sending mail via {operation!r}")
|
||||
|
@ -55,21 +52,24 @@ class MailEncryptionProxy:
|
|||
# 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):
|
||||
self._send_unencrypted(operation, message, envelope, send)
|
||||
self._send_unencrypted(operation, envelope, send)
|
||||
else:
|
||||
LOG.exception('Cannot perform: %s', operation)
|
||||
raise
|
||||
|
||||
except:
|
||||
LOG.exception('Unexpected exception caught, bouncing message')
|
||||
return xport.RESULT_ERROR
|
||||
|
||||
if conf.should_log_headers():
|
||||
LOG.error('Erroneous message headers: %s', self._beginning(envelope))
|
||||
|
||||
return xport.RESULT_ERRORR
|
||||
|
||||
return xport.RESULT_OK
|
||||
|
||||
def _send_unencrypted(self, operation, message, envelope, send: xport.SendFrom):
|
||||
keep = KeepIntact(operation.recipients())
|
||||
new_message = keep.perform(message)
|
||||
send(new_message, operation.recipients())
|
||||
def _send_unencrypted(self, operation, envelope, send: xport.SendFrom):
|
||||
# Do not parse and re-generate the message, just send it as it is.
|
||||
send(envelope.original_content, operation.recipients())
|
||||
|
||||
def _beginning(self, e: Envelope) -> bytes:
|
||||
double_eol_pos = e.original_content.find(DOUBLE_EOL_BYTES)
|
||||
|
@ -80,13 +80,6 @@ class MailEncryptionProxy:
|
|||
end = min(limit, 2560)
|
||||
return e.original_content[0:end]
|
||||
|
||||
def _extract_headers(self, message: email.message.Message):
|
||||
return {
|
||||
'mime' : message.get_content_type(),
|
||||
'charsets' : message.get_charsets(),
|
||||
'cte' : message['Content-Transfer-Encoding']
|
||||
}
|
||||
|
||||
def _seconds_between(self, start_ms, end_ms) -> float:
|
||||
return (end_ms - start_ms) * 1000
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ documentation.
|
|||
import email
|
||||
import email.mime.multipart
|
||||
from email.message import EmailMessage
|
||||
from email.policy import SMTP
|
||||
from email.policy import SMTP, SMTPUTF8
|
||||
from email.errors import HeaderParseError
|
||||
|
||||
import unittest
|
||||
from configparser import RawConfigParser
|
||||
|
@ -165,6 +166,26 @@ class EmailParsingTest(unittest.TestCase):
|
|||
self.assertIsInstance(payload, str)
|
||||
self.assertTrue(message_boundary in payload)
|
||||
|
||||
def test_fail_if_message_id_parsing_is_fixed(self):
|
||||
# Unfortunately, Microsoft sends messages with Message-Id header values
|
||||
# that email parser can't process.
|
||||
#
|
||||
# Bug: https://github.com/python/cpython/issues/105802
|
||||
# Fix: https://github.com/python/cpython/pull/108133
|
||||
|
||||
rawmsg = b"From: alice@lacre.io\r\n" \
|
||||
+ b"To: bob@lacre.io\r\n" \
|
||||
+ b"Subject: Test message\r\n" \
|
||||
+ b"Content-Type: text/plain\r\n" \
|
||||
+ b"Content-Transfer-Encoding: base64\r\n" \
|
||||
+ b"Message-Id: <[yada-yada-yada@microsoft.com]>\r\n" \
|
||||
+ b"\r\n" \
|
||||
+ b"SGVsbG8sIFdvcmxkIQo=\r\n"
|
||||
|
||||
msg = email.message_from_bytes(rawmsg, policy=SMTPUTF8)
|
||||
self.assertEqual(len(msg.defects), 0)
|
||||
self.assertRaises(IndexError, lambda: msg['Message-Id'])
|
||||
|
||||
|
||||
class EmailTest(unittest.TestCase):
|
||||
def test_boundary_generated_after_as_string_call(self):
|
||||
|
|
Loading…
Reference in a new issue