Mercurial > hg-stable
changeset 29249:cca59ef27e60
sslutil: move sslkwargs logic into internal function (API)
As the previous commit documented, sslkwargs() doesn't add any
value since its return is treated as a black box and proxied
to wrapsocket().
We formalize its uselessness by moving its logic into a
new, internal function and make sslkwargs() return an empty
dict.
The certificate arguments that sslkwargs specified have been
removed from wrapsocket() because they should no longer be
set.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 25 May 2016 19:52:02 -0700 |
parents | e6de6ef3e426 |
children | d6b9468eebee |
files | mercurial/sslutil.py |
diffstat | 1 files changed, 46 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/sslutil.py Wed May 25 19:43:22 2016 -0700 +++ b/mercurial/sslutil.py Wed May 25 19:52:02 2016 -0700 @@ -106,8 +106,49 @@ return ssl.wrap_socket(socket, **args) -def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, - ca_certs=None, serverhostname=None): +def _determinecertoptions(ui, host): + """Determine certificate options for a connections. + + Returns a tuple of (cert_reqs, ca_certs). + """ + # If a host key fingerprint is on file, it is the only thing that matters + # and CA certs don't come into play. + hostfingerprint = ui.config('hostfingerprints', host) + if hostfingerprint: + return ssl.CERT_NONE, None + + # The code below sets up CA verification arguments. If --insecure is + # used, we don't take CAs into consideration, so return early. + if ui.insecureconnections: + return ssl.CERT_NONE, None + + cacerts = ui.config('web', 'cacerts') + + # If a value is set in the config, validate against a path and load + # and require those certs. + if cacerts: + cacerts = util.expandpath(cacerts) + if not os.path.exists(cacerts): + raise error.Abort(_('could not find web.cacerts: %s') % cacerts) + + return ssl.CERT_REQUIRED, cacerts + + # No CAs in config. See if we can load defaults. + cacerts = _defaultcacerts() + + # We found an alternate CA bundle to use. Load it. + if cacerts: + ui.debug('using %s to enable OS X system CA\n' % cacerts) + ui.setconfig('web', 'cacerts', cacerts, 'defaultcacerts') + return ssl.CERT_REQUIRED, cacerts + + # FUTURE this can disappear once wrapsocket() is secure by default. + if _canloaddefaultcerts: + return ssl.CERT_REQUIRED, None + + return ssl.CERT_NONE, None + +def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): """Add SSL/TLS to a socket. This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane @@ -123,6 +164,8 @@ if not serverhostname: raise error.Abort('serverhostname argument is required') + cert_reqs, ca_certs = _determinecertoptions(ui, serverhostname) + # Despite its name, PROTOCOL_SSLv23 selects the highest protocol # that both ends support, including TLS protocols. On legacy stacks, # the highest it likely goes in TLS 1.0. On modern stacks, it can @@ -243,53 +286,7 @@ return None def sslkwargs(ui, host): - """Determine arguments to pass to wrapsocket(). - - ``host`` is the hostname being connected to. - """ - kws = {} - - # If a host key fingerprint is on file, it is the only thing that matters - # and CA certs don't come into play. - hostfingerprint = ui.config('hostfingerprints', host) - if hostfingerprint: - return kws - - # The code below sets up CA verification arguments. If --insecure is - # used, we don't take CAs into consideration, so return early. - if ui.insecureconnections: - return kws - - cacerts = ui.config('web', 'cacerts') - - # If a value is set in the config, validate against a path and load - # and require those certs. - if cacerts: - cacerts = util.expandpath(cacerts) - if not os.path.exists(cacerts): - raise error.Abort(_('could not find web.cacerts: %s') % cacerts) - - kws.update({'ca_certs': cacerts, - 'cert_reqs': ssl.CERT_REQUIRED}) - return kws - - # No CAs in config. See if we can load defaults. - cacerts = _defaultcacerts() - - # We found an alternate CA bundle to use. Load it. - if cacerts: - ui.debug('using %s to enable OS X system CA\n' % cacerts) - ui.setconfig('web', 'cacerts', cacerts, 'defaultcacerts') - kws.update({'ca_certs': cacerts, - 'cert_reqs': ssl.CERT_REQUIRED}) - return kws - - # FUTURE this can disappear once wrapsocket() is secure by default. - if _canloaddefaultcerts: - kws['cert_reqs'] = ssl.CERT_REQUIRED - return kws - - return kws + return {} def validatesocket(sock, strict=False): """Validate a socket meets security requiremnets.