Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/sslutil.py @ 29507:97dcdcf75f4f
sslutil: move protocol determination to _hostsettings
Most of the logic for configuring TLS is now in this function.
Let's move protocol determination code there as well.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 06 Jul 2016 22:47:24 -0700 |
parents | be68a4445041 |
children | d65ec41b6384 |
comparison
equal
deleted
inserted
replaced
29506:2550604f5ec7 | 29507:97dcdcf75f4f |
---|---|
124 'cafile': None, | 124 'cafile': None, |
125 # Whether certificate verification should be disabled. | 125 # Whether certificate verification should be disabled. |
126 'disablecertverification': False, | 126 'disablecertverification': False, |
127 # Whether the legacy [hostfingerprints] section has data for this host. | 127 # Whether the legacy [hostfingerprints] section has data for this host. |
128 'legacyfingerprint': False, | 128 'legacyfingerprint': False, |
129 # PROTOCOL_* constant to use for SSLContext.__init__. | |
130 'protocol': None, | |
129 # ssl.CERT_* constant used by SSLContext.verify_mode. | 131 # ssl.CERT_* constant used by SSLContext.verify_mode. |
130 'verifymode': None, | 132 'verifymode': None, |
131 } | 133 } |
134 | |
135 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | |
136 # that both ends support, including TLS protocols. On legacy stacks, | |
137 # the highest it likely goes in TLS 1.0. On modern stacks, it can | |
138 # support TLS 1.2. | |
139 # | |
140 # The PROTOCOL_TLSv* constants select a specific TLS version | |
141 # only (as opposed to multiple versions). So the method for | |
142 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and | |
143 # disable protocols via SSLContext.options and OP_NO_* constants. | |
144 # However, SSLContext.options doesn't work unless we have the | |
145 # full/real SSLContext available to us. | |
146 if modernssl: | |
147 s['protocol'] = ssl.PROTOCOL_SSLv23 | |
148 else: | |
149 s['protocol'] = ssl.PROTOCOL_TLSv1 | |
132 | 150 |
133 # Look for fingerprints in [hostsecurity] section. Value is a list | 151 # Look for fingerprints in [hostsecurity] section. Value is a list |
134 # of <alg>:<fingerprint> strings. | 152 # of <alg>:<fingerprint> strings. |
135 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname, | 153 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname, |
136 []) | 154 []) |
213 # is insecure. We allow the connection and abort during | 231 # is insecure. We allow the connection and abort during |
214 # validation (once we have the fingerprint to print to the | 232 # validation (once we have the fingerprint to print to the |
215 # user). | 233 # user). |
216 s['verifymode'] = ssl.CERT_NONE | 234 s['verifymode'] = ssl.CERT_NONE |
217 | 235 |
236 assert s['protocol'] is not None | |
218 assert s['verifymode'] is not None | 237 assert s['verifymode'] is not None |
219 | 238 |
220 return s | 239 return s |
221 | 240 |
222 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): | 241 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): |
235 if not serverhostname: | 254 if not serverhostname: |
236 raise error.Abort(_('serverhostname argument is required')) | 255 raise error.Abort(_('serverhostname argument is required')) |
237 | 256 |
238 settings = _hostsettings(ui, serverhostname) | 257 settings = _hostsettings(ui, serverhostname) |
239 | 258 |
240 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | 259 # TODO use ssl.create_default_context() on modernssl. |
241 # that both ends support, including TLS protocols. On legacy stacks, | 260 sslcontext = SSLContext(settings['protocol']) |
242 # the highest it likely goes in TLS 1.0. On modern stacks, it can | 261 |
243 # support TLS 1.2. | |
244 # | |
245 # The PROTOCOL_TLSv* constants select a specific TLS version | |
246 # only (as opposed to multiple versions). So the method for | |
247 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and | |
248 # disable protocols via SSLContext.options and OP_NO_* constants. | |
249 # However, SSLContext.options doesn't work unless we have the | |
250 # full/real SSLContext available to us. | |
251 # | |
252 # SSLv2 and SSLv3 are broken. We ban them outright. | 262 # SSLv2 and SSLv3 are broken. We ban them outright. |
253 if modernssl: | |
254 protocol = ssl.PROTOCOL_SSLv23 | |
255 else: | |
256 protocol = ssl.PROTOCOL_TLSv1 | |
257 | |
258 # TODO use ssl.create_default_context() on modernssl. | |
259 sslcontext = SSLContext(protocol) | |
260 | |
261 # This is a no-op on old Python. | 263 # This is a no-op on old Python. |
262 sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 | 264 sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 |
263 | 265 |
264 # This still works on our fake SSLContext. | 266 # This still works on our fake SSLContext. |
265 sslcontext.verify_mode = settings['verifymode'] | 267 sslcontext.verify_mode = settings['verifymode'] |