Comments
Patch
@@ -32,16 +32,24 @@ from . import (
configprotocols = set([
'tls1.0',
'tls1.1',
'tls1.2',
])
hassni = getattr(ssl, 'HAS_SNI', False)
+# TLS 1.1 and 1.2 may not be supported if the OpenSSL Python is compiled
+# against don't support them.
+supportedprotocols = set(['tls1.0'])
+if getattr(ssl, 'PROTOCOL_TLSv1_1', 0):
+ supportedprotocols.add('tls1.1')
+if getattr(ssl, 'PROTOCOL_TLSv1_2', 0):
+ supportedprotocols.add('tls1.2')
+
try:
# ssl.SSLContext was added in 2.7.9 and presence indicates modern
# SSL/TLS features are available.
SSLContext = ssl.SSLContext
modernssl = True
_canloaddefaultcerts = util.safehasattr(SSLContext, 'load_default_certs')
except AttributeError:
modernssl = False
@@ -143,25 +151,23 @@ def _hostsettings(ui, hostname):
def validateprotocol(protocol, key):
if protocol not in configprotocols:
raise error.Abort(
_('unsupported protocol from hostsecurity.%s: %s') %
(key, protocol),
hint=_('valid protocols: %s') %
' '.join(sorted(configprotocols)))
- # Legacy Python can only do TLS 1.0. We default to TLS 1.1+ where we
- # can because TLS 1.0 has known vulnerabilities (like BEAST and POODLE).
- # We allow users to downgrade to TLS 1.0+ via config options in case a
- # legacy server is encountered.
- if modernssl:
+ # We default to TLS 1.1+ where we can because TLS 1.0 has known
+ # vulnerabilities (like BEAST and POODLE). We allow users to downgrade to
+ # TLS 1.0+ via config options in case a legacy server is encountered.
+ if 'tls1.1' in supportedprotocols:
defaultprotocol = 'tls1.1'
else:
- # Let people on legacy Python versions know they are borderline
- # secure.
+ # Let people know they are borderline secure.
# We don't document this config option because we want people to see
# the bold warnings on the web site.
# internal config: hostsecurity.disabletls10warning
if not ui.configbool('hostsecurity', 'disabletls10warning'):
ui.warn(_('warning: connecting to %s using legacy security '
'technology (TLS 1.0); see '
'https://mercurial-scm.org/wiki/SecureConnections for '
'more info\n') % hostname)
@@ -283,17 +289,17 @@ def protocolsettings(protocol):
# support TLS 1.2.
#
# The PROTOCOL_TLSv* constants select a specific TLS version
# only (as opposed to multiple versions). So the method for
# supporting multiple TLS versions is to use PROTOCOL_SSLv23 and
# disable protocols via SSLContext.options and OP_NO_* constants.
# However, SSLContext.options doesn't work unless we have the
# full/real SSLContext available to us.
- if not modernssl:
+ if supportedprotocols == set(['tls1.0']):
if protocol != 'tls1.0':
raise error.Abort(_('current Python does not support protocol '
'setting %s') % protocol,
hint=_('upgrade Python or disable setting since '
'only TLS 1.0 is supported'))
return ssl.PROTOCOL_TLSv1, 0