How do I properly support STARTTLS with aiosmtpd?

Viewed 1987

I have the following server taken almost directly from the aiosmtpd docs:

import asyncio
import ssl
from aiosmtpd.controller import Controller


class ExampleHandler:
    async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
        if not address.endswith('@example.com'):
            return '550 not relaying to that domain'
        envelope.rcpt_tos.append(address)
        return '250 OK'

    async def handle_DATA(self, server, session, envelope):
        print(f'Message from {envelope.mail_from}')
        print(f'Message for {envelope.rcpt_tos}')
        print(f'Message data:\n{envelope.content.decode("utf8", errors="replace")}')
        print('End of message')
        return '250 Message accepted for delivery'

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
controller = Controller(ExampleHandler(), port=8026, ssl_context=context)
controller.start()

input('Press enter to stop')
controller.stop()

However, when I start this server and try to send an email to it using swaks:

echo 'Testing' | swaks --to wayne@example.com --from "something@example.org" --server localhost --port 8026 -tls

It times out after 30s. If I remove the ssl_context=context from the server and -tls from the client then it sends the mail fine.

Additionally, when I try to connect via telnet and just send EHLO whatever then the server actually closes the connection.

What's the correct way to implement an aiosmtpd server that supports tls?

2 Answers
Related