Compare commits

...

8 commits
main ... main

5 changed files with 25 additions and 25 deletions

View file

@ -52,15 +52,15 @@ def main():
to_addrs = sys.argv[1:]
# Read e-mail from stdin, parse it
raw = sys.stdin.read()
raw_message = email.message_from_string(raw, policy=SMTPUTF8)
raw = sys.stdin.buffer.read()
raw_message = email.message_from_bytes(raw, policy=SMTPUTF8)
from_addr = raw_message['From']
lmessage = LazyMessage(to_addrs, lambda: raw_message)
lmessage = LazyMessage(to_addrs, lambda: raw)
try:
# Let's start
core.deliver_message(raw_message, from_addr, to_addrs)
core.deliver_message(lmessage, from_addr, to_addrs)
delivered = True
except:
LOG.exception('Could not handle message')
@ -71,7 +71,7 @@ def main():
# message, we just try recoding the message body and delivering it.
try:
from_addr = raw_message['From']
core.failover_delivery(raw_message, to_addrs, from_addr)
core.failover_delivery(lmessage, to_addrs, from_addr)
except:
LOG.exception('Failover delivery failed too')

View file

@ -11,7 +11,7 @@ class KeyCache:
With keyring_dir given, set location of the directory from which keys should be loaded.
"""
self._keys = keys
self._keys = { fpr: eml.upper() for (fpr, eml) in keys.items() }
def __getitem__(self, fingerpring):
"""Look up email assigned to the given fingerprint."""
@ -29,7 +29,7 @@ class KeyCache:
def has_email(self, email):
"""Check if cache contains a key assigned to the given email."""
return email in self._keys.values()
return email.upper() in self._keys.values()
def __repr__(self):
"""Return text representation of this object."""

View file

@ -323,25 +323,14 @@ def _recode(m: EmailMessage):
m.set_content(payload)
def failover_delivery(message: EmailMessage, recipients, from_address):
def failover_delivery(lmessage: LazyMessage, recipients, from_address):
"""Try delivering message just one last time."""
LOG.debug('Failover delivery')
send = SendFrom(from_address)
if message.get_content_maintype() == 'text':
LOG.debug('Flat text message, adjusting coding')
_recode(message)
b = message.as_bytes(policy=SMTPUTF8)
send(b, recipients)
elif message.get_content_maintype() == 'multipart':
LOG.debug('Multipart message, adjusting coding of text entities')
for part in message.iter_parts():
if part.get_content_maintype() == 'text':
_recode(part)
b = message.as_bytes(policy=SMTPUTF8)
send(b, recipients)
else:
LOG.warning('No failover strategy, giving up')
orig = lmessage.get_original_content()
send(orig, recipients)
def _is_encrypted(raw_message: EmailMessage, lmessage: LazyMessage = None):
@ -383,11 +372,13 @@ def delivery_plan(recipients, message: EmailMessage, key_cache: kcache.KeyCache,
return plan
def deliver_message(raw_message: EmailMessage, from_address, to_addrs):
def deliver_message(message: LazyMessage, from_address, to_addrs):
"""Send RAW_MESSAGE to all TO_ADDRS using the best encryption method available."""
# Ugly workaround to keep the code working without too many changes.
register_sender(from_address)
raw_message = message.get_message()
sanitize = text.choose_sanitizer(conf.get_item('default', 'mail_case_insensitive'))
recipients_left = [sanitize(recipient) for recipient in to_addrs]
@ -413,5 +404,5 @@ def deliver_message(raw_message: EmailMessage, from_address, to_addrs):
return
# Send out mail to recipients which are left
LOG.debug("Sending the rest as text/plain")
LOG.debug("Sending the rest as cleartext")
send(raw_message.as_bytes(policy=SMTPUTF8), recipients_left)

View file

@ -110,7 +110,7 @@ class AdvancedMailFilterE2ETest(unittest.TestCase):
self._execute_case(self.config, case_name=case_name)
def _execute_case(self, config, case_name):
logging.info(f"Executing case {case_name}")
logging.info("Executing case %s", case_name)
python = os.getenv("PYTHON", "python")
relay_mock = _spawn([python, "test/utils/relay.py", "2500"])

View file

@ -18,3 +18,12 @@ class LacreKeyCacheTest(unittest.TestCase):
self.assertTrue(kc.has_email('bob@example.com'))
self.assertFalse(kc.has_email('dave@example.com'))
def test_case_insensitivity(self):
kc = KeyCache({
'FINGERPRINT': 'alice@example.com',
'OTHERPRINT': 'bob@example.com',
})
self.assertTrue(kc.has_email('Alice@example.com'))
self.assertTrue(kc.has_email('BOB@EXAMPLE.COM'))