comparison mercurial/sslutil.py @ 29619:53e80179bd6a stable

sslutil: improve messaging around unsupported protocols (issue5303) There are various causes for the inability to negotiate common SSL/TLS protocol between client and server. Previously, we had a single, not very actionable warning message for all of them. As people encountered TLS 1.0 servers in real life, it was quickly obvious that the existing messaging was inadequate to help users rectify the situation. This patch makes the warning messages much more verbose in hopes of making them more actionable while simultaneously encouraging users and servers to adopt better security practices. This messaging flirts with the anti-pattern of "never blame the user" by signaling out poorly-configured servers. But if we're going to disallow TLS 1.0 by default, I think we need to say *something* or people are just going to blame Mercurial for not being able to connect. The messaging tries to exonerate Mercurial from being the at fault party by pointing out the server is the entity that doesn't support proper security (when appropriate, of course).
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 19 Jul 2016 21:09:58 -0700
parents fbf4adc0d8f2
children 387bdd53c77e
comparison
equal deleted inserted replaced
29618:fbf4adc0d8f2 29619:53e80179bd6a
415 'were loaded; see ' 415 'were loaded; see '
416 'https://mercurial-scm.org/wiki/SecureConnections for ' 416 'https://mercurial-scm.org/wiki/SecureConnections for '
417 'how to configure Mercurial to avoid this error)\n')) 417 'how to configure Mercurial to avoid this error)\n'))
418 # Try to print more helpful error messages for known failures. 418 # Try to print more helpful error messages for known failures.
419 if util.safehasattr(e, 'reason'): 419 if util.safehasattr(e, 'reason'):
420 # This error occurs when the client and server don't share a
421 # common/supported SSL/TLS protocol. We've disabled SSLv2 and SSLv3
422 # outright. Hopefully the reason for this error is that we require
423 # TLS 1.1+ and the server only supports TLS 1.0. Whatever the
424 # reason, try to emit an actionable warning.
420 if e.reason == 'UNSUPPORTED_PROTOCOL': 425 if e.reason == 'UNSUPPORTED_PROTOCOL':
421 ui.warn(_('(could not negotiate a common protocol; see ' 426 # We attempted TLS 1.0+.
422 'https://mercurial-scm.org/wiki/SecureConnections ' 427 if settings['protocolui'] == 'tls1.0':
423 'for how to configure Mercurial to avoid this ' 428 # We support more than just TLS 1.0+. If this happens,
424 'error)\n')) 429 # the likely scenario is either the client or the server
430 # is really old. (e.g. server doesn't support TLS 1.0+ or
431 # client doesn't support modern TLS versions introduced
432 # several years from when this comment was written).
433 if supportedprotocols != set(['tls1.0']):
434 ui.warn(_(
435 '(could not communicate with %s using security '
436 'protocols %s; if you are using a modern Mercurial '
437 'version, consider contacting the operator of this '
438 'server; see '
439 'https://mercurial-scm.org/wiki/SecureConnections '
440 'for more info)\n') % (
441 serverhostname,
442 ', '.join(sorted(supportedprotocols))))
443 else:
444 ui.warn(_(
445 '(could not communicate with %s using TLS 1.0; the '
446 'likely cause of this is the server no longer '
447 'supports TLS 1.0 because it has known security '
448 'vulnerabilities; see '
449 'https://mercurial-scm.org/wiki/SecureConnections '
450 'for more info)\n') % serverhostname)
451 else:
452 # We attempted TLS 1.1+. We can only get here if the client
453 # supports the configured protocol. So the likely reason is
454 # the client wants better security than the server can
455 # offer.
456 ui.warn(_(
457 '(could not negotiate a common security protocol (%s+) '
458 'with %s; the likely cause is Mercurial is configured '
459 'to be more secure than the server can support)\n') % (
460 settings['protocolui'], serverhostname))
461 ui.warn(_('(consider contacting the operator of this '
462 'server and ask them to support modern TLS '
463 'protocol versions; or, set '
464 'hostsecurity.%s:minimumprotocol=tls1.0 to allow '
465 'use of legacy, less secure protocols when '
466 'communicating with this server)\n') %
467 serverhostname)
468 ui.warn(_(
469 '(see https://mercurial-scm.org/wiki/SecureConnections '
470 'for more info)\n'))
425 raise 471 raise
426 472
427 # check if wrap_socket failed silently because socket had been 473 # check if wrap_socket failed silently because socket had been
428 # closed 474 # closed
429 # - see http://bugs.python.org/issue13721 475 # - see http://bugs.python.org/issue13721