aiosmtpd icon indicating copy to clipboard operation
aiosmtpd copied to clipboard

Allow setting ssl_handshake_timeout on a Controller

Open bebleo opened this issue 4 years ago • 0 comments
trafficstars

The 60 seconds default timeout in sslproto.SSLProto for the SSL handshake to complete is longer than necessary for many scenarios (e.g. testing against a local SMTP server) with aiosmtpd.

If a client does not complete the SSL handshake the current behaviour is that the connection will close after the ssl_handshake_timeout of 60 seconds on python 3.7 and later. This raises a smtplib.SMTPServerDisconnected exception. The following test (which assumes that it is included in test_smtps.py) is an example of triggering this using the smtplib.SMTP client (which never completes the handshake):

# in ./aiosmtpd/tests/test_smtps.py

@pytest.mark.skipif(sys.version_info < (3, 7),
                    reason="SSL timeout implemented implemented with 3.7")
def test_SSL_timeout(self, ssl_controller):
    with pytest.raises(SMTPServerDisconnected) as ex,\
         SMTP(*Global.SrvAddr) as smtp_client:
        # smtplib.SMTP does not support opporutnistic SSL so the SSL
        # handshake never completes. On Python 3.6 and earlier this means
        # that the connection will hang.
        smtp_client.helo("example.com")
    assert "Connection unexpectedly closed" in str(ex)

To partially mitigate the effect of this the ssl_handshake_timeout parameter on the loop.create_server() can be set to a shorter time in environments that don't need the full minute to complete. Unfortunately this is available only as of python 3.7; I have been unable to find a reasonable solution that would work for python 3.6.

My proposal is:

  • Add a parameter to the Controller classes for the ssl_handshake_timeout that is passed to loop.create_server() if using python 3.7 or later.
  • Use the same timeout for STARTTLS on python 3.7 or later.
  • Warn on python 3.6 (or earlier for completeness even if not supported) that this has no effect.
  • Do not add an argument for the SSL handshake timeout to the CLI until python 3.6 support is dropped from aiosmtpd at some point in the future.

bebleo avatar May 12 '21 09:05 bebleo