[Checkins] SVN: zope.sendmail/trunk/src/zope/sendmail/ merging

Andreas Jung andreas at andreas-jung.com
Sun Aug 19 14:35:53 EDT 2007


Log message for revision 79001:
  merging
  
  svn+ssh://svn.zope.org/repos/main/zope.sendmail/branches/ajung-encryption-branch
  
  This branch provides TLS/SSL encryption support.
  
  

Changed:
  U   zope.sendmail/trunk/src/zope/sendmail/interfaces.py
  U   zope.sendmail/trunk/src/zope/sendmail/mailer.py

-=-
Modified: zope.sendmail/trunk/src/zope/sendmail/interfaces.py
===================================================================
--- zope.sendmail/trunk/src/zope/sendmail/interfaces.py	2007-08-19 16:47:49 UTC (rev 79000)
+++ zope.sendmail/trunk/src/zope/sendmail/interfaces.py	2007-08-19 18:35:53 UTC (rev 79001)
@@ -55,7 +55,7 @@
 __docformat__ = 'restructuredtext'
 
 from zope.interface import Interface, Attribute
-from zope.schema import Object, TextLine, Int, Password, BytesLine
+from zope.schema import Object, TextLine, Int, Password, BytesLine, Bool
 
 from zope.i18nmessageid import MessageFactory
 _ = MessageFactory('zope')
@@ -165,7 +165,15 @@
         title=_(u"Password"),
         description=_(u"Password used for optional SMTP authentication."))
 
+    no_tls = Bool(
+        title=_(u"No TLS"),
+        description=_(u"Never use TLS for sending email."))
 
+    force_tls = Bool(
+        title=_(u"Force TLS"),
+        description=_(u"Use TLS always for sending email."))
+
+
 class IMailEvent(Interface):
     """Generic mail event."""
 

Modified: zope.sendmail/trunk/src/zope/sendmail/mailer.py
===================================================================
--- zope.sendmail/trunk/src/zope/sendmail/mailer.py	2007-08-19 16:47:49 UTC (rev 79000)
+++ zope.sendmail/trunk/src/zope/sendmail/mailer.py	2007-08-19 18:35:53 UTC (rev 79001)
@@ -19,11 +19,13 @@
 """
 __docformat__ = 'restructuredtext'
 
+import socket
 from smtplib import SMTP
 
 from zope.interface import implements
 from zope.sendmail.interfaces import ISMTPMailer
 
+have_ssl = hasattr(socket, 'ssl')
 
 class SMTPMailer(object):
 
@@ -32,15 +34,38 @@
     smtp = SMTP
 
     def __init__(self, hostname='localhost', port=25,
-                 username=None, password=None):
+                 username=None, password=None, no_tls=False, force_tls=False):
         self.hostname = hostname
         self.port = port
         self.username = username
         self.password = password
+        self.force_tls = force_tls
+        self.no_tls = no_tls
 
     def send(self, fromaddr, toaddrs, message):
         connection = self.smtp(self.hostname, str(self.port))
-        if self.username is not None and self.password is not None:
-            connection.login(self.username, self.password)
+
+        # send EHLO
+        code, response = connection.ehlo()
+        if code < 200 or code >300:
+            raise RuntimeError('Error sending EHLO to the SMTP server '
+                                '(code=%s, response=%s)' % (code, response))
+
+        # encryption support
+        have_tls =  connection.has_extn('starttls') 
+        if not have_tls and self.force_tls:
+            raise RuntimeError('TLS is not available but TLS is required')
+
+        if have_tls and have_ssl and not self.no_tls: 
+            connection.starttls()
+            connection.ehlo()
+
+        if connection.does_esmtp: 
+            if self.username is not None and self.password is not None:
+                connection.login(self.username, self.password)
+        elif self.username:
+            raise RuntimeError('Mailhost does not support ESMTP but a username '
+                                'is configured')
+
         connection.sendmail(fromaddr, toaddrs, message)
         connection.quit()



More information about the Checkins mailing list