Ejemplo n.º 1
0
 def test_enhancement_no_updater(self, mock_geti):
     FAKEINDEX = [{
         "name": "Test",
         "class": enhancements.AutoHSTSEnhancement,
         "updater_function": None,
         "deployer_function": "deploy_autohsts",
         "enable_function": "enable_autohsts"
     }]
     mock_geti.return_value = self.mockinstaller
     with mock.patch("certbot.plugins.enhancements._INDEX", FAKEINDEX):
         updater.run_generic_updaters(self.config, mock.MagicMock(), None)
     self.assertFalse(self.mockinstaller.update_autohsts.called)
Ejemplo n.º 2
0
    def test_server_updates(self, _, mock_geti, mock_select, mock_getsave):
        mock_getsave.return_value = mock.MagicMock()
        mock_generic_updater = self.generic_updater

        # Generic Updater
        mock_select.return_value = (mock_generic_updater, None)
        mock_geti.return_value = mock_generic_updater
        with mock.patch('certbot._internal.main._init_le_client'):
            main.renew_cert(self.config, None, mock.MagicMock())
        self.assertTrue(mock_generic_updater.restart.called)

        mock_generic_updater.restart.reset_mock()
        mock_generic_updater.generic_updates.reset_mock()
        updater.run_generic_updaters(self.config, mock.MagicMock(), None)
        self.assertEqual(mock_generic_updater.generic_updates.call_count, 1)
        self.assertFalse(mock_generic_updater.restart.called)
Ejemplo n.º 3
0
def handle_renewal_request(config):
    """Examine each lineage; renew if due and report results"""

    # This is trivially False if config.domains is empty
    if any(domain not in config.webroot_map for domain in config.domains):
        # If more plugins start using cli.add_domains,
        # we may want to only log a warning here
        raise errors.Error(
            "Currently, the renew verb is capable of either "
            "renewing all installed certificates that are due "
            "to be renewed or renewing a single certificate specified "
            "by its name. If you would like to renew specific "
            "certificates by their domains, use the certonly command "
            "instead. The renew verb may provide other options "
            "for selecting certificates to renew in the future.")

    if config.certname:
        conf_files = [
            storage.renewal_file_for_certname(config, config.certname)
        ]
    else:
        conf_files = storage.renewal_conf_files(config)

    renew_successes = []
    renew_failures = []
    renew_skipped = []
    parse_failures = []

    # Noninteractive renewals include a random delay in order to spread
    # out the load on the certificate authority servers, even if many
    # users all pick the same time for renewals.  This delay precedes
    # running any hooks, so that side effects of the hooks (such as
    # shutting down a web service) aren't prolonged unnecessarily.
    apply_random_sleep = not sys.stdin.isatty(
    ) and config.random_sleep_on_renew

    for renewal_file in conf_files:
        display_util.notification("Processing " + renewal_file, pause=False)
        lineage_config = copy.deepcopy(config)
        lineagename = storage.lineagename_for_filename(renewal_file)

        # Note that this modifies config (to add back the configuration
        # elements from within the renewal configuration file).
        try:
            renewal_candidate = _reconstitute(lineage_config, renewal_file)
        except Exception as e:  # pylint: disable=broad-except
            logger.error(
                "Renewal configuration file %s (cert: %s) "
                "produced an unexpected error: %s. Skipping.", renewal_file,
                lineagename, e)
            logger.debug("Traceback was:\n%s", traceback.format_exc())
            parse_failures.append(renewal_file)
            continue

        try:
            if renewal_candidate is None:
                parse_failures.append(renewal_file)
            else:
                # This call is done only for retro-compatibility purposes.
                # TODO: Remove this call once zope dependencies are removed from Certbot.
                zope.component.provideUtility(lineage_config,
                                              interfaces.IConfig)
                renewal_candidate.ensure_deployed()
                from certbot._internal import main
                plugins = plugins_disco.PluginsRegistry.find_all()
                if should_renew(lineage_config, renewal_candidate):
                    # Apply random sleep upon first renewal if needed
                    if apply_random_sleep:
                        sleep_time = random.uniform(1, 60 * 8)
                        logger.info(
                            "Non-interactive renewal: random delay of %s seconds",
                            sleep_time)
                        time.sleep(sleep_time)
                        # We will sleep only once this day, folks.
                        apply_random_sleep = False

                    # domains have been restored into lineage_config by reconstitute
                    # but they're unnecessary anyway because renew_cert here
                    # will just grab them from the certificate
                    # we already know it's time to renew based on should_renew
                    # and we have a lineage in renewal_candidate
                    main.renew_cert(lineage_config, plugins, renewal_candidate)
                    renew_successes.append(renewal_candidate.fullchain)
                else:
                    expiry = crypto_util.notAfter(
                        renewal_candidate.version(
                            "cert", renewal_candidate.latest_common_version()))
                    renew_skipped.append("%s expires on %s" %
                                         (renewal_candidate.fullchain,
                                          expiry.strftime("%Y-%m-%d")))
                # Run updater interface methods
                updater.run_generic_updaters(lineage_config, renewal_candidate,
                                             plugins)

        except Exception as e:  # pylint: disable=broad-except
            # obtain_cert (presumably) encountered an unanticipated problem.
            logger.error("Failed to renew certificate %s with error: %s",
                         lineagename, e)
            logger.debug("Traceback was:\n%s", traceback.format_exc())
            renew_failures.append(renewal_candidate.fullchain)

    # Describe all the results
    _renew_describe_results(config, renew_successes, renew_failures,
                            renew_skipped, parse_failures)

    if renew_failures or parse_failures:
        raise errors.Error("{0} renew failure(s), {1} parse failure(s)".format(
            len(renew_failures), len(parse_failures)))

    # Windows installer integration tests rely on handle_renewal_request behavior here.
    # If the text below changes, these tests will need to be updated accordingly.
    logger.debug("no renewal failures")
Ejemplo n.º 4
0
 def test_enhancement_updates_not_called(self, mock_geti):
     self.config.disable_renew_updates = True
     mock_geti.return_value = self.mockinstaller
     updater.run_generic_updaters(self.config, mock.MagicMock(), None)
     self.assertFalse(self.mockinstaller.update_autohsts.called)
Ejemplo n.º 5
0
 def test_enhancement_updates(self, mock_geti):
     mock_geti.return_value = self.mockinstaller
     updater.run_generic_updaters(self.config, mock.MagicMock(), None)
     self.assertTrue(self.mockinstaller.update_autohsts.called)
     self.assertEqual(self.mockinstaller.update_autohsts.call_count, 1)
Ejemplo n.º 6
0
 def test_updater_skip_dry_run(self, mock_log):
     self.config.dry_run = True
     updater.run_generic_updaters(self.config, None, None)
     self.assertTrue(mock_log.called)
     self.assertEqual(mock_log.call_args[0][0],
                      "Skipping updaters in dry-run mode.")