Package: python2.3-twisted
Version: 1.3.0-5
Severity: normal
Tags: patch

Hi. Twisted 1.3 contains two bad mail-related bugs, which are really
harmful for my application scalemail:

 - insufficient error handling in mail delivery, causing mail loss
   (fixed by r12036)

 - unable to send mail from <> (fixed by r12767, which broke receiving
   mail from <>, which is fixed in r12858).

Attached are the the SVN commits, rediffed to apply nicely to 1.3.0-5.
I have tested them, and I am the original author for r12767 and r12858.

I'd really love it if you could upload a twisted 1.3.0-6 with these
changes.

diff -Naur twisted-1.3.0.orig/twisted/protocols/smtp.py twisted-1.3.0/twisted/protocols/smtp.py
--- twisted-1.3.0.orig/twisted/protocols/smtp.py	2004-04-09 06:06:54.000000000 +0300
+++ twisted-1.3.0/twisted/protocols/smtp.py	2005-01-12 10:32:24.000000000 +0200
@@ -419,6 +419,9 @@
     host = DNSNAME
     portal = None
 
+    # Control whether we log SMTP events
+    noisy = True
+
     # A factory for IMessageDelivery objects.  If an
     # avatar implementing IMessageDeliveryFactory can
     # be acquired from the portal, it will be used to
@@ -656,8 +659,9 @@
                 self.mode = COMMAND
                 return
         self.sendCode(354, 'Continue')
-        fmt = 'Receiving message for delivery: from=%s to=%s'
-        log.msg(fmt % (origin, [str(u) for (u, f) in recipients]))
+        if self.noisy:
+            fmt = 'Receiving message for delivery: from=%s to=%s'
+            log.msg(fmt % (origin, [str(u) for (u, f) in recipients]))
 
     def connectionLost(self, reason):
         # self.sendCode(421, 'Dropping connection.') # This does nothing...
@@ -667,7 +671,10 @@
         if self.mode is DATA:
             try:
                 for message in self.__messages:
-                    message.connectionLost()
+                    try:
+                        message.connectionLost()
+                    except:
+                        log.err()
                 del self.__messages
             except AttributeError:
                 pass
@@ -694,8 +701,8 @@
                     return
                 defer.DeferredList([
                     m.eomReceived() for m in self.__messages
-                ]).addCallback(self._messageHandled
-                ).addErrback(self._messageNotHandled)
+                ], consumeErrors=True).addCallback(self._messageHandled
+                                                   )
                 del self.__messages
                 return
             line = line[1:]
@@ -726,19 +733,20 @@
                 message.connectionLost()
     state_DATA = dataLineReceived
 
-    def _messageHandled(self, _):
-        self.sendCode(250, 'Delivery in progress')
-        log.msg('Accepted message for delivery')
-
-    def _messageNotHandled(self, failure):
-        if failure.check(SMTPServerError):
-            self.sendCode(failure.value.code, failure.value.resp)
-            fmt = 'Message not handled: (%d) %s'
-            log.msg(fmt % (failure.value.code, failure.value.resp))
+    def _messageHandled(self, resultList):
+        failures = 0
+        for (success, result) in resultList:
+            if not success:
+                failures += 1
+                log.err(result)
+        if failures:
+            msg = 'Could not send e-mail'
+            L = len(resultList)
+            if L > 1:
+                msg += ' (%d failures out of %d recipients)' % (failures, L)
+            self.sendCode(550, msg)
         else:
-            self.sendCode(550, 'Could not send e-mail')
-            log.msg('Message not handled: (550) Could not send e-mail')
-        log.err(failure)
+            self.sendCode(250, 'Delivery in progress')
 
     def _cbAuthenticated(self, (iface, avatar, logout)):
         if issubclass(iface, IMessageDeliveryFactory):
diff -Naur twisted-1.3.0.r12036/twisted/mail/protocols.py twisted-1.3.0/twisted/mail/protocols.py
--- twisted-1.3.0.r12036/twisted/mail/protocols.py	2003-10-08 05:06:44.000000000 +0300
+++ twisted-1.3.0/twisted/mail/protocols.py	2005-01-12 10:36:44.000000000 +0200
@@ -70,7 +70,7 @@
     def validateFrom(self, helo, origin):
         if not helo:
             raise smtp.SMTPBadSender(origin, 503, "Who are you?  Say HELO first.")
-        if not origin.domain:
+        if origin.local != '' and origin.domain == '':
             raise smtp.SMTPBadSender(origin, 501, "Sender address must contain domain.")
         return origin
 
diff -Naur twisted-1.3.0.r12036/twisted/protocols/smtp.py twisted-1.3.0/twisted/protocols/smtp.py
--- twisted-1.3.0.r12036/twisted/protocols/smtp.py	2005-01-12 10:32:24.000000000 +0200
+++ twisted-1.3.0/twisted/protocols/smtp.py	2005-01-12 10:35:54.000000000 +0200
@@ -334,7 +334,7 @@
 
         self.local = ''.join(local)
         self.domain = ''.join(domain)
-        if self.domain == '':
+        if self.local != '' and self.domain == '':
             if defaultDomain is None:
                 defaultDomain = DNSNAME
             self.domain = defaultDomain
@@ -358,7 +358,10 @@
         return ''.join(res)
 
     def __str__(self):
-        return '@'.join((self.local, self.domain))
+        if self.local or self.domain:
+            return '@'.join((self.local, self.domain))
+        else:
+            return ''
 
     def __repr__(self):
         return "%s.%s(%s)" % (self.__module__, self.__class__.__name__,
diff -Naur twisted-1.3.0.r12036/twisted/test/test_mail.py twisted-1.3.0/twisted/test/test_mail.py
--- twisted-1.3.0.r12036/twisted/test/test_mail.py	2004-03-13 18:27:12.000000000 +0200
+++ twisted-1.3.0/twisted/test/test_mail.py	2005-01-12 10:36:05.000000000 +0200
@@ -378,6 +378,10 @@
         origin = smtp.Address('<[EMAIL PROTECTED]>')
         self.failUnless(self.D.validateFrom(helo, origin) is origin)
 
+        helo = ('hostname', '1.2.3.4')
+        origin = smtp.Address('<>')
+        self.failUnless(self.D.validateFrom(helo, origin) is origin)
+
         self.assertRaises(
             smtp.SMTPBadSender,
             self.D.validateFrom, None, origin
diff -Naur twisted-1.3.0.r12036/twisted/test/test_smtp.py twisted-1.3.0/twisted/test/test_smtp.py
--- twisted-1.3.0.r12036/twisted/test/test_smtp.py	2004-01-19 23:04:53.000000000 +0200
+++ twisted-1.3.0/twisted/test/test_smtp.py	2005-01-12 10:35:48.000000000 +0200
@@ -427,6 +427,8 @@
             ['[EMAIL PROTECTED]', '<[EMAIL PROTECTED]>'],
             ['"User Name" <[EMAIL PROTECTED]>', '<[EMAIL PROTECTED]>'],
             [smtp.Address('[EMAIL PROTECTED]'), '<[EMAIL PROTECTED]>'],
+            ['', '<>'],
+            [smtp.Address(''), '<>'],
         ]
         
         for (c, e) in cases:

Reply via email to