diff options
-rw-r--r-- | acme/acme/crypto_util.py | 3 | ||||
-rw-r--r-- | certbot-apache/certbot_apache/display_ops.py | 5 | ||||
-rwxr-xr-x | certbot-auto | 42 | ||||
-rw-r--r-- | certbot/cli.py | 208 | ||||
-rw-r--r-- | certbot/constants.py | 88 | ||||
-rw-r--r-- | certbot/main.py | 10 | ||||
-rw-r--r-- | certbot/tests/cli_test.py | 19 | ||||
-rw-r--r-- | certbot/tests/client_test.py | 2 | ||||
-rw-r--r-- | certbot/tests/main_test.py | 20 | ||||
-rw-r--r-- | certbot/tests/util.py | 15 | ||||
-rw-r--r-- | docs/cli-help.txt | 2 | ||||
-rwxr-xr-x | letsencrypt-auto | 42 | ||||
-rw-r--r-- | letsencrypt-auto-source/certbot-auto.asc | 14 | ||||
-rwxr-xr-x | letsencrypt-auto-source/letsencrypt-auto | 24 | ||||
-rw-r--r-- | letsencrypt-auto-source/letsencrypt-auto.sig | bin | 256 -> 256 bytes | |||
-rw-r--r-- | letsencrypt-auto-source/pieces/certbot-requirements.txt | 24 | ||||
-rwxr-xr-x | tests/letstest/scripts/test_letsencrypt_auto_certonly_standalone.sh | 2 |
17 files changed, 347 insertions, 173 deletions
diff --git a/acme/acme/crypto_util.py b/acme/acme/crypto_util.py index de15284c0..b8fba0348 100644 --- a/acme/acme/crypto_util.py +++ b/acme/acme/crypto_util.py @@ -2,6 +2,7 @@ import binascii import contextlib import logging +import os import re import socket import sys @@ -243,7 +244,7 @@ def gen_ss_cert(key, domains, not_before=None, """ assert domains, "Must provide one or more hostnames for the cert." cert = OpenSSL.crypto.X509() - cert.set_serial_number(int(binascii.hexlify(OpenSSL.rand.bytes(16)), 16)) + cert.set_serial_number(int(binascii.hexlify(os.urandom(16)), 16)) cert.set_version(2) extensions = [ diff --git a/certbot-apache/certbot_apache/display_ops.py b/certbot-apache/certbot_apache/display_ops.py index 7aec26f81..9529c1ab3 100644 --- a/certbot-apache/certbot_apache/display_ops.py +++ b/certbot-apache/certbot_apache/display_ops.py @@ -86,10 +86,11 @@ def _vhost_menu(domain, vhosts): choices, force_interactive=True) except errors.MissingCommandlineFlag: msg = ( - "Encountered vhost ambiguity but unable to ask for user " + "Encountered vhost ambiguity when trying to find a vhost for " + "{0} but was unable to ask for user " "guidance in non-interactive mode. Certbot may need " "vhosts to be explicitly labelled with ServerName or " - "ServerAlias directives.") + "ServerAlias directives.".format(domain)) logger.warning(msg) raise errors.MissingCommandlineFlag(msg) diff --git a/certbot-auto b/certbot-auto index 223fbfd32..0738db84d 100755 --- a/certbot-auto +++ b/certbot-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="0.18.0" +LE_AUTO_VERSION="0.18.1" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -187,8 +187,7 @@ SetRootAuthMechanism() { if [ "$1" = "--cb-auto-has-root" ]; then shift 1 -elif [ "$1" != "--le-auto-phase2" ]; then - # if $1 is --le-auto-phase2, we've executed this branch before +else SetRootAuthMechanism if [ -n "$SUDO" ]; then echo "Requesting to rerun $0 with root privileges..." @@ -197,6 +196,14 @@ elif [ "$1" != "--le-auto-phase2" ]; then fi fi +# Runs this script again with the given arguments. --cb-auto-has-root is added +# to the command line arguments to ensure we don't try to acquire root a +# second time. After the script is rerun, we exit the current script. +RerunWithArgs() { + "$0" --cb-auto-has-root "$@" + exit 0 +} + BootstrapMessage() { # Arguments: Platform name say "Bootstrapping dependencies for $1... (you can skip this with --no-bootstrap)" @@ -825,8 +832,7 @@ if [ "$1" = "--le-auto-phase2" ]; then # if non-interactive mode or stdin and stdout are connected to a terminal if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then rm -rf "$VENV_PATH" - "$0" "$@" - exit 0 + RerunWithArgs "$@" else error "Skipping upgrade because new OS dependencies may need to be installed." error @@ -1071,18 +1077,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.18.0 \ - --hash=sha256:941925f045aaae2a7e5b1d322b68ea3e042a1c2d6a3b3de76c5b8a5122e515a7 \ - --hash=sha256:f70bdfd7a455f0c1f72610b48bf4a462e4aecd8e66baa9d2278f7bc4a4f4195f -acme==0.18.0 \ - --hash=sha256:e35b2dbc27a40ca35d9120cb417abde667e9c59436662a10f260f3eaa2eb8fe0 \ - --hash=sha256:301b0c9108f80d1182add10e8fd0fa962a143731b8208615631a711b8cd98938 -certbot-apache==0.18.0 \ - --hash=sha256:e08504b1e13e0698dffd4b6437cdf24480f6666b60455c83e9a55cad56ab8c2d \ - --hash=sha256:44b65d61f4d284da188c578ad0dc700d4743d03ae5382be86716ff26a82def94 -certbot-nginx==0.18.0 \ - --hash=sha256:da58201350b0d02cd4b43ea53abd34a4a56cbb7d5564004c25607bdcbec5e890 \ - --hash=sha256:528db0f8e5d5ac6956e4df15ab4809f313114ff2817c4b2f04c43913d750ca28 +certbot==0.18.1 \ + --hash=sha256:46e5f0b225ceef0afe81f7f2442c0dd23485f96b5e16cbd78c9e692dc551203e \ + --hash=sha256:ae0aaf0cc1af53713232a222fb20891475ec9ff9d128a277c4e0f92ea7c36b4c +acme==0.18.1 \ + --hash=sha256:a1c3d8dddb573b69573294ccc089f9a12fd91ebdfe72d9bfcacc260df28c50cf \ + --hash=sha256:1e4c6c0a3fb9906f0d1389a39c76d730e2691d7f168a219e464237381ddcc667 +certbot-apache==0.18.1 \ + --hash=sha256:2eb78c6b22bc6028e4d7f169e1cbdca1ddedf3aa60e69f5f38952654b7a2a94d \ + --hash=sha256:2a25b2909167ae5c583b034957e59e9923017cf52c6fa4b310cfca2a3a005fb4 +certbot-nginx==0.18.1 \ + --hash=sha256:19be0c3800cacf97d4ca8a20c7a65585fb24af3a2c9164484b12c4da634b6833 \ + --hash=sha256:bda89d4ebcfc9dc7ee41fe23ea2fc19e6c773a4a2873737d4b19210c752f5aca UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -1491,5 +1497,5 @@ UNLIKELY_EOF fi # A newer version is available. fi # Self-upgrading is allowed. - "$0" --le-auto-phase2 "$@" + RerunWithArgs --le-auto-phase2 "$@" fi diff --git a/certbot/cli.py b/certbot/cli.py index 97954004b..9d17c7a25 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -282,7 +282,7 @@ def flag_default(name): # argparse has been set up; it is not accurate for all flags. Call it # with caution. Plugin defaults are missing, and some things are using # defaults defined in this file, not in constants.py :( - return constants.CLI_DEFAULTS[name] + return copy.deepcopy(constants.CLI_DEFAULTS[name]) def config_help(name, hidden=False): @@ -356,7 +356,7 @@ VERB_HELP = [ " before and after renewal; see" " https://certbot.eff.org/docs/using.html#renewal for more" " information on these."), - "usage": "\n\n certbot renew [--cert-name NAME] [options]\n\n" + "usage": "\n\n certbot renew [--cert-name CERTNAME] [options]\n\n" }), ("certificates", { "short": "List certificates managed by Certbot", @@ -866,9 +866,10 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "e.g. -vvv.") helpful.add( None, "-t", "--text", dest="text_mode", action="store_true", - help=argparse.SUPPRESS) + default=flag_default("text_mode"), help=argparse.SUPPRESS) helpful.add( - None, "--max-log-backups", type=nonnegative_int, default=1000, + None, "--max-log-backups", type=nonnegative_int, + default=flag_default("max_log_backups"), help="Specifies the maximum number of backup logs that should " "be kept by Certbot's built in log rotation. Setting this " "flag to 0 disables log rotation entirely, causing " @@ -876,19 +877,22 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis helpful.add( [None, "automation", "run", "certonly"], "-n", "--non-interactive", "--noninteractive", dest="noninteractive_mode", action="store_true", + default=flag_default("noninteractive_mode"), help="Run without ever asking for user input. This may require " "additional command line flags; the client will try to explain " "which ones are required if it finds one missing") helpful.add( [None, "register", "run", "certonly"], constants.FORCE_INTERACTIVE_FLAG, action="store_true", + default=flag_default("force_interactive"), help="Force Certbot to be interactive even if it detects it's not " "being run in a terminal. This flag cannot be used with the " "renew subcommand.") helpful.add( [None, "run", "certonly", "certificates"], "-d", "--domains", "--domain", dest="domains", - metavar="DOMAIN", action=_DomainsAction, default=[], + metavar="DOMAIN", action=_DomainsAction, + default=flag_default("domains"), help="Domain names to apply. For multiple domains you can use " "multiple -d flags or enter a comma separated list of domains " "as a parameter. The first provided domain will be used in " @@ -897,9 +901,9 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "specified or you already have a certificate for the same " "domains. (default: Ask)") helpful.add( - [None, "run", "certonly", "manage", "delete", "certificates"], + [None, "run", "certonly", "manage", "delete", "certificates", "renew"], "--cert-name", dest="certname", - metavar="CERTNAME", default=None, + metavar="CERTNAME", default=flag_default("certname"), help="Certificate name to apply. This name is used by Certbot for housekeeping " "and in file paths; it doesn't affect the content of the certificate itself. " "To see certificate names, run 'certbot certificates'. " @@ -909,6 +913,7 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis helpful.add( [None, "testing", "renew", "certonly"], "--dry-run", action="store_true", dest="dry_run", + default=flag_default("dry_run"), help="Perform a test run of the client, obtaining test (invalid) certificates" " but not saving them to disk. This can currently only be used" " with the 'certonly' and 'renew' subcommands. \nNote: Although --dry-run" @@ -921,6 +926,7 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis " renewal. --deploy-hook commands are not called.") helpful.add( ["register", "automation"], "--register-unsafely-without-email", action="store_true", + default=flag_default("register_unsafely_without_email"), help="Specifying this flag enables registering an account with no " "email address. This is strongly discouraged, because in the " "event of key loss or account compromise you will irrevocably " @@ -931,27 +937,29 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "update to the web site.") helpful.add( "register", "--update-registration", action="store_true", + default=flag_default("update_registration"), help="With the register verb, indicates that details associated " "with an existing registration, such as the e-mail address, " "should be updated, rather than registering a new account.") helpful.add( ["register", "unregister", "automation"], "-m", "--email", + default=flag_default("email"), help=config_help("email")) helpful.add(["register", "automation"], "--eff-email", action="store_true", - default=None, dest="eff_email", + default=flag_default("eff_email"), dest="eff_email", help="Share your e-mail address with EFF") helpful.add(["register", "automation"], "--no-eff-email", action="store_false", - default=None, dest="eff_email", + default=flag_default("eff_email"), dest="eff_email", help="Don't share your e-mail address with EFF") helpful.add( ["automation", "certonly", "run"], "--keep-until-expiring", "--keep", "--reinstall", - dest="reinstall", action="store_true", + dest="reinstall", action="store_true", default=flag_default("reinstall"), help="If the requested certificate matches an existing certificate, always keep the " "existing one until it is due for renewal (for the " "'run' subcommand this means reinstall the existing certificate). (default: Ask)") helpful.add( - "automation", "--expand", action="store_true", + "automation", "--expand", action="store_true", default=flag_default("expand"), help="If an existing certificate is a strict subset of the requested names, " "always expand and replace it with the additional names. (default: Ask)") helpful.add( @@ -960,21 +968,24 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis help="show program's version number and exit") helpful.add( ["automation", "renew"], - "--force-renewal", "--renew-by-default", - action="store_true", dest="renew_by_default", help="If a certificate " + "--force-renewal", "--renew-by-default", dest="renew_by_default", + action="store_true", default=flag_default("renew_by_default"), + help="If a certificate " "already exists for the requested domains, renew it now, " "regardless of whether it is near expiry. (Often " "--keep-until-expiring is more appropriate). Also implies " "--expand.") helpful.add( - "automation", "--renew-with-new-domains", - action="store_true", dest="renew_with_new_domains", help="If a " + "automation", "--renew-with-new-domains", dest="renew_with_new_domains", + action="store_true", default=flag_default("renew_with_new_domains"), + help="If a " "certificate already exists for the requested certificate name " "but does not match the requested domains, renew it now, " "regardless of whether it is near expiry.") helpful.add( ["automation", "renew", "certonly"], "--allow-subset-of-names", action="store_true", + default=flag_default("allow_subset_of_names"), help="When performing domain validation, do not consider it a failure " "if authorizations can not be obtained for a strict subset of " "the requested domains. This may be useful for allowing renewals for " @@ -982,39 +993,46 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "at this system. This option cannot be used with --csr.") helpful.add( "automation", "--agree-tos", dest="tos", action="store_true", + default=flag_default("tos"), help="Agree to the ACME Subscriber Agreement (default: Ask)") helpful.add( ["unregister", "automation"], "--account", metavar="ACCOUNT_ID", + default=flag_default("account"), help="Account ID to use") helpful.add( "automation", "--duplicate", dest="duplicate", action="store_true", + default=flag_default("duplicate"), help="Allow making a certificate lineage that duplicates an existing one " "(both can be renewed in parallel)") helpful.add( "automation", "--os-packages-only", action="store_true", + default=flag_default("os_packages_only"), help="(certbot-auto only) install OS package dependencies and then stop") helpful.add( "automation", "--no-self-upgrade", action="store_true", + default=flag_default("no_self_upgrade"), help="(certbot-auto only) prevent the certbot-auto script from" " upgrading itself to newer released versions (default: Upgrade" " automatically)") helpful.add( "automation", "--no-bootstrap", action="store_true", + default=flag_default("no_bootstrap"), help="(certbot-auto only) prevent the certbot-auto script from" " installing OS-level dependencies (default: Prompt to install " " OS-wide dependencies, but exit if the user says 'No')") helpful.add( ["automation", "renew", "certonly", "run"], "-q", "--quiet", dest="quiet", action="store_true", + default=flag_default("quiet"), help="Silence all output except errors. Useful for automation via cron." " Implies --non-interactive.") # overwrites server, handled in HelpfulArgumentParser.parse_args() helpful.add(["testing", "revoke", "run"], "--test-cert", "--staging", - action='store_true', dest='staging', - help='Use the staging server to obtain or revoke test (invalid) certificates; equivalent' - ' to --server ' + constants.STAGING_URI) + dest="staging", action="store_true", default=flag_default("staging"), + help="Use the staging server to obtain or revoke test (invalid) certificates; equivalent" + " to --server " + constants.STAGING_URI) helpful.add( - "testing", "--debug", action="store_true", + "testing", "--debug", action="store_true", default=flag_default("debug"), help="Show tracebacks in case of errors, and allow certbot-auto " "execution on experimental platforms") helpful.add( @@ -1044,6 +1062,7 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis default=flag_default("http01_address"), help=config_help("http01_address")) helpful.add( "testing", "--break-my-certs", action="store_true", + default=flag_default("break_my_certs"), help="Be willing to replace or renew valid certificates with invalid " "(testing/staging) certificates") helpful.add( @@ -1051,47 +1070,51 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis default=flag_default("rsa_key_size"), help=config_help("rsa_key_size")) helpful.add( "security", "--must-staple", action="store_true", - help=config_help("must_staple"), dest="must_staple", default=False) + dest="must_staple", default=flag_default("must_staple"), + help=config_help("must_staple")) helpful.add( - "security", "--redirect", action="store_true", + "security", "--redirect", action="store_true", dest="redirect", + default=flag_default("redirect"), help="Automatically redirect all HTTP traffic to HTTPS for the newly " - "authenticated vhost. (default: Ask)", dest="redirect", default=None) + "authenticated vhost. (default: Ask)") helpful.add( - "security", "--no-redirect", action="store_false", + "security", "--no-redirect", action="store_false", dest="redirect", + default=flag_default("redirect"), help="Do not automatically redirect all HTTP traffic to HTTPS for the newly " - "authenticated vhost. (default: Ask)", dest="redirect", default=None) + "authenticated vhost. (default: Ask)") helpful.add( - "security", "--hsts", action="store_true", + "security", "--hsts", action="store_true", dest="hsts", default=flag_default("hsts"), help="Add the Strict-Transport-Security header to every HTTP response." " Forcing browser to always use SSL for the domain." - " Defends against SSL Stripping.", dest="hsts", default=False) + " Defends against SSL Stripping.") helpful.add( - "security", "--no-hsts", action="store_false", - help=argparse.SUPPRESS, dest="hsts", default=False) + "security", "--no-hsts", action="store_false", dest="hsts", + default=flag_default("hsts"), help=argparse.SUPPRESS) helpful.add( - "security", "--uir", action="store_true", - help="Add the \"Content-Security-Policy: upgrade-insecure-requests\"" - " header to every HTTP response. Forcing the browser to use" - " https:// for every http:// resource.", dest="uir", default=None) + "security", "--uir", action="store_true", dest="uir", default=flag_default("uir"), + help='Add the "Content-Security-Policy: upgrade-insecure-requests"' + ' header to every HTTP response. Forcing the browser to use' + ' https:// for every http:// resource.') helpful.add( - "security", "--no-uir", action="store_false", - help=argparse.SUPPRESS, dest="uir", default=None) + "security", "--no-uir", action="store_false", dest="uir", default=flag_default("uir"), + help=argparse.SUPPRESS) helpful.add( - "security", "--staple-ocsp", action="store_true", + "security", "--staple-ocsp", action="store_true", dest="staple", + default=flag_default("staple"), help="Enables OCSP Stapling. A valid OCSP response is stapled to" - " the certificate that the server offers during TLS.", - dest="staple", default=None) + " the certificate that the server offers during TLS.") helpful.add( - "security", "--no-staple-ocsp", action="store_false", - help=argparse.SUPPRESS, dest="staple", default=None) + "security", "--no-staple-ocsp", action="store_false", dest="staple", + default=flag_default("staple"), help=argparse.SUPPRESS) helpful.add( "security", "--strict-permissions", action="store_true", + default=flag_default("strict_permissions"), help="Require that all configuration files are owned by the current " "user; only needed if your config is somewhere unsafe like /tmp/") helpful.add( ["manual", "standalone", "certonly", "renew"], "--preferred-challenges", dest="pref_challs", - action=_PrefChallAction, default=[], + action=_PrefChallAction, default=flag_default("pref_challs"), help='A sorted, comma delimited list of the preferred challenge to ' 'use during authorization with the most preferred challenge ' 'listed first (Eg, "dns" or "tls-sni-01,http,dns"). ' @@ -1120,17 +1143,18 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis action=_RenewHookAction, help=argparse.SUPPRESS) helpful.add( "renew", "--deploy-hook", action=_DeployHookAction, - help="Command to be run in a shell once for each successfully" - " issued certificate. For this command, the shell variable" - " $RENEWED_LINEAGE will point to the config live subdirectory" + help='Command to be run in a shell once for each successfully' + ' issued certificate. For this command, the shell variable' + ' $RENEWED_LINEAGE will point to the config live subdirectory' ' (for example, "/etc/letsencrypt/live/example.com") containing' - " the new certificates and keys; the shell variable" - " $RENEWED_DOMAINS will contain a space-delimited list of" + ' the new certificates and keys; the shell variable' + ' $RENEWED_DOMAINS will contain a space-delimited list of' ' renewed certificate domains (for example, "example.com' ' www.example.com"') helpful.add( "renew", "--disable-hook-validation", - action='store_false', dest='validate_hooks', default=True, + action="store_false", dest="validate_hooks", + default=flag_default("validate_hooks"), help="Ordinarily the commands specified for" " --pre-hook/--post-hook/--deploy-hook will be checked for" " validity, to see if the programs being run are in the $PATH," @@ -1156,48 +1180,53 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis def _create_subparsers(helpful): - helpful.add("config_changes", "--num", type=int, + helpful.add("config_changes", "--num", type=int, default=flag_default("num"), help="How many past revisions you want to be displayed") from certbot.client import sample_user_agent # avoid import loops helpful.add( - None, "--user-agent", default=None, - 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 " + 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=None, type=_user_agent_comment_type, + 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", type=read_file, + "--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=0, + action=_EncodeReasonAction, default=flag_default("reason"), help="Specify reason for revoking certificate. (default: unspecified)") 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", help="Initialize plugins.") + "--init", action="store_true", default=flag_default("init"), + help="Initialize plugins.") helpful.add("plugins", - "--prepare", action="store_true", help="Initialize and prepare 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.") @@ -1263,53 +1292,68 @@ def _plugins_parsing(helpful, plugins): "a particular plugin by setting options provided below. Running " "--help <plugin_name> will list flags specific to that plugin.") - helpful.add("plugins", "--configurator", + 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", help="Authenticator plugin name.") - helpful.add("plugins", "-i", "--installer", + 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", "config_changes"], - "--apache", action="store_true", + "--apache", action="store_true", default=flag_default("apache"), help="Obtain and install certificates using Apache") helpful.add(["plugins", "certonly", "run", "install", "config_changes"], - "--nginx", action="store_true", help="Obtain and install certificates using Nginx") + "--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", - help='Provide laborious manual instructions for obtaining a certificate') + default=flag_default("manual"), + help="Provide laborious manual instructions for obtaining a certificate") helpful.add(["plugins", "certonly"], "--webroot", action="store_true", - help='Obtain certificates by placing files in a webroot directory.') + default=flag_default("webroot"), + help="Obtain certificates by placing files in a webroot directory.") helpful.add(["plugins", "certonly"], "--dns-cloudflare", action="store_true", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using Cloudflare for DNS).')) + 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", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using CloudXNS for DNS).')) + 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", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using DigitalOcean for DNS).')) + 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", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using DNSimple for DNS).')) + 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", - help=('Obtain certificates using a DNS TXT record (if you are' - 'using DNS Made Easy for DNS).')) + 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-google", action="store_true", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using Google Cloud DNS).')) + 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-luadns", action="store_true", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using LuaDNS for DNS).')) + 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", - help=('Obtain certificates using a DNS TXT record (if you are ' - 'using NS1 for DNS).')) + 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-rfc2136", action="store_true", - help='Obtain certificates using a DNS TXT record (if you are using BIND for DNS).') + 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", - help=('Obtain certificates using a DNS TXT record (if you are using Route53 for ' - 'DNS).')) + default=flag_default("dns_route53"), + help=("Obtain certificates using a DNS TXT record (if you are using Route53 for " + "DNS).")) # things should not be reorder past/pre this comment: # plugins_group should be displayed in --help before plugin diff --git a/certbot/constants.py b/certbot/constants.py index 557ccd4c6..cae9864a9 100644 --- a/certbot/constants.py +++ b/certbot/constants.py @@ -19,23 +19,91 @@ CLI_DEFAULTS = dict( os.path.join(os.environ.get("XDG_CONFIG_HOME", "~/.config"), "letsencrypt", "cli.ini"), ], + + # Main parser verbose_count=-int(logging.INFO / 10), - server="https://acme-v01.api.letsencrypt.org/directory", - rsa_key_size=2048, - rollback_checkpoints=1, - config_dir="/etc/letsencrypt", - work_dir="/var/lib/letsencrypt", - logs_dir="/var/log/letsencrypt", + text_mode=False, + max_log_backups=1000, + noninteractive_mode=False, + force_interactive=False, + domains=[], + certname=None, + dry_run=False, + register_unsafely_without_email=False, + update_registration=False, + email=None, + eff_email=None, + reinstall=False, + expand=False, + renew_by_default=False, + renew_with_new_domains=False, + allow_subset_of_names=False, + tos=False, + account=None, + duplicate=False, + os_packages_only=False, + no_self_upgrade=False, + no_bootstrap=False, + quiet=False, + staging=False, + debug=False, + debug_challenges=False, no_verify_ssl=False, - http01_port=challenges.HTTP01Response.PORT, - http01_address="", tls_sni_01_port=challenges.TLSSNI01Response.PORT, tls_sni_01_address="", + http01_port=challenges.HTTP01Response.PORT, + http01_address="", + break_my_certs=False, + rsa_key_size=2048, + must_staple=False, + redirect=None, + hsts=None, + uir=None, + staple=None, + strict_permissions=False, + pref_challs=[], + validate_hooks=True, + + # Subparsers + num=None, + user_agent=None, + user_agent_comment=None, + csr=None, + reason=0, + rollback_checkpoints=1, + init=False, + prepare=False, + ifaces=None, + # Path parsers auth_cert_path="./cert.pem", auth_chain_path="./chain.pem", - strict_permissions=False, - debug_challenges=False, + key_path=None, + config_dir="/etc/letsencrypt", + work_dir="/var/lib/letsencrypt", + logs_dir="/var/log/letsencrypt", + server="https://acme-v01.api.letsencrypt.org/directory", + + # Plugins parsers + configurator=None, + authenticator=None, + installer=None, + apache=False, + nginx=False, + standalone=False, + manual=False, + webroot=False, + dns_cloudflare=False, + dns_cloudxns=False, + dns_digitalocean=False, + dns_dnsimple=False, + dns_dnsmadeeasy=False, + dns_google=False, + dns_luadns=False, + dns_nsone=False, + dns_rfc2136=False, + dns_route53=False + ) STAGING_URI = "https://acme-staging.api.letsencrypt.org/directory" diff --git a/certbot/main.py b/certbot/main.py index d1ed6fe2b..9d33d6059 100644 --- a/certbot/main.py +++ b/certbot/main.py @@ -743,8 +743,14 @@ def main(cli_args=sys.argv[1:]): config = configuration.NamespaceConfig(args) zope.component.provideUtility(config) - log.post_arg_parse_setup(config) - make_or_verify_needed_dirs(config) + try: + log.post_arg_parse_setup(config) + make_or_verify_needed_dirs(config) + except errors.Error: + # Let plugins_cmd be run as un-privileged user. + if config.func != plugins_cmd: + raise + set_displayer(config) # Reporter diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py index 1a3742348..e887e3043 100644 --- a/certbot/tests/cli_test.py +++ b/certbot/tests/cli_test.py @@ -3,6 +3,7 @@ import argparse import unittest import os import tempfile +import copy import mock import six @@ -81,7 +82,11 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods def test_cli_ini_domains(self, mock_flag_default): tmp_config = tempfile.NamedTemporaryFile() # use a shim to get ConfigArgParse to pick up tmp_config - shim = lambda v: constants.CLI_DEFAULTS[v] if v != "config_files" else [tmp_config.name] + shim = ( + lambda v: copy.deepcopy(constants.CLI_DEFAULTS[v]) + if v != "config_files" + else [tmp_config.name] + ) mock_flag_default.side_effect = shim namespace = self.parse(["certonly"]) @@ -391,6 +396,18 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods namespace = self.parse(["--max-log-backups", value]) self.assertEqual(namespace.max_log_backups, int(value)) + def test_unchanging_defaults(self): + namespace = self.parse([]) + self.assertEqual(namespace.domains, []) + self.assertEqual(namespace.pref_challs, []) + + namespace.pref_challs = [challenges.HTTP01.typ] + namespace.domains = ['example.com'] + + namespace = self.parse([]) + self.assertEqual(namespace.domains, []) + self.assertEqual(namespace.pref_challs, []) + class DefaultTest(unittest.TestCase): """Tests for certbot.cli._Default.""" diff --git a/certbot/tests/client_test.py b/certbot/tests/client_test.py index 2416acf95..09c4a50ca 100644 --- a/certbot/tests/client_test.py +++ b/certbot/tests/client_test.py @@ -28,6 +28,7 @@ class RegisterTest(test_util.ConfigTestCase): super(RegisterTest, self).setUp() self.config.rsa_key_size = 1024 self.config.register_unsafely_without_email = False + self.config.email = "alias@example.com" self.account_storage = account.AccountMemoryStorage() self.tos_cb = mock.MagicMock() @@ -75,6 +76,7 @@ class RegisterTest(test_util.ConfigTestCase): @mock.patch("certbot.account.report_new_account") def test_email_invalid_noninteractive(self, _rep): from acme import messages + self.config.noninteractive_mode = True msg = "DNS problem: NXDOMAIN looking up MX for example.com" mx_err = messages.Error.with_code('invalidContact', detail=msg) with mock.patch("certbot.client.acme_client.Client") as mock_client: diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py index f0b055d4c..4b9e4cf67 100644 --- a/certbot/tests/main_test.py +++ b/certbot/tests/main_test.py @@ -547,6 +547,26 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met @mock.patch('certbot.main.plugins_disco') @mock.patch('certbot.main.cli.HelpfulArgumentParser.determine_help_topics') + def test_plugins_no_args_unprivileged(self, _det, mock_disco): + ifaces = [] + plugins = mock_disco.PluginsRegistry.find_all() + + def throw_error(directory, mode, uid, strict): + """Raises error.Error.""" + _, _, _, _ = directory, mode, uid, strict + raise errors.Error() + + with mock.patch('certbot.util.set_up_core_dir') as mock_set_up_core_dir: + mock_set_up_core_dir.side_effect = throw_error + + _, stdout, _, _ = self._call(['plugins']) + plugins.visible.assert_called_once_with() + plugins.visible().ifaces.assert_called_once_with(ifaces) + filtered = plugins.visible().ifaces() + self.assertEqual(stdout.getvalue().strip(), str(filtered)) + + @mock.patch('certbot.main.plugins_disco') + @mock.patch('certbot.main.cli.HelpfulArgumentParser.determine_help_topics') def test_plugins_init(self, _det, mock_disco): ifaces = [] plugins = mock_disco.PluginsRegistry.find_all() diff --git a/certbot/tests/util.py b/certbot/tests/util.py index 698962516..73d002989 100644 --- a/certbot/tests/util.py +++ b/certbot/tests/util.py @@ -277,13 +277,16 @@ class ConfigTestCase(TempDirTestCase): def setUp(self): super(ConfigTestCase, self).setUp() self.config = configuration.NamespaceConfig( - mock.MagicMock( - config_dir=os.path.join(self.tempdir, 'config'), - work_dir=os.path.join(self.tempdir, 'work'), - logs_dir=os.path.join(self.tempdir, 'logs'), - server="example.com", - ) + mock.MagicMock(**constants.CLI_DEFAULTS) ) + self.config.verb = "certonly" + self.config.config_dir = os.path.join(self.tempdir, 'config') + self.config.work_dir = os.path.join(self.tempdir, 'work') + self.config.logs_dir = os.path.join(self.tempdir, 'logs') + self.config.cert_path = constants.CLI_DEFAULTS['auth_cert_path'] + self.config.fullchain_path = constants.CLI_DEFAULTS['auth_chain_path'] + self.config.chain_path = constants.CLI_DEFAULTS['auth_chain_path'] + self.config.server = "example.com" def lock_and_call(func, lock_path): """Grab a lock for lock_path and call func. diff --git a/docs/cli-help.txt b/docs/cli-help.txt index 14198ced5..32603f195 100644 --- a/docs/cli-help.txt +++ b/docs/cli-help.txt @@ -102,7 +102,7 @@ optional arguments: 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: CertbotACMEClient/0.18.0 (certbot; + "". (default: CertbotACMEClient/0.18.1 (certbot; Ubuntu 16.04.3 LTS) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/2.7.12). The flags encoded in the user agent are: --duplicate, --force- diff --git a/letsencrypt-auto b/letsencrypt-auto index 223fbfd32..0738db84d 100755 --- a/letsencrypt-auto +++ b/letsencrypt-auto @@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then fi VENV_BIN="$VENV_PATH/bin" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" -LE_AUTO_VERSION="0.18.0" +LE_AUTO_VERSION="0.18.1" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -187,8 +187,7 @@ SetRootAuthMechanism() { if [ "$1" = "--cb-auto-has-root" ]; then shift 1 -elif [ "$1" != "--le-auto-phase2" ]; then - # if $1 is --le-auto-phase2, we've executed this branch before +else SetRootAuthMechanism if [ -n "$SUDO" ]; then echo "Requesting to rerun $0 with root privileges..." @@ -197,6 +196,14 @@ elif [ "$1" != "--le-auto-phase2" ]; then fi fi +# Runs this script again with the given arguments. --cb-auto-has-root is added +# to the command line arguments to ensure we don't try to acquire root a +# second time. After the script is rerun, we exit the current script. +RerunWithArgs() { + "$0" --cb-auto-has-root "$@" + exit 0 +} + BootstrapMessage() { # Arguments: Platform name say "Bootstrapping dependencies for $1... (you can skip this with --no-bootstrap)" @@ -825,8 +832,7 @@ if [ "$1" = "--le-auto-phase2" ]; then # if non-interactive mode or stdin and stdout are connected to a terminal if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then rm -rf "$VENV_PATH" - "$0" "$@" - exit 0 + RerunWithArgs "$@" else error "Skipping upgrade because new OS dependencies may need to be installed." error @@ -1071,18 +1077,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.18.0 \ - --hash=sha256:941925f045aaae2a7e5b1d322b68ea3e042a1c2d6a3b3de76c5b8a5122e515a7 \ - --hash=sha256:f70bdfd7a455f0c1f72610b48bf4a462e4aecd8e66baa9d2278f7bc4a4f4195f -acme==0.18.0 \ - --hash=sha256:e35b2dbc27a40ca35d9120cb417abde667e9c59436662a10f260f3eaa2eb8fe0 \ - --hash=sha256:301b0c9108f80d1182add10e8fd0fa962a143731b8208615631a711b8cd98938 -certbot-apache==0.18.0 \ - --hash=sha256:e08504b1e13e0698dffd4b6437cdf24480f6666b60455c83e9a55cad56ab8c2d \ - --hash=sha256:44b65d61f4d284da188c578ad0dc700d4743d03ae5382be86716ff26a82def94 -certbot-nginx==0.18.0 \ - --hash=sha256:da58201350b0d02cd4b43ea53abd34a4a56cbb7d5564004c25607bdcbec5e890 \ - --hash=sha256:528db0f8e5d5ac6956e4df15ab4809f313114ff2817c4b2f04c43913d750ca28 +certbot==0.18.1 \ + --hash=sha256:46e5f0b225ceef0afe81f7f2442c0dd23485f96b5e16cbd78c9e692dc551203e \ + --hash=sha256:ae0aaf0cc1af53713232a222fb20891475ec9ff9d128a277c4e0f92ea7c36b4c +acme==0.18.1 \ + --hash=sha256:a1c3d8dddb573b69573294ccc089f9a12fd91ebdfe72d9bfcacc260df28c50cf \ + --hash=sha256:1e4c6c0a3fb9906f0d1389a39c76d730e2691d7f168a219e464237381ddcc667 +certbot-apache==0.18.1 \ + --hash=sha256:2eb78c6b22bc6028e4d7f169e1cbdca1ddedf3aa60e69f5f38952654b7a2a94d \ + --hash=sha256:2a25b2909167ae5c583b034957e59e9923017cf52c6fa4b310cfca2a3a005fb4 +certbot-nginx==0.18.1 \ + --hash=sha256:19be0c3800cacf97d4ca8a20c7a65585fb24af3a2c9164484b12c4da634b6833 \ + --hash=sha256:bda89d4ebcfc9dc7ee41fe23ea2fc19e6c773a4a2873737d4b19210c752f5aca UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -1491,5 +1497,5 @@ UNLIKELY_EOF fi # A newer version is available. fi # Self-upgrading is allowed. - "$0" --le-auto-phase2 "$@" + RerunWithArgs --le-auto-phase2 "$@" fi diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc index 32e2c216b..c8f085d5d 100644 --- a/letsencrypt-auto-source/certbot-auto.asc +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 -iQEcBAABCAAGBQJZry3aAAoJEE0XyZXNl3Xy2foH/0ehCksUM0JQWdHNjmEexo0l -XBvtZz59BkQpERZRd7tuwiXzFCJ9VwxlCUo4DhmdT7IYrM3/qb5HoVWPMrw70ySX -CgKB/SKKYiHFXLT0w/sT6RJDp1y/dt1+8+BWCCztI+1yaQiAsJBK3rzVjpcQRb15 -yoQs9tNQIBBKdocZISjOTX1pYcwkA7fBGbnep9ndsM1PSuGXk3CBDF2YRfVnxnwF -Y6R1Psjjk6vsUK9KY8uPtNtH4w3W30tRVbQmBf2qOsPrr532W/Zjvo1UERhqpM/w -fxjgo8XyJdMvilL/U3lZEsdzq2WTbS8nXto1mB0/QgVLENICsWoE8SVSql10iYo= -=wcEX +iQEcBAABCAAGBQJZsuPcAAoJEE0XyZXNl3XyrCkIAI+fJyipTParZlfPd87cYWOY +QJeg7madSmRajYCUvtOn4Cm6bwcXZClHwXtiAlS7qXfDRDlKECoKGak7aUP7pd5w +qG+efRB53XOyVGjl0PVSqOslhKaSved4k6vTZtHl/qqruVaDxiipoX3NdzWfeYdu +LN0j87/y7BNxRqL9UirjsASfmMlx+41eDOuCC8tmnMsHOSnMll5siPSCngv/Mn4Q +itHJRAGL4P8oRI7qsId3Yv+HwK46tT0L8ZbaxfsGbHUFWw5pOgb+Ea8QDqCSnqfR +uuqHfNzjvY6wwcyAV945A3LK5MizxRkP3UX1MmvT8EWPT7lXMsf22Cicm8eas+k= +=QEPM -----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index dd03c14e7..4b55e480f 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -1077,18 +1077,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.18.0 \ - --hash=sha256:941925f045aaae2a7e5b1d322b68ea3e042a1c2d6a3b3de76c5b8a5122e515a7 \ - --hash=sha256:f70bdfd7a455f0c1f72610b48bf4a462e4aecd8e66baa9d2278f7bc4a4f4195f -acme==0.18.0 \ - --hash=sha256:e35b2dbc27a40ca35d9120cb417abde667e9c59436662a10f260f3eaa2eb8fe0 \ - --hash=sha256:301b0c9108f80d1182add10e8fd0fa962a143731b8208615631a711b8cd98938 -certbot-apache==0.18.0 \ - --hash=sha256:e08504b1e13e0698dffd4b6437cdf24480f6666b60455c83e9a55cad56ab8c2d \ - --hash=sha256:44b65d61f4d284da188c578ad0dc700d4743d03ae5382be86716ff26a82def94 -certbot-nginx==0.18.0 \ - --hash=sha256:da58201350b0d02cd4b43ea53abd34a4a56cbb7d5564004c25607bdcbec5e890 \ - --hash=sha256:528db0f8e5d5ac6956e4df15ab4809f313114ff2817c4b2f04c43913d750ca28 +certbot==0.18.1 \ + --hash=sha256:46e5f0b225ceef0afe81f7f2442c0dd23485f96b5e16cbd78c9e692dc551203e \ + --hash=sha256:ae0aaf0cc1af53713232a222fb20891475ec9ff9d128a277c4e0f92ea7c36b4c +acme==0.18.1 \ + --hash=sha256:a1c3d8dddb573b69573294ccc089f9a12fd91ebdfe72d9bfcacc260df28c50cf \ + --hash=sha256:1e4c6c0a3fb9906f0d1389a39c76d730e2691d7f168a219e464237381ddcc667 +certbot-apache==0.18.1 \ + --hash=sha256:2eb78c6b22bc6028e4d7f169e1cbdca1ddedf3aa60e69f5f38952654b7a2a94d \ + --hash=sha256:2a25b2909167ae5c583b034957e59e9923017cf52c6fa4b310cfca2a3a005fb4 +certbot-nginx==0.18.1 \ + --hash=sha256:19be0c3800cacf97d4ca8a20c7a65585fb24af3a2c9164484b12c4da634b6833 \ + --hash=sha256:bda89d4ebcfc9dc7ee41fe23ea2fc19e6c773a4a2873737d4b19210c752f5aca UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig Binary files differindex 7ba0ac00c..87573f1b3 100644 --- a/letsencrypt-auto-source/letsencrypt-auto.sig +++ b/letsencrypt-auto-source/letsencrypt-auto.sig diff --git a/letsencrypt-auto-source/pieces/certbot-requirements.txt b/letsencrypt-auto-source/pieces/certbot-requirements.txt index f0f961420..7d12e35a8 100644 --- a/letsencrypt-auto-source/pieces/certbot-requirements.txt +++ b/letsencrypt-auto-source/pieces/certbot-requirements.txt @@ -1,12 +1,12 @@ -certbot==0.18.0 \ - --hash=sha256:941925f045aaae2a7e5b1d322b68ea3e042a1c2d6a3b3de76c5b8a5122e515a7 \ - --hash=sha256:f70bdfd7a455f0c1f72610b48bf4a462e4aecd8e66baa9d2278f7bc4a4f4195f -acme==0.18.0 \ - --hash=sha256:e35b2dbc27a40ca35d9120cb417abde667e9c59436662a10f260f3eaa2eb8fe0 \ - --hash=sha256:301b0c9108f80d1182add10e8fd0fa962a143731b8208615631a711b8cd98938 -certbot-apache==0.18.0 \ - --hash=sha256:e08504b1e13e0698dffd4b6437cdf24480f6666b60455c83e9a55cad56ab8c2d \ - --hash=sha256:44b65d61f4d284da188c578ad0dc700d4743d03ae5382be86716ff26a82def94 -certbot-nginx==0.18.0 \ - --hash=sha256:da58201350b0d02cd4b43ea53abd34a4a56cbb7d5564004c25607bdcbec5e890 \ - --hash=sha256:528db0f8e5d5ac6956e4df15ab4809f313114ff2817c4b2f04c43913d750ca28 +certbot==0.18.1 \ + --hash=sha256:46e5f0b225ceef0afe81f7f2442c0dd23485f96b5e16cbd78c9e692dc551203e \ + --hash=sha256:ae0aaf0cc1af53713232a222fb20891475ec9ff9d128a277c4e0f92ea7c36b4c +acme==0.18.1 \ + --hash=sha256:a1c3d8dddb573b69573294ccc089f9a12fd91ebdfe72d9bfcacc260df28c50cf \ + --hash=sha256:1e4c6c0a3fb9906f0d1389a39c76d730e2691d7f168a219e464237381ddcc667 +certbot-apache==0.18.1 \ + --hash=sha256:2eb78c6b22bc6028e4d7f169e1cbdca1ddedf3aa60e69f5f38952654b7a2a94d \ + --hash=sha256:2a25b2909167ae5c583b034957e59e9923017cf52c6fa4b310cfca2a3a005fb4 +certbot-nginx==0.18.1 \ + --hash=sha256:19be0c3800cacf97d4ca8a20c7a65585fb24af3a2c9164484b12c4da634b6833 \ + --hash=sha256:bda89d4ebcfc9dc7ee41fe23ea2fc19e6c773a4a2873737d4b19210c752f5aca diff --git a/tests/letstest/scripts/test_letsencrypt_auto_certonly_standalone.sh b/tests/letstest/scripts/test_letsencrypt_auto_certonly_standalone.sh index 1df424974..2cbe66a83 100755 --- a/tests/letstest/scripts/test_letsencrypt_auto_certonly_standalone.sh +++ b/tests/letstest/scripts/test_letsencrypt_auto_certonly_standalone.sh @@ -38,7 +38,7 @@ if [ "$REVOKED" != 1 ] ; then exit 1 fi -if ! letsencrypt-auto --help | grep -F "letsencrypt-auto [SUBCOMMAND]"; then +if ! letsencrypt-auto --help --no-self-upgrade | grep -F "letsencrypt-auto [SUBCOMMAND]"; then echo "letsencrypt-auto not included in help output!" exit 1 fi |