comparison mercurial/sslutil.py @ 29508:d65ec41b6384

sslutil: move context options flags to _hostsettings Again, moving configuration determination to a single location.
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 06 Jul 2016 22:53:22 -0700
parents 97dcdcf75f4f
children 5f8b36d5a6ec
comparison
equal deleted inserted replaced
29507:97dcdcf75f4f 29508:d65ec41b6384
128 'legacyfingerprint': False, 128 'legacyfingerprint': False,
129 # PROTOCOL_* constant to use for SSLContext.__init__. 129 # PROTOCOL_* constant to use for SSLContext.__init__.
130 'protocol': None, 130 'protocol': None,
131 # ssl.CERT_* constant used by SSLContext.verify_mode. 131 # ssl.CERT_* constant used by SSLContext.verify_mode.
132 'verifymode': None, 132 'verifymode': None,
133 # Defines extra ssl.OP* bitwise options to set.
134 'ctxoptions': None,
133 } 135 }
134 136
135 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol 137 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol
136 # that both ends support, including TLS protocols. On legacy stacks, 138 # 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 139 # the highest it likely goes in TLS 1.0. On modern stacks, it can
146 if modernssl: 148 if modernssl:
147 s['protocol'] = ssl.PROTOCOL_SSLv23 149 s['protocol'] = ssl.PROTOCOL_SSLv23
148 else: 150 else:
149 s['protocol'] = ssl.PROTOCOL_TLSv1 151 s['protocol'] = ssl.PROTOCOL_TLSv1
150 152
153 # SSLv2 and SSLv3 are broken. We ban them outright.
154 # WARNING: ctxoptions doesn't have an effect unless the modern ssl module
155 # is available. Be careful when adding flags!
156 s['ctxoptions'] = OP_NO_SSLv2 | OP_NO_SSLv3
157
151 # Look for fingerprints in [hostsecurity] section. Value is a list 158 # Look for fingerprints in [hostsecurity] section. Value is a list
152 # of <alg>:<fingerprint> strings. 159 # of <alg>:<fingerprint> strings.
153 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname, 160 fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname,
154 []) 161 [])
155 for fingerprint in fingerprints: 162 for fingerprint in fingerprints:
232 # validation (once we have the fingerprint to print to the 239 # validation (once we have the fingerprint to print to the
233 # user). 240 # user).
234 s['verifymode'] = ssl.CERT_NONE 241 s['verifymode'] = ssl.CERT_NONE
235 242
236 assert s['protocol'] is not None 243 assert s['protocol'] is not None
244 assert s['ctxoptions'] is not None
237 assert s['verifymode'] is not None 245 assert s['verifymode'] is not None
238 246
239 return s 247 return s
240 248
241 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): 249 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None):
257 settings = _hostsettings(ui, serverhostname) 265 settings = _hostsettings(ui, serverhostname)
258 266
259 # TODO use ssl.create_default_context() on modernssl. 267 # TODO use ssl.create_default_context() on modernssl.
260 sslcontext = SSLContext(settings['protocol']) 268 sslcontext = SSLContext(settings['protocol'])
261 269
262 # SSLv2 and SSLv3 are broken. We ban them outright. 270 # This is a no-op unless using modern ssl.
263 # This is a no-op on old Python. 271 sslcontext.options |= settings['ctxoptions']
264 sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3
265 272
266 # This still works on our fake SSLContext. 273 # This still works on our fake SSLContext.
267 sslcontext.verify_mode = settings['verifymode'] 274 sslcontext.verify_mode = settings['verifymode']
268 275
269 if certfile is not None: 276 if certfile is not None: