--- a/mercurial/mail.py Sun Apr 07 23:25:50 2013 -0700
+++ b/mercurial/mail.py Tue Mar 26 02:27:23 2013 +0900
@@ -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 @@
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')