matrixsynapse: Better checking for valid certificate

If a valid certificate is available but not yet setup, the earlier code assumes
there is a valid certificate.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
Sunil Mohan Adapa 2019-02-13 19:02:28 -08:00
parent b169739867
commit e448ab6380
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
2 changed files with 35 additions and 11 deletions

View File

@ -20,6 +20,7 @@ Configuration helper for Matrix-Synapse server.
""" """
import argparse import argparse
import filecmp
import os import os
import shutil import shutil
import sys import sys
@ -52,7 +53,7 @@ def parse_arguments():
help_le = "Add/drop Let's Encrypt certificate if configured domain matches" help_le = "Add/drop Let's Encrypt certificate if configured domain matches"
subparser = subparsers.add_parser('letsencrypt', help=help_le) subparser = subparsers.add_parser('letsencrypt', help=help_le)
subparser.add_argument('command', choices=('add', 'drop'), subparser.add_argument('command', choices=('add', 'drop', 'get-status'),
help='Whether to add or drop the certificate') help='Whether to add or drop the certificate')
subparser.add_argument('--domain', subparser.add_argument('--domain',
help='Domain name to renew certificates for') help='Domain name to renew certificates for')
@ -61,6 +62,30 @@ def parse_arguments():
return parser.parse_args() return parser.parse_args()
def _get_certificate_status():
"""Return if the current certificate is an up-to-date LE certificate."""
configured_domain = get_configured_domain_name()
if not configured_domain:
return False
if not os.path.exists(letsencrypt.LIVE_DIRECTORY):
return False
source_dir = os.path.join(letsencrypt.LIVE_DIRECTORY, configured_domain)
source_certificate_path = os.path.join(source_dir, 'fullchain.pem')
source_private_key_path = os.path.join(source_dir, 'privkey.pem')
dest_dir = '/etc/matrix-synapse'
dest_certificate_path = os.path.join(dest_dir, 'homeserver.tls.crt')
dest_private_key_path = os.path.join(dest_dir, 'homeserver.tls.key')
if filecmp.cmp(source_certificate_path, dest_certificate_path) and \
filecmp.cmp(source_private_key_path, dest_private_key_path):
return True
return False
def _update_tls_certificate(): def _update_tls_certificate():
"""Update the TLS certificate and private key used by Matrix Synapse. """Update the TLS certificate and private key used by Matrix Synapse.
@ -182,7 +207,7 @@ def subcommand_public_registration(argument):
def subcommand_letsencrypt(arguments): def subcommand_letsencrypt(arguments):
"""Add/drop usage of Let's Encrypt cert. """Add/drop usage of Let's Encrypt cert or show status.
The command 'add' applies only to current domain, will be called by action The command 'add' applies only to current domain, will be called by action
'letsencrypt run_renew_hooks', when certbot renews the cert (if 'letsencrypt run_renew_hooks', when certbot renews the cert (if
@ -190,9 +215,13 @@ def subcommand_letsencrypt(arguments):
for any domain to respond to domain change. for any domain to respond to domain change.
""" """
if arguments.command != 'add': if arguments.command == 'drop':
print('Dropping certificates is not supported for Matrix Synapse.') print('Dropping certificates is not supported for Matrix Synapse.')
sys.exit(0) return
if arguments.command == 'get-status':
print('valid' if _get_certificate_status() else 'invalid')
return
configured_domain = get_configured_domain_name() configured_domain = get_configured_domain_name()
if arguments.domain is not None and \ if arguments.domain is not None and \

View File

@ -164,10 +164,5 @@ def get_public_registration_status():
def has_valid_certificate(): def has_valid_certificate():
"""Return whether the configured domain name has a valid certificate.""" """Return whether the configured domain name has a valid certificate."""
domain_name = get_configured_domain_name() status = actions.superuser_run('matrixsynapse', ['letsencrypt', 'get-status'])
status = actions.superuser_run('letsencrypt', ['get-status']) return status.startswith('valid')
status = json.loads(status)
if domain_name in status['domains']:
return status['domains'][domain_name]['certificate_available']
return False