[PATCH 2 of 2] url: check server certificates when connecting through proxy (issue2407)

Mads Kiilerich mads at kiilerich.com
Sun Oct 31 20:11:38 CDT 2010


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1288573886 -3600
# Branch stable
# Node ID 391543217c1a222deb236d1fcc426e264921cd82
# Parent  191f4f62a3ae7d9f27b3b16267c4f1400fd2451f
url: check server certificates when connecting through proxy (issue2407)

diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -540,8 +540,25 @@
                 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                 self.sock.connect((self.host, self.port))
                 if _generic_proxytunnel(self):
-                    self.sock = _ssl_wrap_socket(self.sock, self.key_file,
-                            self.cert_file)
+                    if hasattr(self, 'ui'):
+                        cacerts = self.ui.config('web', 'cacerts')
+                    else:
+                        cacerts = None
+
+                    if cacerts:
+                        self.sock = _ssl_wrap_socket(self.sock, self.key_file,
+                                self.cert_file, cert_reqs=CERT_REQUIRED,
+                                ca_certs=cacerts)
+                        realhost = self.realhostport.rsplit(':', 1)[0]
+                        msg = _verifycert(self.sock.getpeercert(), realhost)
+                        if msg:
+                            raise util.Abort(_('%s certificate error: %s') %
+                                             (realhost, msg))
+                        self.ui.debug('%s certificate successfully verified\n' %
+                                      realhost)
+                    else:
+                        self.sock = _ssl_wrap_socket(self.sock, self.key_file,
+                                self.cert_file)
             else:
                 BetterHTTPS.connect(self)
 
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -169,3 +169,36 @@
   $ hg -R copy-pull pull --config web.cacerts=pub-expired.pem https://localhost:$HGPORT2/
   abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
   [255]
+
+Prepare for connecting through proxy
+
+  $ kill `cat hg1.pid`
+  $ sleep 1
+
+  $ ("$TESTDIR/tinyproxy.py" $HGPORT1 localhost >proxy.log 2>&1 </dev/null &
+  $ echo $! > proxy.pid)
+  $ cat proxy.pid >> $DAEMON_PIDS
+  $ sleep 2
+
+Test verification of certificates when connecting with https through proxy
+
+  $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True -R copy-pull pull
+  pulling from https://localhost:$HGPORT/
+  searching for changes
+  no changes found
+
+Test using cacert through proxy
+
+  $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True -R copy-pull pull --config web.cacerts=pub.pem
+  pulling from https://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/
+  abort: 127.0.0.1 certificate error: certificate is for localhost
+  [255]
+  $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True -R copy-pull pull --config web.cacerts=pub-other.pem
+  abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
+  [255]
+  $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True -R copy-pull pull --config web.cacerts=pub-expired.pem https://localhost:$HGPORT2/
+  abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
+  [255]


More information about the Mercurial-devel mailing list