← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~lgp171188/launchpad:mirror-prober-sni-fix into launchpad:master

 

Guruprasad has proposed merging ~lgp171188/launchpad:mirror-prober-sni-fix into launchpad:master.

Commit message:
Send SNI when connecting to a HTTPS mirror through a proxy

Thanks to Keyu Tao (https://launchpad.net/~taoky) for suggesting the fix.

LP: #1885585


Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1885585 in Launchpad itself: "Mirror prober incorrectly reports an invalid SSL certificate"
  https://bugs.launchpad.net/launchpad/+bug/1885585

For more details, see:
https://code.launchpad.net/~lgp171188/launchpad/+git/launchpad/+merge/474546
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~lgp171188/launchpad:mirror-prober-sni-fix into launchpad:master.
diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py
index aed0097..d63904b 100644
--- a/lib/lp/registry/tests/test_distributionmirror_prober.py
+++ b/lib/lp/registry/tests/test_distributionmirror_prober.py
@@ -25,6 +25,7 @@ from testtools.twistedsupport import (
 from twisted.internet import defer, reactor, ssl
 from twisted.python.failure import Failure
 from twisted.web import server
+from twisted.web.client import URI as TwistedWebClientURI
 from twisted.web.client import BrowserLikePolicyForHTTPS
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
@@ -259,22 +260,6 @@ class TestProberHTTPSProtocolAndFactory(TestCase):
 
         return deferred.addCallback(got_result)
 
-    def test_https_prober_uses_proxy(self):
-        proxy_port = 6654
-        self.pushConfig(
-            "launchpad", http_proxy="http://localhost:%s"; % proxy_port
-        )
-
-        url = "https://localhost:%s/valid-mirror/file"; % self.port
-        prober = RedirectAwareProberFactory(url, timeout=0.5)
-        self.assertEqual(prober.url, url)
-
-        # We just want to check that it did the request using the correct
-        # Agent, pointing to the correct proxy config.
-        agent = prober.getHttpsClient()._agent
-        self.assertIsInstance(agent, TunnelingAgent)
-        self.assertEqual(("localhost", proxy_port, None), agent._proxyConf)
-
     def test_https_fails_on_invalid_certificates(self):
         """Changes set back the default browser-like policy for HTTPS
         request and make sure the request is failing due to invalid
@@ -316,6 +301,30 @@ class TestProberHTTPSProtocolAndFactory(TestCase):
         return assert_fails_with(deferred, InvalidHTTPSCertificateSkipped)
 
 
+class TestProberHTTPSProxy(TestCase):
+    def test_https_prober_uses_proxy_and_sends_sni(self):
+        proxy_port = 6654
+        self.pushConfig(
+            "launchpad", http_proxy=f"http://localhost:{proxy_port}";
+        )
+
+        url = "https://mirror.example.com/valid-mirror/file";
+        prober = RedirectAwareProberFactory(url, timeout=0.5)
+        self.assertEqual(prober.url, url)
+
+        # We just want to check that it did the request using the correct
+        # Agent, pointing to the correct proxy config, configured with the
+        # correct SNI hostname.
+        agent = prober.getHttpsClient()._agent
+        self.assertIsInstance(agent, TunnelingAgent)
+        self.assertEqual(("localhost", proxy_port, None), agent._proxyConf)
+        endpoint = agent._getEndpoint(
+            TwistedWebClientURI.fromBytes(url.encode())
+        )
+        sni_hostname = endpoint._contextFactory._hostname
+        self.assertEqual("mirror.example.com", sni_hostname)
+
+
 class TestProberProtocolAndFactory(TestCase):
     layer = TwistedLayer
     run_tests_with = AsynchronousDeferredRunTestForBrokenTwisted.make_factory(
diff --git a/lib/lp/services/httpproxy/connect_tunneling.py b/lib/lp/services/httpproxy/connect_tunneling.py
index c2f945c..deb6f7f 100644
--- a/lib/lp/services/httpproxy/connect_tunneling.py
+++ b/lib/lp/services/httpproxy/connect_tunneling.py
@@ -44,7 +44,7 @@ class TunnelingTCP4ClientEndpoint(TCP4ClientEndpoint):
         super().__init__(reactor, proxyHost, proxyPort, timeout, bindAddress)
         self._tunneledHost = host
         self._tunneledPort = port
-        self._contextFactory = contextFactory
+        self._contextFactory = contextFactory.creatorForNetloc(host, port)
         self._tunnelReadyDeferred = defer.Deferred()
         self._connectDeferred = None
         self._protocol = None

Follow ups