-
-
Notifications
You must be signed in to change notification settings - Fork 34.4k
bpo-36094: Update smtplib.py #23635
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
Closed
+3
−1
Closed
bpo-36094: Update smtplib.py #23635
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be preferable if
server_hostnamewas maintained as a separate parameter fromhostfor the reasons outlined in msg376344.The work-around that I am currently employing for this issue involves:
smtp = smtplib.SMTP(…)without ahostparameter in order to avoid initially establishing a connectionsmtp._host = server_hostnamein order to set the parameter to the ssl.SSLContext.wrap_socket() callsmtp.connect(address, …)whereaddressis an IP address previously obtained from a call tosocket.getaddrinfo(server_hostname, …)This approach is necessary because TLS server certificates rarely contain IP address information that would be required for certificate validation, the expectation being that validation be performed against the server's hostname.
The solution that you propose here will break this work-around, as
self._hostis no longer passed asserver_hostname; the ability to provide separate parameters for establishing a socket connection (i.e.address) and the correspondingserver_hostnamevalidation will have been removed.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an additional concern that users of my own library fell prey to (frequently, you may notice) in attempting to patch the problem from the side of my library: passing in a hostname establishes a connection, calling
self.connect(host, port)quite early on, preventing invocation ofset_debuglevelprior to the connection attempt.Other than "it's always done this, historically" or hypothetical convenience, is there an actual reason for an object initializer / constructor to establish TCP connections outbound? I.e. actually do something, procedurally, and not just prepare the object for subsequent method invocation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be preferable if server_hostname was maintained as a separate parameter from host for the reasons outlined in msg376344.class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)........If the optional host and port parameters are given, the SMTP connect() method is called with those parameters during initializationThen either you have to change the documentation, or it's the API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot identify the discrepancy between the implementation and the documentation to which you appear to be alluding; can you elaborate?
Providing either a String containing a hostname (e.g.
example.com) or a String containing an address (e.g.1.2.3.4) is a fairly well established behaviour when dealing with network socket connections. My desire to provide thehostin IP address form, which necessitates the work-around that I initially described, is specifically highlighted within the socket - Socket families documentation:Basically, I'm proposing a solution along the lines of:
with support for specifying
server_hostnamebeing plumbed through the various function call layers such that it is exposed by the SMTP library's public API.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot identify the discrepancy between the implementation and the documentation to which you appear to be alluding; can you elaborate?I want to integrate smtplib in LibreOffice / OpenOffice.
For that, I have a wizard allowing to configure the connection (host, port, connection mode: not secure, SSL or TLS, authentication method: without, login, OAuth2 ...) using Mozilla ISPDB technology ...
This wizard needs to load the smtplib.SMTP or smtplib.SMTP_SSL class without connection for 2 reasons:
For the moment it is not possible to instantiate the smtplib.SMTP or smtplib.SMTP_SSL class without providing the host parameter without having an error (see bug , contrary to what the documentation says: host is optional ...)
There is never any question of connecting with an ip addressI understand the need to have a deterministic connection mode on the ip address, but in this case it is necessary to modify the API, because it does not offer anything like method or property to allow it... , and assign a private attribute (self._host) is not very pythonic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see; basically you're saying that this bug should be addressed. I totally agree; sorry, I presumed that was a given.
Indeed, I believe that it is necessary to expand the API (e.g. to introduce a
server_hostnameargument to the various connection methods) in order to correctly handle support for TLS validation, initially introduced in a5768f72 and which broke the ability to establish a connection outside of the scope of the initialisation function.I am by no means advocating that my work-around, of manually overriding the value of
self._host, is a good one, but it does at least allow me to provide a viable solution. My initial comment on your proposed changes was to highlight the comment I made on the original bug report and to pre-empt the next bug report I would otherwise be forced to create in order to highlight that it is not valid to assume thatserver_hostnameshould be the same ashostin every scenario.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit that my proposed modifications cannot be used if we want to have a deterministic connection mode.
But it would be good to definitely solve both problems: initialization without host parameter and deterministic connection.
If the API change is needed then do it, as we can't be happy with how it works right now ...
Edit:
I am ready to make a new pull request incorporating the changes you suggest.
It remains to be decided where self._host should be set to its value in the connect() procedure when it is not supplied at initialization.
We must also plan to update the documentation to integrate the new optional parameter
server_hostnameThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be most welcome if you could fix these issues. I do not mind if my current work-around is broken by any proposed changes (i.e. I should not be modifying the internal implementation detail represented by
self._host). All I ask is for it to be possible to perform TLS validation in a scenario whereserver_hostnamemay not be assumed to be equal tohost. I am perfectly happy to fix-up my current implementation (e.g. to adopt the new API parameter).