Commit aa5e726a authored by Andrew Kuchling's avatar Andrew Kuchling

#16042: CVE-2013-1752: Limit amount of data read by limiting the call to readline().

The SSLFakeFile.readline() method needs to support limiting readline() as
well.  It's not a full emulation of readline()'s signature, but this class
is only used by smtplib's code, so it doesn't have to be.

Modified version of original patch by Christian Heimes.
parent 6169b814
......@@ -57,6 +57,7 @@ __all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
SMTP_PORT = 25
SMTP_SSL_PORT = 465
CRLF="\r\n"
_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3
OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
......@@ -170,10 +171,14 @@ else:
def __init__(self, sslobj):
self.sslobj = sslobj
def readline(self):
def readline(self, size=-1):
if size < 0:
size = None
str = ""
chr = None
while chr != "\n":
if size is not None and len(str) >= size:
break
chr = self.sslobj.read(1)
if not chr: break
str += chr
......@@ -334,11 +339,13 @@ class SMTP:
if self.file is None:
self.file = self.sock.makefile('rb')
while 1:
line = self.file.readline()
line = self.file.readline(_MAXLINE + 1)
if line == '':
self.close()
raise SMTPServerDisconnected("Connection unexpectedly closed")
if self.debuglevel > 0: print>>stderr, 'reply:', repr(line)
if self.debuglevel > 0: print >>stderr, 'reply:', repr(line)
if len(line) > _MAXLINE:
raise SMTPResponseException(500, "Line too long.")
resp.append(line[4:].strip())
code=line[:3]
# Check that the error code is syntactically correct.
......
......@@ -273,6 +273,32 @@ class BadHELOServerTests(TestCase):
HOST, self.port, 'localhost', 3)
class TooLongLineTests(TestCase):
respdata = '250 OK' + ('.' * smtplib._MAXLINE * 2) + '\n'
def setUp(self):
self.old_stdout = sys.stdout
self.output = StringIO.StringIO()
sys.stdout = self.output
self.evt = threading.Event()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(15)
self.port = test_support.bind_port(self.sock)
servargs = (self.evt, self.respdata, self.sock)
threading.Thread(target=server, args=servargs).start()
self.evt.wait()
self.evt.clear()
def tearDown(self):
self.evt.wait()
sys.stdout = self.old_stdout
def testLineTooLong(self):
self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP,
HOST, self.port, 'localhost', 3)
sim_users = {'Mr.A@somewhere.com':'John A',
'Ms.B@somewhere.com':'Sally B',
'Mrs.C@somewhereesle.com':'Ruth C',
......@@ -482,7 +508,8 @@ class SMTPSimTests(TestCase):
def test_main(verbose=None):
test_support.run_unittest(GeneralTests, DebuggingServerTests,
NonConnectingTests,
BadHELOServerTests, SMTPSimTests)
BadHELOServerTests, SMTPSimTests,
TooLongLineTests)
if __name__ == '__main__':
test_main()
......@@ -16,13 +16,16 @@ Library
- Issue #16248: Disable code execution from the user's home directory by
tkinter when the -E flag is passed to Python. Patch by Zachary Ware.
- Issue #16042: CVE-2013-1752: smtplib: Limit amount of data read by
limiting the call to readline(). Original patch by Christian Heimes.
Extension Modules
-----------------
- Issue #18709: Fix CVE-2013-4238. The SSL module now handles NULL bytes
inside subjectAltName correctly. Formerly the module has used OpenSSL's
GENERAL_NAME_print() function to get the string represention of ASN.1
strings for `rfc822Name` (email), `dNSName` (DNS) and
strings for `rfc822Name` (email), `dNSName` (DNS) and
`uniformResourceIdentifier` (URI).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment