comparison mercurial/sslutil.py @ 29618:fbf4adc0d8f2 stable

sslutil: capture string string representation of protocol This will be used in a subsequent patch to improve messaging.
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 19 Jul 2016 20:30:29 -0700
parents 2960ceee1948
children 53e80179bd6a
comparison
equal deleted inserted replaced
29617:2960ceee1948 29618:fbf4adc0d8f2
137 'disablecertverification': False, 137 'disablecertverification': False,
138 # Whether the legacy [hostfingerprints] section has data for this host. 138 # Whether the legacy [hostfingerprints] section has data for this host.
139 'legacyfingerprint': False, 139 'legacyfingerprint': False,
140 # PROTOCOL_* constant to use for SSLContext.__init__. 140 # PROTOCOL_* constant to use for SSLContext.__init__.
141 'protocol': None, 141 'protocol': None,
142 # String representation of minimum protocol to be used for UI
143 # presentation.
144 'protocolui': None,
142 # ssl.CERT_* constant used by SSLContext.verify_mode. 145 # ssl.CERT_* constant used by SSLContext.verify_mode.
143 'verifymode': None, 146 'verifymode': None,
144 # Defines extra ssl.OP* bitwise options to set. 147 # Defines extra ssl.OP* bitwise options to set.
145 'ctxoptions': None, 148 'ctxoptions': None,
146 # OpenSSL Cipher List to use (instead of default). 149 # OpenSSL Cipher List to use (instead of default).
185 # We always print a "connection security to %s is disabled..." message when 188 # We always print a "connection security to %s is disabled..." message when
186 # --insecure is used. So no need to print anything more here. 189 # --insecure is used. So no need to print anything more here.
187 if ui.insecureconnections: 190 if ui.insecureconnections:
188 protocol = 'tls1.0' 191 protocol = 'tls1.0'
189 192
190 s['protocol'], s['ctxoptions'] = protocolsettings(protocol) 193 s['protocol'], s['ctxoptions'], s['protocolui'] = protocolsettings(protocol)
191 194
192 ciphers = ui.config('hostsecurity', 'ciphers') 195 ciphers = ui.config('hostsecurity', 'ciphers')
193 ciphers = ui.config('hostsecurity', '%s:ciphers' % hostname, ciphers) 196 ciphers = ui.config('hostsecurity', '%s:ciphers' % hostname, ciphers)
194 s['ciphers'] = ciphers 197 s['ciphers'] = ciphers
195 198
283 assert s['verifymode'] is not None 286 assert s['verifymode'] is not None
284 287
285 return s 288 return s
286 289
287 def protocolsettings(protocol): 290 def protocolsettings(protocol):
288 """Resolve the protocol and context options for a config value.""" 291 """Resolve the protocol for a config value.
292
293 Returns a 3-tuple of (protocol, options, ui value) where the first
294 2 items are values used by SSLContext and the last is a string value
295 of the ``minimumprotocol`` config option equivalent.
296 """
289 if protocol not in configprotocols: 297 if protocol not in configprotocols:
290 raise ValueError('protocol value not supported: %s' % protocol) 298 raise ValueError('protocol value not supported: %s' % protocol)
291 299
292 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol 300 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol
293 # that both ends support, including TLS protocols. On legacy stacks, 301 # that both ends support, including TLS protocols. On legacy stacks,
305 raise error.Abort(_('current Python does not support protocol ' 313 raise error.Abort(_('current Python does not support protocol '
306 'setting %s') % protocol, 314 'setting %s') % protocol,
307 hint=_('upgrade Python or disable setting since ' 315 hint=_('upgrade Python or disable setting since '
308 'only TLS 1.0 is supported')) 316 'only TLS 1.0 is supported'))
309 317
310 return ssl.PROTOCOL_TLSv1, 0 318 return ssl.PROTOCOL_TLSv1, 0, 'tls1.0'
311 319
312 # WARNING: returned options don't work unless the modern ssl module 320 # WARNING: returned options don't work unless the modern ssl module
313 # is available. Be careful when adding options here. 321 # is available. Be careful when adding options here.
314 322
315 # SSLv2 and SSLv3 are broken. We ban them outright. 323 # SSLv2 and SSLv3 are broken. We ban them outright.
327 335
328 # Prevent CRIME. 336 # Prevent CRIME.
329 # There is no guarantee this attribute is defined on the module. 337 # There is no guarantee this attribute is defined on the module.
330 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) 338 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0)
331 339
332 return ssl.PROTOCOL_SSLv23, options 340 return ssl.PROTOCOL_SSLv23, options, protocol
333 341
334 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): 342 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None):
335 """Add SSL/TLS to a socket. 343 """Add SSL/TLS to a socket.
336 344
337 This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane 345 This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane
443 451
444 ``requireclientcert`` specifies whether to require client certificates. 452 ``requireclientcert`` specifies whether to require client certificates.
445 453
446 Typically ``cafile`` is only defined if ``requireclientcert`` is true. 454 Typically ``cafile`` is only defined if ``requireclientcert`` is true.
447 """ 455 """
448 protocol, options = protocolsettings('tls1.0') 456 protocol, options, _protocolui = protocolsettings('tls1.0')
449 457
450 # This config option is intended for use in tests only. It is a giant 458 # This config option is intended for use in tests only. It is a giant
451 # footgun to kill security. Don't define it. 459 # footgun to kill security. Don't define it.
452 exactprotocol = ui.config('devel', 'serverexactprotocol') 460 exactprotocol = ui.config('devel', 'serverexactprotocol')
453 if exactprotocol == 'tls1.0': 461 if exactprotocol == 'tls1.0':