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

python 3.7/3.8 compatibilty fix: need to pass host and port at init time to the SMTP session object #91

Closed
wants to merge 2 commits into from

Conversation

digiturtle
Copy link

The new version of smtplib requires an hostname at init time. Also if the mail provider uses a non-standard port (as an example, iCloud uses port 587) and the port is not passed at init time, marrow.mailer will fail with a "connection refused" error (errno 61)

@digiturtle digiturtle closed this Sep 26, 2020
@amcgregor
Copy link
Member

amcgregor commented Sep 28, 2020

The fundamental problem here appears to be within Python's standard library. The traceback is internal to Python itself:

Python 3.8.5 (default, Jul 21 2020, 10:48:26) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from smtplib import SMTP_SSL              

In [2]: conn = SMTP_SSL()                         

In [3]: conn.connect('secure.emailsrvr.com', 465) 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-0be580ca6f29> in <module>
----> 1 conn.connect('secure.emailsrvr.com', 465)

/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/smtplib.py in connect(self, host, port, source_address)
    337             self._print_debug('connect:', (host, port))
    338         sys.audit("smtplib.connect", self, host, port)
--> 339         self.sock = self._get_socket(host, port, self.timeout)
    340         self.file = None
    341         (code, msg) = self.getreply()

/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/smtplib.py in _get_socket(self, host, port, timeout)
   1040             new_socket = socket.create_connection((host, port), timeout,
   1041                     self.source_address)
-> 1042             new_socket = self.context.wrap_socket(new_socket,
   1043                                                   server_hostname=self._host)
   1044             return new_socket

/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
    498         # SSLSocket class handles server_hostname encoding before it calls
    499         # ctx._wrap_socket()
--> 500         return self.sslsocket_class._create(
    501             sock=sock,
    502             server_side=server_side,

/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
   1029             # create the SSL object
   1030             try:
-> 1031                 self._sslobj = self._context._wrap_socket(
   1032                     self, server_side, self.server_hostname,
   1033                     owner=self, session=self._session,

ValueError: server_hostname cannot be an empty string or start with a leading dot.

Is an undocumented change (with documentation linked in other PR), and differs from earlier behavior, even across majors:

Python 3.6.8 (v3.6.8:3c6b436a57, Dec 24 2018, 02:04:31) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from smtplib import SMTP_SSL
>>> conn = SMTP_SSL()
>>> conn.connect('secure.emailsrvr.com', 465)
(220, b'smtp22.relay.ord1c.emailsrvr.com ESMTP - VA Code Section 18.2-152.3:1 forbids use of this system for unsolicited bulk electronic mail (Spam)')

Python's official bug tracker would be the correct place to report this regression. I'd register an account and do so myself, however their bug tracker is, itself, bugged, and prevents participation by users with names containing non-ASCII:

Screen Shot 2020-09-27 at 22 08 38

¯_(ツ)_/¯


Edit to add a copy of the documentation links from the other PR:

There seems to be no change attributed to Python 3.5 within the documentation:

There is a deprecation in how the acceptable certificate context should be properly configured, but this does not seem to relate?

@digiturtle
Copy link
Author

digiturtle commented Sep 28, 2020 via email

@amcgregor
Copy link
Member

@digiturtle Thank you very much for your interest in the project and your attempt to help out! You've found yourself a good'un. 😉 Unfortunately, this will have to absolutely be documented, but a correction for a very specific regression in a specific version of Python isn't something that can be reasonably accounted for when the cost is sacrificing initial connection debug-ability. 🙁

If I can get my account working over there I'll see about +1'ing with a back-reference to this issue.

Thank you again!

@amcgregor amcgregor linked an issue Oct 1, 2020 that may be closed by this pull request
@amcgregor amcgregor added meta:rejected This does not seem right and/or will not be worked on. transport:smtp labels Oct 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta:rejected This does not seem right and/or will not be worked on. transport:smtp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SMTP regression and failure during TLS negotiation under Python 3.7.
3 participants