summaryrefslogtreecommitdiffstats
path: root/Lib/smtplib.py
diff options
context:
space:
mode:
authorSenthil Kumaran <senthil@uthcode.com>2021-03-13 00:53:13 (GMT)
committerGitHub <noreply@github.com>2021-03-13 00:53:13 (GMT)
commit8cadc2c9cacfa1710cb5ca28a70f7782cacf09aa (patch)
treed397e193ecbffee4dd672876a4bb1f44d6f2e779 /Lib/smtplib.py
parent1a5001c606b55226c03fa1046aa8f5e1db2fa67d (diff)
downloadcpython-8cadc2c9cacfa1710cb5ca28a70f7782cacf09aa.zip
cpython-8cadc2c9cacfa1710cb5ca28a70f7782cacf09aa.tar.gz
cpython-8cadc2c9cacfa1710cb5ca28a70f7782cacf09aa.tar.bz2
[3.8] bpo-27820: Fix AUTH LOGIN logic in smtplib.SMTP (GH-24118) (#24833)
* bpo-27820: Fix AUTH LOGIN logic in smtplib.SMTP (GH-24118) * Fix auth_login logic (bpo-27820) * Also fix a longstanding bug in the SimSMTPChannel.found_terminator() method that causes inability to test SMTP AUTH with initial_response_ok=False. (cherry picked from commit 7591d9455eb37525c832da3d65e1a7b3e6dbf613) * Set timeout to 15 directly. Co-authored-by: Pandu E POLUAN <pepoluan@gmail.com>
Diffstat (limited to 'Lib/smtplib.py')
-rwxr-xr-xLib/smtplib.py15
1 files changed, 13 insertions, 2 deletions
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 6513842e..b7a2715 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -64,6 +64,7 @@ SMTP_SSL_PORT = 465
CRLF = "\r\n"
bCRLF = b"\r\n"
_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3
+_MAXCHALLENGE = 5 # Maximum number of AUTH challenges sent
OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
@@ -248,6 +249,7 @@ class SMTP:
self.esmtp_features = {}
self.command_encoding = 'ascii'
self.source_address = source_address
+ self._auth_challenge_count = 0
if host:
(code, msg) = self.connect(host, port)
@@ -631,14 +633,23 @@ class SMTP:
if initial_response is not None:
response = encode_base64(initial_response.encode('ascii'), eol='')
(code, resp) = self.docmd("AUTH", mechanism + " " + response)
+ self._auth_challenge_count = 1
else:
(code, resp) = self.docmd("AUTH", mechanism)
+ self._auth_challenge_count = 0
# If server responds with a challenge, send the response.
- if code == 334:
+ while code == 334:
+ self._auth_challenge_count += 1
challenge = base64.decodebytes(resp)
response = encode_base64(
authobject(challenge).encode('ascii'), eol='')
(code, resp) = self.docmd(response)
+ # If server keeps sending challenges, something is wrong.
+ if self._auth_challenge_count > _MAXCHALLENGE:
+ raise SMTPException(
+ "Server AUTH mechanism infinite loop. Last response: "
+ + repr((code, resp))
+ )
if code in (235, 503):
return (code, resp)
raise SMTPAuthenticationError(code, resp)
@@ -660,7 +671,7 @@ class SMTP:
def auth_login(self, challenge=None):
""" Authobject to use with LOGIN authentication. Requires self.user and
self.password to be set."""
- if challenge is None:
+ if challenge is None or self._auth_challenge_count < 2:
return self.user
else:
return self.password