From: Giampaolo RodolĂ  <g.rodola@gmail.com>
Date: Mon, 23 Aug 2010 22:34:37 +0000 (+0000)
Subject: Merged revisions 84289 via svnmerge from
X-Git-Tag: v3.1.3rc1~308
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ed2ce469f3bf4a0f6fb20761659ce6f5f2f3b399;p=python

Merged revisions 84289 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r84289 | giampaolo.rodola | 2010-08-24 00:28:13 +0200 (mar, 24 ago 2010) | 1 line

  fix issue 9129: adds proper error handling on accept() when smtpd accepts new incoming connections.
........
---

diff --git a/Lib/smtpd.py b/Lib/smtpd.py
index 76df67355a..57ad089841 100755
--- a/Lib/smtpd.py
+++ b/Lib/smtpd.py
@@ -121,7 +121,15 @@ class SMTPChannel(asynchat.async_chat):
         self.__rcpttos = []
         self.__data = ''
         self.__fqdn = socket.getfqdn()
-        self.__peer = conn.getpeername()
+        try:
+            self.__peer = conn.getpeername()
+        except socket.error as err:
+            # a race condition  may occur if the other end is closing
+            # before we can get the peername
+            self.close()
+            if err.args[0] != errno.ENOTCONN:
+                raise
+            return
         print('Peer:', repr(self.__peer), file=DEBUGSTREAM)
         self.push('220 %s %s' % (self.__fqdn, __version__))
         self.set_terminator(b'\r\n')
@@ -289,7 +297,20 @@ class SMTPServer(asyncore.dispatcher):
                 localaddr, remoteaddr), file=DEBUGSTREAM)
 
     def handle_accept(self):
-        conn, addr = self.accept()
+        try:
+            conn, addr = self.accept()
+        except TypeError:
+            # sometimes accept() might return None
+            return
+        except socket.error as err:
+            # ECONNABORTED might be thrown
+            if err.args[0] != errno.ECONNABORTED:
+                raise
+            return
+        else:
+            # sometimes addr == None instead of (ip, port)
+            if addr == None:
+                return
         print('Incoming connection from %s' % repr(addr), file=DEBUGSTREAM)
         channel = SMTPChannel(self, conn, addr)
 
diff --git a/Misc/NEWS b/Misc/NEWS
index b94623dc7d..4c2ebe4322 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -95,6 +95,9 @@ C-API
 Library
 -------
 
+- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing 
+  error handling when accepting a new connection.
+
 - Issue #658749: asyncore's connect() method now correctly interprets winsock
   errors.