From 8175a1ea22b463c1a039d77fd3bc4c6998fb94b9 Mon Sep 17 00:00:00 2001 From: Peter Eckersley Date: Wed, 18 Jul 2018 06:22:53 -0700 Subject: [PATCH] Begin protecting autohsts users against renewal failure consequences --- certbot-apache/certbot_apache/configurator.py | 20 +++++++++++++ certbot/plugins/enhancements.py | 16 ++++++++++- certbot/updater.py | 28 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/certbot-apache/certbot_apache/configurator.py b/certbot-apache/certbot_apache/configurator.py index bb77e2e41..0782db950 100644 --- a/certbot-apache/certbot_apache/configurator.py +++ b/certbot-apache/certbot_apache/configurator.py @@ -2471,5 +2471,25 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): # Update AutoHSTS storage (We potentially removed vhosts from managed) self._autohsts_save_state() + def handle_autohsts_error(self, lineage, details): + self._autohsts_fetch_state() + if not self._autohsts: + # No autohsts enabled for any vhost + return + if details != "renewal failure": + logger.info("Ignoring unknown error in auto-hsts code: {0}".format(details)) + return + + # Renewal failure experienced; figure out which vhosts it affects + for id_str, config in list(self._autohsts.items()): + vhost = self.find_vhost_by_id(id_str) + if self._autohsts_vhost_in_lineage(vhost, lineage): + config["laststep"] + + + + + + AutoHSTSEnhancement.register(ApacheConfigurator) # pylint: disable=no-member diff --git a/certbot/plugins/enhancements.py b/certbot/plugins/enhancements.py index 7ca096610..fc3f662bf 100644 --- a/certbot/plugins/enhancements.py +++ b/certbot/plugins/enhancements.py @@ -143,6 +143,19 @@ class AutoHSTSEnhancement(object): :type domains: str """ + @abc.abstractmethod + def handle_autohsts_error(self, lineage, details, *args, **kwargs): + """ + Handle an error that potentially has implications for AutoHSTS safety. + For now, this is just details == "renewal failure". + + :param lineage: Certificate lineage object + :type lineage: certbot.storage.RenewableCert + + :param details: Helpful string characterizing error + :type details: str + """ + # This is used to configure internal new style enhancements in Certbot. These # enhancement interfaces need to be defined in this file. Please do not modify # this list from plugin code. @@ -159,6 +172,7 @@ _INDEX = [ "class": AutoHSTSEnhancement, "updater_function": "update_autohsts", "deployer_function": "deploy_autohsts", - "enable_function": "enable_autohsts" + "enable_function": "enable_autohsts", + "error_handler_function", "handle_autohsts_error" } ] # type: List[Dict[str, Any]] diff --git a/certbot/updater.py b/certbot/updater.py index 58df6fcb4..330f8618c 100644 --- a/certbot/updater.py +++ b/certbot/updater.py @@ -120,3 +120,31 @@ def _run_enhancement_deployers(lineage, installer, config): for enh in enhancements._INDEX: # pylint: disable=protected-access if isinstance(installer, enh["class"]) and enh["deployer_function"]: getattr(installer, enh["deployer_function"])(lineage) + +def _run_enhancement_error_handlers(lineage, installer, config, details): + """Iterates through known enhancement interfaces. If the installer implements + an enhancement interface and the enhance interface has an updater method, its + error_handler method gets run. + + :param lineage: Certificate lineage object + :type lineage: storage.RenewableCert + + :param installer: Installer object + :type installer: interfaces.IInstaller + + :param config: Configuration object + :type config: interfaces.IConfig + + :param code: Helpful and possibly standardized error code! Can be any of: + ["renewal failure"] + :type code: str + """ + + if config.disable_renew_updates: + return + for enh in enhancements._INDEX: # pylint: disable=protected-access + if isinstance(installer, enh["class"]) and enh["error_handler_function"]: + getattr(installer, enh["error_handler_function"])(lineage, details) + + +