Compare commits
7 Commits
update-ser
...
v0.22.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea445ed11e | ||
|
|
8d061e5dfc | ||
|
|
0131c649d0 | ||
|
|
eda458b2da | ||
|
|
cedbf8906c | ||
|
|
d0b336085c | ||
|
|
c9f278e6c8 |
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
26
certbot-auto
26
certbot-auto
@@ -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
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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__':
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
2
certbot/tests/testdata/sample-renewal.conf
vendored
2
certbot/tests/testdata/sample-renewal.conf
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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-----
|
||||||
|
|||||||
@@ -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
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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>Jܡ<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>!
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user