diff --git a/mercurial/mail.py b/mercurial/mail.py --- a/mercurial/mail.py +++ b/mercurial/mail.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import util, encoding +import util, encoding, sslutil import os, smtplib, socket, quopri, time import email.Header, email.MIMEText, email.Utils @@ -30,6 +30,33 @@ def _unifiedheaderinit(self, *args, **kw email.Header.Header.__dict__['__init__'] = _unifiedheaderinit +class STARTTLS(smtplib.SMTP): + '''Derived class to verify the peer certificate for STARTTLS. + + This class allows to pass any keyword arguments to SSL socket creation. + ''' + def __init__(self, sslkwargs, **kwargs): + smtplib.SMTP.__init__(self, **kwargs) + self._sslkwargs = sslkwargs + + def starttls(self, keyfile=None, certfile=None): + if not self.has_extn("starttls"): + msg = "STARTTLS extension not supported by server" + raise smtplib.SMTPException(msg) + (resp, reply) = self.docmd("STARTTLS") + if resp == 220: + self.sock = sslutil.ssl_wrap_socket(self.sock, keyfile, certfile, + **self._sslkwargs) + if not util.safehasattr(self.sock, "read"): + # using httplib.FakeSocket with Python 2.5.x or earlier + self.sock.read = self.sock.recv + self.file = smtplib.SSLFakeFile(self.sock) + self.helo_resp = None + self.ehlo_resp = None + self.esmtp_features = {} + self.does_esmtp = 0 + return (resp, reply) + def _smtp(ui): '''build an smtp connection and return a function to send mail''' local_hostname = ui.config('smtp', 'local_hostname')