mirror of https://github.com/python/cpython
Fixes (accepts patch) issue1339 - http://bugs.python.org/issue1339
- Factor out the duplication of EHLO/HELO in login() and sendmail() to a new function, ehlo_or_helo_if_needed(). - Use ehlo_or_helo_if_needed() in starttls() - Check for the starttls exception in starttls() in the same way as login() checks for the auth extension. Contributed by Bill Fenner.
This commit is contained in:
parent
d59f457279
commit
bde4ae4bde
|
@ -191,6 +191,16 @@ An :class:`SMTP` instance has the following methods:
|
|||
necessary to call this method explicitly. It will be implicitly called by
|
||||
:meth:`sendmail` when necessary.
|
||||
|
||||
.. method:: SMTP.ehlo_or_helo_if_needed()
|
||||
|
||||
This method call :meth:`ehlo` and or :meth:`helo` if there has been no
|
||||
previous ``EHLO`` or ``HELO`` command this session. It tries ESMTP ``EHLO``
|
||||
first.
|
||||
|
||||
:exc:SMTPHeloError
|
||||
The server didn't reply properly to the ``HELO`` greeting.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
.. method:: SMTP.has_extn(name)
|
||||
|
||||
|
@ -237,6 +247,22 @@ An :class:`SMTP` instance has the following methods:
|
|||
If *keyfile* and *certfile* are provided, these are passed to the :mod:`socket`
|
||||
module's :func:`ssl` function.
|
||||
|
||||
If there has been no previous ``EHLO`` or ``HELO`` command this session,
|
||||
this method tries ESMTP ``EHLO`` first.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
|
||||
:exc:`SMTPHeloError`
|
||||
The server didn't reply properly to the ``HELO`` greeting.
|
||||
|
||||
:exc:`SMTPException`
|
||||
The server does not support the STARTTLS extension.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
|
||||
:exc:`RuntimeError`
|
||||
SSL/TLS support is not available to your python interpreter.
|
||||
|
||||
|
||||
.. method:: SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
|
||||
|
||||
|
|
|
@ -492,6 +492,23 @@ class SMTP:
|
|||
|
||||
# some useful methods
|
||||
|
||||
def ehlo_or_helo_if_needed(self):
|
||||
"""Call self.ehlo() and/or self.helo() if needed.
|
||||
|
||||
If there has been no previous EHLO or HELO command this session, this
|
||||
method tries ESMTP EHLO first.
|
||||
|
||||
This method may raise the following exceptions:
|
||||
|
||||
SMTPHeloError The server didn't reply properly to
|
||||
the helo greeting.
|
||||
"""
|
||||
if self.helo_resp is None and self.ehlo_resp is None:
|
||||
if not (200 <= self.ehlo()[0] <= 299):
|
||||
(code, resp) = self.helo()
|
||||
if not (200 <= code <= 299):
|
||||
raise SMTPHeloError(code, resp)
|
||||
|
||||
def login(self, user, password):
|
||||
"""Log in on an SMTP server that requires authentication.
|
||||
|
||||
|
@ -527,11 +544,7 @@ class SMTP:
|
|||
AUTH_CRAM_MD5 = "CRAM-MD5"
|
||||
AUTH_LOGIN = "LOGIN"
|
||||
|
||||
if self.helo_resp is None and self.ehlo_resp is None:
|
||||
if not (200 <= self.ehlo()[0] <= 299):
|
||||
(code, resp) = self.helo()
|
||||
if not (200 <= code <= 299):
|
||||
raise SMTPHeloError(code, resp)
|
||||
self.ehlo_or_helo_if_needed()
|
||||
|
||||
if not self.has_extn("auth"):
|
||||
raise SMTPException("SMTP AUTH extension not supported by server.")
|
||||
|
@ -577,12 +590,23 @@ class SMTP:
|
|||
def starttls(self, keyfile = None, certfile = None):
|
||||
"""Puts the connection to the SMTP server into TLS mode.
|
||||
|
||||
If there has been no previous EHLO or HELO command this session, this
|
||||
method tries ESMTP EHLO first.
|
||||
|
||||
If the server supports TLS, this will encrypt the rest of the SMTP
|
||||
session. If you provide the keyfile and certfile parameters,
|
||||
the identity of the SMTP server and client can be checked. This,
|
||||
however, depends on whether the socket module really checks the
|
||||
certificates.
|
||||
|
||||
This method may raise the following exceptions:
|
||||
|
||||
SMTPHeloError The server didn't reply properly to
|
||||
the helo greeting.
|
||||
"""
|
||||
self.ehlo_or_helo_if_needed()
|
||||
if not self.has_extn("starttls"):
|
||||
raise SMTPException("STARTTLS extension not supported by server.")
|
||||
(resp, reply) = self.docmd("STARTTLS")
|
||||
if resp == 220:
|
||||
if not _have_ssl:
|
||||
|
@ -656,11 +680,7 @@ class SMTP:
|
|||
empty dictionary.
|
||||
|
||||
"""
|
||||
if self.helo_resp is None and self.ehlo_resp is None:
|
||||
if not (200 <= self.ehlo()[0] <= 299):
|
||||
(code,resp) = self.helo()
|
||||
if not (200 <= code <= 299):
|
||||
raise SMTPHeloError(code, resp)
|
||||
self.ehlo_or_helo_if_needed()
|
||||
esmtp_opts = []
|
||||
if self.does_esmtp:
|
||||
# Hmmm? what's this? -ddm
|
||||
|
|
|
@ -990,6 +990,12 @@ Library
|
|||
RFC 3207 and forgets any knowledge obtained from the server not obtained
|
||||
from the TLS negotiation itself. Patch contributed by Bill Fenner.
|
||||
|
||||
- Issue1339: The smtplib.SMTP class has been refactored a bit such
|
||||
that the SMTP.starttls() caller no longer needs to call ehlo()
|
||||
beforehand. SMTP.starttls() now raises an exception of the server
|
||||
does not claim to support starttls. Adds the SMTP.ehlo_or_helo_if_needed()
|
||||
method. Patch contributed by Bill Fenner.
|
||||
|
||||
Extension Modules
|
||||
-----------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue