mercurial/mail.py
changeset 18885 cf1304fbc184
parent 17428 72803c8edaa4
child 18886 14a60a0f7122
--- 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')