Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to connect to aiosmtpd server using TLS v1.1 ? #459

Open
cnicodeme opened this issue May 16, 2024 · 0 comments
Open

Unable to connect to aiosmtpd server using TLS v1.1 ? #459

cnicodeme opened this issue May 16, 2024 · 0 comments

Comments

@cnicodeme
Copy link
Contributor

Hi!

I'm trying to set up an Aiosmtpd server to accept TLS1.1 too, and I can't make it work. Regardless of how I configure TLSContext, the server only accepts TLS1.2.

Here's a reproducible code to show the issue:

# Server:

from aiosmtpd.controller import Controller
from aiosmtpd.smtp import SMTP
from aiosmtpd.handlers import Debugging
import ssl, certifi, signal


class CustomController(Controller):
    def factory(self):
        context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=certifi.where())
        context.set_ciphers('HIGH:MEDIUM:!LOW:!DHE')
        context.set_ecdh_curve("secp384r1")
        context.options |= ssl.OP_NO_SSLv2
        context.options |= ssl.OP_NO_SSLv3
        context.options |= ssl.PROTOCOL_TLSv1
        context.options |= ssl.PROTOCOL_TLSv1_1
        context.options |= ssl.PROTOCOL_TLSv1_2
        context.options |= ssl.PROTOCOL_TLSv1_3

        context.minimum_version = ssl.TLSVersion.TLSv1
        context.maximum_version = ssl.TLSVersion.TLSv1_3

        base_path = '/etc/letsencrypt/live/smtp.server.com'
        context.load_cert_chain(
            '{}/fullchain.pem'.format(base_path),
            '{}/privkey.pem'.format(base_path)
        )  # via Let's Encrypt

        return SMTP(
            handler=self.handler,
            ident="Welcome.",
            tls_context=context,
        )


if __name__ == '__main__':
    controller = CustomController(Debugging(), hostname="localhost", port=2525)

    # Run the event loop in a separate thread.
    controller.start()
    print("Daemong started. Waiting for SIGINT or SIGQUIT to quit.")
    sig = signal.sigwait([signal.SIGINT, signal.SIGQUIT])
    print("Quitting SMTP Daemon")
    controller.stop()

The above configured context should accept TLSv1 up to TLSv1_3.

Now, here's a client, that only have TLS1.1 enabled:

import smtplib, ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.minimum_version = ssl.TLSVersion.TLSv1_1
context.maximum_version = ssl.TLSVersion.TLSv1_1

smtp = smtplib.SMTP('127.0.0.1', port='2525')
print(smtp.ehlo('client'))

try:
    print(smtp.starttls(context=context))
    print(smtp.sock.cipher())
    print(smtp.sock.version())
    print(smtp.ehlo('client'))
    print(smtp.quit())
except OSError as e:
    print(e)
    print(smtp.quit())

The exchange fails with the following SSL error:

[SSL: NO_PROTOCOLS_AVAILABLE] no protocols available (_ssl.c:1000)
Traceback (most recent call last):
  File "/home/user/st.py", line 23, in <module>
    print(smtp.starttls(context=context))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/smtplib.py", line 779, in starttls
    self.sock = context.wrap_socket(self.sock,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/ssl.py", line 1042, in _create
    self.do_handshake()
  File "/usr/lib64/python3.12/ssl.py", line 1320, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: NO_PROTOCOLS_AVAILABLE] no protocols available (_ssl.c:1000)

=> NO_PROTOCOLS_AVAILABLE

Why is that? Am I missing something? An option to enable to allow more than TLS1.2 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant