diff --git a/gpg-mailgate.py b/gpg-mailgate.py index fe49bb8..acf6a93 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -43,6 +43,7 @@ if missing_params: try: +delivered = False # Read e-mail from stdin, parse it raw = sys.stdin.read() raw_message = email.message_from_string(raw, policy=SMTPUTF8) @@ -55,6 +56,12 @@ try: process_t = (time.process_time() - start) * 1000 LOG.info("Message delivered in {process:.2f} ms".format(process=process_t)) + delivered = True except: LOG.exception('Could not handle message') + +if not delivered: + # It seems we weren't able to deliver the message. In case it was some + # silly message-encoding issue that shouldn't bounce the message, we just + # try recoding the message body and delivering it. core.failover_delivery(raw_message, to_addrs) diff --git a/lacre/core.py b/lacre/core.py index e26e8a8..99c2d26 100644 --- a/lacre/core.py +++ b/lacre/core.py @@ -578,13 +578,9 @@ def send_msg(message: str, recipients, fromaddr=None): if recipients: LOG.info(f"Sending email to: {recipients!r}") relay = conf.relay_params() - LOG.debug('Got relay parameters: %s', relay) smtp = smtplib.SMTP(relay[0], relay[1]) - LOG.debug('have session') if conf.flag_enabled('relay', 'starttls'): - LOG.debug('Issuing STARTTLS') smtp.starttls() - LOG.debug('sending') smtp.sendmail(from_addr, recipients, message) else: LOG.info("No recipient found") @@ -601,30 +597,37 @@ def send_msg_bytes(message: bytes, recipients, fromaddr=None): if recipients: LOG.info(f"Sending email to: {recipients!r}") relay = conf.relay_params() - LOG.debug('Got relay parameters: %s', relay) smtp = smtplib.SMTP(relay[0], relay[1]) - LOG.debug('have session') if conf.flag_enabled('relay', 'starttls'): - LOG.debug('Issuing STARTTLS') smtp.starttls() - LOG.debug('sending') smtp.sendmail(from_addr, recipients, message) else: LOG.info("No recipient found") +def _recode(m: EmailMessage): + payload = m.get_payload() + m.set_content(payload) + + def failover_delivery(message: EmailMessage, recipients): """Try delivering message just one last time.""" LOG.debug('Failover delivery') + if message.get_content_maintype() == 'text': - LOG.debug('Re-packing message content of: %s', message) - message.set_content(message.get_payload()) + LOG.debug('Flat text message, adjusting coding') + _recode(message) + b = message.as_bytes(policy=SMTPUTF8) + send_msg_bytes(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) - LOG.debug('Sending... %s', b) send_msg_bytes(b, recipients) - LOG.debug('Sent!') else: - LOG.warning('No failover strategy') + LOG.warning('No failover strategy, giving up') def _is_encrypted(raw_message: EmailMessage):