##// END OF EJS Templates
url: 'ssh known host'-like checking of fingerprints of HTTPS certificates...
Mads Kiilerich -
r13314:8dc488df stable
parent child Browse files
Show More
@@ -423,6 +423,24 b' Example for ``~/.hgrc``::'
423 423 myfeature = ~/.hgext/myfeature.py
424 424
425 425
426 ``hostfingerprints``
427 """"""""""""""""""""
428
429 Fingerprints of the certificates of known HTTPS servers.
430 A HTTPS connection to a server with a fingerprint configured here will
431 only succeed if the servers certificate matches the fingerprint.
432 This is very similar to how ssh known hosts works.
433 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
434 The CA chain and web.cacerts is not used for servers with a fingerprint.
435
436 For example::
437
438 [hostfingerprints]
439 hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc
440
441 This feature is only supported when using Python 2.6 or later.
442
443
426 444 ``format``
427 445 """"""""""
428 446
@@ -546,7 +546,7 b' def remoteui(src, opts):'
546 546 dst.setconfig('bundle', 'mainreporoot', r)
547 547
548 548 # copy selected local settings to the remote ui
549 for sect in ('auth', 'http_proxy'):
549 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
550 550 for key, val in src.configitems(sect):
551 551 dst.setconfig(sect, key, val)
552 552 v = src.config('web', 'cacerts')
@@ -533,7 +533,8 b' if has_https:'
533 533 else:
534 534 cacerts = None
535 535
536 if cacerts:
536 hostfingerprint = self.ui.config('hostfingerprints', self.host)
537 if cacerts and not hostfingerprint:
537 538 sock = _create_connection((self.host, self.port))
538 539 self.sock = _ssl_wrap_socket(sock, self.key_file,
539 540 self.cert_file, cert_reqs=CERT_REQUIRED,
@@ -545,10 +546,33 b' if has_https:'
545 546 self.ui.debug('%s certificate successfully verified\n' %
546 547 self.host)
547 548 else:
548 self.ui.warn(_("warning: %s certificate not verified "
549 "(check web.cacerts config setting)\n") %
550 self.host)
551 549 httplib.HTTPSConnection.connect(self)
550 if hasattr(self.sock, 'getpeercert'):
551 peercert = self.sock.getpeercert(True)
552 peerfingerprint = util.sha1(peercert).hexdigest()
553 nicefingerprint = ":".join([peerfingerprint[x:x + 2]
554 for x in xrange(0, len(peerfingerprint), 2)])
555 if hostfingerprint:
556 if peerfingerprint.lower() != \
557 hostfingerprint.replace(':', '').lower():
558 raise util.Abort(_('invalid certificate for %s '
559 'with fingerprint %s') %
560 (self.host, nicefingerprint))
561 self.ui.debug('%s certificate matched fingerprint %s\n' %
562 (self.host, nicefingerprint))
563 else:
564 self.ui.warn(_('warning: %s certificate '
565 'with fingerprint %s not verified '
566 '(check hostfingerprints or web.cacerts '
567 'config setting)\n') %
568 (self.host, nicefingerprint))
569 else: # python 2.5 ?
570 if hostfingerprint:
571 raise util.Abort(_('no certificate for %s '
572 'with fingerprint') % self.host)
573 self.ui.warn(_('warning: %s certificate not verified '
574 '(check web.cacerts config setting)\n') %
575 self.host)
552 576
553 577 class httpsconnection(BetterHTTPS):
554 578 response_class = keepalive.HTTPResponse
@@ -106,7 +106,7 b' Test server address cannot be reused'
106 106 clone via pull
107 107
108 108 $ hg clone https://localhost:$HGPORT/ copy-pull
109 warning: localhost certificate not verified (check web.cacerts config setting)
109 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)
110 110 requesting all changes
111 111 adding changesets
112 112 adding manifests
@@ -132,7 +132,7 b' pull without cacert'
132 132 $ echo '[hooks]' >> .hg/hgrc
133 133 $ echo "changegroup = python '$TESTDIR'/printenv.py changegroup" >> .hg/hgrc
134 134 $ hg pull
135 warning: localhost certificate not verified (check web.cacerts config setting)
135 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)
136 136 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=https://localhost:$HGPORT/
137 137 pulling from https://localhost:$HGPORT/
138 138 searching for changes
@@ -188,3 +188,22 b' Test server cert which no longer is vali'
188 188 $ hg -R copy-pull pull --config web.cacerts=pub-expired.pem https://localhost:$HGPORT2/
189 189 abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
190 190 [255]
191
192 Fingerprints
193
194 $ echo "[hostfingerprints]" >> copy-pull/.hg/hgrc
195 $ echo "localhost = 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca" >> copy-pull/.hg/hgrc
196 $ echo "127.0.0.1 = 914f1aff87249c09b6859b88b1906d30756491ca" >> copy-pull/.hg/hgrc
197
198 - works without cacerts
199 $ hg -R copy-pull id https://localhost:$HGPORT/ --config web.cacerts=
200 5fed3813f7f5
201
202 - fails when cert doesn't match hostname (port is ignored)
203 $ hg -R copy-pull id https://localhost:$HGPORT1/
204 abort: invalid certificate for localhost with fingerprint 28:ff:71:bf:65:31:14:23:ad:62:92:b4:0e:31:99:18:fc:83:e3:9b
205 [255]
206
207 - ignores that certificate doesn't match hostname
208 $ hg -R copy-pull id https://127.0.0.1:$HGPORT/
209 5fed3813f7f5
General Comments 0
You need to be logged in to leave comments. Login now