[PATCH 8 of 8] sslutil: reference appropriate config section in messaging

timeless timeless at gmail.com
Sat May 28 22:17:14 EDT 2016


For starters, the hints should be on their own line... (Not a strike
against this patch)
On May 28, 2016 4:05 PM, "Gregory Szorc" <gregory.szorc at gmail.com> wrote:

> # HG changeset patch
> # User Gregory Szorc <gregory.szorc at gmail.com>
> # Date 1464465526 25200
> #      Sat May 28 12:58:46 2016 -0700
> # Node ID 8a57327eb7ab175ce91abdc06dc8a60130575cf7
> # Parent  969eddf5985326d5c4fd26da95fa19247339e6a0
> sslutil: reference appropriate config section in messaging
>
> Error messages reference the config section defining the host
> fingerprint. Now that we have multiple sections where this config
> setting could live, we need to point the user at the appropriate
> one.
>
> We default to the new "hostsecurity" section. But we will still
> refer them to the "hostfingerprint" section if a value is defined
> there.
>
> There are some corner cases where the messaging might be off. e.g.
> they could define a SHA-1 fingerprint in both sections. IMO the
> messaging needs a massive overhaul. I plan to do this as part
> of future refactoring to security settings.
>
> diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
> --- a/mercurial/sslutil.py
> +++ b/mercurial/sslutil.py
> @@ -112,16 +112,18 @@ def _hostsettings(ui, hostname):
>      Returns a dict of settings relevant to that hostname.
>      """
>      s = {
>          # List of 2-tuple of (hash algorithm, hash).
>          'certfingerprints': [],
>          # Path to file containing concatenated CA certs. Used by
>          # SSLContext.load_verify_locations().
>          'cafile': None,
> +        # Whether the legacy [hostfingerprints] section has data for this
> host.
> +        'legacyfingerprint': False,
>          # ssl.CERT_* constant used by SSLContext.verify_mode.
>          'verifymode': None,
>      }
>
>      # Look for fingerprints in [hostsecurity] section. Value is a list
>      # of <alg>:<fingerprint> strings.
>      fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' %
> hostname,
>                                   [])
> @@ -135,16 +137,17 @@ def _hostsettings(ui, hostname):
>          alg, fingerprint = fingerprint.split(':', 1)
>          fingerprint = fingerprint.replace(':', '').lower()
>          s['certfingerprints'].append((alg, fingerprint))
>
>      # Fingerprints from [hostfingerprints] are always SHA-1.
>      for fingerprint in ui.configlist('hostfingerprints', hostname, []):
>          fingerprint = fingerprint.replace(':', '').lower()
>          s['certfingerprints'].append(('sha1', fingerprint))
> +        s['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
>
>      # If --insecure is used, don't take CAs into consideration.
>      elif ui.insecureconnections:
> @@ -345,55 +348,60 @@ def validatesocket(sock, strict=False):
>      peerfingerprints = {
>          'sha1': util.sha1(peercert).hexdigest(),
>          'sha256': util.sha256(peercert).hexdigest(),
>          'sha512': util.sha512(peercert).hexdigest(),
>      }
>      nicefingerprint = ':'.join([peerfingerprints['sha1'][x:x + 2]
>          for x in range(0, len(peerfingerprints['sha1']), 2)])
>
> +    if settings['legacyfingerprint']:
> +        section = 'hostfingerprint'
> +    else:
> +        section = 'hostsecurity'
> +
>      if settings['certfingerprints']:
>          fingerprintmatch = False
>          for hash, fingerprint in settings['certfingerprints']:
>              if peerfingerprints[hash].lower() == fingerprint:
>                  fingerprintmatch = True
>                  break
>          if not fingerprintmatch:
>              raise error.Abort(_('certificate for %s has unexpected '
>                                 'fingerprint %s') % (host,
> nicefingerprint),
> -                             hint=_('check hostfingerprint
> configuration'))
> +                             hint=_('check %s configuration') % section)
>          ui.debug('%s certificate matched fingerprint %s\n' %
>                   (host, nicefingerprint))
>          return
>
>      # If insecure connections were explicitly requested via --insecure,
>      # print a warning and do no verification.
>      #
>      # It may seem odd that this is checked *after* host fingerprint
> pinning.
>      # This is for backwards compatibility (for now). The message is also
>      # the same as below for BC.
>      if ui.insecureconnections:
>          ui.warn(_('warning: %s certificate with fingerprint %s not '
> -                  'verified (check hostfingerprints or web.cacerts '
> +                  'verified (check %s or web.cacerts '
>                    'config setting)\n') %
> -                (host, nicefingerprint))
> +                (host, nicefingerprint, section))
>          return
>
>      if not sock._hgstate['caloaded']:
>          if strict:
>              raise error.Abort(_('%s certificate with fingerprint %s not '
>                                  'verified') % (host, nicefingerprint),
> -                              hint=_('check hostfingerprints or '
> -                                     'web.cacerts config setting'))
> +                              hint=_('check %s or web.cacerts config '
> +                                     'setting') % section)
>          else:
>              ui.warn(_('warning: %s certificate with fingerprint %s '
> -                      'not verified (check hostfingerprints or '
> -                      'web.cacerts config setting)\n') %
> -                    (host, nicefingerprint))
> +                      'not verified (check %s or web.cacerts config '
> +                      'setting)\n') %
> +                    (host, nicefingerprint, section))
>
>          return
>
>      msg = _verifycert(peercert2, host)
>      if msg:
>          raise error.Abort(_('%s certificate error: %s') % (host, msg),
> -                         hint=_('configure hostfingerprint %s or use '
> +                         hint=_('configure %s %s or use '
>                                  '--insecure to connect insecurely') %
> -                              nicefingerprint)
> +                              (section, nicefingerprint))
> diff --git a/tests/test-https.t b/tests/test-https.t
> --- a/tests/test-https.t
> +++ b/tests/test-https.t
> @@ -172,17 +172,17 @@ Apple's OpenSSL. This trick do not work
>    [255]
>
>    $ DISABLEOSXDUMMYCERT="--insecure"
>  #endif
>
>  clone via pull
>
>    $ hg clone https://localhost:$HGPORT/ copy-pull $DISABLEOSXDUMMYCERT
> -  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    requesting all changes
>    adding changesets
>    adding manifests
>    adding file changes
>    added 1 changesets with 4 changes to 4 files
>    updating to branch default
>    4 files updated, 0 files merged, 0 files removed, 0 files unresolved
>    $ hg verify -R copy-pull
> @@ -199,17 +199,17 @@ clone via pull
>
>  pull without cacert
>
>    $ cd copy-pull
>    $ echo '[hooks]' >> .hg/hgrc
>    $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
>    $ hg pull $DISABLEOSXDUMMYCERT
>    pulling from https://localhost:$HGPORT/
> -  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    searching for changes
>    adding changesets
>    adding manifests
>    adding file changes
>    added 1 changesets with 1 changes to 1 files
>    changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
> HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull
> HG_TXNID=TXN:* HG_URL=https://localhost:$HGPORT/ (glob)
>    (run 'hg update' to get a working copy)
>    $ cd ..
> @@ -231,39 +231,39 @@ variables in the filename
>    $ echo "[web]" >> $HGRCPATH
>    $ echo 'cacerts=$P/pub.pem' >> $HGRCPATH
>    $ P=`pwd` hg -R copy-pull pull
>    pulling from https://localhost:$HGPORT/
>    searching for changes
>    no changes found
>    $ P=`pwd` hg -R copy-pull pull --insecure
>    pulling from https://localhost:$HGPORT/
> -  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    searching for changes
>    no changes found
>
>  cacert mismatch
>
>    $ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:
> $HGPORT/
>    pulling from https://127.0.0.1:$HGPORT/
>    abort: 127.0.0.1 certificate error: certificate is for localhost
> -  (configure hostfingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca or use
> --insecure to connect insecurely)
> +  (configure hostsecurity
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca or use
> --insecure to connect insecurely)
>    [255]
>    $ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/
> --insecure
>    pulling from https://127.0.0.1:$HGPORT/
> -  warning: 127.0.0.1 certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: 127.0.0.1 certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    searching for changes
>    no changes found
>    $ hg -R copy-pull pull --config web.cacerts=pub-other.pem
>    pulling from https://localhost:$HGPORT/
>    abort: error: *certificate verify failed* (glob)
>    [255]
>    $ hg -R copy-pull pull --config web.cacerts=pub-other.pem --insecure
>    pulling from https://localhost:$HGPORT/
> -  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    searching for changes
>    no changes found
>
>  Test server cert which isn't valid yet
>
>    $ hg serve -R test -p $HGPORT1 -d --pid-file=hg1.pid
> --certificate=server-not-yet.pem
>    $ cat hg1.pid >> $DAEMON_PIDS
>    $ hg -R copy-pull pull --config web.cacerts=pub-not-yet.pem
> https://localhost:$HGPORT1/
> @@ -311,17 +311,17 @@ Fingerprints
>
>    $ hg --config
> 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef,
> aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
> --insecure
>    abort: certificate for localhost has unexpected fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca
>    (check hostfingerprint configuration)
>    [255]
>
>    $ hg --config
> 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef,
> sha1:aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id
> https://localhost:$HGPORT/
>    abort: certificate for localhost has unexpected fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca
> -  (check hostfingerprint configuration)
> +  (check hostsecurity configuration)
>    [255]
>
>  - fails when cert doesn't match hostname (port is ignored)
>    $ hg -R copy-pull id https://localhost:$HGPORT1/ --config
> hostfingerprints.localhost=914f1aff87249c09b6859b88b1906d30756491ca
>    abort: certificate for localhost has unexpected fingerprint
> 28:ff:71:bf:65:31:14:23:ad:62:92:b4:0e:31:99:18:fc:83:e3:9b
>    (check hostfingerprint configuration)
>    [255]
>
> @@ -343,17 +343,17 @@ Prepare for connecting through proxy
>    $ echo "always=True" >> copy-pull/.hg/hgrc
>    $ echo "[hostfingerprints]" >> copy-pull/.hg/hgrc
>    $ echo "localhost =" >> copy-pull/.hg/hgrc
>
>  Test unvalidated https through proxy
>
>    $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull
> --insecure --traceback
>    pulling from https://localhost:$HGPORT/
> -  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostfingerprints or web.cacerts config setting)
> +  warning: localhost certificate with fingerprint
> 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified
> (check hostsecurity or web.cacerts config setting)
>    searching for changes
>    no changes found
>
>  Test https with cacert and fingerprint through proxy
>
>    $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --config
> web.cacerts=pub.pem
>    pulling from https://localhost:$HGPORT/
>    searching for changes
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20160528/84ddfad2/attachment.html>


More information about the Mercurial-devel mailing list