From ea8150d9dd25217c45bb959db40d64be21483cd7 Mon Sep 17 00:00:00 2001 From: fliu <10025-fliu@users.noreply.salsa.debian.org> Date: Fri, 13 Aug 2021 04:23:20 +0000 Subject: [PATCH] email: setup: Find Let's Encrypt certificates --- plinth/modules/email_server/audit/tls.py | 54 +++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/plinth/modules/email_server/audit/tls.py b/plinth/modules/email_server/audit/tls.py index 8b581a311..72736a9d3 100644 --- a/plinth/modules/email_server/audit/tls.py +++ b/plinth/modules/email_server/audit/tls.py @@ -2,11 +2,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later import logging +import os from plinth import actions from . import models -from plinth.modules.email_server import postconf +from plinth.modules.email_server import interproc, postconf # Mozilla Guideline v5.6, Postfix 1.17.7, OpenSSL 1.1.1d, intermediate # Generated 2021-08 @@ -52,6 +53,13 @@ postfix_config = { 'tls_high_cipherlist': '$tls_medium_cipherlist', } +dovecot_cert_config = '/etc/dovecot/conf.d/91-freedombox-ssl.conf' + +dovecot_cert_template = """# This file is managed by FreedomBox +ssl_cert = <{cert} +ssl_key = <{key} +""" + logger = logging.getLogger(__name__) @@ -79,6 +87,50 @@ def repair_tls(diagnosis): postconf.set_many_unsafe(diagnosis.advice) +def try_set_up_certificates(): + cert_folder = find_cert_folder() + if not cert_folder: + logger.warning('Could not find a suitable TLS certificate') + return + logger.info('Using TLS certificate in %s', cert_folder) + + cert = cert_folder + '/cert.pem' + key = cert_folder + '/privkey.pem' + write_postfix_cert_config(cert, key) + write_dovecot_cert_config(cert, key) + + +def find_cert_folder() -> str: + directory = '/etc/letsencrypt/live' + domains_available = [] + for item in os.listdir(directory): + if item[0] != '.' and os.path.isdir(directory + '/' + item): + domains_available.append(item) + domains_available.sort() + + if len(domains_available) == 0: + return '' + if len(domains_available) == 1: + return directory + '/' + domains_available[0] + # XXX Cannot handle the case with multiple domains + if len(domains_available) > 1: + return '' + + +def write_postfix_cert_config(cert, key): + postconf.set_many_unsafe({ + 'smtpd_tls_cert_file': cert, + 'smtpd_tls_key_file': key + }) + + +def write_dovecot_cert_config(cert, key): + content = dovecot_cert_template.format(cert=cert, key=key) + with interproc.atomically_rewrite(dovecot_cert_config) as fd: + fd.write(content) + + def action_set_up(): with postconf.mutex.lock_all(): repair_tls(check_tls()) + try_set_up_certificates()