smtp: fix for server doesn't support starttls extension

Currently we only support enabling TLS by using SMTP STARTTLS extension. But
not all the servers support it.

With this patch, user can choose which way to enable TLS:

* Default:

      tls = none
      port = 25

* To use STARTTLS:

      tls = starttls
      port = 465

* To use SMTP over SSL:

      tls = smtps
      port = 465

To keep backward compatibility, when tls = true, we use STARTTLS to enable TLS.

Signed-off-by: Zhigang Wang <w1z2g3@gmail.com>
This commit is contained in:
Zhigang Wang 2010-12-20 16:56:54 +08:00
parent e107057815
commit 5376237d45
2 changed files with 15 additions and 8 deletions

View File

@ -709,8 +709,8 @@ Configuration for extensions that need to send email messages.
``port``
Optional. Port to connect to on mail server. Default: 25.
``tls``
Optional. Whether to connect to mail server using TLS. True or
False. Default: False.
Optional. Method to enable TLS when connecting to mail server: starttls,
smtps or none. Default: none.
``username``
Optional. User name for authenticating with the SMTP server.
Default: none.

View File

@ -33,7 +33,17 @@ email.Header.Header.__dict__['__init__'] = _unifiedheaderinit
def _smtp(ui):
'''build an smtp connection and return a function to send mail'''
local_hostname = ui.config('smtp', 'local_hostname')
s = smtplib.SMTP(local_hostname=local_hostname)
tls = ui.config('smtp', 'tls')
# backward compatible: when tls = true, we use starttls.
starttls = tls == 'starttls' or util.parsebool(tls)
smtps = tls == 'smtps'
if (starttls or smtps) and not hasattr(socket, 'ssl'):
raise util.Abort(_("can't use TLS: Python SSL support not installed"))
if smtps:
ui.note(_('(using smtps)\n'))
s = smtplib.SMTP_SSL(local_hostname=local_hostname)
else:
s = smtplib.SMTP(local_hostname=local_hostname)
mailhost = ui.config('smtp', 'host')
if not mailhost:
raise util.Abort(_('smtp.host not configured - cannot send mail'))
@ -41,11 +51,8 @@ def _smtp(ui):
ui.note(_('sending mail: smtp host %s, port %s\n') %
(mailhost, mailport))
s.connect(host=mailhost, port=mailport)
if ui.configbool('smtp', 'tls'):
if not hasattr(socket, 'ssl'):
raise util.Abort(_("can't use TLS: Python SSL support "
"not installed"))
ui.note(_('(using tls)\n'))
if starttls:
ui.note(_('(using starttls)\n'))
s.ehlo()
s.starttls()
s.ehlo()