Exemple #1
0
def _restore_int(name: str, value: str) -> int:
    """Restores an integer key-value pair from a renewal config file.

    :param str name: option name
    :param str value: option value

    :returns: converted option value to be stored in the runtime config
    :rtype: int

    :raises errors.Error: if value can't be converted to an int

    """
    if name == "http01_port" and value == "None":
        logger.info("updating legacy http01_port value")
        return cli.flag_default("http01_port")

    try:
        return int(value)
    except ValueError:
        raise errors.Error(f"Expected a numeric value for {name}")
def renew_cert(config, domains, le_client, lineage):
    "Renew a certificate lineage."
    renewal_params = lineage.configuration["renewalparams"]
    original_server = renewal_params.get("server", cli.flag_default("server"))
    _avoid_invalidating_lineage(config, lineage, original_server)
    if not domains:
        domains = lineage.names()
    # The private key is the existing lineage private key if reuse_key is set.
    # Otherwise, generate a fresh private key by passing None.
    new_key = os.path.normpath(lineage.privkey) if config.reuse_key else None
    new_cert, new_chain, new_key, _ = le_client.obtain_certificate(domains, new_key)
    if config.dry_run:
        logger.debug("Dry run: skipping updating lineage at %s",
                    os.path.dirname(lineage.cert))
    else:
        prior_version = lineage.latest_common_version()
        # TODO: Check return value of save_successor
        lineage.save_successor(prior_version, new_cert, new_key.pem, new_chain, config)
        lineage.update_all_links_to(lineage.latest_common_version())

    hooks.renew_hook(config, domains, lineage.live_dir)
Exemple #3
0
    def test_dry_run_flag(self):
        config_dir = tempfile.mkdtemp()
        short_args = '--dry-run --config-dir {0}'.format(config_dir).split()
        self.assertRaises(errors.Error, self.parse, short_args)

        self._assert_dry_run_flag_worked(
            self.parse(short_args + ['auth']), False)
        self._assert_dry_run_flag_worked(
            self.parse(short_args + ['certonly']), False)
        self._assert_dry_run_flag_worked(
            self.parse(short_args + ['renew']), False)

        account_dir = os.path.join(config_dir, constants.ACCOUNTS_DIR)
        filesystem.mkdir(account_dir)
        filesystem.mkdir(os.path.join(account_dir, 'fake_account_dir'))

        self._assert_dry_run_flag_worked(self.parse(short_args + ['auth']), True)
        self._assert_dry_run_flag_worked(self.parse(short_args + ['renew']), True)
        self._assert_dry_run_flag_worked(self.parse(short_args + ['certonly']), True)

        short_args += ['certonly']

        # `--dry-run --server example.com` should emit example.com
        self.assertEqual(self.parse(short_args + ['--server', 'example.com']).server,
                         'example.com')

        # `--dry-run --server STAGING_URI` should emit STAGING_URI
        self.assertEqual(self.parse(short_args + ['--server', constants.STAGING_URI]).server,
                         constants.STAGING_URI)

        # `--dry-run --server LIVE` should emit STAGING_URI
        self.assertEqual(self.parse(short_args + ['--server', cli.flag_default("server")]).server,
                         constants.STAGING_URI)

        # `--dry-run --server example.com --staging` should emit an error
        conflicts = ['--staging']
        self._check_server_conflict_message(short_args + ['--server', 'example.com', '--staging'],
                                            conflicts)
Exemple #4
0
def _plugins_parsing(helpful, plugins):
    # It's nuts, but there are two "plugins" topics.  Somehow this works
    helpful.add_group(
        "plugins",
        description="Plugin Selection: Certbot client supports an "
        "extensible plugins architecture. See '%(prog)s plugins' for a "
        "list of all installed plugins and their names. You can force "
        "a particular plugin by setting options provided below. Running "
        "--help <plugin_name> will list flags specific to that plugin.")

    helpful.add(
        "plugins",
        "--configurator",
        default=flag_default("configurator"),
        help="Name of the plugin that is both an authenticator and an installer."
        " Should not be used together with --authenticator or --installer. "
        "(default: Ask)")
    helpful.add("plugins",
                "-a",
                "--authenticator",
                default=flag_default("authenticator"),
                help="Authenticator plugin name.")
    helpful.add("plugins",
                "-i",
                "--installer",
                default=flag_default("installer"),
                help="Installer plugin name (also used to find domains).")
    helpful.add(["plugins", "certonly", "run", "install"],
                "--apache",
                action="store_true",
                default=flag_default("apache"),
                help="Obtain and install certificates using Apache")
    helpful.add(["plugins", "certonly", "run", "install"],
                "--nginx",
                action="store_true",
                default=flag_default("nginx"),
                help="Obtain and install certificates using Nginx")
    helpful.add(["plugins", "certonly"],
                "--standalone",
                action="store_true",
                default=flag_default("standalone"),
                help='Obtain certificates using a "standalone" webserver.')
    helpful.add(
        ["plugins", "certonly"],
        "--manual",
        action="store_true",
        default=flag_default("manual"),
        help="Provide laborious manual instructions for obtaining a certificate"
    )
    helpful.add(
        ["plugins", "certonly"],
        "--webroot",
        action="store_true",
        default=flag_default("webroot"),
        help="Obtain certificates by placing files in a webroot directory.")
    helpful.add(["plugins", "certonly"],
                "--dns-cloudflare",
                action="store_true",
                default=flag_default("dns_cloudflare"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using Cloudflare for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-cloudxns",
                action="store_true",
                default=flag_default("dns_cloudxns"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using CloudXNS for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-digitalocean",
                action="store_true",
                default=flag_default("dns_digitalocean"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using DigitalOcean for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-dnsimple",
                action="store_true",
                default=flag_default("dns_dnsimple"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using DNSimple for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-dnsmadeeasy",
                action="store_true",
                default=flag_default("dns_dnsmadeeasy"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using DNS Made Easy for DNS)."))
    helpful.add(
        ["plugins", "certonly"],
        "--dns-gehirn",
        action="store_true",
        default=flag_default("dns_gehirn"),
        help=("Obtain certificates using a DNS TXT record "
              "(if you are using Gehirn Infrastructure Service for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-google",
                action="store_true",
                default=flag_default("dns_google"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using Google Cloud DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-linode",
                action="store_true",
                default=flag_default("dns_linode"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using Linode for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-luadns",
                action="store_true",
                default=flag_default("dns_luadns"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using LuaDNS for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-nsone",
                action="store_true",
                default=flag_default("dns_nsone"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using NS1 for DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-ovh",
                action="store_true",
                default=flag_default("dns_ovh"),
                help=("Obtain certificates using a DNS TXT record (if you are "
                      "using OVH for DNS)."))
    helpful.add(
        ["plugins", "certonly"],
        "--dns-rfc2136",
        action="store_true",
        default=flag_default("dns_rfc2136"),
        help=
        "Obtain certificates using a DNS TXT record (if you are using BIND for DNS)."
    )
    helpful.add(
        ["plugins", "certonly"],
        "--dns-route53",
        action="store_true",
        default=flag_default("dns_route53"),
        help=
        ("Obtain certificates using a DNS TXT record (if you are using Route53 for "
         "DNS)."))
    helpful.add(["plugins", "certonly"],
                "--dns-sakuracloud",
                action="store_true",
                default=flag_default("dns_sakuracloud"),
                help=("Obtain certificates using a DNS TXT record "
                      "(if you are using Sakura Cloud for DNS)."))

    # things should not be reorder past/pre this comment:
    # plugins_group should be displayed in --help before plugin
    # specific groups (so that plugins_group.description makes sense)

    helpful.add_plugin_args(plugins)
Exemple #5
0
    def __init__(self, args, plugins, detect_defaults=False):
        from certbot._internal import main
        self.VERBS = {
            "auth": main.certonly,
            "certonly": main.certonly,
            "run": main.run,
            "install": main.install,
            "plugins": main.plugins_cmd,
            "register": main.register,
            "update_account": main.update_account,
            "unregister": main.unregister,
            "renew": main.renew,
            "revoke": main.revoke,
            "rollback": main.rollback,
            "everything": main.run,
            "update_symlinks": main.update_symlinks,
            "certificates": main.certificates,
            "delete": main.delete,
            "enhance": main.enhance,
        }

        # Get notification function for printing
        try:
            self.notify = zope.component.getUtility(
                interfaces.IDisplay).notification
        except zope_interfaces.ComponentLookupError:
            self.notify = display_util.NoninteractiveDisplay(
                sys.stdout).notification

        # List of topics for which additional help can be provided
        HELP_TOPICS = ["all", "security", "paths", "automation", "testing"]
        HELP_TOPICS += list(self.VERBS) + self.COMMANDS_TOPICS + ["manage"]

        plugin_names = list(plugins)
        self.help_topics = HELP_TOPICS + plugin_names + [None]  # type: ignore

        self.detect_defaults = detect_defaults
        self.args = args

        if self.args and self.args[0] == 'help':
            self.args[0] = '--help'

        self.determine_verb()
        help1 = self.prescan_for_flag("-h", self.help_topics)
        help2 = self.prescan_for_flag("--help", self.help_topics)
        if isinstance(help1, bool) and isinstance(help2, bool):
            self.help_arg = help1 or help2
        else:
            self.help_arg = help1 if isinstance(help1,
                                                six.string_types) else help2

        short_usage = self._usage_string(plugins, self.help_arg)

        self.visible_topics = self.determine_help_topics(self.help_arg)

        # elements are added by .add_group()
        self.groups = {}  # type: Dict[str, argparse._ArgumentGroup]
        # elements are added by .parse_args()
        self.defaults = {}  # type: Dict[str, Any]

        self.parser = configargparse.ArgParser(
            prog="certbot",
            usage=short_usage,
            formatter_class=CustomHelpFormatter,
            args_for_setting_config_path=["-c", "--config"],
            default_config_files=flag_default("config_files"),
            config_arg_help_message="path to config file (default: {0})".
            format(" and ".join(flag_default("config_files"))))

        # This is the only way to turn off overly verbose config flag documentation
        self.parser._add_config_file_help = False
Exemple #6
0
 def test_no_args(self):
     namespace = self.parse([])
     for d in ('config_dir', 'logs_dir', 'work_dir'):
         self.assertEqual(getattr(namespace, d), cli.flag_default(d))
Exemple #7
0
 def test_ecdsa_key_option(self):
     elliptic_curve_option = 'elliptic_curve'
     elliptic_curve_option_value = cli.flag_default(elliptic_curve_option)
     self.parse('--elliptic-curve {0}'.format(elliptic_curve_option_value).split())
     self.assertIs(cli.option_was_set(elliptic_curve_option, elliptic_curve_option_value), True)
Exemple #8
0
def _create_subparsers(helpful):
    from certbot._internal.client import sample_user_agent  # avoid import loops
    helpful.add(
        None,
        "--user-agent",
        default=flag_default("user_agent"),
        help=
        'Set a custom user agent string for the client. User agent strings allow '
        'the CA to collect high level statistics about success rates by OS, '
        'plugin and use case, and to know when to deprecate support for past Python '
        "versions and flags. If you wish to hide this information from the Let's "
        'Encrypt server, set this to "". '
        '(default: {0}). The flags encoded in the user agent are: '
        '--duplicate, --force-renew, --allow-subset-of-names, -n, and '
        'whether any hooks are set.'.format(sample_user_agent()))
    helpful.add(
        None,
        "--user-agent-comment",
        default=flag_default("user_agent_comment"),
        type=_user_agent_comment_type,
        help=
        "Add a comment to the default user agent string. May be used when repackaging Certbot "
        "or calling it from another tool to allow additional statistical data to be collected."
        " Ignored if --user-agent is set. (Example: Foo-Wrapper/1.0)")
    helpful.add(
        "certonly",
        "--csr",
        default=flag_default("csr"),
        type=read_file,
        help="Path to a Certificate Signing Request (CSR) in DER or PEM format."
        " Currently --csr only works with the 'certonly' subcommand.")
    helpful.add(
        "revoke",
        "--reason",
        dest="reason",
        choices=CaseInsensitiveList(
            sorted(constants.REVOCATION_REASONS,
                   key=constants.REVOCATION_REASONS.get)),
        action=_EncodeReasonAction,
        default=flag_default("reason"),
        help="Specify reason for revoking certificate. (default: unspecified)")
    helpful.add(
        "revoke",
        "--delete-after-revoke",
        action="store_true",
        default=flag_default("delete_after_revoke"),
        help=
        "Delete certificates after revoking them, along with all previous and later "
        "versions of those certificates.")
    helpful.add("revoke",
                "--no-delete-after-revoke",
                action="store_false",
                dest="delete_after_revoke",
                default=flag_default("delete_after_revoke"),
                help="Do not delete certificates after revoking them. This "
                "option should be used with caution because the 'renew' "
                "subcommand will attempt to renew undeleted revoked "
                "certificates.")
    helpful.add("rollback",
                "--checkpoints",
                type=int,
                metavar="N",
                default=flag_default("rollback_checkpoints"),
                help="Revert configuration N number of checkpoints.")
    helpful.add("plugins",
                "--init",
                action="store_true",
                default=flag_default("init"),
                help="Initialize plugins.")
    helpful.add("plugins",
                "--prepare",
                action="store_true",
                default=flag_default("prepare"),
                help="Initialize and prepare plugins.")
    helpful.add("plugins",
                "--authenticators",
                action="append_const",
                dest="ifaces",
                default=flag_default("ifaces"),
                const=interfaces.IAuthenticator,
                help="Limit to authenticator plugins only.")
    helpful.add("plugins",
                "--installers",
                action="append_const",
                dest="ifaces",
                default=flag_default("ifaces"),
                const=interfaces.IInstaller,
                help="Limit to installer plugins only.")