Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/mail.py @ 28935:a4c5c23de1d3
mail: retain hostname for sslutil.wrapsocket (issue5203)
SMTPS + STARTTLS need to provide serverhostname,
and we can't store it in sslkwargs because that breaks
something involving the https protocol.
author | timeless <timeless@mozdev.org> |
---|---|
date | Fri, 15 Apr 2016 17:43:47 +0000 |
parents | 8286f551b7ee |
children | bac14dbbbfab |
comparison
equal
deleted
inserted
replaced
28934:c4040a35b5d9 | 28935:a4c5c23de1d3 |
---|---|
46 class STARTTLS(smtplib.SMTP): | 46 class STARTTLS(smtplib.SMTP): |
47 '''Derived class to verify the peer certificate for STARTTLS. | 47 '''Derived class to verify the peer certificate for STARTTLS. |
48 | 48 |
49 This class allows to pass any keyword arguments to SSL socket creation. | 49 This class allows to pass any keyword arguments to SSL socket creation. |
50 ''' | 50 ''' |
51 def __init__(self, sslkwargs, **kwargs): | 51 def __init__(self, sslkwargs, host=None, **kwargs): |
52 smtplib.SMTP.__init__(self, **kwargs) | 52 smtplib.SMTP.__init__(self, **kwargs) |
53 self._sslkwargs = sslkwargs | 53 self._sslkwargs = sslkwargs |
54 self._host = host | |
54 | 55 |
55 def starttls(self, keyfile=None, certfile=None): | 56 def starttls(self, keyfile=None, certfile=None): |
56 if not self.has_extn("starttls"): | 57 if not self.has_extn("starttls"): |
57 msg = "STARTTLS extension not supported by server" | 58 msg = "STARTTLS extension not supported by server" |
58 raise smtplib.SMTPException(msg) | 59 raise smtplib.SMTPException(msg) |
59 (resp, reply) = self.docmd("STARTTLS") | 60 (resp, reply) = self.docmd("STARTTLS") |
60 if resp == 220: | 61 if resp == 220: |
61 self.sock = sslutil.wrapsocket(self.sock, keyfile, certfile, | 62 self.sock = sslutil.wrapsocket(self.sock, keyfile, certfile, |
63 serverhostname=self._host, | |
62 **self._sslkwargs) | 64 **self._sslkwargs) |
63 self.file = smtplib.SSLFakeFile(self.sock) | 65 self.file = smtplib.SSLFakeFile(self.sock) |
64 self.helo_resp = None | 66 self.helo_resp = None |
65 self.ehlo_resp = None | 67 self.ehlo_resp = None |
66 self.esmtp_features = {} | 68 self.esmtp_features = {} |
70 class SMTPS(smtplib.SMTP): | 72 class SMTPS(smtplib.SMTP): |
71 '''Derived class to verify the peer certificate for SMTPS. | 73 '''Derived class to verify the peer certificate for SMTPS. |
72 | 74 |
73 This class allows to pass any keyword arguments to SSL socket creation. | 75 This class allows to pass any keyword arguments to SSL socket creation. |
74 ''' | 76 ''' |
75 def __init__(self, sslkwargs, keyfile=None, certfile=None, **kwargs): | 77 def __init__(self, sslkwargs, keyfile=None, certfile=None, host=None, |
78 **kwargs): | |
76 self.keyfile = keyfile | 79 self.keyfile = keyfile |
77 self.certfile = certfile | 80 self.certfile = certfile |
78 smtplib.SMTP.__init__(self, **kwargs) | 81 smtplib.SMTP.__init__(self, **kwargs) |
82 self._host = host | |
79 self.default_port = smtplib.SMTP_SSL_PORT | 83 self.default_port = smtplib.SMTP_SSL_PORT |
80 self._sslkwargs = sslkwargs | 84 self._sslkwargs = sslkwargs |
81 | 85 |
82 def _get_socket(self, host, port, timeout): | 86 def _get_socket(self, host, port, timeout): |
83 if self.debuglevel > 0: | 87 if self.debuglevel > 0: |
84 print('connect:', (host, port), file=sys.stderr) | 88 print('connect:', (host, port), file=sys.stderr) |
85 new_socket = socket.create_connection((host, port), timeout) | 89 new_socket = socket.create_connection((host, port), timeout) |
86 new_socket = sslutil.wrapsocket(new_socket, | 90 new_socket = sslutil.wrapsocket(new_socket, |
87 self.keyfile, self.certfile, | 91 self.keyfile, self.certfile, |
92 serverhostname=self._host, | |
88 **self._sslkwargs) | 93 **self._sslkwargs) |
89 self.file = smtplib.SSLFakeFile(new_socket) | 94 self.file = smtplib.SSLFakeFile(new_socket) |
90 return new_socket | 95 return new_socket |
91 | 96 |
92 def _smtp(ui): | 97 def _smtp(ui): |
112 else: | 117 else: |
113 # 'ui' is required by sslutil.wrapsocket() and set by sslkwargs() | 118 # 'ui' is required by sslutil.wrapsocket() and set by sslkwargs() |
114 sslkwargs = {'ui': ui} | 119 sslkwargs = {'ui': ui} |
115 if smtps: | 120 if smtps: |
116 ui.note(_('(using smtps)\n')) | 121 ui.note(_('(using smtps)\n')) |
117 s = SMTPS(sslkwargs, local_hostname=local_hostname) | 122 s = SMTPS(sslkwargs, local_hostname=local_hostname, host=mailhost) |
118 elif starttls: | 123 elif starttls: |
119 s = STARTTLS(sslkwargs, local_hostname=local_hostname) | 124 s = STARTTLS(sslkwargs, local_hostname=local_hostname, host=mailhost) |
120 else: | 125 else: |
121 s = smtplib.SMTP(local_hostname=local_hostname) | 126 s = smtplib.SMTP(local_hostname=local_hostname) |
122 if smtps: | 127 if smtps: |
123 defaultport = 465 | 128 defaultport = 465 |
124 else: | 129 else: |