comparison mercurial/sslutil.py @ 29289:3536673a25ae

sslutil: move and change warning when cert verification is disabled A short time ago, validatesocket() didn't know the reasons why cert verification was disabled. Multiple code paths could lead to cert verification being disabled. e.g. --insecure and lack of loaded CAs. With the recent refactorings to sslutil.py, we now know the reasons behind security settings. This means we can recognize when the user requested security be disabled (as opposed to being unable to provide certificate verification due to lack of CAs). This patch moves the check for certificate verification being disabled and changes the wording to distinguish it from other states. The warning message is purposefully more dangerous sounding in order to help discourage people from disabling security outright. We may want to add a URL or hint to this message. I'm going to wait until additional changes to security defaults before committing to something.
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 30 May 2016 13:15:53 -0700
parents 7dee15dee53c
children 01248c37a68e
comparison
equal deleted inserted replaced
29288:7dee15dee53c 29289:3536673a25ae
352 352
353 if not peercert: 353 if not peercert:
354 raise error.Abort(_('%s certificate error: ' 354 raise error.Abort(_('%s certificate error: '
355 'no certificate received') % host) 355 'no certificate received') % host)
356 356
357 if settings['disablecertverification']:
358 # We don't print the certificate fingerprint because it shouldn't
359 # be necessary: if the user requested certificate verification be
360 # disabled, they presumably already saw a message about the inability
361 # to verify the certificate and this message would have printed the
362 # fingerprint. So printing the fingerprint here adds little to no
363 # value.
364 ui.warn(_('warning: connection security to %s is disabled per current '
365 'settings; communication is susceptible to eavesdropping '
366 'and tampering\n') % host)
367 return
368
357 # If a certificate fingerprint is pinned, use it and only it to 369 # If a certificate fingerprint is pinned, use it and only it to
358 # validate the remote cert. 370 # validate the remote cert.
359 peerfingerprints = { 371 peerfingerprints = {
360 'sha1': util.sha1(peercert).hexdigest(), 372 'sha1': util.sha1(peercert).hexdigest(),
361 'sha256': util.sha256(peercert).hexdigest(), 373 'sha256': util.sha256(peercert).hexdigest(),
381 hint=_('check %s configuration') % section) 393 hint=_('check %s configuration') % section)
382 ui.debug('%s certificate matched fingerprint %s\n' % 394 ui.debug('%s certificate matched fingerprint %s\n' %
383 (host, nicefingerprint)) 395 (host, nicefingerprint))
384 return 396 return
385 397
386 # If insecure connections were explicitly requested, print a warning
387 # and do no verification.
388 #
389 # It may seem odd that this is checked *after* host fingerprint pinning.
390 # This is for backwards compatibility (for now). The message is also
391 # the same as below for BC.
392 if settings['disablecertverification']:
393 ui.warn(_('warning: %s certificate with fingerprint %s not '
394 'verified (check %s or web.cacerts '
395 'config setting)\n') %
396 (host, nicefingerprint, section))
397 return
398
399 if not sock._hgstate['caloaded']: 398 if not sock._hgstate['caloaded']:
400 ui.warn(_('warning: %s certificate with fingerprint %s ' 399 ui.warn(_('warning: %s certificate with fingerprint %s '
401 'not verified (check %s or web.cacerts config ' 400 'not verified (check %s or web.cacerts config '
402 'setting)\n') % 401 'setting)\n') %
403 (host, nicefingerprint, section)) 402 (host, nicefingerprint, section))