1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8__metaclass__ = type 9 10import asyncore 11import os.path 12import ssl 13import sys 14 15# Handle TLS and non-TLS support 16try: 17 import smtpd_tls 18 HAS_TLS = True 19except ImportError: 20 import smtpd 21 HAS_TLS = False 22 print('Library smtpd-tls is missing or not supported, hence starttls is NOT supported.') 23 24# Handle custom ports 25port = '25:465' 26if len(sys.argv) > 1: 27 port = sys.argv[1] 28ports = port.split(':') 29if len(ports) > 1: 30 port1, port2 = int(ports[0]), int(ports[1]) 31else: 32 port1, port2 = int(port), None 33 34# Handle custom certificate 35basename = os.path.splitext(sys.argv[0])[0] 36certfile = basename + '.crt' 37if len(sys.argv) > 2: 38 certfile = sys.argv[2] 39 40# Handle custom key 41keyfile = basename + '.key' 42if len(sys.argv) > 3: 43 keyfile = sys.argv[3] 44 45try: 46 ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) 47except AttributeError: 48 ssl_ctx = None 49 if HAS_TLS: 50 print('Python ssl library does not support SSLContext, hence starttls and TLS are not supported.') 51 import smtpd 52 53if HAS_TLS and ssl_ctx is not None: 54 print('Using %s and %s' % (certfile, keyfile)) 55 ssl_ctx.load_cert_chain(certfile=certfile, keyfile=keyfile) 56 57 print('Start SMTP server on port', port1) 58 smtp_server1 = smtpd_tls.DebuggingServer(('127.0.0.1', port1), None, ssl_ctx=ssl_ctx, starttls=True) 59 if port2: 60 print('Start TLS SMTP server on port', port2) 61 smtp_server2 = smtpd_tls.DebuggingServer(('127.0.0.1', port2), None, ssl_ctx=ssl_ctx, starttls=False) 62else: 63 print('Start SMTP server on port', port1) 64 smtp_server1 = smtpd.DebuggingServer(('127.0.0.1', port1), None) 65 if port2: 66 print('WARNING: TLS is NOT supported on this system, not listening on port %s.' % port2) 67 68asyncore.loop() 69