From 8f445a61367875e0daecfad631f1d6844e0bda5a Mon Sep 17 00:00:00 2001 From: Francois Marier Date: Sun, 30 Nov 2014 20:29:12 -0800 Subject: [PATCH 1/2] Use the right URL for the project `lets-encrypt.org` doesn't work but `letsencrypt.org` does so use that. --- EULA | 2 +- letsencrypt/client/schemata/challengeobject.json | 2 +- letsencrypt/client/schemata/jwk.json | 2 +- letsencrypt/client/schemata/responseobject.json | 2 +- letsencrypt/client/schemata/signature.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/EULA b/EULA index 70cdea4aa..3647d561e 100644 --- a/EULA +++ b/EULA @@ -2,4 +2,4 @@ This is a PREVIEW RELEASE of a client application for the Let's Encrypt certific Until publicly-trusted certificates can be issued by Let's Encrypt, this software CANNOT OBTAIN A PUBLICLY-TRUSTED CERTIFICATE FOR YOUR WEB SERVER. You should only use this program if you are a developer interested in experimenting with the ACME protocol or in helping to improve this software. If you want to configure your web site with HTTPS in the meantime, please obtain a certificate from a different authority. -For updates on the status of Let's Encrypt, please visit the Let's Encrypt home page at https://www.lets-encrypt.org/. +For updates on the status of Let's Encrypt, please visit the Let's Encrypt home page at https://www.letsencrypt.org/. diff --git a/letsencrypt/client/schemata/challengeobject.json b/letsencrypt/client/schemata/challengeobject.json index b760e246e..5641b407e 100644 --- a/letsencrypt/client/schemata/challengeobject.json +++ b/letsencrypt/client/schemata/challengeobject.json @@ -1,5 +1,5 @@ { - "id": "https://lets-encrypt.org/schema/01/challengeobject#", + "id": "https://letsencrypt.org/schema/01/challengeobject#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Subschema for an individual challenge (within challenge)", "anyOf": [ diff --git a/letsencrypt/client/schemata/jwk.json b/letsencrypt/client/schemata/jwk.json index 536585e79..b9cca8840 100644 --- a/letsencrypt/client/schemata/jwk.json +++ b/letsencrypt/client/schemata/jwk.json @@ -1,5 +1,5 @@ { - "id": "https://lets-encrypt.org/schema/01/jwk#", + "id": "https://letsencrypt.org/schema/01/jwk#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Schema for a jwk (**kty RSA/e=65537 ONLY**)", "type": "object", diff --git a/letsencrypt/client/schemata/responseobject.json b/letsencrypt/client/schemata/responseobject.json index 7e45853e6..dfb1fac28 100644 --- a/letsencrypt/client/schemata/responseobject.json +++ b/letsencrypt/client/schemata/responseobject.json @@ -1,5 +1,5 @@ { - "id": "https://lets-encrypt.org/schema/01/responseobject#", + "id": "https://letsencrypt.org/schema/01/responseobject#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Subschema for an individual challenge response (within authorizationRequest)", "anyOf": [ diff --git a/letsencrypt/client/schemata/signature.json b/letsencrypt/client/schemata/signature.json index 54828d332..e70652e7c 100644 --- a/letsencrypt/client/schemata/signature.json +++ b/letsencrypt/client/schemata/signature.json @@ -1,5 +1,5 @@ { - "id": "https://lets-encrypt.org/schema/01/signature#", + "id": "https://letsencrypt.org/schema/01/signature#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Schema for a signature (alg RS256/e=65537 or P-256 ONLY)", "type": "object", From cb9263cc4aeda68bbc13ec2ef350d882fa11a6f5 Mon Sep 17 00:00:00 2001 From: James Kasten Date: Mon, 1 Dec 2014 03:05:06 -0800 Subject: [PATCH 2/2] Random small changes --- EULA | 2 +- letsencrypt/client/apache_configurator.py | 68 +++++++++++-------- letsencrypt/client/client.py | 43 +++++++++--- .../client/recovery_contact_challenge.py | 8 ++- .../client/recovery_token_challenge.py | 7 +- 5 files changed, 86 insertions(+), 42 deletions(-) diff --git a/EULA b/EULA index 3647d561e..dd7759361 100644 --- a/EULA +++ b/EULA @@ -2,4 +2,4 @@ This is a PREVIEW RELEASE of a client application for the Let's Encrypt certific Until publicly-trusted certificates can be issued by Let's Encrypt, this software CANNOT OBTAIN A PUBLICLY-TRUSTED CERTIFICATE FOR YOUR WEB SERVER. You should only use this program if you are a developer interested in experimenting with the ACME protocol or in helping to improve this software. If you want to configure your web site with HTTPS in the meantime, please obtain a certificate from a different authority. -For updates on the status of Let's Encrypt, please visit the Let's Encrypt home page at https://www.letsencrypt.org/. +For updates on the status of Let's Encrypt, please visit the Let's Encrypt home page at https://letsencrypt.org/. diff --git a/letsencrypt/client/apache_configurator.py b/letsencrypt/client/apache_configurator.py index d7f62c125..ec772a5af 100644 --- a/letsencrypt/client/apache_configurator.py +++ b/letsencrypt/client/apache_configurator.py @@ -370,7 +370,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Checks if addr has a NameVirtualHost directive in the Apache config - :param str addr: vhost address ie. \*:443 + :param str addr: vhost address ie. *:443 :returns: Success :rtype: bool @@ -1176,26 +1176,7 @@ LogLevel warn \n\ :rtype: bool """ - # TODO: This should be written to use the process returncode - try: - proc = subprocess.Popen(['/etc/init.d/apache2', 'restart'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - text = proc.communicate() - - if proc.returncode != 0: - # Enter recovery routine... - logger.error("Configtest failed") - logger.error(text[0]) - logger.error(text[1]) - return False - - except (OSError, ValueError): - logger.fatal(("Apache Restart Failed - " - "Please Check the Configuration")) - sys.exit(1) - - return True + return apache_restart(quiet) def _add_httpd_transform(self, incl): """Add a transform to Augeas. @@ -1240,6 +1221,9 @@ LogLevel warn \n\ # Challenges Section ########################################################################### + # TODO: Change list_sni_tuple to namedtuple. Also include key within tuple. + # This allows the keys to be different for each SNI challenge + def perform(self, chall_dict): """Perform the configuration related challenge. @@ -1254,11 +1238,14 @@ LogLevel warn \n\ def dvsni_perform(self, chall_dict): """Peform a DVSNI challenge. - Composed of - list_sni_tuple: List of tuples with form (addr, r, nonce) - addr (string), r (base64 string), nonce (hex string) + chall_dict composed of: - dvsni_key: namedtuple - client.Client.Key() + list_sni_tuple: + List of tuples with form `(addr, r, nonce)` + `addr` (`string`), `r` (base64 `str`), `nonce` (hex `str`) + + dvsni_key: + :class:`client.Client.Key` :param dict chall_dict: dvsni challenge - see documentation @@ -1327,12 +1314,12 @@ LogLevel warn \n\ Result: Apache config includes virtual servers for issued challs - :param list_sni_tuple: list of tuples with the form (addr, y, nonce) - addr (string), y (byte array), nonce (hex str) - :type list_sni_tuple: list + :param list list_sni_tuple: list of tuples with the form + `(addr, y, nonce)`, where `addr` is `str`, y is `byte array`, + `nonce` is `str` :param dvsni_key: Namedtuple with file, pem - :type dvsni_key: `client.Client.Key` - namedtuple + :type dvsni_key: :class:`client.Client.Key` :param list ll_addrs: list of list of addresses to apply @@ -1447,6 +1434,29 @@ def check_ssl_loaded(): return False +def apache_restart(quiet=False): + # TODO: This should be written to use the process returncode + try: + proc = subprocess.Popen(['/etc/init.d/apache2', 'restart'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + text = proc.communicate() + + if proc.returncode != 0: + # Enter recovery routine... + logger.error("Configtest failed") + logger.error(text[0]) + logger.error(text[1]) + return False + + except (OSError, ValueError): + logger.fatal(("Apache Restart Failed - " + "Please Check the Configuration")) + sys.exit(1) + + return True + + def verify_setup(): """Verify the setup to ensure safe operating environment. diff --git a/letsencrypt/client/client.py b/letsencrypt/client/client.py index 653b4b6c6..9ff33fdab 100644 --- a/letsencrypt/client/client.py +++ b/letsencrypt/client/client.py @@ -64,10 +64,10 @@ class Client(object): try: self._validate_csr_key_cli() - except errors.LetsEncryptClientError as e: + except errors.LetsEncryptClientError as exc: # TODO: Something nice here... logger.fatal(("%s - until the programmers get their act together, " - "we are just going to exit" % str(e))) + "we are just going to exit" % str(exc))) sys.exit(1) self.server_url = "https://%s/acme/" % self.server @@ -91,8 +91,6 @@ class Client(object): if not self.config.config_test(): sys.exit(1) - self.redirect = redirect - # Display preview warning if not eula: with open('EULA') as eula_file: @@ -141,7 +139,7 @@ class Client(object): cert_file = self.install_certificate(certificate_dict, vhost) # Perform optimal config changes - self.optimize_config(vhost) + self.optimize_config(vhost, redirect) self.config.save("Completed Let's Encrypt Authentication") @@ -428,11 +426,19 @@ class Client(object): return cert_file - def optimize_config(self, vhost): - if self.redirect is None: - self.redirect = display.redirect_by_default() + def optimize_config(self, vhost, redirect): + """Optimize the configuration. - if self.redirect: + :param vhost: vhost to optimize + :type vhost: :class:`apache_configurator.VH` + + :param bool redirect: If traffic should be forwarded from HTTP to HTTPS + + """ + if redirect is None: + redirect = display.redirect_by_default() + + if redirect: self.redirect_to_ssl(vhost) self.config.restart(quiet=self.curses) @@ -447,6 +453,11 @@ class Client(object): # continue def cleanup_challenges(self, challenges): + """Cleanup configuration challenges + + :param dict challenges: challenges from a challenge message + + """ logger.info("Cleaning up challenges...") for chall in challenges: if chall["type"] in CONFIG.CONFIG_CHALLENGES: @@ -541,6 +552,12 @@ class Client(object): return True def redirect_to_ssl(self, vhost): + """Redirect all traffic from HTTP to HTTPS + + :param vhost: list of ssl_vhosts + :type vhost: :class:`apache_configurator.VH` + + """ for ssl_vh in vhost: success, redirect_vhost = self.config.enable_redirect(ssl_vh) logger.info("\nRedirect vhost: " + redirect_vhost.file + @@ -550,6 +567,14 @@ class Client(object): self.config.enable_site(redirect_vhost) def get_virtual_hosts(self, domains): + """Retrieve the appropriate virtual host for the domain + + :param list domains: Domains to find ssl vhosts for + + :returns: associated vhosts + :rtype: :class:`apache_configurator.VH` + + """ vhost = set() for name in domains: host = self.config.choose_virtual_host(name) diff --git a/letsencrypt/client/recovery_contact_challenge.py b/letsencrypt/client/recovery_contact_challenge.py index 6a4fa429e..8e9f005b3 100644 --- a/letsencrypt/client/recovery_contact_challenge.py +++ b/letsencrypt/client/recovery_contact_challenge.py @@ -1,4 +1,9 @@ -"""Recovery Contact Identifier Validation Challenge.""" +"""Recovery Contact Identifier Validation Challenge. + +NOTE: THIS CLASS IS NOT FULLY IMPLEMENTED INTO THE PROJECT +YET. + +""" import time import dialog @@ -101,7 +106,6 @@ class RecoveryContact(challenge.Challenge): return ans.startswith('y') or ans.startswith('Y') - def generate_response(self): if not self.token: return {"type": "recoveryContact"} diff --git a/letsencrypt/client/recovery_token_challenge.py b/letsencrypt/client/recovery_token_challenge.py index ff96babf9..86140c88e 100644 --- a/letsencrypt/client/recovery_token_challenge.py +++ b/letsencrypt/client/recovery_token_challenge.py @@ -1,4 +1,9 @@ -"""Recovery Token Identifier Validation Challenge.""" +"""Recovery Token Identifier Validation Challenge. + +NOTE: THIS CHALLENGE IS NOT IMPLEMENTED OR INCLUDED +IN THE PROJECT CURRENTLY + +""" import dialog from letsencrypt.client import challenge