Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/sslutil.py @ 29268:f200b58497f1
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.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 28 May 2016 12:58:46 -0700 |
parents | f0ccb6cde3e5 |
children | a05a91a3f120 |
comparison
equal
deleted
inserted
replaced
29267:f0ccb6cde3e5 | 29268:f200b58497f1 |
---|---|
115 # List of 2-tuple of (hash algorithm, hash). | 115 # List of 2-tuple of (hash algorithm, hash). |
116 'certfingerprints': [], | 116 'certfingerprints': [], |
117 # Path to file containing concatenated CA certs. Used by | 117 # Path to file containing concatenated CA certs. Used by |
118 # SSLContext.load_verify_locations(). | 118 # SSLContext.load_verify_locations(). |
119 'cafile': None, | 119 'cafile': None, |
120 # Whether the legacy [hostfingerprints] section has data for this host. | |
121 'legacyfingerprint': False, | |
120 # ssl.CERT_* constant used by SSLContext.verify_mode. | 122 # ssl.CERT_* constant used by SSLContext.verify_mode. |
121 'verifymode': None, | 123 'verifymode': None, |
122 } | 124 } |
123 | 125 |
124 # Look for fingerprints in [hostsecurity] section. Value is a list | 126 # Look for fingerprints in [hostsecurity] section. Value is a list |
138 | 140 |
139 # Fingerprints from [hostfingerprints] are always SHA-1. | 141 # Fingerprints from [hostfingerprints] are always SHA-1. |
140 for fingerprint in ui.configlist('hostfingerprints', hostname, []): | 142 for fingerprint in ui.configlist('hostfingerprints', hostname, []): |
141 fingerprint = fingerprint.replace(':', '').lower() | 143 fingerprint = fingerprint.replace(':', '').lower() |
142 s['certfingerprints'].append(('sha1', fingerprint)) | 144 s['certfingerprints'].append(('sha1', fingerprint)) |
145 s['legacyfingerprint'] = True | |
143 | 146 |
144 # If a host cert fingerprint is defined, it is the only thing that | 147 # If a host cert fingerprint is defined, it is the only thing that |
145 # matters. No need to validate CA certs. | 148 # matters. No need to validate CA certs. |
146 if s['certfingerprints']: | 149 if s['certfingerprints']: |
147 s['verifymode'] = ssl.CERT_NONE | 150 s['verifymode'] = ssl.CERT_NONE |
348 'sha512': util.sha512(peercert).hexdigest(), | 351 'sha512': util.sha512(peercert).hexdigest(), |
349 } | 352 } |
350 nicefingerprint = ':'.join([peerfingerprints['sha1'][x:x + 2] | 353 nicefingerprint = ':'.join([peerfingerprints['sha1'][x:x + 2] |
351 for x in range(0, len(peerfingerprints['sha1']), 2)]) | 354 for x in range(0, len(peerfingerprints['sha1']), 2)]) |
352 | 355 |
356 if settings['legacyfingerprint']: | |
357 section = 'hostfingerprint' | |
358 else: | |
359 section = 'hostsecurity' | |
360 | |
353 if settings['certfingerprints']: | 361 if settings['certfingerprints']: |
354 fingerprintmatch = False | 362 fingerprintmatch = False |
355 for hash, fingerprint in settings['certfingerprints']: | 363 for hash, fingerprint in settings['certfingerprints']: |
356 if peerfingerprints[hash].lower() == fingerprint: | 364 if peerfingerprints[hash].lower() == fingerprint: |
357 fingerprintmatch = True | 365 fingerprintmatch = True |
358 break | 366 break |
359 if not fingerprintmatch: | 367 if not fingerprintmatch: |
360 raise error.Abort(_('certificate for %s has unexpected ' | 368 raise error.Abort(_('certificate for %s has unexpected ' |
361 'fingerprint %s') % (host, nicefingerprint), | 369 'fingerprint %s') % (host, nicefingerprint), |
362 hint=_('check hostfingerprint configuration')) | 370 hint=_('check %s configuration') % section) |
363 ui.debug('%s certificate matched fingerprint %s\n' % | 371 ui.debug('%s certificate matched fingerprint %s\n' % |
364 (host, nicefingerprint)) | 372 (host, nicefingerprint)) |
365 return | 373 return |
366 | 374 |
367 # If insecure connections were explicitly requested via --insecure, | 375 # If insecure connections were explicitly requested via --insecure, |
370 # It may seem odd that this is checked *after* host fingerprint pinning. | 378 # It may seem odd that this is checked *after* host fingerprint pinning. |
371 # This is for backwards compatibility (for now). The message is also | 379 # This is for backwards compatibility (for now). The message is also |
372 # the same as below for BC. | 380 # the same as below for BC. |
373 if ui.insecureconnections: | 381 if ui.insecureconnections: |
374 ui.warn(_('warning: %s certificate with fingerprint %s not ' | 382 ui.warn(_('warning: %s certificate with fingerprint %s not ' |
375 'verified (check hostfingerprints or web.cacerts ' | 383 'verified (check %s or web.cacerts ' |
376 'config setting)\n') % | 384 'config setting)\n') % |
377 (host, nicefingerprint)) | 385 (host, nicefingerprint, section)) |
378 return | 386 return |
379 | 387 |
380 if not sock._hgstate['caloaded']: | 388 if not sock._hgstate['caloaded']: |
381 if strict: | 389 if strict: |
382 raise error.Abort(_('%s certificate with fingerprint %s not ' | 390 raise error.Abort(_('%s certificate with fingerprint %s not ' |
383 'verified') % (host, nicefingerprint), | 391 'verified') % (host, nicefingerprint), |
384 hint=_('check hostfingerprints or ' | 392 hint=_('check %s or web.cacerts config ' |
385 'web.cacerts config setting')) | 393 'setting') % section) |
386 else: | 394 else: |
387 ui.warn(_('warning: %s certificate with fingerprint %s ' | 395 ui.warn(_('warning: %s certificate with fingerprint %s ' |
388 'not verified (check hostfingerprints or ' | 396 'not verified (check %s or web.cacerts config ' |
389 'web.cacerts config setting)\n') % | 397 'setting)\n') % |
390 (host, nicefingerprint)) | 398 (host, nicefingerprint, section)) |
391 | 399 |
392 return | 400 return |
393 | 401 |
394 msg = _verifycert(peercert2, host) | 402 msg = _verifycert(peercert2, host) |
395 if msg: | 403 if msg: |
396 raise error.Abort(_('%s certificate error: %s') % (host, msg), | 404 raise error.Abort(_('%s certificate error: %s') % (host, msg), |
397 hint=_('configure hostfingerprint %s or use ' | 405 hint=_('configure %s %s or use ' |
398 '--insecure to connect insecurely') % | 406 '--insecure to connect insecurely') % |
399 nicefingerprint) | 407 (section, nicefingerprint)) |