Mercurial > hg-stable
diff mercurial/sslutil.py @ 43077:687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Done with
python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py')
black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**')
# skip-blame mass-reformatting only
Differential Revision: https://phab.mercurial-scm.org/D6972
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:48:39 -0400 |
parents | 2372284d9457 |
children | 86e4daa2d54c |
line wrap: on
line diff
--- a/mercurial/sslutil.py Sun Oct 06 09:45:02 2019 -0400 +++ b/mercurial/sslutil.py Sun Oct 06 09:48:39 2019 -0400 @@ -36,27 +36,27 @@ # separate code paths depending on support in Python. configprotocols = { - 'tls1.0', - 'tls1.1', - 'tls1.2', + b'tls1.0', + b'tls1.1', + b'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 doesn't support them. -supportedprotocols = {'tls1.0'} -if util.safehasattr(ssl, 'PROTOCOL_TLSv1_1'): - supportedprotocols.add('tls1.1') -if util.safehasattr(ssl, 'PROTOCOL_TLSv1_2'): - supportedprotocols.add('tls1.2') +supportedprotocols = {b'tls1.0'} +if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): + supportedprotocols.add(b'tls1.1') +if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): + supportedprotocols.add(b'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') + _canloaddefaultcerts = util.safehasattr(SSLContext, b'load_default_certs') except AttributeError: modernssl = False _canloaddefaultcerts = False @@ -87,9 +87,9 @@ def load_verify_locations(self, cafile=None, capath=None, cadata=None): if capath: - raise error.Abort(_('capath not supported')) + raise error.Abort(_(b'capath not supported')) if cadata: - raise error.Abort(_('cadata not supported')) + raise error.Abort(_(b'cadata not supported')) self._cacerts = cafile @@ -123,175 +123,182 @@ s = { # Whether we should attempt to load default/available CA certs # if an explicit ``cafile`` is not defined. - 'allowloaddefaultcerts': True, + b'allowloaddefaultcerts': True, # List of 2-tuple of (hash algorithm, hash). - 'certfingerprints': [], + b'certfingerprints': [], # Path to file containing concatenated CA certs. Used by # SSLContext.load_verify_locations(). - 'cafile': None, + b'cafile': None, # Whether certificate verification should be disabled. - 'disablecertverification': False, + b'disablecertverification': False, # Whether the legacy [hostfingerprints] section has data for this host. - 'legacyfingerprint': False, + b'legacyfingerprint': False, # PROTOCOL_* constant to use for SSLContext.__init__. - 'protocol': None, + b'protocol': None, # String representation of minimum protocol to be used for UI # presentation. - 'protocolui': None, + b'protocolui': None, # ssl.CERT_* constant used by SSLContext.verify_mode. - 'verifymode': None, + b'verifymode': None, # Defines extra ssl.OP* bitwise options to set. - 'ctxoptions': None, + b'ctxoptions': None, # OpenSSL Cipher List to use (instead of default). - 'ciphers': None, + b'ciphers': None, } # Allow minimum TLS protocol to be specified in the config. def validateprotocol(protocol, key): if protocol not in configprotocols: raise error.Abort( - _('unsupported protocol from hostsecurity.%s: %s') + _(b'unsupported protocol from hostsecurity.%s: %s') % (key, protocol), - hint=_('valid protocols: %s') - % ' '.join(sorted(configprotocols)), + hint=_(b'valid protocols: %s') + % b' '.join(sorted(configprotocols)), ) # 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' + if b'tls1.1' in supportedprotocols: + defaultprotocol = b'tls1.1' else: # 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'): + if not ui.configbool(b'hostsecurity', b'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' + b'warning: connecting to %s using legacy security ' + b'technology (TLS 1.0); see ' + b'https://mercurial-scm.org/wiki/SecureConnections for ' + b'more info\n' ) % bhostname ) - defaultprotocol = 'tls1.0' + defaultprotocol = b'tls1.0' - key = 'minimumprotocol' - protocol = ui.config('hostsecurity', key, defaultprotocol) + key = b'minimumprotocol' + protocol = ui.config(b'hostsecurity', key, defaultprotocol) validateprotocol(protocol, key) - key = '%s:minimumprotocol' % bhostname - protocol = ui.config('hostsecurity', key, protocol) + key = b'%s:minimumprotocol' % bhostname + protocol = ui.config(b'hostsecurity', key, protocol) validateprotocol(protocol, key) # If --insecure is used, we allow the use of TLS 1.0 despite config options. # We always print a "connection security to %s is disabled..." message when # --insecure is used. So no need to print anything more here. if ui.insecureconnections: - protocol = 'tls1.0' - - s['protocol'], s['ctxoptions'], s['protocolui'] = protocolsettings(protocol) + protocol = b'tls1.0' - ciphers = ui.config('hostsecurity', 'ciphers') - ciphers = ui.config('hostsecurity', '%s:ciphers' % bhostname, ciphers) - s['ciphers'] = ciphers + s[b'protocol'], s[b'ctxoptions'], s[b'protocolui'] = protocolsettings( + protocol + ) + + ciphers = ui.config(b'hostsecurity', b'ciphers') + ciphers = ui.config(b'hostsecurity', b'%s:ciphers' % bhostname, ciphers) + s[b'ciphers'] = ciphers # Look for fingerprints in [hostsecurity] section. Value is a list # of <alg>:<fingerprint> strings. - fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % bhostname) + fingerprints = ui.configlist( + b'hostsecurity', b'%s:fingerprints' % bhostname + ) for fingerprint in fingerprints: - if not (fingerprint.startswith(('sha1:', 'sha256:', 'sha512:'))): + if not (fingerprint.startswith((b'sha1:', b'sha256:', b'sha512:'))): raise error.Abort( - _('invalid fingerprint for %s: %s') % (bhostname, fingerprint), - hint=_('must begin with "sha1:", "sha256:", ' 'or "sha512:"'), + _(b'invalid fingerprint for %s: %s') % (bhostname, fingerprint), + hint=_(b'must begin with "sha1:", "sha256:", ' b'or "sha512:"'), ) - alg, fingerprint = fingerprint.split(':', 1) - fingerprint = fingerprint.replace(':', '').lower() - s['certfingerprints'].append((alg, fingerprint)) + alg, fingerprint = fingerprint.split(b':', 1) + fingerprint = fingerprint.replace(b':', b'').lower() + s[b'certfingerprints'].append((alg, fingerprint)) # Fingerprints from [hostfingerprints] are always SHA-1. - for fingerprint in ui.configlist('hostfingerprints', bhostname): - fingerprint = fingerprint.replace(':', '').lower() - s['certfingerprints'].append(('sha1', fingerprint)) - s['legacyfingerprint'] = True + for fingerprint in ui.configlist(b'hostfingerprints', bhostname): + fingerprint = fingerprint.replace(b':', b'').lower() + s[b'certfingerprints'].append((b'sha1', fingerprint)) + s[b'legacyfingerprint'] = True # If a host cert fingerprint is defined, it is the only thing that # matters. No need to validate CA certs. - if s['certfingerprints']: - s['verifymode'] = ssl.CERT_NONE - s['allowloaddefaultcerts'] = False + if s[b'certfingerprints']: + s[b'verifymode'] = ssl.CERT_NONE + s[b'allowloaddefaultcerts'] = False # If --insecure is used, don't take CAs into consideration. elif ui.insecureconnections: - s['disablecertverification'] = True - s['verifymode'] = ssl.CERT_NONE - s['allowloaddefaultcerts'] = False + s[b'disablecertverification'] = True + s[b'verifymode'] = ssl.CERT_NONE + s[b'allowloaddefaultcerts'] = False - if ui.configbool('devel', 'disableloaddefaultcerts'): - s['allowloaddefaultcerts'] = False + if ui.configbool(b'devel', b'disableloaddefaultcerts'): + s[b'allowloaddefaultcerts'] = False # If both fingerprints and a per-host ca file are specified, issue a warning # because users should not be surprised about what security is or isn't # being performed. - cafile = ui.config('hostsecurity', '%s:verifycertsfile' % bhostname) - if s['certfingerprints'] and cafile: + cafile = ui.config(b'hostsecurity', b'%s:verifycertsfile' % bhostname) + if s[b'certfingerprints'] and cafile: ui.warn( _( - '(hostsecurity.%s:verifycertsfile ignored when host ' - 'fingerprints defined; using host fingerprints for ' - 'verification)\n' + b'(hostsecurity.%s:verifycertsfile ignored when host ' + b'fingerprints defined; using host fingerprints for ' + b'verification)\n' ) % bhostname ) # Try to hook up CA certificate validation unless something above # makes it not necessary. - if s['verifymode'] is None: + if s[b'verifymode'] is None: # Look at per-host ca file first. if cafile: cafile = util.expandpath(cafile) if not os.path.exists(cafile): raise error.Abort( - _('path specified by %s does not exist: %s') - % ('hostsecurity.%s:verifycertsfile' % (bhostname,), cafile) + _(b'path specified by %s does not exist: %s') + % ( + b'hostsecurity.%s:verifycertsfile' % (bhostname,), + cafile, + ) ) - s['cafile'] = cafile + s[b'cafile'] = cafile else: # Find global certificates file in config. - cafile = ui.config('web', 'cacerts') + cafile = ui.config(b'web', b'cacerts') if cafile: cafile = util.expandpath(cafile) if not os.path.exists(cafile): raise error.Abort( - _('could not find web.cacerts: %s') % cafile + _(b'could not find web.cacerts: %s') % cafile ) - elif s['allowloaddefaultcerts']: + elif s[b'allowloaddefaultcerts']: # CAs not defined in config. Try to find system bundles. cafile = _defaultcacerts(ui) if cafile: - ui.debug('using %s for CA file\n' % cafile) + ui.debug(b'using %s for CA file\n' % cafile) - s['cafile'] = cafile + s[b'cafile'] = cafile # Require certificate validation if CA certs are being loaded and # verification hasn't been disabled above. - if cafile or (_canloaddefaultcerts and s['allowloaddefaultcerts']): - s['verifymode'] = ssl.CERT_REQUIRED + if cafile or (_canloaddefaultcerts and s[b'allowloaddefaultcerts']): + s[b'verifymode'] = ssl.CERT_REQUIRED else: # At this point we don't have a fingerprint, aren't being # explicitly insecure, and can't load CA certs. Connecting # is insecure. We allow the connection and abort during # validation (once we have the fingerprint to print to the # user). - s['verifymode'] = ssl.CERT_NONE + s[b'verifymode'] = ssl.CERT_NONE - assert s['protocol'] is not None - assert s['ctxoptions'] is not None - assert s['verifymode'] is not None + assert s[b'protocol'] is not None + assert s[b'ctxoptions'] is not None + assert s[b'verifymode'] is not None return s @@ -304,7 +311,7 @@ of the ``minimumprotocol`` config option equivalent. """ if protocol not in configprotocols: - raise ValueError('protocol value not supported: %s' % protocol) + raise ValueError(b'protocol value not supported: %s' % protocol) # Despite its name, PROTOCOL_SSLv23 selects the highest protocol # that both ends support, including TLS protocols. On legacy stacks, @@ -317,18 +324,18 @@ # 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 supportedprotocols == {'tls1.0'}: - if protocol != 'tls1.0': + if supportedprotocols == {b'tls1.0'}: + if protocol != b'tls1.0': raise error.Abort( - _('current Python does not support protocol ' 'setting %s') + _(b'current Python does not support protocol ' b'setting %s') % protocol, hint=_( - 'upgrade Python or disable setting since ' - 'only TLS 1.0 is supported' + b'upgrade Python or disable setting since ' + b'only TLS 1.0 is supported' ), ) - return ssl.PROTOCOL_TLSv1, 0, 'tls1.0' + return ssl.PROTOCOL_TLSv1, 0, b'tls1.0' # WARNING: returned options don't work unless the modern ssl module # is available. Be careful when adding options here. @@ -336,15 +343,15 @@ # SSLv2 and SSLv3 are broken. We ban them outright. options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 - if protocol == 'tls1.0': + if protocol == b'tls1.0': # Defaults above are to use TLS 1.0+ pass - elif protocol == 'tls1.1': + elif protocol == b'tls1.1': options |= ssl.OP_NO_TLSv1 - elif protocol == 'tls1.2': + elif protocol == b'tls1.2': options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 else: - raise error.Abort(_('this should not happen')) + raise error.Abort(_(b'this should not happen')) # Prevent CRIME. # There is no guarantee this attribute is defined on the module. @@ -367,7 +374,7 @@ to use. """ if not serverhostname: - raise error.Abort(_('serverhostname argument is required')) + raise error.Abort(_(b'serverhostname argument is required')) if b'SSLKEYLOGFILE' in encoding.environ: try: @@ -388,11 +395,11 @@ for f in (keyfile, certfile): if f and not os.path.exists(f): raise error.Abort( - _('certificate file (%s) does not exist; cannot connect to %s') + _(b'certificate file (%s) does not exist; cannot connect to %s') % (f, pycompat.bytesurl(serverhostname)), hint=_( - 'restore missing file or fix references ' - 'in Mercurial config' + b'restore missing file or fix references ' + b'in Mercurial config' ), ) @@ -405,48 +412,48 @@ # bundle with a specific CA cert removed. If the system/default CA bundle # is loaded and contains that removed CA, you've just undone the user's # choice. - sslcontext = SSLContext(settings['protocol']) + sslcontext = SSLContext(settings[b'protocol']) # This is a no-op unless using modern ssl. - sslcontext.options |= settings['ctxoptions'] + sslcontext.options |= settings[b'ctxoptions'] # This still works on our fake SSLContext. - sslcontext.verify_mode = settings['verifymode'] + sslcontext.verify_mode = settings[b'verifymode'] - if settings['ciphers']: + if settings[b'ciphers']: try: - sslcontext.set_ciphers(pycompat.sysstr(settings['ciphers'])) + sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers'])) except ssl.SSLError as e: raise error.Abort( - _('could not set ciphers: %s') + _(b'could not set ciphers: %s') % stringutil.forcebytestr(e.args[0]), - hint=_('change cipher string (%s) in config') - % settings['ciphers'], + hint=_(b'change cipher string (%s) in config') + % settings[b'ciphers'], ) if certfile is not None: def password(): f = keyfile or certfile - return ui.getpass(_('passphrase for %s: ') % f, '') + return ui.getpass(_(b'passphrase for %s: ') % f, b'') sslcontext.load_cert_chain(certfile, keyfile, password) - if settings['cafile'] is not None: + if settings[b'cafile'] is not None: try: - sslcontext.load_verify_locations(cafile=settings['cafile']) + sslcontext.load_verify_locations(cafile=settings[b'cafile']) except ssl.SSLError as e: if len(e.args) == 1: # pypy has different SSLError args msg = e.args[0] else: msg = e.args[1] raise error.Abort( - _('error loading CA file %s: %s') - % (settings['cafile'], stringutil.forcebytestr(msg)), - hint=_('file is empty or malformed?'), + _(b'error loading CA file %s: %s') + % (settings[b'cafile'], stringutil.forcebytestr(msg)), + hint=_(b'file is empty or malformed?'), ) caloaded = True - elif settings['allowloaddefaultcerts']: + elif settings[b'allowloaddefaultcerts']: # This is a no-op on old Python. sslcontext.load_default_certs() caloaded = True @@ -468,24 +475,24 @@ try: if ( caloaded - and settings['verifymode'] == ssl.CERT_REQUIRED + and settings[b'verifymode'] == ssl.CERT_REQUIRED and modernssl and not sslcontext.get_ca_certs() ): ui.warn( _( - '(an attempt was made to load CA certificates but ' - 'none were loaded; see ' - 'https://mercurial-scm.org/wiki/SecureConnections ' - 'for how to configure Mercurial to avoid this ' - 'error)\n' + b'(an attempt was made to load CA certificates but ' + b'none were loaded; see ' + b'https://mercurial-scm.org/wiki/SecureConnections ' + b'for how to configure Mercurial to avoid this ' + b'error)\n' ) ) except ssl.SSLError: pass # Try to print more helpful error messages for known failures. - if util.safehasattr(e, 'reason'): + if util.safehasattr(e, b'reason'): # This error occurs when the client and server don't share a # common/supported SSL/TLS protocol. We've disabled SSLv2 and SSLv3 # outright. Hopefully the reason for this error is that we require @@ -493,36 +500,36 @@ # reason, try to emit an actionable warning. if e.reason == r'UNSUPPORTED_PROTOCOL': # We attempted TLS 1.0+. - if settings['protocolui'] == 'tls1.0': + if settings[b'protocolui'] == b'tls1.0': # We support more than just TLS 1.0+. If this happens, # the likely scenario is either the client or the server # is really old. (e.g. server doesn't support TLS 1.0+ or # client doesn't support modern TLS versions introduced # several years from when this comment was written). - if supportedprotocols != {'tls1.0'}: + if supportedprotocols != {b'tls1.0'}: ui.warn( _( - '(could not communicate with %s using security ' - 'protocols %s; if you are using a modern Mercurial ' - 'version, consider contacting the operator of this ' - 'server; see ' - 'https://mercurial-scm.org/wiki/SecureConnections ' - 'for more info)\n' + b'(could not communicate with %s using security ' + b'protocols %s; if you are using a modern Mercurial ' + b'version, consider contacting the operator of this ' + b'server; see ' + b'https://mercurial-scm.org/wiki/SecureConnections ' + b'for more info)\n' ) % ( pycompat.bytesurl(serverhostname), - ', '.join(sorted(supportedprotocols)), + b', '.join(sorted(supportedprotocols)), ) ) else: ui.warn( _( - '(could not communicate with %s using TLS 1.0; the ' - 'likely cause of this is the server no longer ' - 'supports TLS 1.0 because it has known security ' - 'vulnerabilities; see ' - 'https://mercurial-scm.org/wiki/SecureConnections ' - 'for more info)\n' + b'(could not communicate with %s using TLS 1.0; the ' + b'likely cause of this is the server no longer ' + b'supports TLS 1.0 because it has known security ' + b'vulnerabilities; see ' + b'https://mercurial-scm.org/wiki/SecureConnections ' + b'for more info)\n' ) % pycompat.bytesurl(serverhostname) ) @@ -533,30 +540,30 @@ # offer. ui.warn( _( - '(could not negotiate a common security protocol (%s+) ' - 'with %s; the likely cause is Mercurial is configured ' - 'to be more secure than the server can support)\n' + b'(could not negotiate a common security protocol (%s+) ' + b'with %s; the likely cause is Mercurial is configured ' + b'to be more secure than the server can support)\n' ) % ( - settings['protocolui'], + settings[b'protocolui'], pycompat.bytesurl(serverhostname), ) ) ui.warn( _( - '(consider contacting the operator of this ' - 'server and ask them to support modern TLS ' - 'protocol versions; or, set ' - 'hostsecurity.%s:minimumprotocol=tls1.0 to allow ' - 'use of legacy, less secure protocols when ' - 'communicating with this server)\n' + b'(consider contacting the operator of this ' + b'server and ask them to support modern TLS ' + b'protocol versions; or, set ' + b'hostsecurity.%s:minimumprotocol=tls1.0 to allow ' + b'use of legacy, less secure protocols when ' + b'communicating with this server)\n' ) % pycompat.bytesurl(serverhostname) ) ui.warn( _( - '(see https://mercurial-scm.org/wiki/SecureConnections ' - 'for more info)\n' + b'(see https://mercurial-scm.org/wiki/SecureConnections ' + b'for more info)\n' ) ) @@ -566,8 +573,8 @@ ui.warn( _( - '(the full certificate chain may not be available ' - 'locally; see "hg help debugssl")\n' + b'(the full certificate chain may not be available ' + b'locally; see "hg help debugssl")\n' ) ) raise @@ -576,13 +583,13 @@ # closed # - see http://bugs.python.org/issue13721 if not sslsocket.cipher(): - raise error.Abort(_('ssl connection failed')) + raise error.Abort(_(b'ssl connection failed')) sslsocket._hgstate = { - 'caloaded': caloaded, - 'hostname': serverhostname, - 'settings': settings, - 'ui': ui, + b'caloaded': caloaded, + b'hostname': serverhostname, + b'settings': settings, + b'ui': ui, } return sslsocket @@ -608,27 +615,27 @@ for f in (certfile, keyfile, cafile): if f and not os.path.exists(f): raise error.Abort( - _('referenced certificate file (%s) does not ' 'exist') % f + _(b'referenced certificate file (%s) does not ' b'exist') % f ) - protocol, options, _protocolui = protocolsettings('tls1.0') + protocol, options, _protocolui = protocolsettings(b'tls1.0') # This config option is intended for use in tests only. It is a giant # footgun to kill security. Don't define it. - exactprotocol = ui.config('devel', 'serverexactprotocol') - if exactprotocol == 'tls1.0': + exactprotocol = ui.config(b'devel', b'serverexactprotocol') + if exactprotocol == b'tls1.0': protocol = ssl.PROTOCOL_TLSv1 - elif exactprotocol == 'tls1.1': - if 'tls1.1' not in supportedprotocols: - raise error.Abort(_('TLS 1.1 not supported by this Python')) + elif exactprotocol == b'tls1.1': + if b'tls1.1' not in supportedprotocols: + raise error.Abort(_(b'TLS 1.1 not supported by this Python')) protocol = ssl.PROTOCOL_TLSv1_1 - elif exactprotocol == 'tls1.2': - if 'tls1.2' not in supportedprotocols: - raise error.Abort(_('TLS 1.2 not supported by this Python')) + elif exactprotocol == b'tls1.2': + if b'tls1.2' not in supportedprotocols: + raise error.Abort(_(b'TLS 1.2 not supported by this Python')) protocol = ssl.PROTOCOL_TLSv1_2 elif exactprotocol: raise error.Abort( - _('invalid value for serverexactprotocol: %s') % exactprotocol + _(b'invalid value for serverexactprotocol: %s') % exactprotocol ) if modernssl: @@ -643,7 +650,7 @@ sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) # Use the list of more secure ciphers if found in the ssl module. - if util.safehasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'): + if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) else: @@ -681,13 +688,13 @@ dn = pycompat.bytesurl(dn) hostname = pycompat.bytesurl(hostname) - pieces = dn.split('.') + pieces = dn.split(b'.') leftmost = pieces[0] remainder = pieces[1:] - wildcards = leftmost.count('*') + wildcards = leftmost.count(b'*') if wildcards > maxwildcards: raise wildcarderror( - _('too many wildcards in certificate DNS name: %s') % dn + _(b'too many wildcards in certificate DNS name: %s') % dn ) # speed up common case w/o wildcards @@ -697,11 +704,11 @@ # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in which # the wildcard character comprises a label other than the left-most label. - if leftmost == '*': + if leftmost == b'*': # When '*' is a fragment by itself, it matches a non-empty dotless # fragment. - pats.append('[^.]+') - elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + pats.append(b'[^.]+') + elif leftmost.startswith(b'xn--') or hostname.startswith(b'xn--'): # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or @@ -709,7 +716,7 @@ pats.append(stringutil.reescape(leftmost)) else: # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(stringutil.reescape(leftmost).replace(br'\*', '[^.]*')) + pats.append(stringutil.reescape(leftmost).replace(br'\*', b'[^.]*')) # add the remaining fragments, ignore any wildcards for frag in remainder: @@ -726,7 +733,7 @@ Returns error message if any problems are found and None on success. ''' if not cert: - return _('no certificate received') + return _(b'no certificate received') dnsnames = [] san = cert.get(r'subjectAltName', []) @@ -751,7 +758,7 @@ try: value = value.encode('ascii') except UnicodeEncodeError: - return _('IDN in certificate not supported') + return _(b'IDN in certificate not supported') try: if _dnsnamematch(value, hostname): @@ -763,11 +770,11 @@ dnsnames = [pycompat.bytesurl(d) for d in dnsnames] if len(dnsnames) > 1: - return _('certificate is for %s') % ', '.join(dnsnames) + return _(b'certificate is for %s') % b', '.join(dnsnames) elif len(dnsnames) == 1: - return _('certificate is for %s') % dnsnames[0] + return _(b'certificate is for %s') % dnsnames[0] else: - return _('no commonName or subjectAltName found in certificate') + return _(b'no commonName or subjectAltName found in certificate') def _plainapplepython(): @@ -785,16 +792,16 @@ ): return False exe = os.path.realpath(pycompat.sysexecutable).lower() - return exe.startswith('/usr/bin/python') or exe.startswith( - '/system/library/frameworks/python.framework/' + return exe.startswith(b'/usr/bin/python') or exe.startswith( + b'/system/library/frameworks/python.framework/' ) _systemcacertpaths = [ # RHEL, CentOS, and Fedora - '/etc/pki/tls/certs/ca-bundle.trust.crt', + b'/etc/pki/tls/certs/ca-bundle.trust.crt', # Debian, Ubuntu, Gentoo - '/etc/ssl/certs/ca-certificates.crt', + b'/etc/ssl/certs/ca-certificates.crt', ] @@ -815,7 +822,7 @@ certs = certifi.where() if os.path.exists(certs): - ui.debug('using ca certificates from certifi\n') + ui.debug(b'using ca certificates from certifi\n') return pycompat.fsencode(certs) except (ImportError, AttributeError): pass @@ -829,9 +836,9 @@ if not _canloaddefaultcerts: ui.warn( _( - '(unable to load Windows CA certificates; see ' - 'https://mercurial-scm.org/wiki/SecureConnections for ' - 'how to configure Mercurial to avoid this message)\n' + b'(unable to load Windows CA certificates; see ' + b'https://mercurial-scm.org/wiki/SecureConnections for ' + b'how to configure Mercurial to avoid this message)\n' ) ) @@ -842,7 +849,7 @@ # trick. if _plainapplepython(): dummycert = os.path.join( - os.path.dirname(pycompat.fsencode(__file__)), 'dummycert.pem' + os.path.dirname(pycompat.fsencode(__file__)), b'dummycert.pem' ) if os.path.exists(dummycert): return dummycert @@ -856,9 +863,9 @@ if not _canloaddefaultcerts: ui.warn( _( - '(unable to load CA certificates; see ' - 'https://mercurial-scm.org/wiki/SecureConnections for ' - 'how to configure Mercurial to avoid this message)\n' + b'(unable to load CA certificates; see ' + b'https://mercurial-scm.org/wiki/SecureConnections for ' + b'how to configure Mercurial to avoid this message)\n' ) ) return None @@ -880,12 +887,12 @@ if os.path.isfile(path): ui.warn( _( - '(using CA certificates from %s; if you see this ' - 'message, your Mercurial install is not properly ' - 'configured; see ' - 'https://mercurial-scm.org/wiki/SecureConnections ' - 'for how to configure Mercurial to avoid this ' - 'message)\n' + b'(using CA certificates from %s; if you see this ' + b'message, your Mercurial install is not properly ' + b'configured; see ' + b'https://mercurial-scm.org/wiki/SecureConnections ' + b'for how to configure Mercurial to avoid this ' + b'message)\n' ) % path ) @@ -893,9 +900,9 @@ ui.warn( _( - '(unable to load CA certificates; see ' - 'https://mercurial-scm.org/wiki/SecureConnections for ' - 'how to configure Mercurial to avoid this message)\n' + b'(unable to load CA certificates; see ' + b'https://mercurial-scm.org/wiki/SecureConnections for ' + b'how to configure Mercurial to avoid this message)\n' ) ) @@ -907,23 +914,23 @@ The passed socket must have been created with ``wrapsocket()``. """ - shost = sock._hgstate['hostname'] + shost = sock._hgstate[b'hostname'] host = pycompat.bytesurl(shost) - ui = sock._hgstate['ui'] - settings = sock._hgstate['settings'] + ui = sock._hgstate[b'ui'] + settings = sock._hgstate[b'settings'] try: peercert = sock.getpeercert(True) peercert2 = sock.getpeercert() except AttributeError: - raise error.Abort(_('%s ssl connection error') % host) + raise error.Abort(_(b'%s ssl connection error') % host) if not peercert: raise error.Abort( - _('%s certificate error: ' 'no certificate received') % host + _(b'%s certificate error: ' b'no certificate received') % host ) - if settings['disablecertverification']: + if settings[b'disablecertverification']: # We don't print the certificate fingerprint because it shouldn't # be necessary: if the user requested certificate verification be # disabled, they presumably already saw a message about the inability @@ -932,9 +939,9 @@ # value. ui.warn( _( - 'warning: connection security to %s is disabled per current ' - 'settings; communication is susceptible to eavesdropping ' - 'and tampering\n' + b'warning: connection security to %s is disabled per current ' + b'settings; communication is susceptible to eavesdropping ' + b'and tampering\n' ) % host ) @@ -943,63 +950,63 @@ # If a certificate fingerprint is pinned, use it and only it to # validate the remote cert. peerfingerprints = { - 'sha1': node.hex(hashlib.sha1(peercert).digest()), - 'sha256': node.hex(hashlib.sha256(peercert).digest()), - 'sha512': node.hex(hashlib.sha512(peercert).digest()), + b'sha1': node.hex(hashlib.sha1(peercert).digest()), + b'sha256': node.hex(hashlib.sha256(peercert).digest()), + b'sha512': node.hex(hashlib.sha512(peercert).digest()), } def fmtfingerprint(s): - return ':'.join([s[x : x + 2] for x in range(0, len(s), 2)]) + return b':'.join([s[x : x + 2] for x in range(0, len(s), 2)]) - nicefingerprint = 'sha256:%s' % fmtfingerprint(peerfingerprints['sha256']) + nicefingerprint = b'sha256:%s' % fmtfingerprint(peerfingerprints[b'sha256']) - if settings['certfingerprints']: - for hash, fingerprint in settings['certfingerprints']: + if settings[b'certfingerprints']: + for hash, fingerprint in settings[b'certfingerprints']: if peerfingerprints[hash].lower() == fingerprint: ui.debug( - '%s certificate matched fingerprint %s:%s\n' + b'%s certificate matched fingerprint %s:%s\n' % (host, hash, fmtfingerprint(fingerprint)) ) - if settings['legacyfingerprint']: + if settings[b'legacyfingerprint']: ui.warn( _( - '(SHA-1 fingerprint for %s found in legacy ' - '[hostfingerprints] section; ' - 'if you trust this fingerprint, remove the old ' - 'SHA-1 fingerprint from [hostfingerprints] and ' - 'add the following entry to the new ' - '[hostsecurity] section: %s:fingerprints=%s)\n' + b'(SHA-1 fingerprint for %s found in legacy ' + b'[hostfingerprints] section; ' + b'if you trust this fingerprint, remove the old ' + b'SHA-1 fingerprint from [hostfingerprints] and ' + b'add the following entry to the new ' + b'[hostsecurity] section: %s:fingerprints=%s)\n' ) % (host, host, nicefingerprint) ) return # Pinned fingerprint didn't match. This is a fatal error. - if settings['legacyfingerprint']: - section = 'hostfingerprint' - nice = fmtfingerprint(peerfingerprints['sha1']) + if settings[b'legacyfingerprint']: + section = b'hostfingerprint' + nice = fmtfingerprint(peerfingerprints[b'sha1']) else: - section = 'hostsecurity' - nice = '%s:%s' % (hash, fmtfingerprint(peerfingerprints[hash])) + section = b'hostsecurity' + nice = b'%s:%s' % (hash, fmtfingerprint(peerfingerprints[hash])) raise error.Abort( - _('certificate for %s has unexpected ' 'fingerprint %s') + _(b'certificate for %s has unexpected ' b'fingerprint %s') % (host, nice), - hint=_('check %s configuration') % section, + hint=_(b'check %s configuration') % section, ) # Security is enabled but no CAs are loaded. We can't establish trust # for the cert so abort. - if not sock._hgstate['caloaded']: + if not sock._hgstate[b'caloaded']: raise error.Abort( _( - 'unable to verify security of %s (no loaded CA certificates); ' - 'refusing to connect' + b'unable to verify security of %s (no loaded CA certificates); ' + b'refusing to connect' ) % host, hint=_( - 'see https://mercurial-scm.org/wiki/SecureConnections for ' - 'how to configure Mercurial to avoid this error or set ' - 'hostsecurity.%s:fingerprints=%s to trust this server' + b'see https://mercurial-scm.org/wiki/SecureConnections for ' + b'how to configure Mercurial to avoid this error or set ' + b'hostsecurity.%s:fingerprints=%s to trust this server' ) % (host, nicefingerprint), ) @@ -1007,11 +1014,11 @@ msg = _verifycert(peercert2, shost) if msg: raise error.Abort( - _('%s certificate error: %s') % (host, msg), + _(b'%s certificate error: %s') % (host, msg), hint=_( - 'set hostsecurity.%s:certfingerprints=%s ' - 'config setting or use --insecure to connect ' - 'insecurely' + b'set hostsecurity.%s:certfingerprints=%s ' + b'config setting or use --insecure to connect ' + b'insecurely' ) % (host, nicefingerprint), )