From 8b68e6dfa8036f7d146036cdb3ce2de354b66bf7 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 24 Nov 2023 18:59:31 +0000 Subject: [PATCH] preparations for TLS --- docker/rootfs/start.sh | 3 +++ example.config.ini | 6 ++++++ python/mailserver3.py | 26 ++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/docker/rootfs/start.sh b/docker/rootfs/start.sh index 03f0319..fe724da 100644 --- a/docker/rootfs/start.sh +++ b/docker/rootfs/start.sh @@ -40,6 +40,9 @@ _buildConfig() { echo "MAILPORT=${MAILPORT:-25}" echo "DISCARD_UNKNOWN=${DISCARD_UNKNOWN:-true}" echo "ATTACHMENTS_MAX_SIZE=${ATTACHMENTS_MAX_SIZE:-0}" + echo "MAILPORT_STARTTLS=${MAILPORT_STARTTLS:-0}" + echo "TLS_CERTIFICATE=${TLS_CERTIFICATE:-}" + echo "TLS_PRIVATE_KEY=${TLS_PRIVATE_KEY:-0}" echo "" echo "[DATETIME]" echo "DATEFORMAT=${DATEFORMAT:-D.M.YYYY HH:mm}" diff --git a/example.config.ini b/example.config.ini index 5949899..1a30675 100644 --- a/example.config.ini +++ b/example.config.ini @@ -31,6 +31,12 @@ URL="http://localhost:8080" ; Port that the Mailserver will run on (default 25 but that needs root) MAILPORT=25 +; TLS settings +; +; MAILPORT_STARTTLS=587 +; TLS_CERTIFICATE=/path/to/your/fullchain.pem +; TLS_PRIVATE_KEY=/path/to/your/privkey.pem + ; true or false depending on if you only want to save emails to the above set domains ; this greatly reduces the amount of spam you will receive DISCARD_UNKNOWN=true diff --git a/python/mailserver3.py b/python/mailserver3.py index f63769a..b056b43 100644 --- a/python/mailserver3.py +++ b/python/mailserver3.py @@ -1,4 +1,5 @@ import asyncio +import ssl from aiosmtpd.controller import Controller from email.parser import BytesParser from email import policy @@ -21,6 +22,9 @@ ATTACHMENTS_MAX_SIZE = 0 DOMAINS = [] LAST_CLEANUP = 0 URL = "" +MAILPORT_STARTTLS = 0 +TLS_CERTIFICATE = "" +TLS_PRIVATE_KEY = "" class CustomHandler: async def handle_DATA(self, server, session, envelope): @@ -123,6 +127,8 @@ class CustomHandler: with open("../data/"+em+"/"+filenamebase+".json", "w") as outfile: json.dump(savedata, outfile) + cleanup() + return '250 OK' def handleAttachment(self, part): @@ -173,8 +179,17 @@ def cleanup(): logger.info("Deleted file: " + filepath) async def run(port): - controller = Controller(CustomHandler(), hostname='0.0.0.0', port=port) - controller.start() + + if MAILPORT_STARTTLS > 0 and TLS_CERTIFICATE != "" and TLS_PRIVATE_KEY != "": + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.load_cert_chain(TLS_CERTIFICATE, TLS_PRIVATE_KEY) + controller_starttls = Controller(CustomHandler(), hostname='0.0.0.0', port=MAILPORT_STARTTLS, tls_context=context) + controller_starttls.start() + + controller_plaintext = Controller(CustomHandler(), hostname='0.0.0.0', port=port) + controller_plaintext.start() + + logger.info("[i] Ready to receive Emails") logger.info("") @@ -208,6 +223,13 @@ if __name__ == '__main__': if("CLEANUP" in Config.sections() and "delete_older_than_days" in Config.options("CLEANUP")): DELETE_OLDER_THAN_DAYS = (Config.get("CLEANUP", "DELETE_OLDER_THAN_DAYS").lower() == "true") + + if("mailport_starttls" in Config.options("MAILSERVER")): + MAILPORT_STARTTLS = int(Config.get("MAILSERVER", "MAILPORT_STARTTLS")) + if("tls_certificate" in Config.options("MAILSERVER")): + TLS_CERTIFICATE = Config.get("MAILSERVER", "TLS_CERTIFICATE") + if("tls_private_key" in Config.options("MAILSERVER")): + TLS_PRIVATE_KEY = Config.get("MAILSERVER", "TLS_PRIVATE_KEY") logger.info("[i] Starting Mailserver on port " + str(port)) logger.info("[i] Discard unknown domains: " + str(DISCARD_UNKNOWN))