mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-21 20:24:32 +03:00
Address changes. Make federation_domain_whitelist not None
This commit is contained in:
parent
a8adde0624
commit
e083ae39cd
9 changed files with 40 additions and 53 deletions
|
@ -111,13 +111,11 @@ class ServerConfig(Config):
|
||||||
self.admin_contact = config.get("admin_contact", None)
|
self.admin_contact = config.get("admin_contact", None)
|
||||||
|
|
||||||
# FIXME: federation_domain_whitelist needs sytests
|
# FIXME: federation_domain_whitelist needs sytests
|
||||||
self.federation_domain_whitelist = None
|
self.federation_domain_whitelist = {}
|
||||||
federation_domain_whitelist = config.get(
|
federation_domain_whitelist = config.get(
|
||||||
"federation_domain_whitelist", None
|
"federation_domain_whitelist", [],
|
||||||
)
|
)
|
||||||
# turn the whitelist into a hash for speed of lookup
|
# turn the whitelist into a hash for speed of lookup
|
||||||
if federation_domain_whitelist is not None:
|
|
||||||
self.federation_domain_whitelist = {}
|
|
||||||
for domain in federation_domain_whitelist:
|
for domain in federation_domain_whitelist:
|
||||||
self.federation_domain_whitelist[domain] = True
|
self.federation_domain_whitelist[domain] = True
|
||||||
|
|
||||||
|
|
|
@ -77,14 +77,12 @@ class TlsConfig(Config):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Whitelist of domains to not verify certificates for
|
# Whitelist of domains to not verify certificates for
|
||||||
self.federation_certificate_verification_whitelist = None
|
self.federation_certificate_verification_whitelist = {}
|
||||||
federation_certificate_verification_whitelist = config.get(
|
federation_certificate_verification_whitelist = config.get(
|
||||||
"federation_certificate_verification_whitelist", None
|
"federation_certificate_verification_whitelist", [],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Store whitelisted domains in a hash for fast lookup
|
# Store whitelisted domains in a hash for fast lookup
|
||||||
if federation_certificate_verification_whitelist is not None:
|
|
||||||
self.federation_certificate_verification_whitelist = {}
|
|
||||||
for domain in federation_certificate_verification_whitelist:
|
for domain in federation_certificate_verification_whitelist:
|
||||||
self.federation_certificate_verification_whitelist[domain] = True
|
self.federation_certificate_verification_whitelist[domain] = True
|
||||||
|
|
||||||
|
@ -102,7 +100,7 @@ class TlsConfig(Config):
|
||||||
with open(ca_file, 'rb') as f:
|
with open(ca_file, 'rb') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Failed to read custom CA certificate off disk!")
|
logger.fatal("Failed to read custom CA certificate off disk!")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# Parse the CA certificates
|
# Parse the CA certificates
|
||||||
|
@ -110,10 +108,9 @@ class TlsConfig(Config):
|
||||||
cert_base = Certificate.loadPEM(content)
|
cert_base = Certificate.loadPEM(content)
|
||||||
certs.append(cert_base)
|
certs.append(cert_base)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Failed to parse custom CA certificate off disk!")
|
logger.fatal("Failed to parse custom CA certificate off disk!")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if len(certs) > 0:
|
|
||||||
self.federation_custom_ca_list = trustRootFromCertificates(certs)
|
self.federation_custom_ca_list = trustRootFromCertificates(certs)
|
||||||
|
|
||||||
# This config option applies to non-federation HTTP clients
|
# This config option applies to non-federation HTTP clients
|
||||||
|
@ -146,14 +143,12 @@ class TlsConfig(Config):
|
||||||
with open(self.tls_certificate_file, 'rb') as f:
|
with open(self.tls_certificate_file, 'rb') as f:
|
||||||
cert_pem = f.read()
|
cert_pem = f.read()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Failed to read existing certificate off disk!")
|
logger.fatal("Failed to read existing certificate off disk!")
|
||||||
raise
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tls_certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem)
|
tls_certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Failed to parse existing certificate off disk!")
|
logger.fatal("Failed to parse existing certificate off disk!")
|
||||||
raise
|
|
||||||
|
|
||||||
if not allow_self_signed:
|
if not allow_self_signed:
|
||||||
if tls_certificate.get_subject() == tls_certificate.get_issuer():
|
if tls_certificate.get_subject() == tls_certificate.get_issuer():
|
||||||
|
@ -240,10 +235,18 @@ class TlsConfig(Config):
|
||||||
|
|
||||||
# Whether to verify TLS certificates when sending federation traffic.
|
# Whether to verify TLS certificates when sending federation traffic.
|
||||||
#
|
#
|
||||||
|
# This currently defaults to `false`, however this will change in
|
||||||
|
# Synapse 1.0 when valid federation certificates will be required.
|
||||||
|
#
|
||||||
#federation_verify_certificates: true
|
#federation_verify_certificates: true
|
||||||
|
|
||||||
# Prevent federation certificate validation on the following whitelist
|
# Skip federation certificate validation on the following whitelist of
|
||||||
# of domains. Only effective if federation_verify_certicates is true.
|
# domains.
|
||||||
|
#
|
||||||
|
# Note that this should only be used within the context of private
|
||||||
|
# federation as it will otherwise break things.
|
||||||
|
#
|
||||||
|
# Only effective if federation_verify_certicates is `true`.
|
||||||
#
|
#
|
||||||
#federation_certificate_validation_whitelist:
|
#federation_certificate_validation_whitelist:
|
||||||
# - lon.example.com
|
# - lon.example.com
|
||||||
|
|
|
@ -18,7 +18,10 @@ import logging
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
|
||||||
from OpenSSL import SSL, crypto
|
from OpenSSL import SSL, crypto
|
||||||
from twisted.internet._sslverify import OpenSSLCertificateAuthorities, _defaultCurveName
|
from twisted.internet._sslverify import (
|
||||||
|
ClientTLSOptions as ClientTLSOptionsVerify,
|
||||||
|
_defaultCurveName,
|
||||||
|
)
|
||||||
from twisted.internet.abstract import isIPAddress, isIPv6Address
|
from twisted.internet.abstract import isIPAddress, isIPv6Address
|
||||||
from twisted.internet.interfaces import IOpenSSLClientConnectionCreator
|
from twisted.internet.interfaces import IOpenSSLClientConnectionCreator
|
||||||
from twisted.internet.ssl import CertificateOptions, ContextFactory, platformTrust
|
from twisted.internet.ssl import CertificateOptions, ContextFactory, platformTrust
|
||||||
|
@ -132,7 +135,7 @@ class ClientTLSOptionsFactory(object):
|
||||||
self._options_novalidate = CertificateOptions()
|
self._options_novalidate = CertificateOptions()
|
||||||
|
|
||||||
# Check if we're using a custom list of a CA certificates
|
# Check if we're using a custom list of a CA certificates
|
||||||
if isinstance(config.federation_custom_ca_list, OpenSSLCertificateAuthorities):
|
if config.federation_custom_ca_list is not None:
|
||||||
self._options_validate = CertificateOptions(
|
self._options_validate = CertificateOptions(
|
||||||
# Use custom CA trusted root certs
|
# Use custom CA trusted root certs
|
||||||
trustRoot=config.federation_custom_ca_list,
|
trustRoot=config.federation_custom_ca_list,
|
||||||
|
@ -152,7 +155,7 @@ class ClientTLSOptionsFactory(object):
|
||||||
if (self._config.federation_verify_certificates and
|
if (self._config.federation_verify_certificates and
|
||||||
host not in self._config.federation_certificate_validation_whitelist):
|
host not in self._config.federation_certificate_validation_whitelist):
|
||||||
# Require verification
|
# Require verification
|
||||||
return ClientTLSOptions(host, self._options_validate._makeContext())
|
return ClientTLSOptionsVerify(host, self._options_validate._makeContext())
|
||||||
|
|
||||||
# Otherwise don't require verification
|
# Otherwise don't require verification
|
||||||
return ClientTLSOptions(host, self._options_novalidate._makeContext())
|
return ClientTLSOptions(host, self._options_novalidate._makeContext())
|
||||||
|
|
|
@ -127,10 +127,7 @@ class Authenticator(object):
|
||||||
json_request["origin"] = origin
|
json_request["origin"] = origin
|
||||||
json_request["signatures"].setdefault(origin, {})[key] = sig
|
json_request["signatures"].setdefault(origin, {})[key] = sig
|
||||||
|
|
||||||
if (
|
if (origin not in self.federation_domain_whitelist):
|
||||||
self.federation_domain_whitelist is not None and
|
|
||||||
origin not in self.federation_domain_whitelist
|
|
||||||
):
|
|
||||||
raise FederationDeniedError(origin)
|
raise FederationDeniedError(origin)
|
||||||
|
|
||||||
if not json_request["signatures"]:
|
if not json_request["signatures"]:
|
||||||
|
|
|
@ -177,7 +177,6 @@ class MatrixFederationHttpClient(object):
|
||||||
self.agent = MatrixFederationAgent(
|
self.agent = MatrixFederationAgent(
|
||||||
hs.get_reactor(),
|
hs.get_reactor(),
|
||||||
tls_client_options_factory,
|
tls_client_options_factory,
|
||||||
hs.config,
|
|
||||||
)
|
)
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
self._store = hs.get_datastore()
|
self._store = hs.get_datastore()
|
||||||
|
@ -284,10 +283,7 @@ class MatrixFederationHttpClient(object):
|
||||||
else:
|
else:
|
||||||
_sec_timeout = self.default_timeout
|
_sec_timeout = self.default_timeout
|
||||||
|
|
||||||
if (
|
if (request.destination not in self.hs.config.federation_domain_whitelist):
|
||||||
self.hs.config.federation_domain_whitelist is not None and
|
|
||||||
request.destination not in self.hs.config.federation_domain_whitelist
|
|
||||||
):
|
|
||||||
raise FederationDeniedError(request.destination)
|
raise FederationDeniedError(request.destination)
|
||||||
|
|
||||||
limiter = yield synapse.util.retryutils.get_retry_limiter(
|
limiter = yield synapse.util.retryutils.get_retry_limiter(
|
||||||
|
|
|
@ -139,10 +139,7 @@ class RemoteKey(Resource):
|
||||||
|
|
||||||
store_queries = []
|
store_queries = []
|
||||||
for server_name, key_ids in query.items():
|
for server_name, key_ids in query.items():
|
||||||
if (
|
if (server_name not in self.federation_domain_whitelist):
|
||||||
self.federation_domain_whitelist is not None and
|
|
||||||
server_name not in self.federation_domain_whitelist
|
|
||||||
):
|
|
||||||
logger.debug("Federation denied with %s", server_name)
|
logger.debug("Federation denied with %s", server_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -231,10 +231,7 @@ class MediaRepository(object):
|
||||||
Deferred: Resolves once a response has successfully been written
|
Deferred: Resolves once a response has successfully been written
|
||||||
to request
|
to request
|
||||||
"""
|
"""
|
||||||
if (
|
if (server_name not in self.federation_domain_whitelist):
|
||||||
self.federation_domain_whitelist is not None and
|
|
||||||
server_name not in self.federation_domain_whitelist
|
|
||||||
):
|
|
||||||
raise FederationDeniedError(server_name)
|
raise FederationDeniedError(server_name)
|
||||||
|
|
||||||
self.mark_recently_accessed(server_name, media_id)
|
self.mark_recently_accessed(server_name, media_id)
|
||||||
|
@ -271,10 +268,7 @@ class MediaRepository(object):
|
||||||
Returns:
|
Returns:
|
||||||
Deferred[dict]: The media_info of the file
|
Deferred[dict]: The media_info of the file
|
||||||
"""
|
"""
|
||||||
if (
|
if (server_name not in self.federation_domain_whitelist):
|
||||||
self.federation_domain_whitelist is not None and
|
|
||||||
server_name not in self.federation_domain_whitelist
|
|
||||||
):
|
|
||||||
raise FederationDeniedError(server_name)
|
raise FederationDeniedError(server_name)
|
||||||
|
|
||||||
# We linearize here to ensure that we don't try and download remote
|
# We linearize here to ensure that we don't try and download remote
|
||||||
|
|
|
@ -39,6 +39,7 @@ from synapse.util.logcontext import LoggingContext
|
||||||
from tests.http import ServerTLSContext
|
from tests.http import ServerTLSContext
|
||||||
from tests.server import FakeTransport, ThreadedMemoryReactorClock
|
from tests.server import FakeTransport, ThreadedMemoryReactorClock
|
||||||
from tests.unittest import TestCase
|
from tests.unittest import TestCase
|
||||||
|
from tests.utils import default_config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -49,16 +50,11 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
|
|
||||||
self.mock_resolver = Mock()
|
self.mock_resolver = Mock()
|
||||||
|
|
||||||
config = Mock()
|
|
||||||
config.federation_custom_ca_list = None
|
|
||||||
config.federation_verify_certificates = False
|
|
||||||
config.federation_certificate_validation_whitelist = []
|
|
||||||
|
|
||||||
self.well_known_cache = TTLCache("test_cache", timer=self.reactor.seconds)
|
self.well_known_cache = TTLCache("test_cache", timer=self.reactor.seconds)
|
||||||
|
|
||||||
self.agent = MatrixFederationAgent(
|
self.agent = MatrixFederationAgent(
|
||||||
reactor=self.reactor,
|
reactor=self.reactor,
|
||||||
tls_client_options_factory=ClientTLSOptionsFactory(config),
|
tls_client_options_factory=ClientTLSOptionsFactory(default_config()),
|
||||||
_well_known_tls_policy=TrustingTLSPolicyForHTTPS(),
|
_well_known_tls_policy=TrustingTLSPolicyForHTTPS(),
|
||||||
_srv_resolver=self.mock_resolver,
|
_srv_resolver=self.mock_resolver,
|
||||||
_well_known_cache=self.well_known_cache,
|
_well_known_cache=self.well_known_cache,
|
||||||
|
|
|
@ -136,7 +136,10 @@ def default_config(name):
|
||||||
config.worker_app = None
|
config.worker_app = None
|
||||||
config.email_enable_notifs = False
|
config.email_enable_notifs = False
|
||||||
config.block_non_admin_invites = False
|
config.block_non_admin_invites = False
|
||||||
config.federation_domain_whitelist = None
|
config.federation_domain_whitelist = []
|
||||||
|
config.federation_certificate_verification_whitelist = []
|
||||||
|
config.federation_custom_ca_list = []
|
||||||
|
config.federation_verify_certificates = False
|
||||||
config.federation_rc_reject_limit = 10
|
config.federation_rc_reject_limit = 10
|
||||||
config.federation_rc_sleep_limit = 10
|
config.federation_rc_sleep_limit = 10
|
||||||
config.federation_rc_sleep_delay = 100
|
config.federation_rc_sleep_delay = 100
|
||||||
|
|
Loading…
Reference in a new issue