From 3d605853c8e649ab4b3f91fb0a32cc77ef05d71f Mon Sep 17 00:00:00 2001 From: Jeroen Date: Sun, 24 Jun 2018 22:38:43 +0200 Subject: send SNI for federation requests --- synapse/http/endpoint.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'synapse/http/endpoint.py') diff --git a/synapse/http/endpoint.py b/synapse/http/endpoint.py index 87a482650d..e783f95719 100644 --- a/synapse/http/endpoint.py +++ b/synapse/http/endpoint.py @@ -26,7 +26,6 @@ import time logger = logging.getLogger(__name__) - SERVER_CACHE = {} # our record of an individual server which can be tried to reach a destination. @@ -38,15 +37,15 @@ _Server = collections.namedtuple( ) -def matrix_federation_endpoint(reactor, destination, ssl_context_factory=None, +def matrix_federation_endpoint(reactor, destination, tls_client_options_factory=None, timeout=None): """Construct an endpoint for the given matrix destination. Args: reactor: Twisted reactor. destination (bytes): The name of the server to connect to. - ssl_context_factory (twisted.internet.ssl.ContextFactory): Factory - which generates SSL contexts to use for TLS. + tls_client_options_factory (synapse.crypto.context_factory.ClientTLSOptionsFactory): + Factory which generates TLS options for client connections. timeout (int): connection timeout in seconds """ @@ -59,13 +58,13 @@ def matrix_federation_endpoint(reactor, destination, ssl_context_factory=None, if timeout is not None: endpoint_kw_args.update(timeout=timeout) - if ssl_context_factory is None: + if tls_client_options_factory is None: transport_endpoint = HostnameEndpoint default_port = 8008 else: def transport_endpoint(reactor, host, port, timeout): return wrapClientTLS( - ssl_context_factory, + tls_client_options_factory.get_options(unicode(host)), HostnameEndpoint(reactor, host, port, timeout=timeout)) default_port = 8448 -- cgit 1.4.1 From 07b4f88de9ee534629db29aa4fc398607e7d866e Mon Sep 17 00:00:00 2001 From: Jeroen Date: Mon, 25 Jun 2018 12:31:16 +0200 Subject: formatting changes for pep8 --- synapse/config/tls.py | 4 +++- synapse/crypto/context_factory.py | 4 ++-- synapse/http/endpoint.py | 3 ++- synapse/http/matrixfederationclient.py | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'synapse/http/endpoint.py') diff --git a/synapse/config/tls.py b/synapse/config/tls.py index 4e7d1bd93e..b09dc986ab 100644 --- a/synapse/config/tls.py +++ b/synapse/config/tls.py @@ -47,7 +47,9 @@ class TlsConfig(Config): self.tls_fingerprints = config["tls_fingerprints"] - self.tls_ignore_certificate_validation = config.get("tls_ignore_certificate_validation", False) + self.tls_ignore_certificate_validation = config.get( + "tls_ignore_certificate_validation", False + ) # Check that our own certificate is included in the list of fingerprints # and include it if it is not. diff --git a/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py index 297a5fb045..415899e62b 100644 --- a/synapse/crypto/context_factory.py +++ b/synapse/crypto/context_factory.py @@ -14,8 +14,8 @@ from twisted.internet import ssl from OpenSSL import SSL, crypto -from twisted.internet._sslverify import _defaultCurveName, ClientTLSOptions, OpenSSLCertificateOptions, \ - optionsForClientTLS +from twisted.internet._sslverify import _defaultCurveName, ClientTLSOptions, \ + OpenSSLCertificateOptions, optionsForClientTLS import logging diff --git a/synapse/http/endpoint.py b/synapse/http/endpoint.py index e783f95719..abf4862084 100644 --- a/synapse/http/endpoint.py +++ b/synapse/http/endpoint.py @@ -44,7 +44,8 @@ def matrix_federation_endpoint(reactor, destination, tls_client_options_factory= Args: reactor: Twisted reactor. destination (bytes): The name of the server to connect to. - tls_client_options_factory (synapse.crypto.context_factory.ClientTLSOptionsFactory): + tls_client_options_factory + (synapse.crypto.context_factory.ClientTLSOptionsFactory): Factory which generates TLS options for client connections. timeout (int): connection timeout in seconds """ diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py index 66796a202f..b48d05fcd2 100644 --- a/synapse/http/matrixfederationclient.py +++ b/synapse/http/matrixfederationclient.py @@ -69,7 +69,7 @@ class MatrixFederationEndpointFactory(object): return matrix_federation_endpoint( reactor, destination, timeout=10, - tls_client_options_factory = self.tls_client_options_factory + tls_client_options_factory=self.tls_client_options_factory ) -- cgit 1.4.1 From b7f34ee348c9f064d98922dfdbe24a3cf18ca00a Mon Sep 17 00:00:00 2001 From: Jeroen Date: Tue, 26 Jun 2018 20:41:05 +0200 Subject: allow self-signed certificates --- synapse/config/tls.py | 11 -------- synapse/crypto/context_factory.py | 58 +++++++++++++++++++++++---------------- synapse/http/endpoint.py | 2 +- 3 files changed, 36 insertions(+), 35 deletions(-) (limited to 'synapse/http/endpoint.py') diff --git a/synapse/config/tls.py b/synapse/config/tls.py index b09dc986ab..b66154bc7c 100644 --- a/synapse/config/tls.py +++ b/synapse/config/tls.py @@ -47,10 +47,6 @@ class TlsConfig(Config): self.tls_fingerprints = config["tls_fingerprints"] - self.tls_ignore_certificate_validation = config.get( - "tls_ignore_certificate_validation", False - ) - # Check that our own certificate is included in the list of fingerprints # and include it if it is not. x509_certificate_bytes = crypto.dump_certificate( @@ -77,8 +73,6 @@ class TlsConfig(Config): tls_private_key_path = base_key_name + ".tls.key" tls_dh_params_path = base_key_name + ".tls.dh" - tls_ignore_certificate_validation = False - return """\ # PEM encoded X509 certificate for TLS. # You can replace the self-signed certificate that synapse @@ -123,11 +117,6 @@ class TlsConfig(Config): # tls_fingerprints: [] # tls_fingerprints: [{"sha256": ""}] - - # Ignore certificate validation for TLS client connections to other - # homeservers using federation. Don't enable this in a production - # environment, unless you know what you are doing! - tls_ignore_certificate_validation: %(tls_ignore_certificate_validation)s """ % locals() def read_tls_certificate(self, cert_path): diff --git a/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py index 415899e62b..e93afbf975 100644 --- a/synapse/crypto/context_factory.py +++ b/synapse/crypto/context_factory.py @@ -11,18 +11,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import logging -from twisted.internet import ssl +import idna from OpenSSL import SSL, crypto -from twisted.internet._sslverify import _defaultCurveName, ClientTLSOptions, \ - OpenSSLCertificateOptions, optionsForClientTLS - -import logging +from twisted.internet.ssl import ContextFactory, CertificateOptions +from twisted.internet._sslverify import _defaultCurveName, _tolerateErrors +from twisted.internet.interfaces import IOpenSSLClientConnectionCreator +from zope.interface import implementer logger = logging.getLogger(__name__) -class ServerContextFactory(ssl.ContextFactory): +class ServerContextFactory(ContextFactory): """Factory for PyOpenSSL SSL contexts that are used to handle incoming connections and to make connections to remote servers.""" @@ -51,18 +52,31 @@ class ServerContextFactory(ssl.ContextFactory): return self._context -class ClientTLSOptionsNoCertVerification(ClientTLSOptions): - """Redefinition of ClientTLSOptions to completely ignore certificate - validation. Should be kept in sync with the original class in Twisted. - This version of ClientTLSOptions is only intended for development use.""" +@implementer(IOpenSSLClientConnectionCreator) +class ClientTLSOptions(object): + """ + Client creator for TLS without certificate identity verification. This is a + copy of twisted.internet._sslverify.ClientTLSOptions with the identity + verification left out. For documentation, see the twisted documentation. + """ - def __init__(self, *args, **kwargs): - super(ClientTLSOptionsNoCertVerification, self).__init__(*args, **kwargs) + def __init__(self, hostname, ctx): + self._ctx = ctx + self._hostname = hostname + self._hostnameBytes = idna.encode(hostname) + ctx.set_info_callback( + _tolerateErrors(self._identityVerifyingInfoCallback) + ) - def do_nothing(*_args, **_kwargs): - pass + def clientConnectionForTLS(self, tlsProtocol): + context = self._ctx + connection = SSL.Connection(context, None) + connection.set_app_data(tlsProtocol) + return connection - self._ctx.set_info_callback(do_nothing) + def _identityVerifyingInfoCallback(self, connection, where, ret): + if where & SSL.SSL_CB_HANDSHAKE_START: + connection.set_tlsext_host_name(self._hostnameBytes) class ClientTLSOptionsFactory(object): @@ -70,13 +84,11 @@ class ClientTLSOptionsFactory(object): to remote servers for federation.""" def __init__(self, config): - self._ignore_certificate_validation = config.tls_ignore_certificate_validation + # We don't use config options yet + pass def get_options(self, host): - if self._ignore_certificate_validation: - return ClientTLSOptionsNoCertVerification( - unicode(host), - OpenSSLCertificateOptions(verify=False).getContext() - ) - else: - return optionsForClientTLS(unicode(host)) + return ClientTLSOptions( + unicode(host), + CertificateOptions(verify=False).getContext() + ) diff --git a/synapse/http/endpoint.py b/synapse/http/endpoint.py index abf4862084..39432da452 100644 --- a/synapse/http/endpoint.py +++ b/synapse/http/endpoint.py @@ -65,7 +65,7 @@ def matrix_federation_endpoint(reactor, destination, tls_client_options_factory= else: def transport_endpoint(reactor, host, port, timeout): return wrapClientTLS( - tls_client_options_factory.get_options(unicode(host)), + tls_client_options_factory.get_options(host), HostnameEndpoint(reactor, host, port, timeout=timeout)) default_port = 8448 -- cgit 1.4.1