diff options
author | Pandu E POLUAN <pepoluan@gmail.com> | 2021-03-13 06:25:49 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-12 15:25:49 -0800 |
commit | 7591d9455eb37525c832da3d65e1a7b3e6dbf613 (patch) | |
tree | 443271a487226a130c8851ce2578f4717285bf0a /Lib/smtplib.py | |
parent | ba251c2ae6654bfc8abd9d886b219698ad34ac3c (diff) | |
download | cpython-git-7591d9455eb37525c832da3d65e1a7b3e6dbf613.tar.gz |
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.
Diffstat (limited to 'Lib/smtplib.py')
-rwxr-xr-x | Lib/smtplib.py | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/Lib/smtplib.py b/Lib/smtplib.py index e81a9f05d6..0317248b74 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) @@ -633,14 +635,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) @@ -662,7 +673,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 |