Procházet zdrojové kódy

Use MatrixFederationAgent for binds to Synapse (#157)

Stop using the InsecureInterceptableContextFactory and instead use MatrixFederationAgent which can handle .well-known server files.
Andrew Morgan před 5 roky
rodič
revize
bb346c458f
2 změnil soubory, kde provedl 25 přidání a 34 odebrání
  1. 6 0
      sydent/http/httpclient.py
  2. 19 34
      sydent/threepid/bind.py

+ 6 - 0
sydent/http/httpclient.py

@@ -86,6 +86,12 @@ class HTTPClient(object):
             headers,
             bodyProducer=FileBodyProducer(StringIO(json_str))
         )
+
+        # Ensure the body object is read otherwise we'll leak HTTP connections
+        # as per
+        # https://twistedmatrix.com/documents/current/web/howto/client.html
+        yield readBody(response)
+
         defer.returnValue(response)
 
 class SimpleHttpClient(HTTPClient):

+ 19 - 34
sydent/threepid/bind.py

@@ -26,6 +26,7 @@ from sydent.db.threepid_associations import LocalAssociationStore
 
 from sydent.util import time_msec
 from sydent.threepid.signer import Signer
+from sydent.http.httpclient import FederationHttpClient
 
 from sydent.threepid import ThreepidAssociation
 
@@ -101,29 +102,28 @@ class ThreepidBinder:
         mxid = assoc["mxid"]
         domain = mxid.split(":")[-1]
         server = yield self._pickServer(domain)
-        callbackUrl = "https://%s/_matrix/federation/v1/3pid/onbind" % (
+
+        post_url = "https://%s/_matrix/federation/v1/3pid/onbind" % (
             server,
         )
 
-        logger.info("Making bind callback to: %s", callbackUrl)
-        # TODO: Not be woefully insecure
-        agent = Agent(reactor, InsecureInterceptableContextFactory())
-        reqDeferred = agent.request(
-            "POST",
-            callbackUrl.encode("utf8"),
-            Headers({
-                "Content-Type": ["application/json"],
-                "User-Agent": ["Sydent"],
-            }),
-            FileBodyProducer(StringIO(json.dumps(assoc)))
-        )
-        reqDeferred.addCallback(
-            lambda _: logger.info("Successfully notified on bind for %s" % (mxid,))
-        )
+        logger.info("Making bind callback to: %s", post_url)
 
-        reqDeferred.addErrback(
-            lambda err: self._notifyErrback(assoc, attempt, err)
-        )
+        # Make a POST to the chosen Synapse server
+        http_client = FederationHttpClient(self.sydent)
+        try:
+            response = yield http_client.post_json_get_nothing(post_url, assoc, {})
+        except Exception as e:
+            self._notifyErrback(assoc, attempt, e)
+            return
+
+        # If the request failed, try again with exponential backoff
+        if response.code != 200:
+            self._notifyErrback(
+                assoc, attempt, "Non-OK error code received (%d)" % response.code
+            )
+        else:
+            logger.info("Successfully notified on bind for %s" % (mxid,))
 
     def _notifyErrback(self, assoc, attempt, error):
         logger.warn("Error notifying on bind for %s: %s - rescheduling", assoc["mxid"], error)
@@ -185,18 +185,3 @@ class ThreepidBinder:
 
         servers.sort()
         defer.returnValue(servers)
-
-
-class InsecureInterceptableContextFactory(ssl.ContextFactory):
-    """
-    Factory for PyOpenSSL SSL contexts which accepts any certificate for any domain.
-
-    Do not use this since it allows an attacker to intercept your communications.
-    """
-
-    def __init__(self):
-        self._context = SSL.Context(SSL.SSLv23_METHOD)
-        self._context.set_verify(VERIFY_NONE, lambda *_: None)
-
-    def getContext(self, hostname, port):
-        return self._context