Compare commits

...

7 Commits

Author SHA1 Message Date
Brad Warren
ea445ed11e Release 0.22.2 2018-03-19 17:41:17 -07:00
Brad Warren
8d061e5dfc Fix cleanup_challenges call (#5761) (#5762)
* fixes cleanup_challenges

* add test to prevent regressions

(cherry picked from commit 41ce108881)
2018-03-19 17:29:59 -07:00
Brad Warren
0131c649d0 Fix acme.client.Client.__init__ (#5747) (#5748)
* fixes #5738

* add test to prevent regressions

(cherry picked from commit ba6bdb5099)
2018-03-16 18:44:23 -07:00
Brad Warren
eda458b2da Update instances of acme-staging url to acme-staging-v02 (#5734) (#5746)
* update instances of acme-staging url to acme-staging-v02

* keep example client as v1

* keep deactivate script as v1

(cherry picked from commit 5ecb68f2ed)
2018-03-16 17:11:12 -07:00
Brad Warren
cedbf8906c removes blank line from chain.pem (#5730) (#5733)
(cherry picked from commit b3e73bd2ab)
2018-03-14 18:58:52 -07:00
Brad Warren
d0b336085c fix(acme): client._revoke sends default content_type (#5687) (#5726)
(cherry picked from commit f4bac423fb)
2018-03-14 18:34:59 -07:00
Brad Warren
c9f278e6c8 Fix --allow-subset-of-names (#5690) (#5725)
* Remove aauthzr instance variable

* If domain begins with fail, fail the challenge.

* test --allow-subset-of-names

* Fix renewal and add extra check

* test after hook checks

(cherry picked from commit cc24b4e40a)
2018-03-14 17:28:45 -07:00
36 changed files with 228 additions and 178 deletions

View File

@@ -227,8 +227,7 @@ class ClientBase(object): # pylint: disable=too-many-instance-attributes
response = self._post(url, response = self._post(url,
messages.Revocation( messages.Revocation(
certificate=cert, certificate=cert,
reason=rsn), reason=rsn))
content_type=None)
if response.status_code != http_client.OK: if response.status_code != http_client.OK:
raise errors.ClientError( raise errors.ClientError(
'Successful revocation must return HTTP OK status') 'Successful revocation must return HTTP OK status')
@@ -260,11 +259,12 @@ class Client(ClientBase):
""" """
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
self.key = key self.key = key
self.net = ClientNetwork(key, alg=alg, verify_ssl=verify_ssl) if net is None else net if net is None:
net = ClientNetwork(key, alg=alg, verify_ssl=verify_ssl)
if isinstance(directory, six.string_types): if isinstance(directory, six.string_types):
directory = messages.Directory.from_json( directory = messages.Directory.from_json(
self.net.get(directory).json()) net.get(directory).json())
super(Client, self).__init__(directory=directory, super(Client, self).__init__(directory=directory,
net=net, acme_version=1) net=net, acme_version=1)

View File

@@ -299,6 +299,16 @@ class ClientTest(ClientTestBase):
directory=uri, key=KEY, alg=jose.RS256, net=self.net) directory=uri, key=KEY, alg=jose.RS256, net=self.net)
self.net.get.assert_called_once_with(uri) self.net.get.assert_called_once_with(uri)
@mock.patch('acme.client.ClientNetwork')
def test_init_without_net(self, mock_net):
mock_net.return_value = mock.sentinel.net
alg = jose.RS256
from acme.client import Client
self.client = Client(
directory=self.directory, key=KEY, alg=alg)
mock_net.called_once_with(KEY, alg=alg, verify_ssl=True)
self.assertEqual(self.client.net, mock.sentinel.net)
def test_register(self): def test_register(self):
# "Instance of 'Field' has no to_json/update member" bug: # "Instance of 'Field' has no to_json/update member" bug:
# pylint: disable=no-member # pylint: disable=no-member
@@ -635,8 +645,7 @@ class ClientTest(ClientTestBase):
def test_revoke(self): def test_revoke(self):
self.client.revoke(self.certr.body, self.rsn) self.client.revoke(self.certr.body, self.rsn)
self.net.post.assert_called_once_with( self.net.post.assert_called_once_with(
self.directory[messages.Revocation], mock.ANY, content_type=None, self.directory[messages.Revocation], mock.ANY, acme_version=1)
acme_version=1)
def test_revocation_payload(self): def test_revocation_payload(self):
obj = messages.Revocation(certificate=self.certr.body, reason=self.rsn) obj = messages.Revocation(certificate=self.certr.body, reason=self.rsn)
@@ -776,8 +785,7 @@ class ClientV2Test(ClientTestBase):
def test_revoke(self): def test_revoke(self):
self.client.revoke(messages_test.CERT, self.rsn) self.client.revoke(messages_test.CERT, self.rsn)
self.net.post.assert_called_once_with( self.net.post.assert_called_once_with(
self.directory["revokeCert"], mock.ANY, content_type=None, self.directory["revokeCert"], mock.ANY, acme_version=2)
acme_version=2)
class MockJSONDeSerializable(jose.JSONDeSerializable): class MockJSONDeSerializable(jose.JSONDeSerializable):

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
fi fi
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
LE_AUTO_VERSION="0.22.0" LE_AUTO_VERSION="0.22.2"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -1199,18 +1199,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==0.22.0 \ certbot==0.22.2 \
--hash=sha256:ebfeaf9737dc440a9f263099487523ab4c8d8da9def31a71327439d9186e00fa \ --hash=sha256:c8c63bdf0fed6258bdbc892454314ec37bcd1c35a7f62524a083d93ccdfc420d \
--hash=sha256:ee307dd8f194bd710a3326aa4bacf95d358877498c0b9aa187eff0dc211dcbb3 --hash=sha256:e6e3639293e78397f31f7d99e3c63aff82d91e2b0d50d146ee3c77f830464bef
acme==0.22.0 \ acme==0.22.2 \
--hash=sha256:37e6d8e4eb7dd18edac96de209f451300e04074f14be7fce713db6931a0e4a20 \ --hash=sha256:59a55244612ee305d2caa6bb4cddd400fb60ec841bf011ed29a2899832a682c2 \
--hash=sha256:4a2cd52db32e914b68d8446c8e788f507c20edebbd1c36d4f3eda7b47c555fe8 --hash=sha256:0ecd0ea369f53d5bc744d6e72717f9af2e1ceb558d109dbd433148851027adb4
certbot-apache==0.22.0 \ certbot-apache==0.22.2 \
--hash=sha256:e91f6ec8203b636fa44f01017646fca68406224ee327fd56017103b78bc65539 \ --hash=sha256:b5340d4b9190358fde8eb6a5be0def37e32014b5142ee79ef5d2319ccbbde754 \
--hash=sha256:8fbab1a358ec131996d1c00f7d0ed18ee3624f8469cab3962dfd8ba40ca3e7cd --hash=sha256:3cd26912bb5732d917ddf7aad2fe870090d4ece9a408b2c2de8e9723ec99c759
certbot-nginx==0.22.0 \ certbot-nginx==0.22.2 \
--hash=sha256:d67210cf73cf44e8aeff04f6f228d8bde74444703ce3ccd929a450685b58c30b \ --hash=sha256:91feef0d879496835d355e82841f92e5ecb5abbf6f23ea0ee5bbb8f5a92b278a \
--hash=sha256:b2b26bf9112062b02518407704cad09f7136322163d529a2dde3b6e1578ecb8c --hash=sha256:b10bf04c1a20cf878d5e0d1877deb0e0780bc31b0ffda08ce7199bbc39d0753b
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
install_requires = [ install_requires = [
'certbot', 'certbot',

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -3,7 +3,7 @@ import sys
from distutils.core import setup from distutils.core import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.22.0' version = '0.22.2'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.

View File

@@ -1,4 +1,4 @@
"""Certbot client.""" """Certbot client."""
# version number like 1.2.3a0, must have at least 2 parts, like 1.2 # version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '0.22.0' __version__ = '0.22.2'

View File

@@ -34,8 +34,6 @@ class AuthHandler(object):
:ivar account: Client's Account :ivar account: Client's Account
:type account: :class:`certbot.account.Account` :type account: :class:`certbot.account.Account`
:ivar aauthzrs: ACME Authorization Resources and their active challenges
:type aauthzrs: `list` of `AnnotatedAuthzr`
:ivar list pref_challs: sorted user specified preferred challenges :ivar list pref_challs: sorted user specified preferred challenges
type strings with the most preferred challenge listed first type strings with the most preferred challenge listed first
@@ -45,7 +43,6 @@ class AuthHandler(object):
self.acme = acme self.acme = acme
self.account = account self.account = account
self.aauthzrs = []
self.pref_challs = pref_challs self.pref_challs = pref_challs
def handle_authorizations(self, orderr, best_effort=False): def handle_authorizations(self, orderr, best_effort=False):
@@ -63,29 +60,29 @@ class AuthHandler(object):
authorizations authorizations
""" """
for authzr in orderr.authorizations: aauthzrs = [AnnotatedAuthzr(authzr, [])
self.aauthzrs.append(AnnotatedAuthzr(authzr, [])) for authzr in orderr.authorizations]
self._choose_challenges() self._choose_challenges(aauthzrs)
config = zope.component.getUtility(interfaces.IConfig) config = zope.component.getUtility(interfaces.IConfig)
notify = zope.component.getUtility(interfaces.IDisplay).notification notify = zope.component.getUtility(interfaces.IDisplay).notification
# While there are still challenges remaining... # While there are still challenges remaining...
while self._has_challenges(): while self._has_challenges(aauthzrs):
resp = self._solve_challenges() resp = self._solve_challenges(aauthzrs)
logger.info("Waiting for verification...") logger.info("Waiting for verification...")
if config.debug_challenges: if config.debug_challenges:
notify('Challenges loaded. Press continue to submit to CA. ' notify('Challenges loaded. Press continue to submit to CA. '
'Pass "-v" for more info about challenges.', pause=True) 'Pass "-v" for more info about challenges.', pause=True)
# Send all Responses - this modifies achalls # Send all Responses - this modifies achalls
self._respond(resp, best_effort) self._respond(aauthzrs, resp, best_effort)
# Just make sure all decisions are complete. # Just make sure all decisions are complete.
self.verify_authzr_complete() self.verify_authzr_complete(aauthzrs)
# Only return valid authorizations # Only return valid authorizations
retVal = [aauthzr.authzr for aauthzr in self.aauthzrs retVal = [aauthzr.authzr for aauthzr in aauthzrs
if aauthzr.authzr.body.status == messages.STATUS_VALID] if aauthzr.authzr.body.status == messages.STATUS_VALID]
if not retVal: if not retVal:
@@ -94,10 +91,10 @@ class AuthHandler(object):
return retVal return retVal
def _choose_challenges(self): def _choose_challenges(self, aauthzrs):
"""Retrieve necessary challenges to satisfy server.""" """Retrieve necessary challenges to satisfy server."""
logger.info("Performing the following challenges:") logger.info("Performing the following challenges:")
for aauthzr in self.aauthzrs: for aauthzr in aauthzrs:
aauthzr_challenges = aauthzr.authzr.body.challenges aauthzr_challenges = aauthzr.authzr.body.challenges
if self.acme.acme_version == 1: if self.acme.acme_version == 1:
combinations = aauthzr.authzr.body.combinations combinations = aauthzr.authzr.body.combinations
@@ -113,15 +110,15 @@ class AuthHandler(object):
aauthzr.authzr, path) aauthzr.authzr, path)
aauthzr.achalls.extend(aauthzr_achalls) aauthzr.achalls.extend(aauthzr_achalls)
def _has_challenges(self): def _has_challenges(self, aauthzrs):
"""Do we have any challenges to perform?""" """Do we have any challenges to perform?"""
return any(aauthzr.achalls for aauthzr in self.aauthzrs) return any(aauthzr.achalls for aauthzr in aauthzrs)
def _solve_challenges(self): def _solve_challenges(self, aauthzrs):
"""Get Responses for challenges from authenticators.""" """Get Responses for challenges from authenticators."""
resp = [] resp = []
all_achalls = self._get_all_achalls() all_achalls = self._get_all_achalls(aauthzrs)
with error_handler.ErrorHandler(self._cleanup_challenges): with error_handler.ErrorHandler(self._cleanup_challenges, aauthzrs, all_achalls):
try: try:
if all_achalls: if all_achalls:
resp = self.auth.perform(all_achalls) resp = self.auth.perform(all_achalls)
@@ -134,15 +131,15 @@ class AuthHandler(object):
return resp return resp
def _get_all_achalls(self): def _get_all_achalls(self, aauthzrs):
"""Return all active challenges.""" """Return all active challenges."""
all_achalls = [] all_achalls = []
for aauthzr in self.aauthzrs: for aauthzr in aauthzrs:
all_achalls.extend(aauthzr.achalls) all_achalls.extend(aauthzr.achalls)
return all_achalls return all_achalls
def _respond(self, resp, best_effort): def _respond(self, aauthzrs, resp, best_effort):
"""Send/Receive confirmation of all challenges. """Send/Receive confirmation of all challenges.
.. note:: This method also cleans up the auth_handler state. .. note:: This method also cleans up the auth_handler state.
@@ -150,24 +147,27 @@ class AuthHandler(object):
""" """
# TODO: chall_update is a dirty hack to get around acme-spec #105 # TODO: chall_update is a dirty hack to get around acme-spec #105
chall_update = dict() chall_update = dict()
active_achalls = self._send_responses(resp, chall_update) active_achalls = self._send_responses(aauthzrs, resp, chall_update)
# Check for updated status... # Check for updated status...
try: try:
self._poll_challenges(chall_update, best_effort) self._poll_challenges(aauthzrs, chall_update, best_effort)
finally: finally:
self._cleanup_challenges(active_achalls) self._cleanup_challenges(aauthzrs, active_achalls)
def _send_responses(self, resps, chall_update): def _send_responses(self, aauthzrs, resps, chall_update):
"""Send responses and make sure errors are handled. """Send responses and make sure errors are handled.
:param aauthzrs: authorizations and the selected annotated challenges
to try and perform
:type aauthzrs: `list` of `AnnotatedAuthzr`
:param dict chall_update: parameter that is updated to hold :param dict chall_update: parameter that is updated to hold
aauthzr index to list of outstanding solved annotated challenges aauthzr index to list of outstanding solved annotated challenges
""" """
active_achalls = [] active_achalls = []
resps_iter = iter(resps) resps_iter = iter(resps)
for i, aauthzr in enumerate(self.aauthzrs): for i, aauthzr in enumerate(aauthzrs):
for achall in aauthzr.achalls: for achall in aauthzr.achalls:
# This line needs to be outside of the if block below to # This line needs to be outside of the if block below to
# ensure failed challenges are cleaned up correctly # ensure failed challenges are cleaned up correctly
@@ -184,8 +184,8 @@ class AuthHandler(object):
return active_achalls return active_achalls
def _poll_challenges( def _poll_challenges(self, aauthzrs, chall_update,
self, chall_update, best_effort, min_sleep=3, max_rounds=15): best_effort, min_sleep=3, max_rounds=15):
"""Wait for all challenge results to be determined.""" """Wait for all challenge results to be determined."""
indices_to_check = set(chall_update.keys()) indices_to_check = set(chall_update.keys())
comp_indices = set() comp_indices = set()
@@ -197,7 +197,7 @@ class AuthHandler(object):
all_failed_achalls = set() all_failed_achalls = set()
for index in indices_to_check: for index in indices_to_check:
comp_achalls, failed_achalls = self._handle_check( comp_achalls, failed_achalls = self._handle_check(
index, chall_update[index]) aauthzrs, index, chall_update[index])
if len(comp_achalls) == len(chall_update[index]): if len(comp_achalls) == len(chall_update[index]):
comp_indices.add(index) comp_indices.add(index)
@@ -210,7 +210,7 @@ class AuthHandler(object):
comp_indices.add(index) comp_indices.add(index)
logger.warning( logger.warning(
"Challenge failed for domain %s", "Challenge failed for domain %s",
self.aauthzrs[index].authzr.body.identifier.value) aauthzrs[index].authzr.body.identifier.value)
else: else:
all_failed_achalls.update( all_failed_achalls.update(
updated for _, updated in failed_achalls) updated for _, updated in failed_achalls)
@@ -223,14 +223,14 @@ class AuthHandler(object):
comp_indices.clear() comp_indices.clear()
rounds += 1 rounds += 1
def _handle_check(self, index, achalls): def _handle_check(self, aauthzrs, index, achalls):
"""Returns tuple of ('completed', 'failed').""" """Returns tuple of ('completed', 'failed')."""
completed = [] completed = []
failed = [] failed = []
original_aauthzr = self.aauthzrs[index] original_aauthzr = aauthzrs[index]
updated_authzr, _ = self.acme.poll(original_aauthzr.authzr) updated_authzr, _ = self.acme.poll(original_aauthzr.authzr)
self.aauthzrs[index] = AnnotatedAuthzr(updated_authzr, original_aauthzr.achalls) aauthzrs[index] = AnnotatedAuthzr(updated_authzr, original_aauthzr.achalls)
if updated_authzr.body.status == messages.STATUS_VALID: if updated_authzr.body.status == messages.STATUS_VALID:
return achalls, [] return achalls, []
@@ -287,35 +287,38 @@ class AuthHandler(object):
chall_prefs.extend(plugin_pref) chall_prefs.extend(plugin_pref)
return chall_prefs return chall_prefs
def _cleanup_challenges(self, achall_list=None): def _cleanup_challenges(self, aauthzrs, achalls):
"""Cleanup challenges. """Cleanup challenges.
If achall_list is not provided, cleanup all achallenges. :param aauthzrs: authorizations and their selected annotated
challenges
:type aauthzrs: `list` of `AnnotatedAuthzr`
:param achalls: annotated challenges to cleanup
:type achalls: `list` of :class:`certbot.achallenges.AnnotatedChallenge`
""" """
logger.info("Cleaning up challenges") logger.info("Cleaning up challenges")
if achall_list is None:
achalls = self._get_all_achalls()
else:
achalls = achall_list
if achalls: if achalls:
self.auth.cleanup(achalls) self.auth.cleanup(achalls)
for achall in achalls: for achall in achalls:
for aauthzr in self.aauthzrs: for aauthzr in aauthzrs:
if achall in aauthzr.achalls: if achall in aauthzr.achalls:
aauthzr.achalls.remove(achall) aauthzr.achalls.remove(achall)
break break
def verify_authzr_complete(self): def verify_authzr_complete(self, aauthzrs):
"""Verifies that all authorizations have been decided. """Verifies that all authorizations have been decided.
:param aauthzrs: authorizations and their selected annotated
challenges
:type aauthzrs: `list` of `AnnotatedAuthzr`
:returns: Whether all authzr are complete :returns: Whether all authzr are complete
:rtype: bool :rtype: bool
""" """
for aauthzr in self.aauthzrs: for aauthzr in aauthzrs:
authzr = aauthzr.authzr authzr = aauthzr.authzr
if (authzr.body.status != messages.STATUS_VALID and if (authzr.body.status != messages.STATUS_VALID and
authzr.body.status != messages.STATUS_INVALID): authzr.body.status != messages.STATUS_INVALID):

View File

@@ -107,7 +107,7 @@ CLI_DEFAULTS = dict(
dns_route53=False dns_route53=False
) )
STAGING_URI = "https://acme-staging.api.letsencrypt.org/directory" STAGING_URI = "https://acme-staging-v02.api.letsencrypt.org/directory"
# The set of reasons for revoking a certificate is defined in RFC 5280 in # The set of reasons for revoking a certificate is defined in RFC 5280 in
# section 5.3.1. The reasons that users are allowed to submit are restricted to # section 5.3.1. The reasons that users are allowed to submit are restricted to

View File

@@ -445,5 +445,5 @@ def cert_and_chain_from_fullchain(fullchain_pem):
""" """
cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fullchain_pem)).decode() OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fullchain_pem)).decode()
chain = fullchain_pem[len(cert):] chain = fullchain_pem[len(cert):].lstrip()
return (cert, chain) return (cert, chain)

View File

@@ -101,7 +101,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(self.mock_net.answer_challenge.call_count, 1)
self.assertEqual(mock_poll.call_count, 1) self.assertEqual(mock_poll.call_count, 1)
chall_update = mock_poll.call_args[0][0] chall_update = mock_poll.call_args[0][1]
self.assertEqual(list(six.iterkeys(chall_update)), [0]) self.assertEqual(list(six.iterkeys(chall_update)), [0])
self.assertEqual(len(chall_update.values()), 1) self.assertEqual(len(chall_update.values()), 1)
@@ -132,7 +132,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
self.assertEqual(self.mock_net.answer_challenge.call_count, 3) self.assertEqual(self.mock_net.answer_challenge.call_count, 3)
self.assertEqual(mock_poll.call_count, 1) self.assertEqual(mock_poll.call_count, 1)
chall_update = mock_poll.call_args[0][0] chall_update = mock_poll.call_args[0][1]
self.assertEqual(list(six.iterkeys(chall_update)), [0]) self.assertEqual(list(six.iterkeys(chall_update)), [0])
self.assertEqual(len(chall_update.values()), 1) self.assertEqual(len(chall_update.values()), 1)
@@ -158,7 +158,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
self.assertEqual(self.mock_net.answer_challenge.call_count, 1) self.assertEqual(self.mock_net.answer_challenge.call_count, 1)
self.assertEqual(mock_poll.call_count, 1) self.assertEqual(mock_poll.call_count, 1)
chall_update = mock_poll.call_args[0][0] chall_update = mock_poll.call_args[0][1]
self.assertEqual(list(six.iterkeys(chall_update)), [0]) self.assertEqual(list(six.iterkeys(chall_update)), [0])
self.assertEqual(len(chall_update.values()), 1) self.assertEqual(len(chall_update.values()), 1)
@@ -187,7 +187,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
# Check poll call # Check poll call
self.assertEqual(mock_poll.call_count, 1) self.assertEqual(mock_poll.call_count, 1)
chall_update = mock_poll.call_args[0][0] chall_update = mock_poll.call_args[0][1]
self.assertEqual(len(list(six.iterkeys(chall_update))), 3) self.assertEqual(len(list(six.iterkeys(chall_update))), 3)
self.assertTrue(0 in list(six.iterkeys(chall_update))) self.assertTrue(0 in list(six.iterkeys(chall_update)))
self.assertEqual(len(chall_update[0]), 1) self.assertEqual(len(chall_update[0]), 1)
@@ -278,8 +278,19 @@ class HandleAuthorizationsTest(unittest.TestCase):
self.assertRaises( self.assertRaises(
errors.AuthorizationError, self.handler.handle_authorizations, mock_order) errors.AuthorizationError, self.handler.handle_authorizations, mock_order)
def _validate_all(self, unused_1, unused_2): def test_perform_error(self):
for i, aauthzr in enumerate(self.handler.aauthzrs): self.mock_auth.perform.side_effect = errors.AuthorizationError
authzr = gen_dom_authzr(domain="0", challs=acme_util.CHALLENGES, combos=True)
mock_order = mock.MagicMock(authorizations=[authzr])
self.assertRaises(errors.AuthorizationError, self.handler.handle_authorizations, mock_order)
self.assertEqual(self.mock_auth.cleanup.call_count, 1)
self.assertEqual(
self.mock_auth.cleanup.call_args[0][0][0].typ, "tls-sni-01")
def _validate_all(self, aauthzrs, unused_1, unused_2):
for i, aauthzr in enumerate(aauthzrs):
azr = aauthzr.authzr azr = aauthzr.authzr
updated_azr = acme_util.gen_authzr( updated_azr = acme_util.gen_authzr(
messages.STATUS_VALID, messages.STATUS_VALID,
@@ -287,7 +298,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
[challb.chall for challb in azr.body.challenges], [challb.chall for challb in azr.body.challenges],
[messages.STATUS_VALID] * len(azr.body.challenges), [messages.STATUS_VALID] * len(azr.body.challenges),
azr.body.combinations) azr.body.combinations)
self.handler.aauthzrs[i] = type(aauthzr)(updated_azr, aauthzr.achalls) aauthzrs[i] = type(aauthzr)(updated_azr, aauthzr.achalls)
class PollChallengesTest(unittest.TestCase): class PollChallengesTest(unittest.TestCase):
@@ -304,19 +315,21 @@ class PollChallengesTest(unittest.TestCase):
None, self.mock_net, mock.Mock(key="mock_key"), []) None, self.mock_net, mock.Mock(key="mock_key"), [])
self.doms = ["0", "1", "2"] self.doms = ["0", "1", "2"]
self.handler.aauthzrs.append(AnnotatedAuthzr(acme_util.gen_authzr( self.aauthzrs = [
messages.STATUS_PENDING, self.doms[0], AnnotatedAuthzr(acme_util.gen_authzr(
[acme_util.HTTP01, acme_util.TLSSNI01], messages.STATUS_PENDING, self.doms[0],
[messages.STATUS_PENDING] * 2, False), [])) [acme_util.HTTP01, acme_util.TLSSNI01],
self.handler.aauthzrs.append(AnnotatedAuthzr(acme_util.gen_authzr( [messages.STATUS_PENDING] * 2, False), []),
messages.STATUS_PENDING, self.doms[1], AnnotatedAuthzr(acme_util.gen_authzr(
acme_util.CHALLENGES, [messages.STATUS_PENDING] * 3, False), [])) messages.STATUS_PENDING, self.doms[1],
self.handler.aauthzrs.append(AnnotatedAuthzr(acme_util.gen_authzr( acme_util.CHALLENGES, [messages.STATUS_PENDING] * 3, False), []),
messages.STATUS_PENDING, self.doms[2], AnnotatedAuthzr(acme_util.gen_authzr(
acme_util.CHALLENGES, [messages.STATUS_PENDING] * 3, False), [])) messages.STATUS_PENDING, self.doms[2],
acme_util.CHALLENGES, [messages.STATUS_PENDING] * 3, False), [])
]
self.chall_update = {} self.chall_update = {}
for i, aauthzr in enumerate(self.handler.aauthzrs): for i, aauthzr in enumerate(self.aauthzrs):
self.chall_update[i] = [ self.chall_update[i] = [
challb_to_achall(challb, mock.Mock(key="dummy_key"), self.doms[i]) challb_to_achall(challb, mock.Mock(key="dummy_key"), self.doms[i])
for challb in aauthzr.authzr.body.challenges] for challb in aauthzr.authzr.body.challenges]
@@ -324,17 +337,17 @@ class PollChallengesTest(unittest.TestCase):
@mock.patch("certbot.auth_handler.time") @mock.patch("certbot.auth_handler.time")
def test_poll_challenges(self, unused_mock_time): def test_poll_challenges(self, unused_mock_time):
self.mock_net.poll.side_effect = self._mock_poll_solve_one_valid self.mock_net.poll.side_effect = self._mock_poll_solve_one_valid
self.handler._poll_challenges(self.chall_update, False) self.handler._poll_challenges(self.aauthzrs, self.chall_update, False)
for aauthzr in self.handler.aauthzrs: for aauthzr in self.aauthzrs:
self.assertEqual(aauthzr.authzr.body.status, messages.STATUS_VALID) self.assertEqual(aauthzr.authzr.body.status, messages.STATUS_VALID)
@mock.patch("certbot.auth_handler.time") @mock.patch("certbot.auth_handler.time")
def test_poll_challenges_failure_best_effort(self, unused_mock_time): def test_poll_challenges_failure_best_effort(self, unused_mock_time):
self.mock_net.poll.side_effect = self._mock_poll_solve_one_invalid self.mock_net.poll.side_effect = self._mock_poll_solve_one_invalid
self.handler._poll_challenges(self.chall_update, True) self.handler._poll_challenges(self.aauthzrs, self.chall_update, True)
for aauthzr in self.handler.aauthzrs: for aauthzr in self.aauthzrs:
self.assertEqual(aauthzr.authzr.body.status, messages.STATUS_PENDING) self.assertEqual(aauthzr.authzr.body.status, messages.STATUS_PENDING)
@mock.patch("certbot.auth_handler.time") @mock.patch("certbot.auth_handler.time")
@@ -343,7 +356,7 @@ class PollChallengesTest(unittest.TestCase):
self.mock_net.poll.side_effect = self._mock_poll_solve_one_invalid self.mock_net.poll.side_effect = self._mock_poll_solve_one_invalid
self.assertRaises( self.assertRaises(
errors.AuthorizationError, self.handler._poll_challenges, errors.AuthorizationError, self.handler._poll_challenges,
self.chall_update, False) self.aauthzrs, self.chall_update, False)
@mock.patch("certbot.auth_handler.time") @mock.patch("certbot.auth_handler.time")
def test_unable_to_find_challenge_status(self, unused_mock_time): def test_unable_to_find_challenge_status(self, unused_mock_time):
@@ -353,11 +366,11 @@ class PollChallengesTest(unittest.TestCase):
challb_to_achall(acme_util.DNS01_P, "key", self.doms[0])) challb_to_achall(acme_util.DNS01_P, "key", self.doms[0]))
self.assertRaises( self.assertRaises(
errors.AuthorizationError, self.handler._poll_challenges, errors.AuthorizationError, self.handler._poll_challenges,
self.chall_update, False) self.aauthzrs, self.chall_update, False)
def test_verify_authzr_failure(self): def test_verify_authzr_failure(self):
self.assertRaises( self.assertRaises(errors.AuthorizationError,
errors.AuthorizationError, self.handler.verify_authzr_complete) self.handler.verify_authzr_complete, self.aauthzrs)
def _mock_poll_solve_one_valid(self, authzr): def _mock_poll_solve_one_valid(self, authzr):
# Pending here because my dummy script won't change the full status. # Pending here because my dummy script won't change the full status.

View File

@@ -380,10 +380,12 @@ class CertAndChainFromFullchainTest(unittest.TestCase):
cert_pem = CERT.decode() cert_pem = CERT.decode()
chain_pem = cert_pem + SS_CERT.decode() chain_pem = cert_pem + SS_CERT.decode()
fullchain_pem = cert_pem + chain_pem fullchain_pem = cert_pem + chain_pem
spacey_fullchain_pem = cert_pem + u'\n' + chain_pem
from certbot.crypto_util import cert_and_chain_from_fullchain from certbot.crypto_util import cert_and_chain_from_fullchain
cert_out, chain_out = cert_and_chain_from_fullchain(fullchain_pem) for fullchain in (fullchain_pem, spacey_fullchain_pem):
self.assertEqual(cert_out, cert_pem) cert_out, chain_out = cert_and_chain_from_fullchain(fullchain)
self.assertEqual(chain_out, chain_pem) self.assertEqual(cert_out, cert_pem)
self.assertEqual(chain_out, chain_pem)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -726,7 +726,7 @@ class RenewableCertTests(BaseRenewableCertTest):
self.test_rc.configuration["renewalparams"] = {} self.test_rc.configuration["renewalparams"] = {}
rp = self.test_rc.configuration["renewalparams"] rp = self.test_rc.configuration["renewalparams"]
self.assertEqual(self.test_rc.is_test_cert, False) self.assertEqual(self.test_rc.is_test_cert, False)
rp["server"] = "https://acme-staging.api.letsencrypt.org/directory" rp["server"] = "https://acme-staging-v02.api.letsencrypt.org/directory"
self.assertEqual(self.test_rc.is_test_cert, True) self.assertEqual(self.test_rc.is_test_cert, True)
rp["server"] = "https://staging.someotherca.com/directory" rp["server"] = "https://staging.someotherca.com/directory"
self.assertEqual(self.test_rc.is_test_cert, True) self.assertEqual(self.test_rc.is_test_cert, True)

View File

@@ -61,7 +61,7 @@ chain_path = /home/ubuntu/letsencrypt/chain.pem
break_my_certs = False break_my_certs = False
standalone = True standalone = True
manual = False manual = False
server = https://acme-staging.api.letsencrypt.org/directory server = https://acme-staging-v02.api.letsencrypt.org/directory
standalone_supported_challenges = "tls-sni-01,http-01" standalone_supported_challenges = "tls-sni-01,http-01"
webroot = False webroot = False
os_packages_only = False os_packages_only = False

View File

@@ -107,9 +107,9 @@ optional arguments:
case, and to know when to deprecate support for past case, and to know when to deprecate support for past
Python versions and flags. If you wish to hide this Python versions and flags. If you wish to hide this
information from the Let's Encrypt server, set this to information from the Let's Encrypt server, set this to
"". (default: CertbotACMEClient/0.22.0 (certbot; "". (default: CertbotACMEClient/0.22.2 (certbot;
darwin 10.13.3) Authenticator/XXX Installer/YYY darwin 10.13.3) Authenticator/XXX Installer/YYY
(SUBCOMMAND; flags: FLAGS) Py/3.6.4). The flags (SUBCOMMAND; flags: FLAGS) Py/2.7.14). The flags
encoded in the user agent are: --duplicate, --force- encoded in the user agent are: --duplicate, --force-
renew, --allow-subset-of-names, -n, and whether any renew, --allow-subset-of-names, -n, and whether any
hooks are set. hooks are set.
@@ -199,8 +199,8 @@ testing:
--test-cert, --staging --test-cert, --staging
Use the staging server to obtain or revoke test Use the staging server to obtain or revoke test
(invalid) certificates; equivalent to --server (invalid) certificates; equivalent to --server https
https://acme-staging.api.letsencrypt.org/directory ://acme-staging-v02.api.letsencrypt.org/directory
(default: False) (default: False)
--debug Show tracebacks in case of errors, and allow certbot- --debug Show tracebacks in case of errors, and allow certbot-
auto execution on experimental platforms (default: auto execution on experimental platforms (default:
@@ -308,8 +308,8 @@ renew:
of renewed certificate domains (for example, of renewed certificate domains (for example,
"example.com www.example.com" (default: None) "example.com www.example.com" (default: None)
--disable-hook-validation --disable-hook-validation
Ordinarily the commands specified for --pre- Ordinarily the commands specified for --pre-hook
hook/--post-hook/--deploy-hook will be checked for /--post-hook/--deploy-hook will be checked for
validity, to see if the programs being run are in the validity, to see if the programs being run are in the
$PATH, so that mistakes can be caught early, even when $PATH, so that mistakes can be caught early, even when
the hooks aren't being run just yet. The validation is the hooks aren't being run just yet. The validation is

View File

@@ -43,7 +43,7 @@ each shell where you're working:
.. code-block:: shell .. code-block:: shell
source ./venv/bin/activate source ./venv/bin/activate
export SERVER=https://acme-staging.api.letsencrypt.org/directory export SERVER=https://acme-staging-v02.api.letsencrypt.org/directory
source tests/integration/_common.sh source tests/integration/_common.sh
After that, your shell will be using the virtual environment, your copy of After that, your shell will be using the virtual environment, your copy of
@@ -443,10 +443,10 @@ For squeeze you will need to:
FreeBSD FreeBSD
------- -------
Packages can be installed on FreeBSD using ``pkg``, Packages can be installed on FreeBSD using ``pkg``,
or any other port-management tool (``portupgrade``, ``portmanager``, etc.) or any other port-management tool (``portupgrade``, ``portmanager``, etc.)
from the pre-built package or can be built and installed from ports. from the pre-built package or can be built and installed from ports.
Either way will ensure proper installation of all the dependencies required Either way will ensure proper installation of all the dependencies required
for the package. for the package.
FreeBSD by default uses ``tcsh``. In order to activate virtualenv (see FreeBSD by default uses ``tcsh``. In order to activate virtualenv (see

View File

@@ -1,5 +1,5 @@
# Always use the staging/testing server - avoids rate limiting # Always use the staging/testing server - avoids rate limiting
server = https://acme-staging.api.letsencrypt.org/directory server = https://acme-staging-v02.api.letsencrypt.org/directory
# This is an example configuration file for developers # This is an example configuration file for developers
config-dir = /tmp/le/conf config-dir = /tmp/le/conf

View File

@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
fi fi
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
LE_AUTO_VERSION="0.22.0" LE_AUTO_VERSION="0.22.2"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -1199,18 +1199,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==0.22.0 \ certbot==0.22.2 \
--hash=sha256:ebfeaf9737dc440a9f263099487523ab4c8d8da9def31a71327439d9186e00fa \ --hash=sha256:c8c63bdf0fed6258bdbc892454314ec37bcd1c35a7f62524a083d93ccdfc420d \
--hash=sha256:ee307dd8f194bd710a3326aa4bacf95d358877498c0b9aa187eff0dc211dcbb3 --hash=sha256:e6e3639293e78397f31f7d99e3c63aff82d91e2b0d50d146ee3c77f830464bef
acme==0.22.0 \ acme==0.22.2 \
--hash=sha256:37e6d8e4eb7dd18edac96de209f451300e04074f14be7fce713db6931a0e4a20 \ --hash=sha256:59a55244612ee305d2caa6bb4cddd400fb60ec841bf011ed29a2899832a682c2 \
--hash=sha256:4a2cd52db32e914b68d8446c8e788f507c20edebbd1c36d4f3eda7b47c555fe8 --hash=sha256:0ecd0ea369f53d5bc744d6e72717f9af2e1ceb558d109dbd433148851027adb4
certbot-apache==0.22.0 \ certbot-apache==0.22.2 \
--hash=sha256:e91f6ec8203b636fa44f01017646fca68406224ee327fd56017103b78bc65539 \ --hash=sha256:b5340d4b9190358fde8eb6a5be0def37e32014b5142ee79ef5d2319ccbbde754 \
--hash=sha256:8fbab1a358ec131996d1c00f7d0ed18ee3624f8469cab3962dfd8ba40ca3e7cd --hash=sha256:3cd26912bb5732d917ddf7aad2fe870090d4ece9a408b2c2de8e9723ec99c759
certbot-nginx==0.22.0 \ certbot-nginx==0.22.2 \
--hash=sha256:d67210cf73cf44e8aeff04f6f228d8bde74444703ce3ccd929a450685b58c30b \ --hash=sha256:91feef0d879496835d355e82841f92e5ecb5abbf6f23ea0ee5bbb8f5a92b278a \
--hash=sha256:b2b26bf9112062b02518407704cad09f7136322163d529a2dde3b6e1578ecb8c --hash=sha256:b10bf04c1a20cf878d5e0d1877deb0e0780bc31b0ffda08ce7199bbc39d0753b
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------

View File

@@ -1,11 +1,11 @@
-----BEGIN PGP SIGNATURE----- -----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAlqgLj0ACgkQTRfJlc2X iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAlqwWJwACgkQTRfJlc2X
dfIAtAf/YwRvn17fdJOSXr08LP/qDPefz8AFefUJdKoOa+ikWIOWZTh5hskGtXO0 dfIzmwgAghmc3W63/qpCtJdezYeGLJdu03LvKoWYc7dTNYj2+0P5qmAAgCvKNY34
e894FNcZqbg6NQu/KUBQAz/nBDRz8IOaWN30MFq5B4V2A3In5rn59PNaCDSKSBbC qYzXA1jfCOgILSzRNE5WY+rbgjcmxxsxH+luYm6Ik0909MaMQ0D3h+5cRFs/tTtd
auyU24gYkBxbDPjMpuode7yCsvHxTsB5sLNmHByMyMTBmQaiT5odAjr7PztTP52S 5cX0gxL3RQQTBwpnwbAZibe7lhjs9pXBiob2ek67hVr+xEwem69BQMlOhtYJbOs1
s/29/WOCJAYzBBFFJ9d0QD0drVSIcDM5JCuUK2vXgPuPVD4f3GankgP1nnAJ5ADV osccoKc4NqaKbrfgOjjtMaL8YoRPO9vJHS9rRr6hxRZlPsmvusAHAiCbIrbX4XKE
acJp3cQ3OsofeE/HTw0qq7TiL0dGYf8yhRFovFve7tX+oujMIRALQJW6K9Qi7KTv CgxJFnuHK+amtfRoZg/xCqIK3Z94yZXPezywsri/YvDteOIs+DZ2qG/StfUrNYFX
777V6xHuphrA+1qIrg2H8czOBDclFQ== WYfFFFyld0xwQtb4Oi9u4mx4sPg7lw==
=Ngvl =jZDE
-----END PGP SIGNATURE----- -----END PGP SIGNATURE-----

View File

@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
fi fi
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
LE_AUTO_VERSION="0.22.0" LE_AUTO_VERSION="0.22.2"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -1199,18 +1199,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==0.22.0 \ certbot==0.22.2 \
--hash=sha256:ebfeaf9737dc440a9f263099487523ab4c8d8da9def31a71327439d9186e00fa \ --hash=sha256:c8c63bdf0fed6258bdbc892454314ec37bcd1c35a7f62524a083d93ccdfc420d \
--hash=sha256:ee307dd8f194bd710a3326aa4bacf95d358877498c0b9aa187eff0dc211dcbb3 --hash=sha256:e6e3639293e78397f31f7d99e3c63aff82d91e2b0d50d146ee3c77f830464bef
acme==0.22.0 \ acme==0.22.2 \
--hash=sha256:37e6d8e4eb7dd18edac96de209f451300e04074f14be7fce713db6931a0e4a20 \ --hash=sha256:59a55244612ee305d2caa6bb4cddd400fb60ec841bf011ed29a2899832a682c2 \
--hash=sha256:4a2cd52db32e914b68d8446c8e788f507c20edebbd1c36d4f3eda7b47c555fe8 --hash=sha256:0ecd0ea369f53d5bc744d6e72717f9af2e1ceb558d109dbd433148851027adb4
certbot-apache==0.22.0 \ certbot-apache==0.22.2 \
--hash=sha256:e91f6ec8203b636fa44f01017646fca68406224ee327fd56017103b78bc65539 \ --hash=sha256:b5340d4b9190358fde8eb6a5be0def37e32014b5142ee79ef5d2319ccbbde754 \
--hash=sha256:8fbab1a358ec131996d1c00f7d0ed18ee3624f8469cab3962dfd8ba40ca3e7cd --hash=sha256:3cd26912bb5732d917ddf7aad2fe870090d4ece9a408b2c2de8e9723ec99c759
certbot-nginx==0.22.0 \ certbot-nginx==0.22.2 \
--hash=sha256:d67210cf73cf44e8aeff04f6f228d8bde74444703ce3ccd929a450685b58c30b \ --hash=sha256:91feef0d879496835d355e82841f92e5ecb5abbf6f23ea0ee5bbb8f5a92b278a \
--hash=sha256:b2b26bf9112062b02518407704cad09f7136322163d529a2dde3b6e1578ecb8c --hash=sha256:b10bf04c1a20cf878d5e0d1877deb0e0780bc31b0ffda08ce7199bbc39d0753b
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------

View File

@@ -1 +1,3 @@
_$<24><>{<7B><><EFBFBD><EFBFBD>z<EFBFBD><7A><EFBFBD><EFBFBD><EFBFBD>Q)6("Rmn<6D>f$B|cs<63>;D<><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V,<2C>?<3F><>8樝j<><1E><><EFBFBD><EFBFBD><EFBFBD>|<7C><>G<EFBFBD><47><EFBFBD>f<EFBFBD>b"ߘ<>,<2C><>*<02><><EFBFBD>%<25><><16>]<5D>6#<23><><08>n<EFBFBD>|\`+.X<>,<2C>)#<23><><EFBFBD>QB<51>j@<40>0G<>X<EFBFBD>z5<7A> <14>42+_H<48>`?<EFBFBD>.<2E><><1F><>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>0<07><1D>/<2F><><<3C>t<EFBFBD>p<>N)<29><><EFBFBD>IC<49><43>Q<EFBFBD><51>&i<>8Y<38><59>ܝ<EFBFBD>&<26>R<EFBFBD>6<EFBFBD>^<5E>]<5D>l<EFBFBD><4A><DCA1>#<EFBFBD><EFBFBD>P<EFBFBD><EFBFBD>*<2A><><EFBFBD>n<0E><>mN6B3<42>o<EFBFBD>c{^r%(<28><>dv<64><76><EFBFBD><)<29><EFBFBD> <EFBFBD>c<EFBFBD><EFBFBD>NdC<EFBFBD>f<EFBFBD><EFBFBD><EFBFBD>*2<>;<3B>=uTM,<2C><>]K<>= jy!<EFBFBD>5M<1E>=2D<32>}/ڰ3<DAB0><EFBFBD>.><EFBFBD><EFBFBD><EFBFBD><1A><>:K<><4B>"<16>ta<74><61><EFBFBD>,<2C>Ge<47><65>C<EFBFBD><43><EFBFBD><EFBFBD>r<EFBFBD>F<06><EFBFBD><EFBFBD>q<EFBFBD><EFBFBD><EFBFBD>8d³ m<EFBFBD>q<EFBFBD>S<EFBFBD>
oGQ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Y
<EFBFBD><EFBFBD><EFBFBD>4&F<><46><EFBFBD>8<EFBFBD>W<><57><EFBFBD>xUm<55>|<7C><><EFBFBD><EFBFBD>0wٔ~<7E><1B><>g<16>R<>T)<29><>E<EFBFBD>=<3D> <EFBFBD>ڇ7<EFBFBD>(<28>տ,<2C>(\e<>f<EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD>*<2A><17>!

View File

@@ -1,12 +1,12 @@
certbot==0.22.0 \ certbot==0.22.2 \
--hash=sha256:ebfeaf9737dc440a9f263099487523ab4c8d8da9def31a71327439d9186e00fa \ --hash=sha256:c8c63bdf0fed6258bdbc892454314ec37bcd1c35a7f62524a083d93ccdfc420d \
--hash=sha256:ee307dd8f194bd710a3326aa4bacf95d358877498c0b9aa187eff0dc211dcbb3 --hash=sha256:e6e3639293e78397f31f7d99e3c63aff82d91e2b0d50d146ee3c77f830464bef
acme==0.22.0 \ acme==0.22.2 \
--hash=sha256:37e6d8e4eb7dd18edac96de209f451300e04074f14be7fce713db6931a0e4a20 \ --hash=sha256:59a55244612ee305d2caa6bb4cddd400fb60ec841bf011ed29a2899832a682c2 \
--hash=sha256:4a2cd52db32e914b68d8446c8e788f507c20edebbd1c36d4f3eda7b47c555fe8 --hash=sha256:0ecd0ea369f53d5bc744d6e72717f9af2e1ceb558d109dbd433148851027adb4
certbot-apache==0.22.0 \ certbot-apache==0.22.2 \
--hash=sha256:e91f6ec8203b636fa44f01017646fca68406224ee327fd56017103b78bc65539 \ --hash=sha256:b5340d4b9190358fde8eb6a5be0def37e32014b5142ee79ef5d2319ccbbde754 \
--hash=sha256:8fbab1a358ec131996d1c00f7d0ed18ee3624f8469cab3962dfd8ba40ca3e7cd --hash=sha256:3cd26912bb5732d917ddf7aad2fe870090d4ece9a408b2c2de8e9723ec99c759
certbot-nginx==0.22.0 \ certbot-nginx==0.22.2 \
--hash=sha256:d67210cf73cf44e8aeff04f6f228d8bde74444703ce3ccd929a450685b58c30b \ --hash=sha256:91feef0d879496835d355e82841f92e5ecb5abbf6f23ea0ee5bbb8f5a92b278a \
--hash=sha256:b2b26bf9112062b02518407704cad09f7136322163d529a2dde3b6e1578ecb8c --hash=sha256:b10bf04c1a20cf878d5e0d1877deb0e0780bc31b0ffda08ce7199bbc39d0753b

View File

@@ -327,6 +327,19 @@ CheckDirHooks 1
common renew --cert-name le2.wtf common renew --cert-name le2.wtf
CheckDirHooks 1 CheckDirHooks 1
# manual-dns-auth.sh will skip completing the challenge for domains that begin
# with fail.
common -a manual -d dns1.le.wtf,fail.dns1.le.wtf \
--allow-subset-of-names \
--preferred-challenges dns,tls-sni \
--manual-auth-hook ./tests/manual-dns-auth.sh \
--manual-cleanup-hook ./tests/manual-dns-cleanup.sh
if common certificates | grep "fail\.dns1\.le\.wtf"; then
echo "certificate should not have been issued for domain!" >&2
exit 1
fi
# ECDSA # ECDSA
openssl ecparam -genkey -name secp384r1 -out "${root}/privkey-p384.pem" openssl ecparam -genkey -name secp384r1 -out "${root}/privkey-p384.pem"
SAN="DNS:ecdsa.le.wtf" openssl req -new -sha256 \ SAN="DNS:ecdsa.le.wtf" openssl req -new -sha256 \

View File

@@ -1,4 +1,8 @@
#!/bin/sh #!/bin/bash
curl -X POST 'http://localhost:8055/set-txt' -d \
"{\"host\": \"_acme-challenge.$CERTBOT_DOMAIN.\", \ # If domain begins with fail, fail the challenge by not completing it.
\"value\": \"$CERTBOT_VALIDATION\"}" if [[ "$CERTBOT_DOMAIN" != fail* ]]; then
curl -X POST 'http://localhost:8055/set-txt' -d \
"{\"host\": \"_acme-challenge.$CERTBOT_DOMAIN.\", \
\"value\": \"$CERTBOT_VALIDATION\"}"
fi

View File

@@ -1,3 +1,8 @@
#!/bin/sh #!/bin/bash
curl -X POST 'http://localhost:8055/clear-txt' -d \
"{\"host\": \"_acme-challenge.$CERTBOT_DOMAIN.\"}" # If domain begins with fail, we didn't complete the challenge so there is
# nothing to clean up.
if [[ "$CERTBOT_DOMAIN" != fail* ]]; then
curl -X POST 'http://localhost:8055/clear-txt' -d \
"{\"host\": \"_acme-challenge.$CERTBOT_DOMAIN.\"}"
fi