Example #1
0
def enhance(config, plugins):
    """Add security enhancements to existing configuration

    :param config: Configuration object
    :type config: interfaces.IConfig

    :param plugins: List of plugins
    :type plugins: `list` of `str`

    :returns: `None`
    :rtype: None

    """
    supported_enhancements = ["hsts", "redirect", "uir", "staple"]
    # Check that at least one enhancement was requested on command line
    oldstyle_enh = any(getattr(config, enh) for enh in supported_enhancements)
    if not enhancements.are_requested(config) and not oldstyle_enh:
        msg = ("Please specify one or more enhancement types to configure. To list "
               "the available enhancement types, run:\n\n%s --help enhance\n")
        logger.warning(msg, sys.argv[0])
        raise errors.MisconfigurationError("No enhancements requested, exiting.")

    try:
        installer, _ = plug_sel.choose_configurator_plugins(config, plugins, "enhance")
    except errors.PluginSelectionError as e:
        return str(e)

    if not enhancements.are_supported(config, installer):
        raise errors.NotSupportedError("One ore more of the requested enhancements "
                                       "are not supported by the selected installer")

    certname_question = ("Which certificate would you like to use to enhance "
                         "your configuration?")
    config.certname = cert_manager.get_certnames(
        config, "enhance", allow_multiple=False,
        custom_prompt=certname_question)[0]
    cert_domains = cert_manager.domains_for_certname(config, config.certname)
    if config.noninteractive_mode:
        domains = cert_domains
    else:
        domain_question = ("Which domain names would you like to enable the "
                           "selected enhancements for?")
        domains = display_ops.choose_values(cert_domains, domain_question)
        if not domains:
            raise errors.Error("User cancelled the domain selection. No domains "
                               "defined, exiting.")

    lineage = cert_manager.lineage_for_certname(config, config.certname)
    if not config.chain_path:
        config.chain_path = lineage.chain_path
    if oldstyle_enh:
        le_client = _init_le_client(config, authenticator=None, installer=installer)
        le_client.enhance_config(domains, config.chain_path, redirect_default=False)
    if enhancements.are_requested(config):
        enhancements.enable(lineage, domains, installer, config)

    return None
 def test_found_match(self, mock_renewable_cert, mock_renewal_conf_file,
                      mock_make_or_verify_dir):
     mock_renewal_conf_file.return_value = "somefile.conf"
     mock_match = mock.Mock(lineagename="example.com")
     domains = ["example.com", "example.org"]
     mock_match.names.return_value = domains
     mock_renewable_cert.return_value = mock_match
     from certbot._internal import cert_manager
     self.assertEqual(cert_manager.domains_for_certname(self.config, "example.com"),
         domains)
     self.assertTrue(mock_make_or_verify_dir.called)
Example #3
0
def _find_lineage_for_domains_and_certname(config, domains, certname):
    """Find appropriate lineage based on given domains and/or certname.

    :param config: Configuration object
    :type config: interfaces.IConfig

    :param domains: List of domain names
    :type domains: `list` of `str`

    :param certname: Name of certificate
    :type certname: str

    :returns: Two-element tuple containing desired new-certificate behavior as
              a string token ("reinstall", "renew", or "newcert"), plus either
              a RenewableCert instance or None if renewal should not occur.

    :rtype: `tuple` of `str` and :class:`storage.RenewableCert` or `None`

    :raises errors.Error: If the user would like to rerun the client again.

    """
    if not certname:
        return _find_lineage_for_domains(config, domains)
    else:
        lineage = cert_manager.lineage_for_certname(config, certname)
        if lineage:
            if domains:
                if set(cert_manager.domains_for_certname(
                        config, certname)) != set(domains):
                    _ask_user_to_confirm_new_names(
                        config, domains, certname,
                        lineage.names())  # raises if no
                    return "renew", lineage
            # unnecessarily specified domains or no domains specified
            return _handle_identical_cert_request(config, lineage)
        else:
            if domains:
                return "newcert", None
            else:
                raise errors.ConfigurationError(
                    "No certificate with name {0} found. "
                    "Use -d to specify domains, or run certbot certificates to see "
                    "possible certificate names.".format(certname))
Example #4
0
def _find_domains_or_certname(config, installer, question=None):
    """Retrieve domains and certname from config or user input.

    :param config: Configuration object
    :type config: interfaces.IConfig

    :param installer: Installer object
    :type installer: interfaces.IInstaller

    :param `str` question: Overriding dialog question to ask the user if asked
        to choose from domain names.

    :returns: Two-part tuple of domains and certname
    :rtype: `tuple` of list of `str` and `str`

    :raises errors.Error: Usage message, if parameters are not used correctly

    """
    domains = None
    certname = config.certname
    # first, try to get domains from the config
    if config.domains:
        domains = config.domains
    # if we can't do that but we have a certname, get the domains
    # with that certname
    elif certname:
        domains = cert_manager.domains_for_certname(config, certname)

    # that certname might not have existed, or there was a problem.
    # try to get domains from the user.
    if not domains:
        domains = display_ops.choose_names(installer, question)

    if not domains and not certname:
        raise errors.Error("Please specify --domains, or --installer that "
                           "will help in domain names autodiscovery, or "
                           "--cert-name for an existing certificate name.")

    return domains, certname
 def test_no_match(self, mock_renewal_conf_file, mock_make_or_verify_dir):
     mock_renewal_conf_file.return_value = "somefile.conf"
     from certbot._internal import cert_manager
     self.assertEqual(
         cert_manager.domains_for_certname(self.config, "other.com"), None)
     self.assertTrue(mock_make_or_verify_dir.called)