From 3de3188dd6fe4c8c9952848c155a56944b55ec2d Mon Sep 17 00:00:00 2001 From: schoen Date: Thu, 18 Oct 2018 04:44:45 -0700 Subject: [PATCH] Warn manual authenticator users not to remove/undo previous challenges (#6370) * Warn users not to remove/undo previous challenges * Even more specific DNS challenge message * Fix spacing and variable names * Create a second test DNS challenge for UI testing * Changelog for subsequent manual challenge behavior --- CHANGELOG.md | 2 +- certbot/plugins/manual.py | 21 +++++++++++++++++++++ certbot/plugins/manual_test.py | 3 ++- certbot/tests/acme_util.py | 3 +++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81cc12b15..5dd51ef16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Certbot adheres to [Semantic Versioning](http://semver.org/). ### Changed -* +* `--manual` will explicitly warn users that earlier challenges should remain in place when setting up subsequent challenges. ### Fixed diff --git a/certbot/plugins/manual.py b/certbot/plugins/manual.py index 53533d35a..8723a1c62 100644 --- a/certbot/plugins/manual.py +++ b/certbot/plugins/manual.py @@ -94,6 +94,16 @@ using the secret key {key} when it receives a TLS ClientHello with the SNI extension set to {sni_domain} +""" + _SUBSEQUENT_CHALLENGE_INSTRUCTIONS = """ +(This must be set up in addition to the previous challenges; do not remove, +replace, or undo the previous challenge tasks yet.) +""" + _SUBSEQUENT_DNS_CHALLENGE_INSTRUCTIONS = """ +(This must be set up in addition to the previous challenges; do not remove, +replace, or undo the previous challenge tasks yet. Note that you might be +asked to create multiple distinct TXT records with the same name. This is +permitted by DNS standards.) """ def __init__(self, *args, **kwargs): @@ -103,6 +113,8 @@ when it receives a TLS ClientHello with the SNI extension set to self.env = dict() \ # type: Dict[achallenges.KeyAuthorizationAnnotatedChallenge, Dict[str, str]] self.tls_sni_01 = None + self.subsequent_dns_challenge = False + self.subsequent_any_challenge = False @classmethod def add_parser_arguments(cls, add): @@ -212,8 +224,17 @@ when it receives a TLS ClientHello with the SNI extension set to key=self.tls_sni_01.get_key_path(achall), port=self.config.tls_sni_01_port, sni_domain=self.tls_sni_01.get_z_domain(achall)) + if isinstance(achall.chall, challenges.DNS01): + if self.subsequent_dns_challenge: + # 2nd or later dns-01 challenge + msg += self._SUBSEQUENT_DNS_CHALLENGE_INSTRUCTIONS + self.subsequent_dns_challenge = True + elif self.subsequent_any_challenge: + # 2nd or later challenge of another type + msg += self._SUBSEQUENT_CHALLENGE_INSTRUCTIONS display = zope.component.getUtility(interfaces.IDisplay) display.notification(msg, wrap=False, force_interactive=True) + self.subsequent_any_challenge = True def cleanup(self, achalls): # pylint: disable=missing-docstring if self.conf('cleanup-hook'): diff --git a/certbot/plugins/manual_test.py b/certbot/plugins/manual_test.py index e5c22b377..ba4eb6889 100644 --- a/certbot/plugins/manual_test.py +++ b/certbot/plugins/manual_test.py @@ -20,8 +20,9 @@ class AuthenticatorTest(test_util.TempDirTestCase): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A + self.dns_achall_2 = acme_util.DNS01_A_2 self.tls_sni_achall = acme_util.TLSSNI01_A - self.achalls = [self.http_achall, self.dns_achall, self.tls_sni_achall] + self.achalls = [self.http_achall, self.dns_achall, self.tls_sni_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: os.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in diff --git a/certbot/tests/acme_util.py b/certbot/tests/acme_util.py index 53a2f214a..2f9445694 100644 --- a/certbot/tests/acme_util.py +++ b/certbot/tests/acme_util.py @@ -21,6 +21,7 @@ HTTP01 = challenges.HTTP01( TLSSNI01 = challenges.TLSSNI01( token=jose.b64decode(b"evaGxfADs6pSRb2LAv9IZf17Dt3juxGJyPCt92wrDoA")) DNS01 = challenges.DNS01(token=b"17817c66b60ce2e4012dfad92657527a") +DNS01_2 = challenges.DNS01(token=b"cafecafecafecafecafecafe0feedbac") CHALLENGES = [HTTP01, TLSSNI01, DNS01] @@ -49,6 +50,7 @@ def chall_to_challb(chall, status): # pylint: disable=redefined-outer-name TLSSNI01_P = chall_to_challb(TLSSNI01, messages.STATUS_PENDING) HTTP01_P = chall_to_challb(HTTP01, messages.STATUS_PENDING) DNS01_P = chall_to_challb(DNS01, messages.STATUS_PENDING) +DNS01_P_2 = chall_to_challb(DNS01_2, messages.STATUS_PENDING) CHALLENGES_P = [HTTP01_P, TLSSNI01_P, DNS01_P] @@ -57,6 +59,7 @@ CHALLENGES_P = [HTTP01_P, TLSSNI01_P, DNS01_P] HTTP01_A = auth_handler.challb_to_achall(HTTP01_P, JWK, "example.com") TLSSNI01_A = auth_handler.challb_to_achall(TLSSNI01_P, JWK, "example.net") DNS01_A = auth_handler.challb_to_achall(DNS01_P, JWK, "example.org") +DNS01_A_2 = auth_handler.challb_to_achall(DNS01_P_2, JWK, "esimerkki.example.org") ACHALLENGES = [HTTP01_A, TLSSNI01_A, DNS01_A]