forked from MirrorHub/synapse
Fix error when loading cert if tls is disabled (#4618)
If TLS is disabled, it should not be an error if no cert is given. Fixes #4554.
This commit is contained in:
parent
46b8a79b3a
commit
32b781bfe2
4 changed files with 47 additions and 18 deletions
1
changelog.d/4618.bugfix
Normal file
1
changelog.d/4618.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix failure to start when not TLS certificate was given even if TLS was disabled.
|
|
@ -213,12 +213,13 @@ def refresh_certificate(hs):
|
||||||
Refresh the TLS certificates that Synapse is using by re-reading them from
|
Refresh the TLS certificates that Synapse is using by re-reading them from
|
||||||
disk and updating the TLS context factories to use them.
|
disk and updating the TLS context factories to use them.
|
||||||
"""
|
"""
|
||||||
hs.config.read_certificate_from_disk()
|
|
||||||
|
|
||||||
if not hs.config.has_tls_listener():
|
if not hs.config.has_tls_listener():
|
||||||
# nothing else to do here
|
# attempt to reload the certs for the good of the tls_fingerprints
|
||||||
|
hs.config.read_certificate_from_disk(require_cert_and_key=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
hs.config.read_certificate_from_disk(require_cert_and_key=True)
|
||||||
hs.tls_server_context_factory = context_factory.ServerContextFactory(hs.config)
|
hs.tls_server_context_factory = context_factory.ServerContextFactory(hs.config)
|
||||||
|
|
||||||
if hs._listening_services:
|
if hs._listening_services:
|
||||||
|
|
|
@ -23,7 +23,7 @@ from unpaddedbase64 import encode_base64
|
||||||
|
|
||||||
from OpenSSL import crypto
|
from OpenSSL import crypto
|
||||||
|
|
||||||
from synapse.config._base import Config
|
from synapse.config._base import Config, ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -45,6 +45,19 @@ class TlsConfig(Config):
|
||||||
|
|
||||||
self.tls_certificate_file = self.abspath(config.get("tls_certificate_path"))
|
self.tls_certificate_file = self.abspath(config.get("tls_certificate_path"))
|
||||||
self.tls_private_key_file = self.abspath(config.get("tls_private_key_path"))
|
self.tls_private_key_file = self.abspath(config.get("tls_private_key_path"))
|
||||||
|
|
||||||
|
if self.has_tls_listener():
|
||||||
|
if not self.tls_certificate_file:
|
||||||
|
raise ConfigError(
|
||||||
|
"tls_certificate_path must be specified if TLS-enabled listeners are "
|
||||||
|
"configured."
|
||||||
|
)
|
||||||
|
if not self.tls_private_key_file:
|
||||||
|
raise ConfigError(
|
||||||
|
"tls_certificate_path must be specified if TLS-enabled listeners are "
|
||||||
|
"configured."
|
||||||
|
)
|
||||||
|
|
||||||
self._original_tls_fingerprints = config.get("tls_fingerprints", [])
|
self._original_tls_fingerprints = config.get("tls_fingerprints", [])
|
||||||
|
|
||||||
if self._original_tls_fingerprints is None:
|
if self._original_tls_fingerprints is None:
|
||||||
|
@ -105,26 +118,40 @@ class TlsConfig(Config):
|
||||||
days_remaining = (expires_on - now).days
|
days_remaining = (expires_on - now).days
|
||||||
return days_remaining
|
return days_remaining
|
||||||
|
|
||||||
def read_certificate_from_disk(self):
|
def read_certificate_from_disk(self, require_cert_and_key):
|
||||||
"""
|
"""
|
||||||
Read the certificates from disk.
|
Read the certificates and private key from disk.
|
||||||
"""
|
|
||||||
self.tls_certificate = self.read_tls_certificate()
|
|
||||||
|
|
||||||
if self.has_tls_listener():
|
Args:
|
||||||
|
require_cert_and_key (bool): set to True to throw an error if the certificate
|
||||||
|
and key file are not given
|
||||||
|
"""
|
||||||
|
if require_cert_and_key:
|
||||||
self.tls_private_key = self.read_tls_private_key()
|
self.tls_private_key = self.read_tls_private_key()
|
||||||
|
self.tls_certificate = self.read_tls_certificate()
|
||||||
|
elif self.tls_certificate_file:
|
||||||
|
# we only need the certificate for the tls_fingerprints. Reload it if we
|
||||||
|
# can, but it's not a fatal error if we can't.
|
||||||
|
try:
|
||||||
|
self.tls_certificate = self.read_tls_certificate()
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(
|
||||||
|
"Unable to read TLS certificate (%s). Ignoring as no "
|
||||||
|
"tls listeners enabled.", e,
|
||||||
|
)
|
||||||
|
|
||||||
self.tls_fingerprints = list(self._original_tls_fingerprints)
|
self.tls_fingerprints = list(self._original_tls_fingerprints)
|
||||||
|
|
||||||
# Check that our own certificate is included in the list of fingerprints
|
if self.tls_certificate:
|
||||||
# and include it if it is not.
|
# Check that our own certificate is included in the list of fingerprints
|
||||||
x509_certificate_bytes = crypto.dump_certificate(
|
# and include it if it is not.
|
||||||
crypto.FILETYPE_ASN1, self.tls_certificate
|
x509_certificate_bytes = crypto.dump_certificate(
|
||||||
)
|
crypto.FILETYPE_ASN1, self.tls_certificate
|
||||||
sha256_fingerprint = encode_base64(sha256(x509_certificate_bytes).digest())
|
)
|
||||||
sha256_fingerprints = set(f["sha256"] for f in self.tls_fingerprints)
|
sha256_fingerprint = encode_base64(sha256(x509_certificate_bytes).digest())
|
||||||
if sha256_fingerprint not in sha256_fingerprints:
|
sha256_fingerprints = set(f["sha256"] for f in self.tls_fingerprints)
|
||||||
self.tls_fingerprints.append({u"sha256": sha256_fingerprint})
|
if sha256_fingerprint not in sha256_fingerprints:
|
||||||
|
self.tls_fingerprints.append({u"sha256": sha256_fingerprint})
|
||||||
|
|
||||||
def default_config(self, config_dir_path, server_name, **kwargs):
|
def default_config(self, config_dir_path, server_name, **kwargs):
|
||||||
base_key_name = os.path.join(config_dir_path, server_name)
|
base_key_name = os.path.join(config_dir_path, server_name)
|
||||||
|
|
|
@ -65,7 +65,7 @@ s4niecZKPBizL6aucT59CsunNmmb5Glq8rlAcU+1ZTZZzGYqVYhF6axB9Qg=
|
||||||
|
|
||||||
t = TestConfig()
|
t = TestConfig()
|
||||||
t.read_config(config)
|
t.read_config(config)
|
||||||
t.read_certificate_from_disk()
|
t.read_certificate_from_disk(require_cert_and_key=False)
|
||||||
|
|
||||||
warnings = self.flushWarnings()
|
warnings = self.flushWarnings()
|
||||||
self.assertEqual(len(warnings), 1)
|
self.assertEqual(len(warnings), 1)
|
||||||
|
|
Loading…
Reference in a new issue