Skip to content

Commit

Permalink
Fix detection of SSL on Python 3. Fixes #9
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Aug 28, 2017
1 parent 7d34a75 commit 05580f9
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Expand Up @@ -15,6 +15,8 @@

- Declare explicit dependency on ``pywin32`` on Windows.

- Fix SSL support on Python 3. See `issue 9
<https://github.com/zopefoundation/zope.sendmail/issues/9>`_.

4.0.1 (2014-12-29)
==================
Expand Down
22 changes: 8 additions & 14 deletions src/zope/sendmail/mailer.py
Expand Up @@ -14,25 +14,18 @@
"""Classes which abstract different channels a message could be sent to.
"""
__docformat__ = 'restructuredtext'
import socket

from ssl import SSLError
from smtplib import SMTP

from zope.interface import implementer
from zope.sendmail.interfaces import ISMTPMailer
from zope.sendmail._compat import text_type

try:
from socket import sslerror as SSLError
except ImportError:
# Py3: The error location changed.
from ssl import SSLError

have_ssl = hasattr(socket, 'ssl')

@implementer(ISMTPMailer)
class SMTPMailer(object):


smtp = SMTP

def __init__(self, hostname='localhost', port=25,
Expand All @@ -44,6 +37,8 @@ def __init__(self, hostname='localhost', port=25,
self.force_tls = force_tls
self.no_tls = no_tls
self.connection = None
self.code = None
self.response = None

def vote(self, fromaddr, toaddrs, message):
self.connection = self.smtp(self.hostname, str(self.port))
Expand Down Expand Up @@ -73,15 +68,14 @@ def send(self, fromaddr, toaddrs, message):
if connection is None:
self.vote(fromaddr, toaddrs, message)

connection, code, response = self.connection, self.code, self.response

connection = self.connection

# encryption support
have_tls = connection.has_extn('starttls')
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:
if have_tls and not self.no_tls:
connection.starttls()
connection.ehlo()

Expand All @@ -95,7 +89,7 @@ def send(self, fromaddr, toaddrs, message):
connection.login(username, password)
elif self.username:
raise RuntimeError('Mailhost does not support ESMTP but a username '
'is configured')
'is configured')

connection.sendmail(fromaddr, toaddrs, message)
try:
Expand Down
9 changes: 4 additions & 5 deletions src/zope/sendmail/tests/test_mailer.py
Expand Up @@ -14,11 +14,7 @@
"""Tests for mailers.
"""

try:
from socket import sslerror as SSLError
except ImportError:
# Py3: The error location changed.
from ssl import SSLError
from ssl import SSLError

import unittest
from zope.interface.verify import verifyObject
Expand Down Expand Up @@ -65,6 +61,9 @@ def ehlo(self):
self.does_esmtp = True
return (200, 'Hello, I am your stupid MTA mock')

def starttls(self):
pass


class SMTPWithNoEHLO(SMTP):
does_esmtp = False
Expand Down

0 comments on commit 05580f9

Please sign in to comment.