--- a/mercurial/url.py Thu Jan 27 17:22:37 2011 -0600
+++ b/mercurial/url.py Fri Jan 28 03:09:22 2011 +0100
@@ -551,7 +551,8 @@
else:
cacerts = None
- if cacerts:
+ hostfingerprint = self.ui.config('hostfingerprints', self.host)
+ if cacerts and not hostfingerprint:
sock = _create_connection((self.host, self.port))
self.sock = _ssl_wrap_socket(sock, self.key_file,
self.cert_file, cert_reqs=CERT_REQUIRED,
@@ -563,10 +564,33 @@
self.ui.debug('%s certificate successfully verified\n' %
self.host)
else:
- self.ui.warn(_("warning: %s certificate not verified "
- "(check web.cacerts config setting)\n") %
- self.host)
httplib.HTTPSConnection.connect(self)
+ if hasattr(self.sock, 'getpeercert'):
+ peercert = self.sock.getpeercert(True)
+ peerfingerprint = util.sha1(peercert).hexdigest()
+ nicefingerprint = ":".join([peerfingerprint[x:x + 2]
+ for x in xrange(0, len(peerfingerprint), 2)])
+ if hostfingerprint:
+ if peerfingerprint.lower() != \
+ hostfingerprint.replace(':', '').lower():
+ raise util.Abort(_('invalid certificate for %s '
+ 'with fingerprint %s') %
+ (self.host, nicefingerprint))
+ self.ui.debug('%s certificate matched fingerprint %s\n' %
+ (self.host, nicefingerprint))
+ else:
+ self.ui.warn(_('warning: %s certificate '
+ 'with fingerprint %s not verified '
+ '(check hostfingerprints or web.cacerts '
+ 'config setting)\n') %
+ (self.host, nicefingerprint))
+ else: # python 2.5 ?
+ if hostfingerprint:
+ raise util.Abort(_('no certificate for %s '
+ 'with fingerprint') % self.host)
+ self.ui.warn(_('warning: %s certificate not verified '
+ '(check web.cacerts config setting)\n') %
+ self.host)
class httpsconnection(BetterHTTPS):
response_class = keepalive.HTTPResponse