From 6a8113fa87ff8f55aa16395b9208ac0afe820a34 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 16 Feb 2017 10:24:48 -0800 Subject: [PATCH 01/27] Remove reference to #certbot on OFTC The #letsencrypt channel on Freenode is much more active, and is the defacto place for questions about Certbot. Users posting questions on #certbot on OFTC are not getting prompt answers. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f986703ac..ab12562df 100644 --- a/README.rst +++ b/README.rst @@ -88,7 +88,7 @@ Main Website: https://certbot.eff.org Let's Encrypt Website: https://letsencrypt.org -IRC Channel: #letsencrypt on `Freenode`_ or #certbot on `OFTC`_ +IRC Channel: #letsencrypt on `Freenode`_ Community: https://community.letsencrypt.org From e5909d379c5e0144481c7c848ccf1c13b71c2a73 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Mon, 27 Feb 2017 13:35:29 -0800 Subject: [PATCH 02/27] Don't crash on listen unix: (#4259) Fixes #4225. * don't crash on listen unix: * correctly merge #4221 --- certbot-nginx/certbot_nginx/parser.py | 7 ++++--- certbot-nginx/certbot_nginx/tests/parser_test.py | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/certbot-nginx/certbot_nginx/parser.py b/certbot-nginx/certbot_nginx/parser.py index c586aa459..eddc7b9b0 100644 --- a/certbot-nginx/certbot_nginx/parser.py +++ b/certbot-nginx/certbot_nginx/parser.py @@ -586,9 +586,10 @@ def _parse_server_raw(server): continue if directive[0] == 'listen': addr = obj.Addr.fromstring(directive[1]) - parsed_server['addrs'].add(addr) - if addr.ssl: - parsed_server['ssl'] = True + if addr: + parsed_server['addrs'].add(addr) + if addr.ssl: + parsed_server['ssl'] = True elif directive[0] == 'server_name': parsed_server['names'].update( _get_servernames(directive[1])) diff --git a/certbot-nginx/certbot_nginx/tests/parser_test.py b/certbot-nginx/certbot_nginx/tests/parser_test.py index 921cc3c5a..6a3f2f1de 100644 --- a/certbot-nginx/certbot_nginx/tests/parser_test.py +++ b/certbot-nginx/certbot_nginx/tests/parser_test.py @@ -323,6 +323,12 @@ class NginxParserTest(util.NginxTest): ]) self.assertTrue(server['ssl']) + def test_parse_server_raw_unix(self): + server = parser._parse_server_raw([ #pylint: disable=protected-access + ['listen', 'unix:/var/run/nginx.sock'] + ]) + self.assertEqual(len(server['addrs']), 0) + def test_parse_server_global_ssl_applied(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) server = nparser.parse_server([ From 80055ec770ee0e896a52b19c6420c4f2cf6a59fb Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 27 Feb 2017 15:15:19 -0800 Subject: [PATCH 03/27] Cleanup issue template (#4256) --- ISSUE_TEMPLATE.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index e4e56f93d..e648a21b4 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,16 +1,14 @@ ## My operating system is (include version): -## My web server is (include version): +## I installed Certbot with (certbot-auto, OS package manager, pip, etc): -## How did you install Certbot: +## I ran this command and it produced this output: -## What command did you run and what output did it produce? - - -## Can you provide a Certbot error log showing the issue? -###### It is stored by default in `/var/log/letsencrypt` - feel free to redact domain names, e-mail and IP addresses as you see fit +## Certbot's behavior differed from what I expected because: +## Here is a Certbot log showing the issue (if available): +###### Logs are stored in `/var/log/letsencrypt` by default. Feel free to redact domains, e-mail and IP addresses as you see fit. From 402ad8b35311460babb7195095b10d02a0b14e48 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 27 Feb 2017 17:17:08 -0800 Subject: [PATCH 04/27] bump requests requirement to >=2.10 (#4248) --- acme/setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme/setup.py b/acme/setup.py index d1e91e5ec..9b43278af 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -15,7 +15,11 @@ install_requires = [ 'PyOpenSSL>=0.13', 'pyrfc3339', 'pytz', - 'requests[security]>=2.4.1', # security extras added in 2.4.1 + # requests>=2.10 is required to fix + # https://github.com/shazow/urllib3/issues/556. This requirement can be + # relaxed to 'requests[security]>=2.4.1', however, less useful errors + # will be raised for some network/SSL errors. + 'requests[security]>=2.10', # For pkg_resources. >=1.0 so pip resolves it to a version cryptography # will tolerate; see #2599: 'setuptools>=1.0', From 44a6ec29c58e6bcceb05543ea8c5503fc8c5b772 Mon Sep 17 00:00:00 2001 From: Damien Tournoud Date: Tue, 28 Feb 2017 03:13:06 +0100 Subject: [PATCH 05/27] Fix direct usages of the root logger (#4236) Some code uses `logging.debug` and `logging.info` instead of the file-specific logger in `logger.debug` and `logger.info`. --- acme/acme/challenges.py | 4 ++-- acme/acme/client.py | 6 +++--- acme/acme/client_test.py | 2 +- certbot-nginx/certbot_nginx/configurator.py | 2 +- certbot/ocsp.py | 6 +++--- certbot/tests/ocsp_test.py | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/acme/acme/challenges.py b/acme/acme/challenges.py index 83b9b9edd..3b1e90166 100644 --- a/acme/acme/challenges.py +++ b/acme/acme/challenges.py @@ -425,7 +425,7 @@ class TLSSNI01Response(KeyAuthorizationChallengeResponse): # TODO: domain is not necessary if host is provided if "host" not in kwargs: host = socket.gethostbyname(domain) - logging.debug('%s resolved to %s', domain, host) + logger.debug('%s resolved to %s', domain, host) kwargs["host"] = host kwargs.setdefault("port", self.PORT) @@ -445,7 +445,7 @@ class TLSSNI01Response(KeyAuthorizationChallengeResponse): """ # pylint: disable=protected-access sans = crypto_util._pyopenssl_cert_or_req_san(cert) - logging.debug('Certificate %s. SANs: %s', cert.digest('sha1'), sans) + logger.debug('Certificate %s. SANs: %s', cert.digest('sha1'), sans) return self.z_domain.decode() in sans def simple_verify(self, chall, domain, account_public_key, diff --git a/acme/acme/client.py b/acme/acme/client.py index 168574d58..23eabe4b9 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -600,10 +600,10 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes """ if method == "POST": - logging.debug('Sending POST request to %s:\n%s', + logger.debug('Sending POST request to %s:\n%s', url, kwargs['data']) else: - logging.debug('Sending %s request to %s.', method, url) + logger.debug('Sending %s request to %s.', method, url) kwargs['verify'] = self.verify_ssl kwargs.setdefault('headers', {}) kwargs['headers'].setdefault('User-Agent', self.user_agent) @@ -651,7 +651,7 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes def _get_nonce(self, url): if not self._nonces: - logging.debug('Requesting fresh nonce') + logger.debug('Requesting fresh nonce') self._add_nonce(self.head(url)) return self._nonces.pop() diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index b7bd0740c..3621a0824 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -544,7 +544,7 @@ class ClientNetworkTest(unittest.TestCase): # pylint: disable=protected-access self.net._send_request('HEAD', 'http://example.com/', 'foo', timeout=mock.ANY, bar='baz') - mock_logger.debug.assert_called_once_with( + mock_logger.debug.assert_called_with( 'Received response:\nHTTP %d\n%s\n\n%s', 200, 'Content-Type: application/pkix-cert', b'aGk=') diff --git a/certbot-nginx/certbot_nginx/configurator.py b/certbot-nginx/certbot_nginx/configurator.py index 6d51ca641..7348def2f 100644 --- a/certbot-nginx/certbot_nginx/configurator.py +++ b/certbot-nginx/certbot_nginx/configurator.py @@ -630,7 +630,7 @@ class NginxConfigurator(common.Plugin): stderr=subprocess.PIPE) text = proc.communicate()[1] # nginx prints output to stderr except (OSError, ValueError) as error: - logging.debug(error, exc_info=True) + logger.debug(error, exc_info=True) raise errors.PluginError( "Unable to run %s -V" % self.conf('ctl')) diff --git a/certbot/ocsp.py b/certbot/ocsp.py index 8921dbb88..d34110f88 100644 --- a/certbot/ocsp.py +++ b/certbot/ocsp.py @@ -16,7 +16,7 @@ class RevocationChecker(object): self.broken = False if not util.exe_exists("openssl"): - logging.info("openssl not installed, can't check revocation") + logger.info("openssl not installed, can't check revocation") self.broken = True return @@ -61,7 +61,7 @@ class RevocationChecker(object): logger.debug("Querying OCSP for %s", cert_path) logger.debug(" ".join(cmd)) try: - output, err = util.run_script(cmd, log=logging.debug) + output, err = util.run_script(cmd, log=logger.debug) except errors.SubprocessError: logger.info("OCSP check failed for %s (are we offline?)", cert_path) return False @@ -80,7 +80,7 @@ class RevocationChecker(object): try: url, _err = util.run_script( ["openssl", "x509", "-in", cert_path, "-noout", "-ocsp_uri"], - log=logging.debug) + log=logger.debug) except errors.SubprocessError: logger.info("Cannot extract OCSP URI from %s", cert_path) return None, None diff --git a/certbot/tests/ocsp_test.py b/certbot/tests/ocsp_test.py index 549e83ca8..91dd6f8d6 100644 --- a/certbot/tests/ocsp_test.py +++ b/certbot/tests/ocsp_test.py @@ -28,7 +28,7 @@ class OCSPTest(unittest.TestCase): def tearDown(self): pass - @mock.patch('certbot.ocsp.logging.info') + @mock.patch('certbot.ocsp.logger.info') @mock.patch('certbot.ocsp.Popen') @mock.patch('certbot.util.exe_exists') def test_init(self, mock_exists, mock_popen, mock_log): From 0d8a4b4ebdf12d6664550cd52a40c9f70e864c03 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 28 Feb 2017 15:17:07 -0800 Subject: [PATCH 06/27] Make mod-check more flexible (#4268) * fixes #4166 * Run mod-check from anywhere * pass TRAVIS_BRANCH through in tox --- tests/modification-check.sh | 61 ++++++++++++++++--------------------- tox.ini | 4 ++- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/tests/modification-check.sh b/tests/modification-check.sh index 5168f5ab5..6f412ba47 100755 --- a/tests/modification-check.sh +++ b/tests/modification-check.sh @@ -1,46 +1,39 @@ #!/bin/bash temp_dir=`mktemp -d` +trap "rm -rf $temp_dir" EXIT -# Script should be run from Certbot's root directory - -SCRIPT_PATH=`dirname $0` -SCRIPT_PATH=`readlink -f $SCRIPT_PATH` +# cd to repo root +cd $(dirname $(dirname $(readlink -f $0))) FLAG=false -# Compare root letsencrypt-auto and certbot-auto with published versions - -cp letsencrypt-auto ${temp_dir}/letsencrypt-to-be-checked -cp certbot-auto ${temp_dir}/certbot-to-be-checked - -cp letsencrypt-auto-source/pieces/fetch.py ${temp_dir}/fetch.py -cd ${temp_dir} - -LATEST_VERSION=`python fetch.py --latest-version` -python fetch.py --le-auto-script v${LATEST_VERSION} - -cmp -s letsencrypt-auto letsencrypt-to-be-checked - -if [ $? != 0 ]; then - echo "Root letsencrypt-auto has changed." - FLAG=true +if ! cmp -s certbot-auto letsencrypt-auto; then + echo "Root certbot-auto and letsencrypt-auto differ." + FLAG=true else - echo "Root letsencrypt-auto is unchanged." + cp certbot-auto "$temp_dir/local-auto" + cp letsencrypt-auto-source/pieces/fetch.py "$temp_dir/fetch.py" + cd $temp_dir + + # Compare file against current version in the target branch + BRANCH=${TRAVIS_BRANCH:-master} + URL="https://raw.githubusercontent.com/certbot/certbot/$BRANCH/certbot-auto" + curl -sS $URL > certbot-auto + if cmp -s certbot-auto local-auto; then + echo "Root *-auto were unchanged." + else + # Compare file against the latest released version + python fetch.py --le-auto-script "v$(python fetch.py --latest-version)" + if cmp -s letsencrypt-auto local-auto; then + echo "Root *-auto were updated to the latest version." + else + echo "Root *-auto have unexpected changes." + FLAG=true + fi + fi + cd ~- fi -cmp -s letsencrypt-auto certbot-to-be-checked - -if [ $? != 0 ]; then - echo "Root certbot-auto has changed." - FLAG=true -else - echo "Root certbot-auto is unchanged." -fi - -# Cleanup -rm ${temp_dir}/* -cd ${SCRIPT_PATH}/../ - # Compare letsencrypt-auto-source/letsencrypt-auto with output of build.py cp letsencrypt-auto-source/letsencrypt-auto ${temp_dir}/original-lea diff --git a/tox.ini b/tox.ini index 232010d40..ea1423415 100644 --- a/tox.ini +++ b/tox.ini @@ -151,7 +151,9 @@ commands = docker run --rm -t -i lea whitelist_externals = docker -passenv = DOCKER_* +passenv = + DOCKER_* + TRAVIS_BRANCH [testenv:le_auto_wheezy] # At the moment, this tests under Python 2.7 only, as only that version is From 11ec1eb91148f6420e10d2296b8a507c90337792 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 2 Mar 2017 10:31:15 -0800 Subject: [PATCH 07/27] Revert "Remove Link rel=next for authzs and new-certs." (#4277) --- acme/acme/client.py | 40 ++++++++++++++++++++++-------- acme/acme/client_test.py | 40 ++++++++++++++++++++++++------ acme/acme/jose/json_util.py | 2 +- acme/acme/messages.py | 6 ++++- acme/acme/messages_test.py | 6 ++++- acme/examples/example_client.py | 3 ++- certbot/auth_handler.py | 3 ++- certbot/tests/account_test.py | 2 +- certbot/tests/acme_util.py | 1 + certbot/tests/auth_handler_test.py | 3 ++- certbot/tests/display/ops_test.py | 4 +-- 11 files changed, 84 insertions(+), 26 deletions(-) diff --git a/acme/acme/client.py b/acme/acme/client.py index 23eabe4b9..ddcba7635 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -71,13 +71,20 @@ class Client(object): # pylint: disable=too-many-instance-attributes self.directory = directory @classmethod - def _regr_from_response(cls, response, uri=None, terms_of_service=None): + def _regr_from_response(cls, response, uri=None, new_authzr_uri=None, + terms_of_service=None): if 'terms-of-service' in response.links: terms_of_service = response.links['terms-of-service']['url'] + if 'next' in response.links: + new_authzr_uri = response.links['next']['url'] + + if new_authzr_uri is None: + raise errors.ClientError('"next" link missing') return messages.RegistrationResource( body=messages.Registration.from_json(response.json()), uri=response.headers.get('Location', uri), + new_authzr_uri=new_authzr_uri, terms_of_service=terms_of_service) def register(self, new_reg=None): @@ -110,7 +117,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes # (c.f. acme-spec #94) return self._regr_from_response( - response, uri=regr.uri, + response, uri=regr.uri, new_authzr_uri=regr.new_authzr_uri, terms_of_service=regr.terms_of_service) def update_registration(self, regr, update=None): @@ -167,30 +174,43 @@ class Client(object): # pylint: disable=too-many-instance-attributes return self.update_registration( regr.update(body=regr.body.update(agreement=regr.terms_of_service))) - def _authzr_from_response(self, response, identifier, uri=None): + def _authzr_from_response(self, response, identifier, + uri=None, new_cert_uri=None): + # pylint: disable=no-self-use + if new_cert_uri is None: + try: + new_cert_uri = response.links['next']['url'] + except KeyError: + raise errors.ClientError('"next" link missing') + authzr = messages.AuthorizationResource( body=messages.Authorization.from_json(response.json()), - uri=response.headers.get('Location', uri)) + uri=response.headers.get('Location', uri), + new_cert_uri=new_cert_uri) if authzr.body.identifier != identifier: raise errors.UnexpectedUpdate(authzr) return authzr - def request_challenges(self, identifier): + def request_challenges(self, identifier, new_authzr_uri=None): """Request challenges. :param .messages.Identifier identifier: Identifier to be challenged. + :param str new_authzr_uri: ``new-authorization`` URI. If omitted, + will default to value found in ``directory``. :returns: Authorization Resource. :rtype: `.AuthorizationResource` """ new_authz = messages.NewAuthorization(identifier=identifier) - response = self.net.post(self.directory.new_authz, new_authz) + response = self.net.post(self.directory.new_authz + if new_authzr_uri is None else new_authzr_uri, + new_authz) # TODO: handle errors assert response.status_code == http_client.CREATED return self._authzr_from_response(response, identifier) - def request_domain_challenges(self, domain): + def request_domain_challenges(self, domain, new_authzr_uri=None): """Request challenges for domain names. This is simply a convenience function that wraps around @@ -205,7 +225,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes """ return self.request_challenges(messages.Identifier( - typ=messages.IDENTIFIER_FQDN, value=domain)) + typ=messages.IDENTIFIER_FQDN, value=domain), new_authzr_uri) def answer_challenge(self, challb, response): """Answer challenge. @@ -280,7 +300,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes """ response = self.net.get(authzr.uri) updated_authzr = self._authzr_from_response( - response, authzr.body.identifier, authzr.uri) + response, authzr.body.identifier, authzr.uri, authzr.new_cert_uri) # TODO: check and raise UnexpectedUpdate return updated_authzr, response @@ -304,7 +324,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes content_type = DER_CONTENT_TYPE # TODO: add 'cert_type 'argument response = self.net.post( - self.directory.new_cert, + authzrs[0].new_cert_uri, # TODO: acme-spec #90 req, content_type=content_type, headers={'Accept': content_type}) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index 3621a0824..b3db21ac9 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -40,8 +40,6 @@ class ClientTest(unittest.TestCase): 'https://www.letsencrypt-demo.org/acme/revoke-cert', messages.NewAuthorization: 'https://www.letsencrypt-demo.org/acme/new-authz', - messages.CertificateRequest: - 'https://www.letsencrypt-demo.org/acme/new-cert', }) from acme.client import Client @@ -58,6 +56,7 @@ class ClientTest(unittest.TestCase): self.new_reg = messages.NewRegistration(**dict(reg)) self.regr = messages.RegistrationResource( body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1', + new_authzr_uri='https://www.letsencrypt-demo.org/acme/new-reg', terms_of_service='https://www.letsencrypt-demo.org/tos') # Authorization @@ -73,7 +72,8 @@ class ClientTest(unittest.TestCase): typ=messages.IDENTIFIER_FQDN, value='example.com'), challenges=(challb,), combinations=None) self.authzr = messages.AuthorizationResource( - body=self.authz, uri=authzr_uri) + body=self.authz, uri=authzr_uri, + new_cert_uri='https://www.letsencrypt-demo.org/acme/new-cert') # Request issuance self.certr = messages.CertificateResource( @@ -98,12 +98,18 @@ class ClientTest(unittest.TestCase): self.response.json.return_value = self.regr.body.to_json() self.response.headers['Location'] = self.regr.uri self.response.links.update({ + 'next': {'url': self.regr.new_authzr_uri}, 'terms-of-service': {'url': self.regr.terms_of_service}, }) self.assertEqual(self.regr, self.client.register(self.new_reg)) # TODO: test POST call arguments + def test_register_missing_next(self): + self.response.status_code = http_client.CREATED + self.assertRaises( + errors.ClientError, self.client.register, self.new_reg) + def test_update_registration(self): # "Instance of 'Field' has no to_json/update member" bug: # pylint: disable=no-member @@ -136,6 +142,13 @@ class ClientTest(unittest.TestCase): self.response.json.return_value = self.regr.body.to_json() self.assertEqual(self.regr, self.client.query_registration(self.regr)) + def test_query_registration_updates_new_authzr_uri(self): + self.response.json.return_value = self.regr.body.to_json() + self.response.links = {'next': {'url': 'UPDATED'}} + self.assertEqual( + 'UPDATED', + self.client.query_registration(self.regr).new_authzr_uri) + def test_agree_to_tos(self): self.client.update_registration = mock.Mock() self.client.agree_to_tos(self.regr) @@ -146,6 +159,9 @@ class ClientTest(unittest.TestCase): self.response.status_code = http_client.CREATED self.response.headers['Location'] = self.authzr.uri self.response.json.return_value = self.authz.to_json() + self.response.links = { + 'next': {'url': self.authzr.new_cert_uri}, + } def test_request_challenges(self): self._prepare_response_for_request_challenges() @@ -156,9 +172,8 @@ class ClientTest(unittest.TestCase): def test_request_challenges_custom_uri(self): self._prepare_response_for_request_challenges() - self.client.request_challenges(self.identifier) - self.net.post.assert_called_once_with( - 'https://www.letsencrypt-demo.org/acme/new-authz', mock.ANY) + self.client.request_challenges(self.identifier, 'URI') + self.net.post.assert_called_once_with('URI', mock.ANY) def test_request_challenges_unexpected_update(self): self._prepare_response_for_request_challenges() @@ -166,7 +181,12 @@ class ClientTest(unittest.TestCase): identifier=self.identifier.update(value='foo')).to_json() self.assertRaises( errors.UnexpectedUpdate, self.client.request_challenges, - self.identifier) + self.identifier, self.authzr.uri) + + def test_request_challenges_missing_next(self): + self.response.status_code = http_client.CREATED + self.assertRaises(errors.ClientError, self.client.request_challenges, + self.identifier) def test_request_domain_challenges(self): self.client.request_challenges = mock.MagicMock() @@ -174,6 +194,12 @@ class ClientTest(unittest.TestCase): self.client.request_challenges(self.identifier), self.client.request_domain_challenges('example.com')) + def test_request_domain_challenges_custom_uri(self): + self.client.request_challenges = mock.MagicMock() + self.assertEqual( + self.client.request_challenges(self.identifier, 'URI'), + self.client.request_domain_challenges('example.com', 'URI')) + def test_answer_challenge(self): self.response.links['up'] = {'url': self.challr.authzr_uri} self.response.json.return_value = self.challr.body.to_json() diff --git a/acme/acme/jose/json_util.py b/acme/acme/jose/json_util.py index 4baadda5e..d474f4aac 100644 --- a/acme/acme/jose/json_util.py +++ b/acme/acme/jose/json_util.py @@ -267,7 +267,7 @@ class JSONObjectWithFields(util.ImmutableMap, interfaces.JSONDeSerializable): if missing: raise errors.DeserializationError( - 'The following fields are required: {0}'.format( + 'The following field are required: {0}'.format( ','.join(missing))) @classmethod diff --git a/acme/acme/messages.py b/acme/acme/messages.py index c3df4998c..54cd25c94 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -191,7 +191,7 @@ class Directory(jose.JSONDeSerializable): try: return self[name.replace('_', '-')] except KeyError as error: - raise AttributeError(str(error) + ': ' + name) + raise AttributeError(str(error)) def __getitem__(self, name): try: @@ -315,10 +315,12 @@ class RegistrationResource(ResourceWithURI): """Registration Resource. :ivar acme.messages.Registration body: + :ivar unicode new_authzr_uri: URI found in the 'next' ``Link`` header :ivar unicode terms_of_service: URL for the CA TOS. """ body = jose.Field('body', decoder=Registration.from_json) + new_authzr_uri = jose.Field('new_authzr_uri') terms_of_service = jose.Field('terms_of_service', omitempty=True) @@ -423,9 +425,11 @@ class AuthorizationResource(ResourceWithURI): """Authorization Resource. :ivar acme.messages.Authorization body: + :ivar unicode new_cert_uri: URI found in the 'next' ``Link`` header """ body = jose.Field('body', decoder=Authorization.from_json) + new_cert_uri = jose.Field('new_cert_uri') @Directory.register diff --git a/acme/acme/messages_test.py b/acme/acme/messages_test.py index e84c3e992..b3454f25b 100644 --- a/acme/acme/messages_test.py +++ b/acme/acme/messages_test.py @@ -225,12 +225,14 @@ class RegistrationResourceTest(unittest.TestCase): from acme.messages import RegistrationResource self.regr = RegistrationResource( body=mock.sentinel.body, uri=mock.sentinel.uri, + new_authzr_uri=mock.sentinel.new_authzr_uri, terms_of_service=mock.sentinel.terms_of_service) def test_to_partial_json(self): self.assertEqual(self.regr.to_json(), { 'body': mock.sentinel.body, 'uri': mock.sentinel.uri, + 'new_authzr_uri': mock.sentinel.new_authzr_uri, 'terms_of_service': mock.sentinel.terms_of_service, }) @@ -344,7 +346,9 @@ class AuthorizationResourceTest(unittest.TestCase): from acme.messages import AuthorizationResource authzr = AuthorizationResource( uri=mock.sentinel.uri, - body=mock.sentinel.body) + body=mock.sentinel.body, + new_cert_uri=mock.sentinel.new_cert_uri, + ) self.assertTrue(isinstance(authzr, jose.JSONDeSerializable)) diff --git a/acme/examples/example_client.py b/acme/examples/example_client.py index 1386491b1..261b37603 100644 --- a/acme/examples/example_client.py +++ b/acme/examples/example_client.py @@ -32,7 +32,8 @@ acme.agree_to_tos(regr) logging.debug(regr) authzr = acme.request_challenges( - identifier=messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=DOMAIN)) + identifier=messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=DOMAIN), + new_authzr_uri=regr.new_authzr_uri) logging.debug(authzr) authzr, authzr_response = acme.poll(authzr) diff --git a/certbot/auth_handler.py b/certbot/auth_handler.py index 53346a77c..6e9ab25a7 100644 --- a/certbot/auth_handler.py +++ b/certbot/auth_handler.py @@ -63,7 +63,8 @@ class AuthHandler(object): """ for domain in domains: - self.authzr[domain] = self.acme.request_domain_challenges(domain) + self.authzr[domain] = self.acme.request_domain_challenges( + domain, self.account.regr.new_authzr_uri) self._choose_challenges(domains) diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index 7367717bf..8ed591c98 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -110,7 +110,7 @@ class AccountFileStorageTest(unittest.TestCase): from certbot.account import Account self.acc = Account( regr=messages.RegistrationResource( - uri=None, body=messages.Registration()), + uri=None, new_authzr_uri=None, body=messages.Registration()), key=KEY) def tearDown(self): diff --git a/certbot/tests/acme_util.py b/certbot/tests/acme_util.py index f0549666a..5e6b190a7 100644 --- a/certbot/tests/acme_util.py +++ b/certbot/tests/acme_util.py @@ -96,5 +96,6 @@ def gen_authzr(authz_status, domain, challs, statuses, combos=True): # pylint: disable=star-args return messages.AuthorizationResource( uri="https://trusted.ca/new-authz-resource", + new_cert_uri="https://trusted.ca/new-cert", body=messages.Authorization(**authz_kwargs) ) diff --git a/certbot/tests/auth_handler_test.py b/certbot/tests/auth_handler_test.py index 9d22843db..046eb5ef1 100644 --- a/certbot/tests/auth_handler_test.py +++ b/certbot/tests/auth_handler_test.py @@ -309,6 +309,7 @@ class PollChallengesTest(unittest.TestCase): new_authzr = messages.AuthorizationResource( uri=authzr.uri, + new_cert_uri=authzr.new_cert_uri, body=messages.Authorization( identifier=authzr.body.identifier, challenges=new_challbs, @@ -436,7 +437,7 @@ def gen_auth_resp(chall_list): for chall in chall_list] -def gen_dom_authzr(domain, challs, combos=True): +def gen_dom_authzr(domain, unused_new_authzr_uri, challs, combos=True): """Generates new authzr for domains.""" return acme_util.gen_authzr( messages.STATUS_PENDING, domain, challs, diff --git a/certbot/tests/display/ops_test.py b/certbot/tests/display/ops_test.py index f2a9b3d07..f6de33a92 100644 --- a/certbot/tests/display/ops_test.py +++ b/certbot/tests/display/ops_test.py @@ -104,10 +104,10 @@ class ChooseAccountTest(unittest.TestCase): self.key = KEY self.acc1 = account.Account(messages.RegistrationResource( - uri=None, body=messages.Registration.from_data( + uri=None, new_authzr_uri=None, body=messages.Registration.from_data( email="email1@g.com")), self.key) self.acc2 = account.Account(messages.RegistrationResource( - uri=None, body=messages.Registration.from_data( + uri=None, new_authzr_uri=None, body=messages.Registration.from_data( email="email2@g.com", phone="phone")), self.key) @classmethod From 5e6a6f51d3627d2ec297d5e1bdb4c2ddfb113654 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 2 Mar 2017 10:31:37 -0800 Subject: [PATCH 08/27] Fix test_leauto_upgrades.sh (#4278) * fix-test-leauto-upgrades * redirect stderr * redirect stderr part 2 --- .../letstest/scripts/test_leauto_upgrades.sh | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index f7a74821b..b46080eff 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -4,13 +4,6 @@ # are dynamically set at execution cd letsencrypt -#git checkout v0.1.0 use --branch instead -SAVE="$PIP_EXTRA_INDEX_URL" -unset PIP_EXTRA_INDEX_URL -export PIP_INDEX_URL="https://isnot.org/pip/0.1.0/" - -#OLD_LEAUTO="https://raw.githubusercontent.com/letsencrypt/letsencrypt/5747ab7fd9641986833bad474d71b46a8c589247/letsencrypt-auto" - if ! command -v git ; then if [ "$OS_TYPE" = "ubuntu" ] ; then @@ -22,15 +15,18 @@ if ! command -v git ; then fi fi BRANCH=`git rev-parse --abbrev-ref HEAD` -git checkout -f v0.1.0 -./letsencrypt-auto -v --debug --version -unset PIP_INDEX_URL - -export PIP_EXTRA_INDEX_URL="$SAVE" +# 0.4.1 is the oldest version of letsencrypt-auto that can be used because +# it's the first version that both pins package versions and properly supports +# --no-self-upgrade. +git checkout -f v0.4.1 +if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | grep 0.4.1 ; then + echo initial installation appeared to fail + exit 1 +fi git checkout -f "$BRANCH" EXPECTED_VERSION=$(grep -m1 LE_AUTO_VERSION letsencrypt-auto | cut -d\" -f2) -if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade | grep $EXPECTED_VERSION ; then +if ! ./letsencrypt-auto -v --debug --version --no-self-upgrade 2>&1 | grep $EXPECTED_VERSION ; then echo upgrade appeared to fail exit 1 fi From b040717e4d6841342991067bc722c5cb5b990656 Mon Sep 17 00:00:00 2001 From: Noah Swartz Date: Thu, 2 Mar 2017 10:31:55 -0800 Subject: [PATCH 09/27] Changelog (#4252) * made a changelog * fix date for 0.6.0 * fix brad nits * fix typo --- CHANGELOG.md | 326 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..4cf02e954 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,326 @@ +# 0.11.1 +## 02/01/2017 + +* Resolve a problem where Certbot would crash while parsing command line +arguments in some cases. +* Fix a typo. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/pulls?q=is%3Apr%20milestone%3A0.11.1%20is%3Aclosed + +# 0.11.0 +## 02/01/2017 + +* Providing `--quiet` to `certbot-auto` now silences package manager output. +* The UI has been improved in the standalone plugin. When using the +plugin while running Certbot interactively and a required port is bound +by another process, Certbot will give you the option to retry to grab +the port rather than immediately exiting. +* You are now able to deactivate your account with the Let's Encrypt +server using the `unregister` subcommand. +* When revoking a certificate using the `revoke` subcommand, you now +have the option to provide the reason the certificate is being revoked +to Let's Encrypt with `--reason`. +* Removal of the optional `dnspython` dependency in our `acme` package. +Now the library does not support client side verification of the DNS +challenge. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.11.0+is%3Aclosed + +# 0.10.2 +## 01/25/2017 + +* We now save `--preferred-challenges` values for renewal. Previously +these values were discarded causing a different challenge type to be +used when renewing certs in some cases. +* If Certbot receives a request with a `badNonce` error, we +automatically retry the request. Since nonces from Let's Encrypt expire, +this helps people performing the DNS challenge with the `manual` plugin +who may have to wait an extended period of time for their DNS changes to +propagate. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.2+is%3Aclosed + +# 0.10.1 +## 01/13/2017 + +* Resolve problems where when asking Certbot to update a certificate at +an existing path to include different domain names, the old names would +continue to be used. +* Fix issues successfully running our unit test suite on some systems. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.1+is%3Aclosed + +# 0.10.0 +## 01/11/2017 + +* The ability to customize and automatically complete DNS and HTTP +domain validation challenges with the manual plugin. The flags +`--manual-auth-hook` and `--manual-cleanup-hook` can now be provided +when using the manual plugin to execute commands provided by the user to +perform and clean up challenges provided by the CA. This is best used in +complicated setups where the DNS challenge must be used or Certbot's +existing plugins cannot be used to perform HTTP challenges. For more +information on how this works, see `certbot --help manual`. +* A `--cert-name` flag for specifying the name to use for the +certificate in Certbot's configuration directory. Using this flag in +combination with `-d/--domains`, a user can easily request a new +certificate with different domains and save it with the name provided by +`--cert-name`. Additionally, `--cert-name` can be used to select a +certificate with the `certonly` and `run` subcommands so a full list of +domains in the certificate does not have to be provided. +* The subcommand `certificates` for listing the certificates managed by +Certbot and their properties. +* A `delete` subcommand for removing certificates managed by Certbot +from the configuration directory. +* Support for requesting internationalized domain names (IDNs). +* Removal of the ncurses interface. This change solves problems people +were having on many systems, reduces the number of Certbot dependencies, +and simplifies our code. Certbot's only interface now is the text +interface which was available by providing `-t/--text` to earlier +versions of Certbot. +* Hooks provided to Certbot are now saved to be reused during renewal. +If you run Certbot with `--pre-hook`, `--renew-hook`, or `--post-hook` +flags when obtaining a certificate, the provided commands will +automatically be saved and executed again when renewing the certificate. +A pre-hook and/or post-hook can also be given to the `certbot renew` +command either on the command line or in a [configuration +file](https://certbot.eff.org/docs/using.html#configuration-file) to run +an additional command before/after any certificate is renewed. Hooks +will only be run if a certificate is renewed. +* Recategorized `-h/--help` output to improve documentation and +discoverability. +* Busybox support in certbot-auto. +* Many small bug fixes. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.0is%3Aclosed + +# 0.9.3 +## 10/13/2016 + +* Adopt more conservative behavior about reporting a needed port as +unavailable when using the standalone plugin. +* The Apache plugin uses information about your OS to help determine the +layout of your Apache configuration directory. We added a patch to +ensure this code behaves the same way when testing on different systems +as the tests were failing in some cases. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/27?closed=1 + +# 0.9.2 +## 10/12/2016 + +* Ensuring we properly copy `ssl on;` directives as necessary when +performing domain validation in the Nginx plugin. +* Verifying that our optional dependencies version matches what is +required by Certbot. +* A fix for problems where symlinks were becoming files when they were +packaged, causing errors during testing and OS packaging. +* Stop requiring that all possibly required ports are available when +using the standalone plugin. Only verify the ports are available when +you know they are necessary. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/26?closed=1 + +# 0.9.1 +## 10/06/2016 + +* This version of Certbot simply fixes a bug that was introduced in version +0.9.0 where the command line flag -q/--quiet wasn't respected in some cases. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/25?closed=1 + +# 0.9.0 +## 10/05/2016 + +* An alpha version of the Nginx plugin. This plugin fully automates the +process of obtaining and installing certificates with Nginx. +Additionally, it is able to automatically configure security +enhancements such as an HTTP to HTTPS redirect and OCSP stapling. To use +this plugin, you must have the `certbot-nginx` package installed (which +is installed automatically when using `certbot-auto`) and provide +`--nginx` on the command line. This plugin is still in its early stages +so we recommend you use it with some caution and make sure you have a +backup of your Nginx configuration. +* Support for the `DNS` challenge in the `acme` library as well as `DNS` +support in Certbot's `manual` plugin. This allows you to create DNS +records to prove to Let's Encrypt you control the requested the domain +name. To use this feature, include `--manual --preferred-challenges dns` +on the command line. +* Help with enabling Extra Packages for Enterprise Linux (EPEL) on +CentOS 6 when using `certbot-auto`. To use `certbot-auto` on CentOS 6, +the EPEL repository has to be enabled. `certbot-auto` will now prompt +users asking them if they would like the script to enable this for them +automatically. This is done without prompting users when using +`letsencrypt-auto` or if `-n/--non-interactive/--noninteractive` is +included on the command line. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.9.0+is%3Aclosed + +# 0.8.1 +## 06/14/2016 + +* Preserving a certificate's common name when using `renew` +* Save webroot values for renewal when they are entered interactively +* Problems with an invalid user-agent string on OS X +* Gracefully reporting the Apache plugin isn't usable when Augeas is not installed +* Experimental support for Mageia has been added to `certbot-auto` + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.1+ + +# 0.8.0 +## 06/02/2016 + +* The main new feature in this release is the `register` subcommand which +can be used to register an account with the Let's Encrypt CA. +* Additionally, you can run `certbot register --update-registration` to +change the e-mail address associated with your registration. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.0+ + +# 0.7.0 +## 05/27/2016 + +* `--must-staple` to request certificates from Let's Encrypt with the +OCSP must staple extension +* automatic configuration of OSCP stapling for Apache +* requesting certificates for domains found in the common name of a +custom CSR +* a number of bug fixes + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=milestone%3A0.7.0+is%3Aissue + +# 0.6.0 +## 05/12/2016 + +* Renamed the client from `letsencrypt` to `certbot` +* Fixed a small json deserialization error +* Versioned the datetime dependency in setup.py +* Preserve domain order in generated CSRs +* Some minor bug fixes + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.6.0%20is%3Aclosed%20 + +# 0.5.0 +## 04/05/2016 + +* The ability to use the webroot plugin interactively. +* The flags --pre-hook, --post-hook, and --renew-hook which can be used +with the renew subcommand to register shell commands to run in +response to renewal events. Pre-hook commands will be run before +any certs are renewed, post-hook commands will be run after any +certs are renewed, and renew-hook commands will be run after each +cert is renewed. If no certs are due for renewal, no command is run. +* Cleaner renewal configuration files. In /etc/letsencrypt/renewal by +default, these files can be used to control what parameters are used +when renewing a specific certificate. +* A -q/--quiet flag which silences all output except errors. +* An --allow-subset-of-domains flag which can be used with the renew +command to prevent renewal failures for a subset of the requested +domains from causing the client to exit. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.5.0+is%3Aissue + +# 0.4.2 +## 03/03/2016 + +* Resolves problems encountered when compiling letsencrypt +against the new OpenSSL release. +* A patch fixing problems of using letsencrypt renew with configuration files +from private beta has been added. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 + +# 0.4.1 +## 02/29/2016 + +* Fixes Apache parsing errors with some configurations +* Fixes Werkzeug dependency problems on some Red Hat systems +* Fixes bootstrapping failures when using letsencrypt-auto with --no-self-upgrade +* Fixes problems with parsing renewal config files from private beta + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is:issue+milestone:0.4.1 + +# 0.4.0 +## 02/10/2016 + +* The new verb/subcommand `renew` can be used to renew your existing +certificates as they approach expiration. Running `letsencrypt renew` +will examine all existing certificate lineages and determine if any are +less than 30 days from expiration. If so, the client will use the +settings provided when you previously obtained the certificate to renew +it. The subcommand finishes by printing a summary of which renewals were +successful, failed, or not yet due. +* A `--dry-run` flag has been added to help with testing configuration +without affecting production rate limits. Currently supported by the +`renew` and `certonly` subcommands, providing `--dry-run` on the command +line will obtain certificates from the staging server without saving the +resulting certificates to disk. +* Major improvements have been added to letsencrypt-auto. This script +has been rewritten to include full support for Python 2.6, the ability +for letsencrypt-auto to update itself, and improvements to the +stability, security, and performance of the script. +* Support for Apache 2.2 has been added to the Apache plugin. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.0 + +# 0.3.0 +## 01/27/2016 + +* A non-interactive mode which can be enabled by including `-n` or +`--non-interactive` on the command line. This can be used to +guarantee the client will not prompt when run automatically using +cron/systemd. +* Preparation for the new letsencrypt-auto script. Over the past +couple months, we've been working on increasing the reliability and +security of letsencrypt-auto. A number of changes landed in this +release to prepare for the new version of this script. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.3.0 + +# 0.2.0 +## 01/14/2016 + +* Apache plugin support for non-Debian based systems. Support has been +added for modern Red Hat based systems such as Fedora 23, Red Hat 7, +and CentOS 7 running Apache 2.4. In theory, this plugin should be +able to be configured to run on any Unix-like OS running Apache 2.4. +* Relaxed PyOpenSSL version requirements. This adds support for systems +with PyOpenSSL versions 0.13 or 0.14. +* Resolves issues with the Apache plugin enabling an HTTP to HTTPS +redirect on some systems. +* Improved error messages from the client. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.2.0 + +# 0.1.1 +## 12/15/2015 + +* Fix a confusing UI path that caused some users to repeatedly renew +their certs while experimenting with the client, in some cases +hitting issuance rate limits +* Fixes numerous Apache configuration parser fixes +* Avoids attempting to issue for unqualified domain names like +"localhost" +* Fixes --webroot permission handling for non-root users + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.1.1 From 5e671682caac181072141747747a97b9ca2f48cb Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Thu, 2 Mar 2017 15:26:24 -0800 Subject: [PATCH 10/27] Candidate 0.12.0 (#4286) * Release 0.12.0 * Bump version to 0.13.0 --- acme/setup.py | 2 +- certbot-apache/setup.py | 2 +- certbot-auto | 26 +++++++++--------- certbot-compatibility-test/setup.py | 2 +- certbot-nginx/setup.py | 2 +- certbot/__init__.py | 2 +- docs/cli-help.txt | 2 +- letsencrypt-auto | 26 +++++++++--------- letsencrypt-auto-source/certbot-auto.asc | 14 +++++----- letsencrypt-auto-source/letsencrypt-auto | 26 +++++++++--------- letsencrypt-auto-source/letsencrypt-auto.sig | Bin 256 -> 256 bytes .../pieces/letsencrypt-auto-requirements.txt | 24 ++++++++-------- 12 files changed, 64 insertions(+), 64 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index 9b43278af..f169f59a7 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.12.0.dev0' +version = '0.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 87ea1a281..56a48abc6 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.12.0.dev0' +version = '0.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-auto b/certbot-auto index ac721638f..54cc429cf 100755 --- a/certbot-auto +++ b/certbot-auto @@ -23,7 +23,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.11.1" +LE_AUTO_VERSION="0.12.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -833,18 +833,18 @@ letsencrypt==0.7.0 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.11.1 \ - --hash=sha256:9f4efac6dc4477a3baa7eb2392d4f7583f974e4ad336439aa1961ef805622a77 \ - --hash=sha256:db35258edfc13dfe5839215898fe2d5d3caafc9a084f631a032f3fdf712c694e -certbot==0.11.1 \ - --hash=sha256:ba80552df0f390dbc5fcd14b4ea4b1499ea866f5f78c8c1a375abc25101dedf1 \ - --hash=sha256:6c1724486d500c5163c9313d6a14af5af9f4515f79553627303a6b86df2c3af2 -certbot-apache==0.11.1 \ - --hash=sha256:70132d9013509011b9edeba64fc208961f50ef78457f58d3b80a61094102efcd \ - --hash=sha256:efe2224b531595edee366423c115e2874a3c9011890321d3ccda0367efc776c0 -certbot-nginx==0.11.1 \ - --hash=sha256:1895eea1de92ab3dfd762998a4be7868ec3ec4d42cce7772995e4e9b2e488e6a \ - --hash=sha256:e5e5ffe8930ba10139bb61c2a05a30e84d9a69a7d8fc6a7b391f707eae8bfce5 +acme==0.12.0 \ + --hash=sha256:a6050619b3e07b41d197992bb15b32c755dfa0665cfa1c20faa82806a798265b \ + --hash=sha256:a05cba6b5b0fffdfa246b32492a44769011d45205f3ee8efde1f37ee9843fbdf +certbot==0.12.0 \ + --hash=sha256:d018d13665eb4cfe7038c2df636e3f4928742b83769b95edfdb0311277f0eb48 \ + --hash=sha256:4a71925c035b62dfb7c3343c619ee090add76188b47225272b57798ad63388b7 +certbot-apache==0.12.0 \ + --hash=sha256:de86907ea60e7bc35d252b87dec04eab3c7f3a1ea768774876e7ff582d89d640 \ + --hash=sha256:77dde63cf97292b09da8ae09ef8a7a6d83a3b1ee0f8d1fefe513fc77a6292509 +certbot-nginx==0.12.0 \ + --hash=sha256:c66d848c4577f1f91a06a8119b40f1ab90af1546addea27905434bd070f3924d \ + --hash=sha256:4dab2c93304c80d8d0d2e5214939f016804fd46859dd7a39b892d8b7195ab5ec UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index e2d226a72..73d3b704b 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.12.0.dev0' +version = '0.13.0.dev0' install_requires = [ 'certbot', diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 6de2dc6bd..24c2564b9 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.12.0.dev0' +version = '0.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot/__init__.py b/certbot/__init__.py index 6451eb0d5..0c667378d 100644 --- a/certbot/__init__.py +++ b/certbot/__init__.py @@ -1,4 +1,4 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '0.12.0.dev0' +__version__ = '0.13.0.dev0' diff --git a/docs/cli-help.txt b/docs/cli-help.txt index 4cb408002..9ef9d9e6c 100644 --- a/docs/cli-help.txt +++ b/docs/cli-help.txt @@ -86,7 +86,7 @@ optional arguments: statistics about success rates by OS and plugin. If you wish to hide your server OS version from the Let's Encrypt server, set this to "". (default: - CertbotACMEClient/0.11.1 (Ubuntu 16.04.1 LTS) + CertbotACMEClient/0.12.0 (Ubuntu 16.04.2 LTS) Authenticator/XXX Installer/YYY) automation: diff --git a/letsencrypt-auto b/letsencrypt-auto index ac721638f..54cc429cf 100755 --- a/letsencrypt-auto +++ b/letsencrypt-auto @@ -23,7 +23,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.11.1" +LE_AUTO_VERSION="0.12.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -833,18 +833,18 @@ letsencrypt==0.7.0 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.11.1 \ - --hash=sha256:9f4efac6dc4477a3baa7eb2392d4f7583f974e4ad336439aa1961ef805622a77 \ - --hash=sha256:db35258edfc13dfe5839215898fe2d5d3caafc9a084f631a032f3fdf712c694e -certbot==0.11.1 \ - --hash=sha256:ba80552df0f390dbc5fcd14b4ea4b1499ea866f5f78c8c1a375abc25101dedf1 \ - --hash=sha256:6c1724486d500c5163c9313d6a14af5af9f4515f79553627303a6b86df2c3af2 -certbot-apache==0.11.1 \ - --hash=sha256:70132d9013509011b9edeba64fc208961f50ef78457f58d3b80a61094102efcd \ - --hash=sha256:efe2224b531595edee366423c115e2874a3c9011890321d3ccda0367efc776c0 -certbot-nginx==0.11.1 \ - --hash=sha256:1895eea1de92ab3dfd762998a4be7868ec3ec4d42cce7772995e4e9b2e488e6a \ - --hash=sha256:e5e5ffe8930ba10139bb61c2a05a30e84d9a69a7d8fc6a7b391f707eae8bfce5 +acme==0.12.0 \ + --hash=sha256:a6050619b3e07b41d197992bb15b32c755dfa0665cfa1c20faa82806a798265b \ + --hash=sha256:a05cba6b5b0fffdfa246b32492a44769011d45205f3ee8efde1f37ee9843fbdf +certbot==0.12.0 \ + --hash=sha256:d018d13665eb4cfe7038c2df636e3f4928742b83769b95edfdb0311277f0eb48 \ + --hash=sha256:4a71925c035b62dfb7c3343c619ee090add76188b47225272b57798ad63388b7 +certbot-apache==0.12.0 \ + --hash=sha256:de86907ea60e7bc35d252b87dec04eab3c7f3a1ea768774876e7ff582d89d640 \ + --hash=sha256:77dde63cf97292b09da8ae09ef8a7a6d83a3b1ee0f8d1fefe513fc77a6292509 +certbot-nginx==0.12.0 \ + --hash=sha256:c66d848c4577f1f91a06a8119b40f1ab90af1546addea27905434bd070f3924d \ + --hash=sha256:4dab2c93304c80d8d0d2e5214939f016804fd46859dd7a39b892d8b7195ab5ec UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc index 44e2246b7..417d43387 100644 --- a/letsencrypt-auto-source/certbot-auto.asc +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 -iQEcBAABAgAGBQJYkqlBAAoJEE0XyZXNl3XyXUAH/RqwKDOpceChSdH/aIk891HX -VRDBQxIjZ6EB1iyebfihyZd4a5zGJ9ocMj1GxThMyLgSKbgkSRtjE/+ymDWsL0Us -Y8w9fw76BAImaJZEvjkrpqD2bSYdijnF479hBa/huZHKcQhb/sqxkNJO9SO1uj8z -bnF0UjJNjgn1hm2yHNMWwyEX7xCN/Vxiq/Zwqi7HdPus99sInJA7+04nwXaUtash -87MHpCjIiHh3axOCOjJbAWzIfsDUKeaBHgeYO+2ldOPWVQ0Amp7ghXjohryBkiux -dqhhAuvBTmNqPrbPAjdJ7Kd74NOGDo3HvAUiuXIckDWqxX2Q34w5pwxelZcIEnI= -=vmVS +iQEcBAABAgAGBQJYuJdQAAoJEE0XyZXNl3Xyw+oH/1AQ90P3397rKB0jP+5MchtR +Nz4ScKL86x9s+o/OzAN76gLhJNj/gOVWoyeK8wVkJ07MpbGyLBiYFsXPZWYUcJ77 +LRj4sGAxJatptHG+PnzIquAf+swynqVu0QdBv8ImKwYrqOlULR+Kr8QZE95Ena51 +JPkbm5o0ipSbByIpraAYabCOHj7SrsFQtMx+tPTd7xaliO8VkguzLQt93QQC7CNj +JIO/yURnfKzutTOe3OPzBzbb6e2yhHcHZcSyv8S0DCIAoB08N9Bs8aAbVwmD89Fq +fwYxLZherXRZ2VtJ2Sf/hUP2ZrEH/mvCkKjzznZokFGJXLvTEc8fC/O6c/q/nLw= +=YiSx -----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 81e3862c2..cc248a36a 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -23,7 +23,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.12.0.dev0" +LE_AUTO_VERSION="0.13.0.dev0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -833,18 +833,18 @@ letsencrypt==0.7.0 \ # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. -acme==0.11.1 \ - --hash=sha256:9f4efac6dc4477a3baa7eb2392d4f7583f974e4ad336439aa1961ef805622a77 \ - --hash=sha256:db35258edfc13dfe5839215898fe2d5d3caafc9a084f631a032f3fdf712c694e -certbot==0.11.1 \ - --hash=sha256:ba80552df0f390dbc5fcd14b4ea4b1499ea866f5f78c8c1a375abc25101dedf1 \ - --hash=sha256:6c1724486d500c5163c9313d6a14af5af9f4515f79553627303a6b86df2c3af2 -certbot-apache==0.11.1 \ - --hash=sha256:70132d9013509011b9edeba64fc208961f50ef78457f58d3b80a61094102efcd \ - --hash=sha256:efe2224b531595edee366423c115e2874a3c9011890321d3ccda0367efc776c0 -certbot-nginx==0.11.1 \ - --hash=sha256:1895eea1de92ab3dfd762998a4be7868ec3ec4d42cce7772995e4e9b2e488e6a \ - --hash=sha256:e5e5ffe8930ba10139bb61c2a05a30e84d9a69a7d8fc6a7b391f707eae8bfce5 +acme==0.12.0 \ + --hash=sha256:a6050619b3e07b41d197992bb15b32c755dfa0665cfa1c20faa82806a798265b \ + --hash=sha256:a05cba6b5b0fffdfa246b32492a44769011d45205f3ee8efde1f37ee9843fbdf +certbot==0.12.0 \ + --hash=sha256:d018d13665eb4cfe7038c2df636e3f4928742b83769b95edfdb0311277f0eb48 \ + --hash=sha256:4a71925c035b62dfb7c3343c619ee090add76188b47225272b57798ad63388b7 +certbot-apache==0.12.0 \ + --hash=sha256:de86907ea60e7bc35d252b87dec04eab3c7f3a1ea768774876e7ff582d89d640 \ + --hash=sha256:77dde63cf97292b09da8ae09ef8a7a6d83a3b1ee0f8d1fefe513fc77a6292509 +certbot-nginx==0.12.0 \ + --hash=sha256:c66d848c4577f1f91a06a8119b40f1ab90af1546addea27905434bd070f3924d \ + --hash=sha256:4dab2c93304c80d8d0d2e5214939f016804fd46859dd7a39b892d8b7195ab5ec UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig index 7aea42dd07338009aeb411d16b1ede2e47242c4a..711300dda497b4f0de469e0d5f9fdeffcc0ed791 100644 GIT binary patch literal 256 zcmV+b0ssCPKrmxhSd~Gl5(vW|<6opm^3z*2@_s;^(O#c8A(BZ&bT<6@KKsFX>*P^+ z5OMKIYIwR>5CX?W?*GvZf6nD9_+<;knP+ME`_3x{Odk_e&tozlwSx$&=Gd}j4{T;d zN=0Y**I$U*TkAErI2%6WFOxeoL@LtX^L?L>(^-}P0vSB0ac_x}l1H9mca`Z>jI7HK ze*M3p)+_=!N|Mdxjmt%{u8Za)+;9^WpG(BR|)b z`MuJ4TFdF^IQv0a>mH6LZ6Uwm>Ao3CY`8B~Piue4_sWH{fV;aQFnC4iPVzu|)T9g< GmtWvEc7D?U literal 256 zcmV+b0ssE0LMkrq1<;I$4(Z|boMIIj?&t!1cp>;Yh?HTs)6}s^=SfcWN;bWgd`EXf zEhtU0e_$I^0tEloE_&&fmjX6Hni@Oow|k9sJt&yBk3)F3fvE|SyJe#y@%&-O3e7`~ z73zWb(bivi7Ot+2)kS>^Ui$C!RU< Date: Thu, 2 Mar 2017 15:46:16 -0800 Subject: [PATCH 11/27] update changelog (#4287) --- CHANGELOG.md | 360 ++++++++++++++++++++++++++------------------------- 1 file changed, 185 insertions(+), 175 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cf02e954..cc1ad82ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 0.12.0 +## 03/02/2017 + +* Allow non-camelcase Apache VirtualHost names +* Allow more log messages to be silenced +* Fix a regression around using `--cert-name` when getting new certificates + +More information about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.12.0 + # 0.11.1 ## 02/01/2017 @@ -31,70 +41,70 @@ https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.11.0+is%3Ac # 0.10.2 ## 01/25/2017 -* We now save `--preferred-challenges` values for renewal. Previously -these values were discarded causing a different challenge type to be -used when renewing certs in some cases. -* If Certbot receives a request with a `badNonce` error, we -automatically retry the request. Since nonces from Let's Encrypt expire, -this helps people performing the DNS challenge with the `manual` plugin -who may have to wait an extended period of time for their DNS changes to -propagate. +* We now save `--preferred-challenges` values for renewal. Previously +these values were discarded causing a different challenge type to be +used when renewing certs in some cases. +* If Certbot receives a request with a `badNonce` error, we +automatically retry the request. Since nonces from Let's Encrypt expire, +this helps people performing the DNS challenge with the `manual` plugin +who may have to wait an extended period of time for their DNS changes to +propagate. -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.2+is%3Aclosed +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.2+is%3Aclosed # 0.10.1 ## 01/13/2017 -* Resolve problems where when asking Certbot to update a certificate at -an existing path to include different domain names, the old names would -continue to be used. -* Fix issues successfully running our unit test suite on some systems. +* Resolve problems where when asking Certbot to update a certificate at +an existing path to include different domain names, the old names would +continue to be used. +* Fix issues successfully running our unit test suite on some systems. More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.1+is%3Aclosed +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.1+is%3Aclosed # 0.10.0 ## 01/11/2017 -* The ability to customize and automatically complete DNS and HTTP -domain validation challenges with the manual plugin. The flags -`--manual-auth-hook` and `--manual-cleanup-hook` can now be provided -when using the manual plugin to execute commands provided by the user to -perform and clean up challenges provided by the CA. This is best used in -complicated setups where the DNS challenge must be used or Certbot's -existing plugins cannot be used to perform HTTP challenges. For more -information on how this works, see `certbot --help manual`. -* A `--cert-name` flag for specifying the name to use for the -certificate in Certbot's configuration directory. Using this flag in -combination with `-d/--domains`, a user can easily request a new -certificate with different domains and save it with the name provided by -`--cert-name`. Additionally, `--cert-name` can be used to select a -certificate with the `certonly` and `run` subcommands so a full list of -domains in the certificate does not have to be provided. -* The subcommand `certificates` for listing the certificates managed by -Certbot and their properties. -* A `delete` subcommand for removing certificates managed by Certbot -from the configuration directory. -* Support for requesting internationalized domain names (IDNs). -* Removal of the ncurses interface. This change solves problems people -were having on many systems, reduces the number of Certbot dependencies, -and simplifies our code. Certbot's only interface now is the text -interface which was available by providing `-t/--text` to earlier -versions of Certbot. -* Hooks provided to Certbot are now saved to be reused during renewal. -If you run Certbot with `--pre-hook`, `--renew-hook`, or `--post-hook` -flags when obtaining a certificate, the provided commands will -automatically be saved and executed again when renewing the certificate. -A pre-hook and/or post-hook can also be given to the `certbot renew` -command either on the command line or in a [configuration -file](https://certbot.eff.org/docs/using.html#configuration-file) to run -an additional command before/after any certificate is renewed. Hooks -will only be run if a certificate is renewed. -* Recategorized `-h/--help` output to improve documentation and -discoverability. -* Busybox support in certbot-auto. -* Many small bug fixes. +* The ability to customize and automatically complete DNS and HTTP +domain validation challenges with the manual plugin. The flags +`--manual-auth-hook` and `--manual-cleanup-hook` can now be provided +when using the manual plugin to execute commands provided by the user to +perform and clean up challenges provided by the CA. This is best used in +complicated setups where the DNS challenge must be used or Certbot's +existing plugins cannot be used to perform HTTP challenges. For more +information on how this works, see `certbot --help manual`. +* A `--cert-name` flag for specifying the name to use for the +certificate in Certbot's configuration directory. Using this flag in +combination with `-d/--domains`, a user can easily request a new +certificate with different domains and save it with the name provided by +`--cert-name`. Additionally, `--cert-name` can be used to select a +certificate with the `certonly` and `run` subcommands so a full list of +domains in the certificate does not have to be provided. +* The subcommand `certificates` for listing the certificates managed by +Certbot and their properties. +* A `delete` subcommand for removing certificates managed by Certbot +from the configuration directory. +* Support for requesting internationalized domain names (IDNs). +* Removal of the ncurses interface. This change solves problems people +were having on many systems, reduces the number of Certbot dependencies, +and simplifies our code. Certbot's only interface now is the text +interface which was available by providing `-t/--text` to earlier +versions of Certbot. +* Hooks provided to Certbot are now saved to be reused during renewal. +If you run Certbot with `--pre-hook`, `--renew-hook`, or `--post-hook` +flags when obtaining a certificate, the provided commands will +automatically be saved and executed again when renewing the certificate. +A pre-hook and/or post-hook can also be given to the `certbot renew` +command either on the command line or in a [configuration +file](https://certbot.eff.org/docs/using.html#configuration-file) to run +an additional command before/after any certificate is renewed. Hooks +will only be run if a certificate is renewed. +* Recategorized `-h/--help` output to improve documentation and +discoverability. +* Busybox support in certbot-auto. +* Many small bug fixes. More details about these changes can be found on our GitHub repo: https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.0is%3Aclosed @@ -102,31 +112,31 @@ https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.0is%3Acl # 0.9.3 ## 10/13/2016 -* Adopt more conservative behavior about reporting a needed port as -unavailable when using the standalone plugin. -* The Apache plugin uses information about your OS to help determine the -layout of your Apache configuration directory. We added a patch to -ensure this code behaves the same way when testing on different systems -as the tests were failing in some cases. +* Adopt more conservative behavior about reporting a needed port as +unavailable when using the standalone plugin. +* The Apache plugin uses information about your OS to help determine the +layout of your Apache configuration directory. We added a patch to +ensure this code behaves the same way when testing on different systems +as the tests were failing in some cases. More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/27?closed=1 +https://github.com/certbot/certbot/milestone/27?closed=1 # 0.9.2 ## 10/12/2016 -* Ensuring we properly copy `ssl on;` directives as necessary when -performing domain validation in the Nginx plugin. -* Verifying that our optional dependencies version matches what is -required by Certbot. -* A fix for problems where symlinks were becoming files when they were -packaged, causing errors during testing and OS packaging. -* Stop requiring that all possibly required ports are available when -using the standalone plugin. Only verify the ports are available when -you know they are necessary. +* Ensuring we properly copy `ssl on;` directives as necessary when +performing domain validation in the Nginx plugin. +* Verifying that our optional dependencies version matches what is +required by Certbot. +* A fix for problems where symlinks were becoming files when they were +packaged, causing errors during testing and OS packaging. +* Stop requiring that all possibly required ports are available when +using the standalone plugin. Only verify the ports are available when +you know they are necessary. More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/26?closed=1 +https://github.com/certbot/certbot/milestone/26?closed=1 # 0.9.1 ## 10/06/2016 @@ -135,43 +145,43 @@ https://github.com/certbot/certbot/milestone/26?closed=1 0.9.0 where the command line flag -q/--quiet wasn't respected in some cases. More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/25?closed=1 +https://github.com/certbot/certbot/milestone/25?closed=1 # 0.9.0 ## 10/05/2016 -* An alpha version of the Nginx plugin. This plugin fully automates the -process of obtaining and installing certificates with Nginx. -Additionally, it is able to automatically configure security -enhancements such as an HTTP to HTTPS redirect and OCSP stapling. To use -this plugin, you must have the `certbot-nginx` package installed (which -is installed automatically when using `certbot-auto`) and provide -`--nginx` on the command line. This plugin is still in its early stages -so we recommend you use it with some caution and make sure you have a -backup of your Nginx configuration. -* Support for the `DNS` challenge in the `acme` library as well as `DNS` -support in Certbot's `manual` plugin. This allows you to create DNS -records to prove to Let's Encrypt you control the requested the domain -name. To use this feature, include `--manual --preferred-challenges dns` -on the command line. -* Help with enabling Extra Packages for Enterprise Linux (EPEL) on -CentOS 6 when using `certbot-auto`. To use `certbot-auto` on CentOS 6, -the EPEL repository has to be enabled. `certbot-auto` will now prompt -users asking them if they would like the script to enable this for them -automatically. This is done without prompting users when using -`letsencrypt-auto` or if `-n/--non-interactive/--noninteractive` is -included on the command line. +* An alpha version of the Nginx plugin. This plugin fully automates the +process of obtaining and installing certificates with Nginx. +Additionally, it is able to automatically configure security +enhancements such as an HTTP to HTTPS redirect and OCSP stapling. To use +this plugin, you must have the `certbot-nginx` package installed (which +is installed automatically when using `certbot-auto`) and provide +`--nginx` on the command line. This plugin is still in its early stages +so we recommend you use it with some caution and make sure you have a +backup of your Nginx configuration. +* Support for the `DNS` challenge in the `acme` library as well as `DNS` +support in Certbot's `manual` plugin. This allows you to create DNS +records to prove to Let's Encrypt you control the requested the domain +name. To use this feature, include `--manual --preferred-challenges dns` +on the command line. +* Help with enabling Extra Packages for Enterprise Linux (EPEL) on +CentOS 6 when using `certbot-auto`. To use `certbot-auto` on CentOS 6, +the EPEL repository has to be enabled. `certbot-auto` will now prompt +users asking them if they would like the script to enable this for them +automatically. This is done without prompting users when using +`letsencrypt-auto` or if `-n/--non-interactive/--noninteractive` is +included on the command line. More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.9.0+is%3Aclosed +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.9.0+is%3Aclosed # 0.8.1 ## 06/14/2016 -* Preserving a certificate's common name when using `renew` -* Save webroot values for renewal when they are entered interactively -* Problems with an invalid user-agent string on OS X -* Gracefully reporting the Apache plugin isn't usable when Augeas is not installed +* Preserving a certificate's common name when using `renew` +* Save webroot values for renewal when they are entered interactively +* Problems with an invalid user-agent string on OS X +* Gracefully reporting the Apache plugin isn't usable when Augeas is not installed * Experimental support for Mageia has been added to `certbot-auto` More details about these changes can be found on our GitHub repo: @@ -180,10 +190,10 @@ https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.1+ # 0.8.0 ## 06/02/2016 -* The main new feature in this release is the `register` subcommand which -can be used to register an account with the Let's Encrypt CA. -* Additionally, you can run `certbot register --update-registration` to -change the e-mail address associated with your registration. +* The main new feature in this release is the `register` subcommand which +can be used to register an account with the Let's Encrypt CA. +* Additionally, you can run `certbot register --update-registration` to +change the e-mail address associated with your registration. More details about these changes can be found on our GitHub repo: https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.0+ @@ -191,18 +201,18 @@ https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.0+ # 0.7.0 ## 05/27/2016 -* `--must-staple` to request certificates from Let's Encrypt with the -OCSP must staple extension -* automatic configuration of OSCP stapling for Apache -* requesting certificates for domains found in the common name of a -custom CSR -* a number of bug fixes +* `--must-staple` to request certificates from Let's Encrypt with the +OCSP must staple extension +* automatic configuration of OSCP stapling for Apache +* requesting certificates for domains found in the common name of a +custom CSR +* a number of bug fixes More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=milestone%3A0.7.0+is%3Aissue +https://github.com/certbot/certbot/issues?q=milestone%3A0.7.0+is%3Aissue # 0.6.0 -## 05/12/2016 +## 05/12/2016 * Renamed the client from `letsencrypt` to `certbot` * Fixed a small json deserialization error @@ -216,34 +226,34 @@ https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.6.0%20is% # 0.5.0 ## 04/05/2016 -* The ability to use the webroot plugin interactively. -* The flags --pre-hook, --post-hook, and --renew-hook which can be used -with the renew subcommand to register shell commands to run in -response to renewal events. Pre-hook commands will be run before -any certs are renewed, post-hook commands will be run after any -certs are renewed, and renew-hook commands will be run after each -cert is renewed. If no certs are due for renewal, no command is run. -* Cleaner renewal configuration files. In /etc/letsencrypt/renewal by -default, these files can be used to control what parameters are used -when renewing a specific certificate. -* A -q/--quiet flag which silences all output except errors. -* An --allow-subset-of-domains flag which can be used with the renew -command to prevent renewal failures for a subset of the requested -domains from causing the client to exit. +* The ability to use the webroot plugin interactively. +* The flags --pre-hook, --post-hook, and --renew-hook which can be used +with the renew subcommand to register shell commands to run in +response to renewal events. Pre-hook commands will be run before +any certs are renewed, post-hook commands will be run after any +certs are renewed, and renew-hook commands will be run after each +cert is renewed. If no certs are due for renewal, no command is run. +* Cleaner renewal configuration files. In /etc/letsencrypt/renewal by +default, these files can be used to control what parameters are used +when renewing a specific certificate. +* A -q/--quiet flag which silences all output except errors. +* An --allow-subset-of-domains flag which can be used with the renew +command to prevent renewal failures for a subset of the requested +domains from causing the client to exit. More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.5.0+is%3Aissue +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.5.0+is%3Aissue # 0.4.2 ## 03/03/2016 -* Resolves problems encountered when compiling letsencrypt -against the new OpenSSL release. +* Resolves problems encountered when compiling letsencrypt +against the new OpenSSL release. * A patch fixing problems of using letsencrypt renew with configuration files -from private beta has been added. +from private beta has been added. More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 # 0.4.1 ## 02/29/2016 @@ -254,73 +264,73 @@ https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 * Fixes problems with parsing renewal config files from private beta More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is:issue+milestone:0.4.1 +https://github.com/letsencrypt/letsencrypt/issues?q=is:issue+milestone:0.4.1 # 0.4.0 ## 02/10/2016 -* The new verb/subcommand `renew` can be used to renew your existing -certificates as they approach expiration. Running `letsencrypt renew` -will examine all existing certificate lineages and determine if any are -less than 30 days from expiration. If so, the client will use the -settings provided when you previously obtained the certificate to renew -it. The subcommand finishes by printing a summary of which renewals were -successful, failed, or not yet due. -* A `--dry-run` flag has been added to help with testing configuration -without affecting production rate limits. Currently supported by the -`renew` and `certonly` subcommands, providing `--dry-run` on the command -line will obtain certificates from the staging server without saving the -resulting certificates to disk. -* Major improvements have been added to letsencrypt-auto. This script -has been rewritten to include full support for Python 2.6, the ability -for letsencrypt-auto to update itself, and improvements to the -stability, security, and performance of the script. -* Support for Apache 2.2 has been added to the Apache plugin. +* The new verb/subcommand `renew` can be used to renew your existing +certificates as they approach expiration. Running `letsencrypt renew` +will examine all existing certificate lineages and determine if any are +less than 30 days from expiration. If so, the client will use the +settings provided when you previously obtained the certificate to renew +it. The subcommand finishes by printing a summary of which renewals were +successful, failed, or not yet due. +* A `--dry-run` flag has been added to help with testing configuration +without affecting production rate limits. Currently supported by the +`renew` and `certonly` subcommands, providing `--dry-run` on the command +line will obtain certificates from the staging server without saving the +resulting certificates to disk. +* Major improvements have been added to letsencrypt-auto. This script +has been rewritten to include full support for Python 2.6, the ability +for letsencrypt-auto to update itself, and improvements to the +stability, security, and performance of the script. +* Support for Apache 2.2 has been added to the Apache plugin. More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.0 - +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.0 + # 0.3.0 ## 01/27/2016 -* A non-interactive mode which can be enabled by including `-n` or -`--non-interactive` on the command line. This can be used to -guarantee the client will not prompt when run automatically using -cron/systemd. -* Preparation for the new letsencrypt-auto script. Over the past -couple months, we've been working on increasing the reliability and -security of letsencrypt-auto. A number of changes landed in this -release to prepare for the new version of this script. +* A non-interactive mode which can be enabled by including `-n` or +`--non-interactive` on the command line. This can be used to +guarantee the client will not prompt when run automatically using +cron/systemd. +* Preparation for the new letsencrypt-auto script. Over the past +couple months, we've been working on increasing the reliability and +security of letsencrypt-auto. A number of changes landed in this +release to prepare for the new version of this script. More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.3.0 +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.3.0 # 0.2.0 ## 01/14/2016 -* Apache plugin support for non-Debian based systems. Support has been -added for modern Red Hat based systems such as Fedora 23, Red Hat 7, -and CentOS 7 running Apache 2.4. In theory, this plugin should be -able to be configured to run on any Unix-like OS running Apache 2.4. -* Relaxed PyOpenSSL version requirements. This adds support for systems -with PyOpenSSL versions 0.13 or 0.14. -* Resolves issues with the Apache plugin enabling an HTTP to HTTPS -redirect on some systems. -* Improved error messages from the client. +* Apache plugin support for non-Debian based systems. Support has been +added for modern Red Hat based systems such as Fedora 23, Red Hat 7, +and CentOS 7 running Apache 2.4. In theory, this plugin should be +able to be configured to run on any Unix-like OS running Apache 2.4. +* Relaxed PyOpenSSL version requirements. This adds support for systems +with PyOpenSSL versions 0.13 or 0.14. +* Resolves issues with the Apache plugin enabling an HTTP to HTTPS +redirect on some systems. +* Improved error messages from the client. More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.2.0 +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.2.0 # 0.1.1 ## 12/15/2015 -* Fix a confusing UI path that caused some users to repeatedly renew -their certs while experimenting with the client, in some cases -hitting issuance rate limits -* Fixes numerous Apache configuration parser fixes -* Avoids attempting to issue for unqualified domain names like -"localhost" -* Fixes --webroot permission handling for non-root users +* Fix a confusing UI path that caused some users to repeatedly renew +their certs while experimenting with the client, in some cases +hitting issuance rate limits +* Fixes numerous Apache configuration parser fixes +* Avoids attempting to issue for unqualified domain names like +"localhost" +* Fixes --webroot permission handling for non-root users More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.1.1 +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.1.1 From 26a7023b8dd985674dbf9ff2d35d4065ca7cae9d Mon Sep 17 00:00:00 2001 From: Sagi Kedmi Date: Fri, 3 Mar 2017 02:49:34 +0200 Subject: [PATCH 12/27] Change QSA to NE in HTTPS redirection (#4204) * Change QSA to NE in HTTPS redirection * Seamless transition to new HTTPS redirection RewriteRule --- certbot-apache/certbot_apache/configurator.py | 41 +++++++++++++----- certbot-apache/certbot_apache/constants.py | 8 +++- .../certbot_apache/tests/configurator_test.py | 43 ++++++++++++++++--- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/certbot-apache/certbot_apache/configurator.py b/certbot-apache/certbot_apache/configurator.py index 5639dae83..cdfc01626 100644 --- a/certbot-apache/certbot_apache/configurator.py +++ b/certbot-apache/certbot_apache/configurator.py @@ -1315,18 +1315,15 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): # even with save() and load() if not self._is_rewrite_engine_on(general_vh): self.parser.add_dir(general_vh.path, "RewriteEngine", "on") + names = ssl_vhost.get_names() for idx, name in enumerate(names): args = ["%{SERVER_NAME}", "={0}".format(name), "[OR]"] if idx == len(names) - 1: args.pop() self.parser.add_dir(general_vh.path, "RewriteCond", args) - if self.get_version() >= (2, 3, 9): - self.parser.add_dir(general_vh.path, "RewriteRule", - constants.REWRITE_HTTPS_ARGS_WITH_END) - else: - self.parser.add_dir(general_vh.path, "RewriteRule", - constants.REWRITE_HTTPS_ARGS) + + self._set_https_redirection_rewrite_rule(general_vh) self.save_notes += ("Redirecting host in %s to ssl vhost in %s\n" % (general_vh.filep, ssl_vhost.filep)) @@ -1336,12 +1333,24 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): logger.info("Redirecting vhost in %s to ssl vhost in %s", general_vh.filep, ssl_vhost.filep) + def _set_https_redirection_rewrite_rule(self, vhost): + if self.get_version() >= (2, 3, 9): + self.parser.add_dir(vhost.path, "RewriteRule", + constants.REWRITE_HTTPS_ARGS_WITH_END) + else: + self.parser.add_dir(vhost.path, "RewriteRule", + constants.REWRITE_HTTPS_ARGS) + + def _verify_no_certbot_redirect(self, vhost): """Checks to see if a redirect was already installed by certbot. Checks to see if virtualhost already contains a rewrite rule that is identical to Certbot's redirection rewrite rule. + For graceful transition to new rewrite rules for HTTPS redireciton we + delete certbot's old rewrite rules and set the new one instead. + :param vhost: vhost to check :type vhost: :class:`~certbot_apache.obj.VirtualHost` @@ -1355,19 +1364,29 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): # rewrite_args_dict keys are directive ids and the corresponding value # for each is a list of arguments to that directive. rewrite_args_dict = defaultdict(list) - pat = r'.*(directive\[\d+\]).*' + pat = r'(.*directive\[\d+\]).*' for match in rewrite_path: m = re.match(pat, match) if m: - dir_id = m.group(1) - rewrite_args_dict[dir_id].append(match) + dir_path = m.group(1) + rewrite_args_dict[dir_path].append(match) if rewrite_args_dict: redirect_args = [constants.REWRITE_HTTPS_ARGS, constants.REWRITE_HTTPS_ARGS_WITH_END] - for matches in rewrite_args_dict.values(): - if [self.aug.get(x) for x in matches] in redirect_args: + for dir_path, args_paths in rewrite_args_dict.items(): + arg_vals = [self.aug.get(x) for x in args_paths] + + # Search for past redirection rule, delete it, set the new one + if arg_vals in constants.OLD_REWRITE_HTTPS_ARGS: + self.aug.remove(dir_path) + self._set_https_redirection_rewrite_rule(vhost) + self.save() + raise errors.PluginEnhancementAlreadyPresent( + "Certbot has already enabled redirection") + + if arg_vals in redirect_args: raise errors.PluginEnhancementAlreadyPresent( "Certbot has already enabled redirection") diff --git a/certbot-apache/certbot_apache/constants.py b/certbot-apache/certbot_apache/constants.py index dcc635c4b..3cfeb4dd6 100644 --- a/certbot-apache/certbot_apache/constants.py +++ b/certbot-apache/certbot_apache/constants.py @@ -136,15 +136,19 @@ AUGEAS_LENS_DIR = pkg_resources.resource_filename( """Path to the Augeas lens directory""" REWRITE_HTTPS_ARGS = [ - "^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,QSA,R=permanent]"] + "^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,NE,R=permanent]"] """Apache version<2.3.9 rewrite rule arguments used for redirections to https vhost""" REWRITE_HTTPS_ARGS_WITH_END = [ - "^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[END,QSA,R=permanent]"] + "^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[END,NE,R=permanent]"] """Apache version >= 2.3.9 rewrite rule arguments used for redirections to https vhost""" +OLD_REWRITE_HTTPS_ARGS = [ + ["^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,QSA,R=permanent]"], + ["^", "https://%{SERVER_NAME}%{REQUEST_URI}", "[END,QSA,R=permanent]"]] + HSTS_ARGS = ["always", "set", "Strict-Transport-Security", "\"max-age=31536000\""] """Apache header arguments for HSTS""" diff --git a/certbot-apache/certbot_apache/tests/configurator_test.py b/certbot-apache/certbot_apache/tests/configurator_test.py index 937694267..45e701bd5 100644 --- a/certbot-apache/certbot_apache/tests/configurator_test.py +++ b/certbot-apache/certbot_apache/tests/configurator_test.py @@ -18,6 +18,7 @@ from certbot.tests import acme_util from certbot.tests import util as certbot_util from certbot_apache import configurator +from certbot_apache import constants from certbot_apache import parser from certbot_apache import obj @@ -1047,6 +1048,36 @@ class MultipleVhostsTest(util.ApacheTest): self.assertTrue("rewrite_module" in self.config.parser.modules) + @mock.patch("certbot.util.run_script") + @mock.patch("certbot.util.exe_exists") + def test_redirect_with_old_https_redirection(self, mock_exe, _): + self.config.parser.update_runtime_variables = mock.Mock() + mock_exe.return_value = True + self.config.get_version = mock.Mock(return_value=(2, 2, 0)) + + ssl_vhost = self.config.choose_vhost("certbot.demo") + + # pylint: disable=protected-access + http_vhost = self.config._get_http_vhost(ssl_vhost) + + # Create an old (previously suppoorted) https redirectoin rewrite rule + self.config.parser.add_dir( + http_vhost.path, "RewriteRule", + ["^", + "https://%{SERVER_NAME}%{REQUEST_URI}", + "[L,QSA,R=permanent]"]) + + self.config.save() + + try: + self.config.enhance("certbot.demo", "redirect") + except errors.PluginEnhancementAlreadyPresent: + args_paths = self.config.parser.find_dir( + "RewriteRule", None, http_vhost.path, False) + arg_vals = [self.config.aug.get(x) for x in args_paths] + self.assertEqual(arg_vals, constants.REWRITE_HTTPS_ARGS) + + def test_redirect_with_conflict(self): self.config.parser.modules.add("rewrite_module") ssl_vh = obj.VirtualHost( @@ -1134,7 +1165,7 @@ class MultipleVhostsTest(util.ApacheTest): http_vhost.path, "RewriteRule", ["^", "https://%{SERVER_NAME}%{REQUEST_URI}", - "[L,QSA,R=permanent]"]) + "[L,NE,R=permanent]"]) self.config.save() ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0]) @@ -1145,7 +1176,7 @@ class MultipleVhostsTest(util.ApacheTest): conf_text = open(ssl_vhost.filep).read() commented_rewrite_rule = ("# RewriteRule ^ " "https://%{SERVER_NAME}%{REQUEST_URI} " - "[L,QSA,R=permanent]") + "[L,NE,R=permanent]") self.assertTrue(commented_rewrite_rule in conf_text) mock_get_utility().add_message.assert_called_once_with(mock.ANY, @@ -1164,7 +1195,7 @@ class MultipleVhostsTest(util.ApacheTest): "RewriteCond", ["%{DOCUMENT_ROOT}/%{REQUEST_FILENAME}", "!-f"]) self.config.parser.add_dir( http_vhost.path, "RewriteRule", - ["^(.*)$", "b://u%{REQUEST_URI}", "[P,QSA,L]"]) + ["^(.*)$", "b://u%{REQUEST_URI}", "[P,NE,L]"]) # Add a chunk that should be commented out. self.config.parser.add_dir(http_vhost.path, @@ -1175,7 +1206,7 @@ class MultipleVhostsTest(util.ApacheTest): http_vhost.path, "RewriteRule", ["^", "https://%{SERVER_NAME}%{REQUEST_URI}", - "[L,QSA,R=permanent]"]) + "[L,NE,R=permanent]"]) self.config.save() @@ -1186,13 +1217,13 @@ class MultipleVhostsTest(util.ApacheTest): not_commented_cond1 = ("RewriteCond " "%{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f") not_commented_rewrite_rule = ("RewriteRule " - "^(.*)$ b://u%{REQUEST_URI} [P,QSA,L]") + "^(.*)$ b://u%{REQUEST_URI} [P,NE,L]") commented_cond1 = "# RewriteCond %{HTTPS} !=on" commented_cond2 = "# RewriteCond %{HTTPS} !^$" commented_rewrite_rule = ("# RewriteRule ^ " "https://%{SERVER_NAME}%{REQUEST_URI} " - "[L,QSA,R=permanent]") + "[L,NE,R=permanent]") self.assertTrue(not_commented_cond1 in conf_line_set) self.assertTrue(not_commented_rewrite_rule in conf_line_set) From 53117b0ce0f9e781ae9a44570cfc7dc3891bb918 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 2 Mar 2017 17:27:29 -0800 Subject: [PATCH 13/27] Remove UnexpectedUpdate exceptions. (#4197) * Remove UnexpectedUpdate exceptions. These exceptions trigger when the server sends the client back an object with a field that doesn't exactly match what the client previously sent. This causes unnecessary breakage in various cases, doesn't prevent any problems, and isn't required by spec. * Back out all UnexpectedUpdate removals except registration update. --- acme/acme/client.py | 3 --- acme/acme/client_test.py | 10 ---------- certbot/client.py | 2 -- 3 files changed, 15 deletions(-) diff --git a/acme/acme/client.py b/acme/acme/client.py index ddcba7635..6c5ed79a2 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -134,8 +134,6 @@ class Client(object): # pylint: disable=too-many-instance-attributes update = regr.body if update is None else update body = messages.UpdateRegistration(**dict(update)) updated_regr = self._send_recv_regr(regr, body=body) - if updated_regr != regr: - raise errors.UnexpectedUpdate(regr) return updated_regr def deactivate_registration(self, regr): @@ -301,7 +299,6 @@ class Client(object): # pylint: disable=too-many-instance-attributes response = self.net.get(authzr.uri) updated_authzr = self._authzr_from_response( response, authzr.body.identifier, authzr.uri, authzr.new_cert_uri) - # TODO: check and raise UnexpectedUpdate return updated_authzr, response def request_issuance(self, csr, authzrs): diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index b3db21ac9..7e7ffe779 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -121,8 +121,6 @@ class ClientTest(unittest.TestCase): # TODO: split here and separate test self.response.json.return_value = self.regr.body.update( contact=()).to_json() - self.assertRaises( - errors.UnexpectedUpdate, self.client.update_registration, self.regr) def test_deactivate_account(self): self.response.headers['Location'] = self.regr.uri @@ -130,14 +128,6 @@ class ClientTest(unittest.TestCase): self.assertEqual(self.regr, self.client.deactivate_registration(self.regr)) - def test_deactivate_account_bad_registration_returned(self): - self.response.headers['Location'] = self.regr.uri - self.response.json.return_value = "some wrong registration thing" - self.assertRaises( - errors.UnexpectedUpdate, - self.client.deactivate_registration, - self.regr) - def test_query_registration(self): self.response.json.return_value = self.regr.body.to_json() self.assertEqual(self.regr, self.client.query_registration(self.regr)) diff --git a/certbot/client.py b/certbot/client.py index 95882a9fc..a342c1bf3 100644 --- a/certbot/client.py +++ b/certbot/client.py @@ -155,8 +155,6 @@ def perform_registration(acme, config): :returns: Registration Resource. :rtype: `acme.messages.RegistrationResource` - - :raises .UnexpectedUpdate: """ try: return acme.register(messages.NewRegistration.from_data(email=config.email)) From 93908a33bcdf79db297c38445cc31266ea066a31 Mon Sep 17 00:00:00 2001 From: yomna Date: Thu, 2 Mar 2017 17:28:45 -0800 Subject: [PATCH 14/27] [#3451] small changes to the standalone documentation (#4247) --- docs/using.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/using.rst b/docs/using.rst index 628043ff9..1582c5ab7 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -144,6 +144,10 @@ the ``--nginx`` flag on the commandline. Standalone ---------- +Use standalone mode to obtain a cert if you don't want to use (or don't currently have) +existing server software. The standalone plugin does not rely on any other server +software running on the machine where you obtain the cert. + To obtain a cert using a "standalone" webserver, you can use the standalone plugin by including ``certonly`` and ``--standalone`` on the command line. This plugin needs to bind to port 80 or 443 in @@ -154,10 +158,8 @@ one of the options shown below on the command line. * ``--standalone-supported-challenges http-01`` to use port 80 * ``--standalone-supported-challenges tls-sni-01`` to use port 443 -The standalone plugin does not rely on any other server software running -on the machine where you obtain the certificate. It must still be possible -for that machine to accept inbound connections from the Internet on the -specified port using each requested domain name. +It must still be possible for your machine to accept inbound connections from +the Internet on the specified port using each requested domain name. Manual ------ From 12a6e49cf11d3b7de623c6279ffbf1387328688f Mon Sep 17 00:00:00 2001 From: Blake Griffith Date: Thu, 2 Mar 2017 21:16:19 -0800 Subject: [PATCH 15/27] Remove use of sha1 (#4271) These are not security critical uses of sha1 but they should still be removed. --- acme/acme/challenges.py | 2 +- certbot/tests/crypto_util_test.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/acme/acme/challenges.py b/acme/acme/challenges.py index 3b1e90166..ac4e3d60a 100644 --- a/acme/acme/challenges.py +++ b/acme/acme/challenges.py @@ -445,7 +445,7 @@ class TLSSNI01Response(KeyAuthorizationChallengeResponse): """ # pylint: disable=protected-access sans = crypto_util._pyopenssl_cert_or_req_san(cert) - logger.debug('Certificate %s. SANs: %s', cert.digest('sha1'), sans) + logger.debug('Certificate %s. SANs: %s', cert.digest('sha256'), sans) return self.z_domain.decode() in sans def simple_verify(self, chall, domain, account_public_key, diff --git a/certbot/tests/crypto_util_test.py b/certbot/tests/crypto_util_test.py index a580574a4..946e772c1 100644 --- a/certbot/tests/crypto_util_test.py +++ b/certbot/tests/crypto_util_test.py @@ -336,8 +336,8 @@ class CertLoaderTest(unittest.TestCase): from certbot.crypto_util import pyopenssl_load_certificate cert, file_type = pyopenssl_load_certificate(CERT) - self.assertEqual(cert.digest('sha1'), - OpenSSL.crypto.load_certificate(file_type, CERT).digest('sha1')) + self.assertEqual(cert.digest('sha256'), + OpenSSL.crypto.load_certificate(file_type, CERT).digest('sha256')) def test_load_invalid_cert(self): from certbot.crypto_util import pyopenssl_load_certificate From 1507b6b7316b0e0ba5aabc56cbaf64904ae15d59 Mon Sep 17 00:00:00 2001 From: yonjah Date: Sat, 4 Mar 2017 00:34:30 +0800 Subject: [PATCH 16/27] Added documentation about renew exit status #Fixes #4090 (#4234) * Added documentation about renew exit status #Fixes #4090 * recommend using post-hook instead of renew-hook --- docs/using.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/using.rst b/docs/using.rst index 1582c5ab7..104c688e7 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -411,6 +411,13 @@ Certbot is working hard to improve the renewal process, and we apologize for any inconvenience you encounter in integrating these commands into your individual environment. +.. note:: ``certbot renew`` exit status will only be 1 if a renewal attempt failed. + This means ``certbot renew`` exit status will be 0 if no cert needs to be updated. + If you write a custom script and expect to run a command only after a cert was actually renewed + you will need to use the ``--post-hook`` since the exit status will be 0 both on successful renewal + and when renewal is not necessary. + + Modifying the Renewal Configuration File ---------------------------------------- From 80326511bb1f0f7392f2c5bd259a74e3c6c0c195 Mon Sep 17 00:00:00 2001 From: Alex Bowers Date: Fri, 3 Mar 2017 18:28:05 +0000 Subject: [PATCH 17/27] Improve error reporting for hooks (#4235) * Improve error reporting for hooks * My bad * Whitespace. --- certbot/hooks.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/certbot/hooks.py b/certbot/hooks.py index 5cda478cc..ada3d3aaa 100644 --- a/certbot/hooks.py +++ b/certbot/hooks.py @@ -44,8 +44,12 @@ def validate_hook(shell_cmd, hook_name): cmd = shell_cmd.split(None, 1)[0] if not _prog(cmd): path = os.environ["PATH"] - msg = "Unable to find {2}-hook command {0} in the PATH.\n(PATH is {1})".format( - cmd, path, hook_name) + if os.path.exists(cmd): + msg = "{1}-hook command {0} exists, but is not executable.".format(cmd, hook_name) + else: + msg = "Unable to find {2}-hook command {0} in the PATH.\n(PATH is {1})".format( + cmd, path, hook_name) + raise errors.HookCommandNotFound(msg) def pre_hook(config): From ea578870da558c86546fb6b9b34d95ffea6f12a3 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Fri, 3 Mar 2017 10:37:31 -0800 Subject: [PATCH 18/27] ipdb can now be run without pip installing. (#4257) --- docs/contributing.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 5f939e947..de9904936 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -69,10 +69,8 @@ either in the same directory as ``foo.py`` or in the ``tests`` subdirectory (if there isn't, make one). While you are working on your code and tests, run ``python foo_test.py`` to run the relevant tests. -For debugging, we recommend running ``pip install ipdb`` and putting -``import ipdb; ipdb.set_trace()`` statements inside the source -code. Alternatively, you can use Python's standard library `pdb`, -but you won't get TAB completion. +For debugging, we recommend putting +``import ipdb; ipdb.set_trace()`` statements inside the source code. Once you are done with your code changes, and the tests in ``foo_test.py`` pass, run all of the unittests for Certbot with ``tox -e py27`` (this uses Python From 2862ade0b12c3970ba36c9cefa8f4b89b7a82e0f Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Fri, 3 Mar 2017 13:44:12 -0500 Subject: [PATCH 19/27] docs(ciphers): newer keylength.com recommendations (#4266) --- docs/ciphers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ciphers.rst b/docs/ciphers.rst index 31ce45963..1b320cdf9 100644 --- a/docs/ciphers.rst +++ b/docs/ciphers.rst @@ -255,7 +255,7 @@ I have access to an English-language summary of the recommendations. Keylength.com ~~~~~~~~~~~~~ -Damien Giry collects recommendations by academic researchers and standards organizations about keylengths for particular cryptoperiods, years, or security levels. The keylength recommendations of the various sources are summarized in a chart. This site has been updated over time and includes expert guidance from eight sources published between 2000 and 2015. +Damien Giry collects recommendations by academic researchers and standards organizations about keylengths for particular cryptoperiods, years, or security levels. The keylength recommendations of the various sources are summarized in a chart. This site has been updated over time and includes expert guidance from eight sources published between 2000 and 2017. http://www.keylength.com/ From 4a2582dda4f4e9ff0090179eb10752377cdd47e9 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 6 Mar 2017 17:31:28 -0800 Subject: [PATCH 20/27] Remove broken known issues link (#4294) --- docs/contributing.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index de9904936..e05c302b8 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -283,8 +283,7 @@ Steps: including coverage. The ``--skip-missing-interpreters`` argument ignores missing versions of Python needed for running the tests. Fix any errors. 5. If your code touches communication with an ACME server/Boulder, you - should run the integration tests, see `integration`_. See `Known Issues`_ - for some common failures that have nothing to do with your code. + should run the integration tests, see `integration`_. 6. Submit the PR. 7. Did your tests pass on Travis? If they didn't, fix any errors. From 82736e21d4966f2c68f2d3dfcd88856580af55bf Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 6 Mar 2017 17:32:49 -0800 Subject: [PATCH 21/27] Improve path_surgery warning (#4293) Stops output like: Failed to find certbot.log in PATH: ... renew-hook command certbot.log exists, but is not executable. --- certbot/plugins/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot/plugins/util.py b/certbot/plugins/util.py index e45c26735..f0e2f4c5b 100644 --- a/certbot/plugins/util.py +++ b/certbot/plugins/util.py @@ -33,6 +33,6 @@ def path_surgery(cmd): return True else: expanded = " expanded" if any(added) else "" - logger.warning("Failed to find %s in%s PATH: %s", cmd, + logger.warning("Failed to find executable %s in%s PATH: %s", cmd, expanded, path) return False From 5d75906b2761a4aefa908afe0a252fe5759067fb Mon Sep 17 00:00:00 2001 From: sedrubal Date: Tue, 7 Mar 2017 02:34:03 +0100 Subject: [PATCH 22/27] Fix print for python3 in certbot-auto (#4263) Use printfunction from __future__ in order to get letsencrypt installed on a python3 only system. --- letsencrypt-auto-source/letsencrypt-auto | 7 +++++-- letsencrypt-auto-source/pieces/fetch.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index cc248a36a..35c7a530c 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -1093,6 +1093,9 @@ else On failure, return non-zero. """ + +from __future__ import print_function + from distutils.version import LooseVersion from json import loads from os import devnull, environ @@ -1194,12 +1197,12 @@ def main(): flag = argv[1] try: if flag == '--latest-version': - print latest_stable_version(get) + print(latest_stable_version(get)) elif flag == '--le-auto-script': tag = argv[2] verified_new_le_auto(get, tag, dirname(argv[0])) except ExpectedError as exc: - print exc.args[0], exc.args[1] + print(exc.args[0], exc.args[1]) return 1 else: return 0 diff --git a/letsencrypt-auto-source/pieces/fetch.py b/letsencrypt-auto-source/pieces/fetch.py index 365a5a36a..e7ebb9e0a 100644 --- a/letsencrypt-auto-source/pieces/fetch.py +++ b/letsencrypt-auto-source/pieces/fetch.py @@ -10,6 +10,9 @@ On failure, return non-zero. """ + +from __future__ import print_function + from distutils.version import LooseVersion from json import loads from os import devnull, environ @@ -111,12 +114,12 @@ def main(): flag = argv[1] try: if flag == '--latest-version': - print latest_stable_version(get) + print(latest_stable_version(get)) elif flag == '--le-auto-script': tag = argv[2] verified_new_le_auto(get, tag, dirname(argv[0])) except ExpectedError as exc: - print exc.args[0], exc.args[1] + print(exc.args[0], exc.args[1]) return 1 else: return 0 From 6669b95a4e4a805aee274a45c5c19ba275ff34a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B8=89?= Date: Wed, 8 Mar 2017 03:19:55 +0800 Subject: [PATCH 23/27] Updated the deprecated arguments (#4306) --- docs/using.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/using.rst b/docs/using.rst index 104c688e7..e579a70b7 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -155,8 +155,8 @@ order to perform domain validation, so you may need to stop your existing webserver. To control which port the plugin uses, include one of the options shown below on the command line. - * ``--standalone-supported-challenges http-01`` to use port 80 - * ``--standalone-supported-challenges tls-sni-01`` to use port 443 + * ``--preferred-challenges http-01`` to use port 80 + * ``--preferred-challenges tls-sni-01`` to use port 443 It must still be possible for your machine to accept inbound connections from the Internet on the specified port using each requested domain name. From 8f101034960ffc1e47879314585898efda234e60 Mon Sep 17 00:00:00 2001 From: Erik Rose Date: Wed, 8 Mar 2017 20:10:12 -0500 Subject: [PATCH 24/27] Make argparse dependency unconditional. (#2249) The primary motivation is to avoid a branch, giving bugs one fewer place to hide. But, as a bonus, more people get a more bugfixed version of argparse. (To use the example from the argparse docs, people stuck on Python 3.2.3 can get bugfixes that made it into the stdlib only in 3.2.4.) --- acme/setup.py | 3 +-- setup.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index f169f59a7..48210108a 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -8,6 +8,7 @@ version = '0.13.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ + 'argparse', # load_pem_private/public_key (>=0.6) # rsa_recover_prime_factors (>=0.8) 'cryptography>=0.8', @@ -30,8 +31,6 @@ install_requires = [ # Keep in sync with conditional_requirements.py. if sys.version_info < (2, 7): install_requires.extend([ - # only some distros recognize stdlib argparse as already satisfying - 'argparse', 'mock<1.1.0', ]) else: diff --git a/setup.py b/setup.py index 0c47b973f..8ce4c51c9 100644 --- a/setup.py +++ b/setup.py @@ -36,6 +36,7 @@ version = meta['version'] # https://github.com/pypa/pip/issues/988 for more info. install_requires = [ 'acme=={0}'.format(version), + 'argparse', # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but # saying so here causes a runtime error against our temporary fork of 0.9.3 # in which we added 2.6 support (see #2243), so we relax the requirement. @@ -58,8 +59,6 @@ install_requires = [ # Keep in sync with conditional_requirements.py. if sys.version_info < (2, 7): install_requires.extend([ - # only some distros recognize stdlib argparse as already satisfying - 'argparse', 'mock<1.1.0', ]) else: From 662c323b55711f0f32a99cb32e846ab6961dce2d Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 10 Mar 2017 10:58:03 -0800 Subject: [PATCH 25/27] Build wheels correctly for Python 2.6 (#4313) * stop conditionally pinning mock version in acme * stop conditionally pinning mock version in certbot * stop conditionally pinning mock version in apache * stop conditionally pinning mock version in nginx * stop conditionally pinning mock version in letshelp * stop conditionally pinning mock version in compatibility-test --- acme/setup.py | 10 +--------- certbot-apache/setup.py | 6 +----- certbot-compatibility-test/setup.py | 6 +----- certbot-nginx/setup.py | 6 +----- letshelp-certbot/setup.py | 5 +---- setup.py | 10 +--------- 6 files changed, 6 insertions(+), 37 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index 48210108a..df9937032 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -13,6 +13,7 @@ install_requires = [ # rsa_recover_prime_factors (>=0.8) 'cryptography>=0.8', # Connection.set_tlsext_host_name (>=0.13) + 'mock', 'PyOpenSSL>=0.13', 'pyrfc3339', 'pytz', @@ -27,15 +28,6 @@ install_requires = [ 'six', ] -# env markers in extras_require cause problems with older pip: #517 -# Keep in sync with conditional_requirements.py. -if sys.version_info < (2, 7): - install_requires.extend([ - 'mock<1.1.0', - ]) -else: - install_requires.append('mock') - dev_extras = [ 'nose', 'tox', diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 56a48abc6..db8cb11db 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -10,6 +10,7 @@ version = '0.13.0.dev0' install_requires = [ 'acme=={0}'.format(version), 'certbot=={0}'.format(version), + 'mock', 'python-augeas', # For pkg_resources. >=1.0 so pip resolves it to a version cryptography # will tolerate; see #2599: @@ -18,11 +19,6 @@ install_requires = [ 'zope.interface', ] -if sys.version_info < (2, 7): - install_requires.append('mock<1.1.0') -else: - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 73d3b704b..238d7a2d5 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -9,16 +9,12 @@ version = '0.13.0.dev0' install_requires = [ 'certbot', 'certbot-apache', + 'mock', 'six', 'requests', 'zope.interface', ] -if sys.version_info < (2, 7): - install_requires.append('mock<1.1.0') -else: - install_requires.append('mock') - if sys.version_info < (2, 7, 9): # For secure SSL connexion with Python 2.7 (InsecurePlatformWarning) install_requires.append('ndg-httpsclient') diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 24c2564b9..bdc45b9b4 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -10,6 +10,7 @@ version = '0.13.0.dev0' install_requires = [ 'acme=={0}'.format(version), 'certbot=={0}'.format(version), + 'mock', 'PyOpenSSL', 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary? # For pkg_resources. >=1.0 so pip resolves it to a version cryptography @@ -18,11 +19,6 @@ install_requires = [ 'zope.interface', ] -if sys.version_info < (2, 7): - install_requires.append('mock<1.1.0') -else: - install_requires.append('mock') - docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 'sphinx_rtd_theme', diff --git a/letshelp-certbot/setup.py b/letshelp-certbot/setup.py index b616da688..b26ab41fe 100644 --- a/letshelp-certbot/setup.py +++ b/letshelp-certbot/setup.py @@ -7,12 +7,9 @@ from setuptools import find_packages version = '0.7.0.dev0' install_requires = [ + 'mock', 'setuptools', # pkg_resources ] -if sys.version_info < (2, 7): - install_requires.append('mock<1.1.0') -else: - install_requires.append('mock') docs_extras = [ 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags diff --git a/setup.py b/setup.py index 8ce4c51c9..0e8d19a22 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ install_requires = [ 'ConfigArgParse>=0.9.3', 'configobj', 'cryptography>=0.7', # load_pem_x509_certificate + 'mock', 'parsedatetime>=1.3', # Calendar.parseDT 'PyOpenSSL', 'pyrfc3339', @@ -55,15 +56,6 @@ install_requires = [ 'zope.interface', ] -# env markers in extras_require cause problems with older pip: #517 -# Keep in sync with conditional_requirements.py. -if sys.version_info < (2, 7): - install_requires.extend([ - 'mock<1.1.0', - ]) -else: - install_requires.append('mock') - dev_extras = [ # Pin astroid==1.3.5, pylint==1.4.2 as a workaround for #289 'astroid==1.3.5', From 91f4b2b571d0ad3b0b09d150206dce2c8e9b9b0d Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 10 Mar 2017 17:27:09 -0800 Subject: [PATCH 26/27] Improve macOS contributor instructions (#4327) * remove instructions about removed Vagrantfile * rewrite docker instructions * say where docker-compose can be run * give better intro for macOS devs * prompt people for permission to install OS packages * reword awkward sentence * Change WORKDIR to /opt/certbot/src This change is OK because all paths used in Dockerfile-dev are absolute paths. * remove 'cd src' instructions for Dockerfile-dev * Improve docker-compose testing instructions --- Dockerfile-dev | 2 +- docs/contributing.rst | 79 +++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/Dockerfile-dev b/Dockerfile-dev index dbb45f75e..2a89b2ff5 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -13,7 +13,7 @@ EXPOSE 443 # authenticator and text mode only?) VOLUME /etc/letsencrypt /var/lib/letsencrypt -WORKDIR /opt/certbot +WORKDIR /opt/certbot/src # no need to mkdir anything: # https://docs.docker.com/reference/builder/#copy diff --git a/docs/contributing.rst b/docs/contributing.rst index e05c302b8..5cdf86147 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -14,15 +14,24 @@ Getting Started Running a local copy of the client ---------------------------------- -Running the client in developer mode from your local tree is a little -different than running ``certbot-auto``. To get set up, do these things -once: +Running the client in developer mode from your local tree is a little different +than running Certbot as a user. To get set up, clone our git repository by +running: .. code-block:: shell git clone https://github.com/certbot/certbot + +If you're on macOS, we recommend you skip the rest of this section and instead +run Certbot in Docker. You can find instructions for how to do this :ref:`here +`. If you're running on Linux, you can run the following commands to +install dependencies and set up a virtual environment where you can run +Certbot. You only need to do this once. + +.. code-block:: shell + cd certbot - ./letsencrypt-auto-source/letsencrypt-auto --os-packages-only + ./certbot-auto --os-packages-only ./tools/venv.sh Then in each shell where you're working on the client, do: @@ -343,56 +352,36 @@ This should generate documentation in the ``docs/_build/html`` directory. -Other methods for running the client -==================================== +.. _docker: -Vagrant -------- +Running the client with Docker +============================== -If you are a Vagrant user, Certbot comes with a Vagrantfile that -automates setting up a development environment in an Ubuntu 14.04 -LTS VM. To set it up, simply run ``vagrant up``. The repository is -synced to ``/vagrant``, so you can get started with: +You can use Docker Compose to quickly set up an environment for running and +testing Certbot. This is especially useful for macOS users. To install Docker +Compose, follow the instructions at https://docs.docker.com/compose/install/. -.. code-block:: shell +.. note:: Linux users can simply run ``pip install docker-compose`` to get + Docker Compose after installing Docker Engine and activating your shell as + described in the :ref:`Getting Started ` section. - vagrant ssh - cd /vagrant - sudo ./venv/bin/certbot +Now you can develop on your host machine, but run Certbot and test your changes +in Docker. When using ``docker-compose`` make sure you are inside your clone of +the Certbot repository. As an example, you can run the following command to +check for linting errors:: -Support for other Linux distributions coming soon. + docker-compose run --rm --service-ports development bash -c 'tox -e lint' -.. note:: - Unfortunately, Python distutils and, by extension, setup.py and - tox, use hard linking quite extensively. Hard linking is not - supported by the default sync filesystem in Vagrant. As a result, - all actions with these commands are *significantly slower* in - Vagrant. One potential fix is to `use NFS`_ (`related issue`_). +You can also leave a terminal open running a shell in the Docker container and +modify Certbot code in another window. The Certbot repo on your host machine is +mounted inside of the container so any changes you make immediately take +effect. To do this, run:: -.. _use NFS: http://docs.vagrantup.com/v2/synced-folders/nfs.html -.. _related issue: https://github.com/ClusterHQ/flocker/issues/516 + docker-compose run --rm --service-ports development bash +Now running the check for linting errors described above is as easy as:: -Docker ------- - -OSX users will probably find it easiest to set up a Docker container for -development. Certbot comes with a Dockerfile (``Dockerfile-dev``) -for doing so. To use Docker on OSX, install and setup docker-machine using the -instructions at https://docs.docker.com/installation/mac/. - -To build the development Docker image:: - - docker build -t certbot -f Dockerfile-dev . - -Now run tests inside the Docker image: - -.. code-block:: shell - - docker run -it certbot bash - cd src - tox -e py27 - + tox -e lint .. _prerequisites: From 0e735e360c197a1a77e97d806ff4a4a9b90a073a Mon Sep 17 00:00:00 2001 From: Amjad Mashaal Date: Sat, 11 Mar 2017 04:09:39 +0200 Subject: [PATCH 27/27] remove unnecessary whitespace from tools/release.sh --- tools/release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/release.sh b/tools/release.sh index 75a4af29c..81582cef0 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -88,9 +88,9 @@ SetVersion() { sed -i "s/^version.*/version = '$ver'/" $pkg_dir/setup.py done sed -i "s/^__version.*/__version__ = '$ver'/" certbot/__init__.py - + # interactive user input - git add -p certbot $SUBPKGS certbot-compatibility-test + git add -p certbot $SUBPKGS certbot-compatibility-test }