marrow / mailer

A light-weight, modular, message representation and mail delivery framework for Python.
MIT License
279 stars 62 forks source link

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

Closed digiturtle closed 3 years ago

digiturtle commented 3 years ago

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)

amcgregor commented 3 years ago

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 commented 3 years ago

I was going to report it, but it seems it’s already been reported:

https://bugs.python.org/issue36094 https://bugs.python.org/issue36094

and in the “patch review” stage

Will wait and see if either in 3.8.6 or in 3.9 will be fixed

Thanks

Il giorno 28 set 2020, alle ore 04:09, Alice Zoë Bevan–McGregor notifications@github.com ha scritto:

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)

in ----> 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: ¯_(ツ)_/¯ — You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub , or unsubscribe .
amcgregor commented 3 years ago

@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!