python-emails icon indicating copy to clipboard operation
python-emails copied to clipboard

How to set TLS 1.2 smtp?

Open italanchan opened this issue 3 years ago • 9 comments

As the SMTP is required TLS 1.2, how to force smtp use TLS 1.2?

italanchan avatar Jan 06 '22 10:01 italanchan

I'd recommend creating custom backend class. Inherit from SMTPClientWithResponse and redefine initialize method to call starttls with custom context. Something like this: self.startls(context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)) (not tested)

lavr avatar Jan 06 '22 11:01 lavr

Can you please elaborate more here? How do you setup the custom backend? I just ran into an issue while trying to send an email with outlook's smtp server.

I'm getting some SSL versions mismatch.

mabounassif avatar Aug 05 '24 18:08 mabounassif

Hello, @mabounassif
Please provide more information about your issue and your environment. In general, for a regular connection with outlook.com, you don't need to create a custom backend. Your issue might be something else.

lavr avatar Aug 06 '24 09:08 lavr

Hello @lavr ! I've tried something like the following:

    message = emails.Message(
        subject=JinjaTemplate(subject_template),
        html=JinjaTemplate(html_template),
        mail_from=(settings.emails_from_name, settings.emails_from_email),
    )
    smtp_options = {"host": settings.smtp_host, "port": settings.smtp_port, "fail_silently": False}
    smtp_options["ssl"] = True
    smtp_options["user"] = settings.smtp_user
    smtp_options["password"] = settings.smtp_password

    # Add common template environment elements
    environment["server_host"] = settings.server_host
    environment["server_name"] = settings.server_name
    environment["server_bot"] = settings.server_bot

    response = message.send(to=email_to, render=environment, smtp=smtp_options)

Taken from https://github.com/whythawk/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/utilities/email.py

The error I'm getting is:

 File "/usr/local/lib/python3.10/site-packages/emails/message.py", line 406, in send
    return smtp.sendmail(**params)
  File "/usr/local/lib/python3.10/site-packages/emails/backend/smtp/backend.py", line 115, in sendmail
    response = send(from_addr=from_addr,
  File "/usr/local/lib/python3.10/site-packages/emails/backend/smtp/backend.py", line 80, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/emails/backend/smtp/backend.py", line 100, in _send
    response.raise_if_needed()
  File "/usr/local/lib/python3.10/site-packages/emails/backend/response.py", line 18, in raise_if_needed
    raise self._exc
emails.backend.smtp.exceptions.SMTPConnectNetworkError: [Errno 1] [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1007): None

mabounassif avatar Aug 06 '24 12:08 mabounassif

One more thing to add is that I'm using Outlook SMTP settings as specified here.

I've setup an App password for the outlook account.

mabounassif avatar Aug 06 '24 12:08 mabounassif

Running something as simple as:

import socket
import ssl

hostname = 'smtp-mail.outlook.com'
port = 587
context = ssl.create_default_context()

with socket.create_connection((hostname, port)) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())

leads to the same issue

mabounassif avatar Aug 06 '24 12:08 mabounassif

Looks like 587 is not ssl port

  ~ curl smtp://smtp-mail.outlook.com:587 -v
* Host smtp-mail.outlook.com:587 was resolved.
*   Trying 52.98.241.182:587...
* Connected to smtp-mail.outlook.com (52.98.241.182) port 587
< 220 FR0P281CA0216.outlook.office365.com Microsoft ESMTP MAIL Service ready at Tue, 6 Aug 2024 13:48:30 +0000 [08DCB5A7CDF164F5]
> EHLO lavr-macbook
< 250-FR0P281CA0216.outlook.office365.com Hello [95.165.110.17]
< 250-SIZE 157286400
< 250-PIPELINING
< 250-DSN
< 250-ENHANCEDSTATUSCODES
< 250-STARTTLS
< 250-8BITMIME
< 250-BINARYMIME
< 250-CHUNKING
< 250 SMTPUTF8
> HELP

lavr avatar Aug 06 '24 13:08 lavr

In python-email there is tls flag, set it to True to use STARTTLS And ssl flag should be False

lavr avatar Aug 06 '24 13:08 lavr

Bingo! Thank you :)

mabounassif avatar Aug 06 '24 14:08 mabounassif