From 83ccba79682e01922a071dc49d93a97353fb14e8 Mon Sep 17 00:00:00 2001
From: Kali Kaneko <kali@leap.se>
Date: Mon, 11 Nov 2013 13:43:30 -0200
Subject: remove print

---
 mail/src/leap/mail/imap/server.py | 1 -
 1 file changed, 1 deletion(-)

(limited to 'mail/src/leap')

diff --git a/mail/src/leap/mail/imap/server.py b/mail/src/leap/mail/imap/server.py
index 7a9f810..11f3ccf 100644
--- a/mail/src/leap/mail/imap/server.py
+++ b/mail/src/leap/mail/imap/server.py
@@ -1153,7 +1153,6 @@ class SoledadMailbox(WithMsgFields):
         # the server itself is a listener to the mailbox.
         # so we can notify it (and should!) after chanes in flags
         # and number of messages.
-        print "emptying the listeners"
         map(lambda i: self.listeners.remove(i), self.listeners)
 
     def addListener(self, listener):
-- 
cgit v1.2.3


From b54aae4b24a6f57e2f0d779dc13d097a89f42402 Mon Sep 17 00:00:00 2001
From: Kali Kaneko <kali@leap.se>
Date: Mon, 11 Nov 2013 13:44:54 -0200
Subject: add a fqdn as the local domain, always

---
 mail/src/leap/mail/smtp/gateway.py | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

(limited to 'mail/src/leap')

diff --git a/mail/src/leap/mail/smtp/gateway.py b/mail/src/leap/mail/smtp/gateway.py
index 06405b4..6367c0d 100644
--- a/mail/src/leap/mail/smtp/gateway.py
+++ b/mail/src/leap/mail/smtp/gateway.py
@@ -71,6 +71,8 @@ generator.Generator = RFC3156CompliantGenerator
 # Helper utilities
 #
 
+LOCAL_FQDN = "bitmask.local"
+
 def validate_address(address):
     """
     Validate C{address} as defined in RFC 2822.
@@ -96,10 +98,18 @@ def validate_address(address):
 # SMTPFactory
 #
 
+class SMTPHeloLocalhost(smtp.SMTP):
+
+    def __init__(self, *args):
+        smtp.SMTP.__init__(self, *args)
+        self.host = LOCAL_FQDN
+
+
 class SMTPFactory(ServerFactory):
     """
     Factory for an SMTP server with encrypted gatewaying capabilities.
     """
+    domain = LOCAL_FQDN
 
     def __init__(self, userid, keymanager, host, port, cert, key,
                  encrypted_only):
@@ -152,7 +162,7 @@ class SMTPFactory(ServerFactory):
         @return: The protocol.
         @rtype: SMTPDelivery
         """
-        smtpProtocol = smtp.SMTP(SMTPDelivery(
+        smtpProtocol = SMTPHeloLocalhost(SMTPDelivery(
             self._userid, self._km, self._host, self._port, self._cert,
             self._key, self._encrypted_only))
         smtpProtocol.factory = self
@@ -451,8 +461,10 @@ class EncryptedMessage(object):
             self._user.dest.addrstr,
             StringIO(msg),
             d,
+            heloFallback=True,
             requireAuthentication=False,
             requireTransportSecurity=True)
+        factory.domain = LOCAL_FQDN
         signal(proto.SMTP_SEND_MESSAGE_START, self._user.dest.addrstr)
         reactor.connectSSL(
             self._host, self._port, factory,
-- 
cgit v1.2.3


From 6c25d79fa94aab81f3ee9e106e4ba0964797238d Mon Sep 17 00:00:00 2001
From: Kali Kaneko <kali@leap.se>
Date: Mon, 11 Nov 2013 13:45:14 -0200
Subject: refactor callbacks so we properly catch remote errors

---
 mail/src/leap/mail/smtp/gateway.py | 49 ++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 13 deletions(-)

(limited to 'mail/src/leap')

diff --git a/mail/src/leap/mail/smtp/gateway.py b/mail/src/leap/mail/smtp/gateway.py
index 6367c0d..7e9e420 100644
--- a/mail/src/leap/mail/smtp/gateway.py
+++ b/mail/src/leap/mail/smtp/gateway.py
@@ -14,7 +14,6 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
-
 """
 LEAP SMTP encrypted gateway.
 
@@ -32,7 +31,6 @@ The following classes comprise the SMTP gateway service:
 
 
 """
-
 import re
 from StringIO import StringIO
 from email.Header import Header
@@ -46,6 +44,7 @@ from twisted.mail import smtp
 from twisted.internet.protocol import ServerFactory
 from twisted.internet import reactor, ssl
 from twisted.internet import defer
+from twisted.internet.threads import deferToThread
 from twisted.python import log
 
 from leap.common.check import leap_assert, leap_assert_type
@@ -415,6 +414,15 @@ class EncryptedMessage(object):
         # unexpected loss of connection; don't save
         self.lines = []
 
+    def sendQueued(self, r):
+        """
+        Callback for the queued message.
+
+        @param r: The result from the last previous callback in the chain.
+        @type r: anything
+        """
+        log.msg(r)
+
     def sendSuccess(self, r):
         """
         Callback for a successful send.
@@ -425,33 +433,51 @@ class EncryptedMessage(object):
         log.msg(r)
         signal(proto.SMTP_SEND_MESSAGE_SUCCESS, self._user.dest.addrstr)
 
-    def sendError(self, e):
+    def sendError(self, failure):
         """
         Callback for an unsuccessfull send.
 
         :param e: The result from the last errback.
         :type e: anything
         """
-        log.msg(e)
-        log.err()
         signal(proto.SMTP_SEND_MESSAGE_ERROR, self._user.dest.addrstr)
+        err = failure.value
+        log.err(err)
+        raise err
 
     def sendMessage(self):
         """
-        Send the message.
-
-        This method will prepare the message (headers and possibly encrypted
-        body) and send it using the ESMTPSenderFactory.
-
+        Sends the message.
         @return: A deferred with callbacks for error and success of this
             message send.
         @rtype: twisted.internet.defer.Deferred
         """
+        # FIXME this should not be blocking the main ui, since it returns
+        # a deferred and it has its own cb set. ???!
+        d = deferToThread(self._sendMessage)
+        d.addCallbacks(self._route_msg, self.sendError)
+        d.addCallbacks(self.sendQueued, self.sendError)
+        return d
+
+    def _sendMessage(self):
+        """
+        Send the message.
+
+        This method will prepare the message (headers and possibly encrypted
+        body)
+        """
         msg = self._msg.as_string(False)
+        return msg
 
+    def _route_msg(self, msg):
+        """
+        Sends the msg using the ESMTPSenderFactory.
+        """
         log.msg("Connecting to SMTP server %s:%s" % (self._host, self._port))
 
+        # we construct a defer to pass to the ESMTPSenderFactory
         d = defer.Deferred()
+        d.addCallbacks(self.sendSuccess, self.sendError)
         # we don't pass an ssl context factory to the ESMTPSenderFactory
         # because ssl will be handled by reactor.connectSSL() below.
         factory = smtp.ESMTPSenderFactory(
@@ -469,9 +495,6 @@ class EncryptedMessage(object):
         reactor.connectSSL(
             self._host, self._port, factory,
             contextFactory=SSLContextFactory(self._cert, self._key))
-        d.addCallback(self.sendSuccess)
-        d.addErrback(self.sendError)
-        return d
 
     #
     # encryption methods
-- 
cgit v1.2.3


From bad92bb10d89bc39582aaca1b68ab9486c3f3053 Mon Sep 17 00:00:00 2001
From: Kali Kaneko <kali@leap.se>
Date: Mon, 11 Nov 2013 18:01:13 -0200
Subject: use deferToThread in the sendMail. Closes: #3937

---
 mail/src/leap/mail/smtp/gateway.py | 80 ++++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 34 deletions(-)

(limited to 'mail/src/leap')

diff --git a/mail/src/leap/mail/smtp/gateway.py b/mail/src/leap/mail/smtp/gateway.py
index 7e9e420..f6366af 100644
--- a/mail/src/leap/mail/smtp/gateway.py
+++ b/mail/src/leap/mail/smtp/gateway.py
@@ -72,6 +72,7 @@ generator.Generator = RFC3156CompliantGenerator
 
 LOCAL_FQDN = "bitmask.local"
 
+
 def validate_address(address):
     """
     Validate C{address} as defined in RFC 2822.
@@ -98,6 +99,13 @@ def validate_address(address):
 #
 
 class SMTPHeloLocalhost(smtp.SMTP):
+    """
+    An SMTP class that ensures a proper FQDN
+    for localhost.
+
+    This avoids a problem in which unproperly configured providers
+    would complain about the helo not being a fqdn.
+    """
 
     def __init__(self, *args):
         smtp.SMTP.__init__(self, *args)
@@ -388,21 +396,14 @@ class EncryptedMessage(object):
         Handle end of message.
 
         This method will encrypt and send the message.
+
+        :returns: a deferred
         """
         log.msg("Message data complete.")
         self.lines.append('')  # add a trailing newline
-        try:
-            self._maybe_encrypt_and_sign()
-            return self.sendMessage()
-        except KeyNotFound:
-            return None
-
-    def parseMessage(self):
-        """
-        Separate message headers from body.
-        """
-        parser = Parser()
-        return parser.parsestr('\r\n'.join(self.lines))
+        d = deferToThread(self._maybe_encrypt_and_sign)
+        d.addCallbacks(self.sendMessage, self.skipNoKeyErrBack)
+        return d
 
     def connectionLost(self):
         """
@@ -414,12 +415,34 @@ class EncryptedMessage(object):
         # unexpected loss of connection; don't save
         self.lines = []
 
+    # ends IMessage implementation
+
+    def skipNoKeyErrBack(self, failure):
+        """
+        Errback that ignores a KeyNotFound
+
+        :param failure: the failure
+        :type Failure: Failure
+        """
+        err = failure.value
+        if failure.check(KeyNotFound):
+            pass
+        else:
+            raise err
+
+    def parseMessage(self):
+        """
+        Separate message headers from body.
+        """
+        parser = Parser()
+        return parser.parsestr('\r\n'.join(self.lines))
+
     def sendQueued(self, r):
         """
         Callback for the queued message.
 
-        @param r: The result from the last previous callback in the chain.
-        @type r: anything
+        :param r: The result from the last previous callback in the chain.
+        :type r: anything
         """
         log.msg(r)
 
@@ -445,35 +468,24 @@ class EncryptedMessage(object):
         log.err(err)
         raise err
 
-    def sendMessage(self):
+    def sendMessage(self, *args):
         """
         Sends the message.
-        @return: A deferred with callbacks for error and success of this
-            message send.
-        @rtype: twisted.internet.defer.Deferred
-        """
-        # FIXME this should not be blocking the main ui, since it returns
-        # a deferred and it has its own cb set. ???!
-        d = deferToThread(self._sendMessage)
-        d.addCallbacks(self._route_msg, self.sendError)
-        d.addCallbacks(self.sendQueued, self.sendError)
-        return d
 
-    def _sendMessage(self):
+        :return: A deferred with callbacks for error and success of this
+                 #message send.
+        :rtype: twisted.internet.defer.Deferred
         """
-        Send the message.
-
-        This method will prepare the message (headers and possibly encrypted
-        body)
-        """
-        msg = self._msg.as_string(False)
-        return msg
+        d = deferToThread(self._route_msg)
+        d.addCallbacks(self.sendQueued, self.sendError)
+        return
 
-    def _route_msg(self, msg):
+    def _route_msg(self):
         """
         Sends the msg using the ESMTPSenderFactory.
         """
         log.msg("Connecting to SMTP server %s:%s" % (self._host, self._port))
+        msg = self._msg.as_string(False)
 
         # we construct a defer to pass to the ESMTPSenderFactory
         d = defer.Deferred()
-- 
cgit v1.2.3