From 1c06144e18b379b4aa1fff67cdc2242419e9092f Mon Sep 17 00:00:00 2001 From: Alex Dehnert Date: Wed, 28 Sep 2016 02:59:21 -0400 Subject: [PATCH 01/31] Mention that the domain is used to choose filename The cert filename is chosen based on the first domain listed. With certs with overlapping domains or where some domains are less canonical, it's therefore useful to put the most canonical/unique domain first. This updates the help text to inform users of this fact. --- docs/cli-help.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/cli-help.txt b/docs/cli-help.txt index 4265056ce..f0c86f85c 100644 --- a/docs/cli-help.txt +++ b/docs/cli-help.txt @@ -50,7 +50,9 @@ optional arguments: -d DOMAIN, --domains DOMAIN, --domain DOMAIN Domain names to apply. For multiple domains you can use multiple -d flags or enter a comma separated list - of domains as a parameter. (default: Ask) + of domains as a parameter. The first domain in the list + will be used to decide where to store the new certificate, + unless otherwise specified. (default: []) --cert-name CERTNAME Certificate name to apply. Only one certificate name can be used per Certbot run. To see certificate names, run 'certbot certificates'. When creating a new From 595745e04469ba3faea152a21186745e17f04cde Mon Sep 17 00:00:00 2001 From: Peter Eckersley Date: Mon, 30 Jan 2017 19:25:03 -0800 Subject: [PATCH 02/31] Clarify domain name <-> cert name docs --- certbot/cli.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/certbot/cli.py b/certbot/cli.py index 14874e63e..d70a28242 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -867,14 +867,19 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis metavar="DOMAIN", action=_DomainsAction, default=[], help="Domain names to apply. For multiple domains you can use " "multiple -d flags or enter a comma separated list of domains " - "as a parameter. (default: Ask)") + "as a parameter. (default: Ask) Note: the first provided domain " + "will be most prominent in filenames and some software user " + "interfaces") helpful.add( [None, "run", "certonly", "manage", "delete", "certificates"], "--cert-name", dest="certname", metavar="CERTNAME", default=None, - help="Certificate name to apply. Only one certificate name can be used " - "per Certbot run. To see certificate names, run 'certbot certificates'. " - "When creating a new certificate, specifies the new certificate's name.") + help="Certificate name to apply. This name is used by Certbot for housekeeping " + "and in file paths; it doesn't affect the content of the certificate itself. " + "To see certificate names, run 'certbot certificates'. " + "When creating a new certificate, specifies the new certificate's name. " + " (default: use the first of the domain names provided with -d or entered " + "interactively)") helpful.add( [None, "testing", "renew", "certonly"], "--dry-run", action="store_true", dest="dry_run", From df8b374916d2e76b2377def98a6ffcdd2a09b112 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Fri, 17 Mar 2017 13:37:47 -0700 Subject: [PATCH 03/31] Adding 'What Is a Certificate' section - adding what.rst to index.rst - Bigger link to instruction generator in intro.rst, some edits to what.rst in response to comments on What is a Certificate? section first draft #4370 - Responding to St_Ranger's comment on 4370 - Edits to using.rst related to --expand - Initial edit pass through challenges.rst - Edits to what.rst and challenges.rst to resolve #3664 and #4153 - Incorpoprating feedback from #4370 - Finally going after those last few comments before the restructuring of the plugin stuff (coming soon) - Fixing --expand example in using.rst and adding to Apache/NGINX bullet in challenges.rst --- docs/challenges.rst | 210 ++++++++++++++------------------------------ docs/index.rst | 1 + docs/intro.rst | 3 + docs/using.rst | 24 ++++- docs/what.rst | 31 +++++++ 5 files changed, 125 insertions(+), 144 deletions(-) create mode 100644 docs/what.rst diff --git a/docs/challenges.rst b/docs/challenges.rst index c00cd3bdf..fa0a6ca58 100644 --- a/docs/challenges.rst +++ b/docs/challenges.rst @@ -1,159 +1,85 @@ Challenges ========== -Digital certificates can only be issued to people who are entitled to them. For example, assuming you don't run google.com, you're not entitled to a certificate for it. Nor is someone else entitled to receive a certificate for your web site. +To receive a certificate from Let's Encrypt certificate authority (CA), you must pass a *challenge* to +prove you control each of the domain names that will be listed in the certificate. A challenge is one of +three tasks that only someone who controls the domain should be able to accomplish: -In order to receive a certificate from Let's Encrypt certificate authority (CA), you have to prove your control over each of the domain names that will be listed in the certificate. You can do so by making certain publicly-visible changes, proving that the person who's requested a particular certificate is the same person who controls the site(s) that the certificate will refer to. +* Posting a specified file in a specified location on a web site (the HTTP-01 challenge) +* Offering a specified temporary certificate on a web site (the TLS-SNI-01 challenge) +* Posting a specified DNS record in the domain name system (the DNS-01 challenge) -Let’s Encrypt specifies three different ways to prove your control over a domain (each of which Certbot may be able to do for you). These are called "challenges," because you are being challenged to perform tasks that only someone who controls the domain should be able to accomplish. +It’s possible to complete each type of challenge *automatically* (Certbot directly makes the necessary +changes itself, or runs another program that does so), or *manually* (Certbot tells you to make a +certain change, and you edit a configuration file of some kind in order to accomplish it). Certbot's +design favors performing challenges automatically, and this is the normal case for most users of Certbot. -When you use Certbot, it will attempt to help you prove control over your domains automatically in a way that's acceptable to the CA. Especially if this doesn't work the way you expected, it can be helpful to understand what Certbot is trying to do in each case. +Some plugins offer an *authenticator*, meaning that they can satisfy challenges: -The three ways to prove your control over a domain for the Let’s Encrypt CA are: +* Apache plugin: (TLS-SNI-01) Tries to edit your Apache configuration files to temporarily serve + a Certbot-generated certificate for a specified name. Use the Apache plugin when you're running + Certbot on a web server with Apache listening on port 443. +* NGINX plugin: (TLS-SNI-01) Tries to edit your NGINX configuration files to temporarily serve a + Certbot-generated certificate for a specified name. Use the NGINX plugin when you're running + Certbot on a web server with NGINX listening on port 443. +* Webroot plugin: (HTTP-01) Tries to place a file where it can be served over HTTP on port 80 by a + web server running on your system. Use the Webroot plugin when you're running Certbot on + a web server with any server application listening on port 80 serving files from a folder on disk in response. +* Standalone plugin: (TLS-SNI-01 or HTTP-01) Tries to run a temporary web server listening on either HTTP on + port 80 (for HTTP-01) or HTTPS on port 443 (for TLS-SNI-01). Use the Standalone plugin if no existing program + is listening to these ports. Choose TLS-SNI-01 or HTTP-01 using the `--preferred-challenges` option. +* Manual plugin: (DNS-01 or HTTP-01) Either tells you what changes to make to your configuration or updates + your DNS records using an external script (for DNS-01) or your webroot (for HTTP-01). Use the Manual + plugin if you have the technical knowledge to make configuration changes yourself when asked to do so. -* Posting a specified file on a web site +Tips for Challenges +------------------- +General tips: -This method is called the HTTP-01 challenge. In this challenge, the certificate authority will expect a specified file to be posted in a specified location on a web site. The file will be downloaded using an HTTP request on TCP port 80. Since part of what this challenge shows is the ability to create a file at an arbitrary location, you cannot choose a different location or port number. +* Run Certbot on your web server, not on your laptop or another server. It’s usually the easiest way to get a certificate. +* Use a tool like the DNSchecker at dnsstuff.com to check your DNS records to make sure + there are no serious errors. A DNS error can prevent a certificate authority from + issuing a certificate, even if it does not prevent your site from loading in a browser. +* If you are using Apache or NGINX plugins, make sure the configuration of your Apache or NGINX server is correct. -* Offering a specified certificate on a web site +HTTP-01 Challenge +~~~~~~~~~~~~~~~~~ -This method is called the TLS-SNI-01 challenge. In this challenge, the certificate authority will expect a specified digital certificate to be provided by the web server in response to an HTTPS request using a particular made-up domain name. The request will be made using HTTPS on TCP port 443. You cannot choose a different port number. - -This certificate is a self-signed certificate created by Certbot. You use it only temporarily to prove your control over a domain name. It’s not the same as the certificate for your site that will later be issued by Let's Encrypt once you've proven that you control the site. - -* Posting a specified DNS record in the domain name system - -This method is called the DNS-01 challenge. In this challenge, the certificate authority will expect a specified DNS record to be present in your DNS zone when queried for. The record will be a TXT record for a specific subdomain of the name you're proving your control over. - -For each kind of challenge, the challenge can potentially be completed *automatically* (Certbot directly makes the necessary changes itself, or runs another program that does so), or *manually* (Certbot tells you to make a certain change, and you edit a configuration file of some kind in order to accomplish it). Certbot's design emphasizes performing challenges *automatically*, and this is the normal case for most uses of Certbot. - -Some Certbot *plugins* offer the functionality of an *authenticator*, which simply means that they can satisfy challenges. Different plugins can satisfy different kinds of challenges, as follows: - -apache plugin: Can only use TLS-SNI-01. Tries to edit your Apache configuration files in order to temporarily serve a specified Certbot-generated certificate for a specified name. This can work when you're running Certbot on a web server with an existing installation of Apache that is able to listen on port 443. This makes certain assumptions about your Apache configuration. - -nginx plugin: Can only use TLS-SNI-01. Tries to edit your nginx configuration files in order to temporarily serve a specified Certbot-generated certificate for a specified name. This can work when you're running Certbot on a web server with an existing installation of nginx that is able to listen on port 443. This makes certain assumptions about your nginx configuration. - -webroot plugin: Can only use HTTP-01. Tries to place a file into an appropriate place in order for that file to be served over HTTP on port 80 by an existing web server running on your system. This can work when you're running Certbot on a web server with any existing server application that already listens to web requests on port 80, and that serves files from disk in response. - -standalone plugin: Can use either TLS-SNI-01 or HTTP-01. (You can choose with the `--preferred-challenges` option.) Tries to run its own temporary web server which will speak either HTTP on port 80 (for HTTP-01) or HTTPS on port 443 (for TLS-SNI-01). This can work if either of these ports is free to receive incoming connections at the moment that you run Certbot, because there's no existing program listening to them or because you've temporarily shut down any server application that was listening to them. - -manual plugin: Can use either DNS-01 or HTTP-01. May tell you what changes you are expected to make to your configuration. Or, using an external script, can update your DNS records (for DNS-01) or your webroot (for HTTP-01). This can work if you have appropriate technical knowledge of how to make these kinds of changes yourself when asked to do so. Note that this will prevent automated renewal of your certificate using `certbot renew`. [Can manual also use TLS-SNI-01??] - - -Common problems with passing different challenges - -HTTP-01 challenge: -* (With webroot plugin) You aren't running Certbot on your web server - - Most people should install and run Certbot on their web server hosting their website, not on their laptops or some other computer. While you can use Certbot in manual mode on a laptop and then separately set up the appropriate files on your webserver, it's not likely to be the most convenient way to get a certificate for most users. - -* A domain name you're requesting a certificate for isn't correctly pointed at that web server - - In most cases, every name you're requesting a certificate for should already exist and be pointed to the public IP address of the server where you're requesting that certificate. (Some alternatives exist for complex network configurations, but they're the exception rather than the rule.) - -* A firewall is blocking access to port 80 - - The certificate authority needs to be able to connect to port 80 of your server in order to confirm that you satisfied the HTTP-01 challenge. So that needs to be publicly reachable from the Internet, and not blocked by a router or firewall. - -* (With webroot plugin) You specified the webroot directory incorrectly - - If you used `--webroot`, you need to tell Certbot where it can put - files in order to have them served by your existing web server. - If you said your webroot for example.com was /var/www/example.com, - then a file placed in /var/www/example.com/.well-known/acme-challenge/testfile should appear on - your web site at `http://example.com/.well-known/acme-challenge/testfile` (which you can test using a web browser). (A redirection to HTTPS +* Make sure the domain name exists and is already pointed to the public IP address of the server where + you’re requesting the certificate. +* Make sure port 80 is open, publicly reachable from the Internet, and not blocked by a router or firewall. +* When using the Webroot plugin or the manual plugin, make sure the the webroot directory exists and that you + specify it properly. If you set the webroot directory for example.com to `/var/www/example.com` + then a file placed in `/var/www/example.com/.well-known/acme-challenge/testfile` should appear on + your web site at `http://example.com/.well-known/acme-challenge/testfile` (A redirection to HTTPS is OK here and should not stop the challenge from working.) +* In some web server configurations, all pages are dynamically generated by some kind of framework, + usually using a database backend. In this case, there might not be a particular directory + from which the web server can serve filesdirectly. Using the Webroot plugin in this case + requires making a change to your web server configuration first. +* Make sure your web server serves files properly from the directory where the challenge + file is placed (e. g. `/.well-known/acme-challenge`) to the expected location on the + website without adding a header or footer. +* When using the Standalone plugin, make sure another program is not already listening to port 80 on the server. +* When using the Webroot plugin, make sure there is a web server listening on port 80. - Note that you should *not* specify the .well-known/acme-challenge directory itself. Instead, you should specify the top level directory that web content is served from. +TLS-SNI-01 Challenge +~~~~~~~~~~~~~~~~~~~~ -* (With webroot plugin) You don't have a webroot directory at all +* The TLS-SNI-01 challenge doesn’t work with content delivery networks (CDNs) + like CloudFlare and Akamai because the domain name is pointed at the CDN, not directly at your server. +* Make sure port 443 is open, publicly reachable from the Internet, and not blocked by a router or firewall. +* When using the Apache plugin, make sure you are running Apache and no other web server on port 443. +* When using the NGINX plugin, make sure you are running NGINX and no other web server on port 443. +* With either the Apache or NGINX plugin, certbot modifies your web server configuration. If you get + an installation error then you have received a certificate but the plugin was unable to modify + your web server configuration, meaning that you'll have to install the certificate manually. + In that case, please file a bug to help us improve certbot! +* When using the Standalone plugin, make sure another program is not already listening to port 443 on the server. - In some web server configurations, all pages are dynamically generated by some kind of framework, usually using a database backend. In this case, there might not be a particular directory that files can be directly served from by the existing web server application. Using the webroot plugin in this case requires making a change to your web server configuration first. +DNS-01 Challenge +~~~~~~~~~~~~~~~~ -* (With manual plugin) You updated the webroot directory incorrectly +* When using the manual plugin, make sure your DNS records are correctly updated; + you must be able to make appropriate changes to your DNS zone in order to pass the challenge. - If you used `--manual`, you need to know where you can put files in order to have them served by your existing web server. If you think your webroot for example.com is /var/www/example.com, then a file placed in /var/www/example.com/.well-known/acme-challenge/testfile should appear on - your web site at `http://example.com/.well-known/acme-challenge/testfile`. (A redirection to HTTPS - is OK here and should not stop the challenge from working.) You should also make sure that you don't make a typo in the name of the file when creating it. - -* Your existing web server's configuration refuses to serve files - from /.well-known/acme-challenge, or doesn't serve them at the - /.well-known/acme-challenge location on your site, or serves them - with a header or footer, or serves them with an unusual MIME type. - -* (With standalone plugin) - You tried to use `--standalone` when there was already some other - program on your server listening to port 80 - -* (With webroot plugin) - You tried to use `--webroot` when you don't have an existing web - server listening on port 80 - -* Your DNS records aren't valid - Try checking your DNS records with a tool like the DNSchecker at - http://www.dnsstuff.com/ to make sure there are no serious errors. - Sometimes a DNS error still allows your site to load in a web - browser, but prevents the certificate authority from issuing a - certificate. - -TLS-SNI-01 challenge: -* You aren't running Certbot on your web server - - Most people should install and run Certbot on their web server hosting their website, not on their laptops or some other computer. While you can use Certbot in manual mode on a laptop and then separately set up the appropriate files on your webserver, it's not likely to be the most convenient way to get a certificate for most users. - -* A domain name you're requesting a certificate for isn't correctly - pointed at that web server - - In most cases, every name you're requesting a certificate for should - already exist and be pointed to the server where you're requesting - that certificate. (Some alternatives exist for complex network - configurations, but they're the exception rather than the rule.) - -* You're using a content delivery network (CDN) - - TLS-SNI-01 doesn't work with CDNs (like CloudFlare and Akamai). You - have to use a different challenge type. (This is a special case of - the previous problem: the domain name is pointed at the CDN, not - directly at your server.) - -* A firewall is blocking access to port 443 - - The certificate authority needs to be able to connect to port 443 of - your server in order to confirm that you satisfied the TLS-SNI-01 - challenge. So that needs to be publicly reachable from the Internet, - and not blocked by a router or firewall. - -* (With apache plugin) - Certbot thinks you're running Apache, but you aren't running it, or - you're running a different server of some kind on port 443 - -* (With nginx plugin) - Certbot thinks you're running nginx, but you aren't running it, or - you're running a different server of some kind on port 443 - -* (With apache or nginx plugin) - Certbot doesn't know how to modify your web server configuration correctly - -* (With standalone plugin) - You tried to use `--standalone` when there was already some other - program on your server listening to port 443 - -* Your DNS records aren't valid - Try checking your DNS records with a tool like the DNSchecker at - http://www.dnsstuff.com/ to make sure there are no serious errors. - Sometimes a DNS error still allows your site to load in a web - browser, but prevents the certificate authority from issuing a - certificate. - -DNS-01 challenge: - -* (With manual plugin) Your DNS records weren't correctly updated. - You need to be able to make appropriate changes to your DNS zone - in order to pass the challenge. - -* Your DNS records aren't valid. - Try checking your DNS records with a tool like the DNSchecker at - http://www.dnsstuff.com/ to make sure there are no serious errors. - Sometimes a DNS error still allows your site to load in a web - browser, but prevents the certificate authority from issuing a - certificate. diff --git a/docs/index.rst b/docs/index.rst index 746080864..17cde1adf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,6 +5,7 @@ Welcome to the Certbot documentation! :maxdepth: 2 intro + what install using contributing diff --git a/docs/intro.rst b/docs/intro.rst index 90c3761ec..2d4abdc2d 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -2,6 +2,9 @@ Introduction ===================== +.. note:: + To get started quickly, use the `interactive installation guide `_. + .. include:: ../README.rst :start-after: tag:intro-begin :end-before: tag:intro-end diff --git a/docs/using.rst b/docs/using.rst index c545dc48b..ef81f400e 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -290,6 +290,7 @@ using the ``--cert-name`` flag to specify a particular certificate for the ``run certbot certonly --cert-name example.com +.. _updating_certs: Re-creating and Updating Existing Certificates ---------------------------------------------- @@ -324,7 +325,24 @@ need to issue this command in normal circumstances. ``--expand`` tells Certbot to update an existing certificate with a new certificate that contains all of the old domains and one or more additional -new domains. +new domains. With the ``--expand`` option, use the ``-d`` option to specify +all existing domains and one or more new domains. + +Example: + +.. code-block:: none + + certbot --expand -d existing.com example.com,newdomain.com + +If you prefer, you can specify the domains individually like this: + +.. code-block:: none + + certbot --expand -d existing.com -d example.com -d newdomain.com + +Consider using ``--cert-name`` instead of ``--expand``, as it gives more control +over which certificate is modified and it lets you remove domains as well as adding them. + ``--allow-subset-of-names`` tells Certbot to continue with certificate generation if only some of the specified domain authorizations can be obtained. This may @@ -338,8 +356,10 @@ certificate counts against several rate limits that are intended to prevent abuse of the ACME protocol, as described `here `__. +.. _changing: + Changing a Certificate's Domains --------------------------------- +================================ The ``--cert-name`` flag can also be used to modify the domains a certificate contains, by specifying new domains using the ``-d`` or ``--domains`` flag. If certificate ``example.com`` diff --git a/docs/what.rst b/docs/what.rst new file mode 100644 index 000000000..3d33346c2 --- /dev/null +++ b/docs/what.rst @@ -0,0 +1,31 @@ +====================== +What is a Certificate? +====================== + +A public key or digital *certificate* (formerly called an SSL certificate) uses a public key +and a private key to enable secure communication between a client program (web browser, email client, +etc.) and a server over an encrypted SSL (secure socket layer) or TLS (transport layer security) connection. +The certificate is used both to encrypt the initial stage of communication (secure key exchange) +and to identify the server. The certificate +includes information about the key, information about the server identity, and the digital signature +of the certificate issuer. If the issuer is trusted by the software that initiates the communication, +and the signature is valid, then the key can be used to communicate securely with the server identified by +the certificate. Using a certificate is a good way to prevent "man-in-the-middle" attacks, in which +someone in between you and the server you think you are talking to is able to insert their own (harmful) +content. + +You can use Certbot to easily obtain and configure a free certificate from Let's Encrypt, a +joint project of EFF, Mozilla, and many other sponsors. + +Certificates and Lineages +========================= + +Certbot introduces the concept of a *lineage,* which is a collection of all the versions of a certificate +plus Certbot configuration information maintained for that certificate from +renewal to renewal. Whenever you renew a certificate, Certbot keeps the same configuration unless +you explicitly change it, for example by adding or removing domains. If you add domains, you can +either add them to an existing lineage or create +a new one. + +See also: +:ref:`updating_certs` From 447d3d867de03f0e8972ee5095e882fb704fc960 Mon Sep 17 00:00:00 2001 From: Noah Swartz Date: Wed, 19 Jul 2017 15:27:13 -0700 Subject: [PATCH 04/31] fix a few nits --- docs/challenges.rst | 6 +++--- docs/using.rst | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/challenges.rst b/docs/challenges.rst index fa0a6ca58..25d190147 100644 --- a/docs/challenges.rst +++ b/docs/challenges.rst @@ -2,7 +2,7 @@ Challenges ========== To receive a certificate from Let's Encrypt certificate authority (CA), you must pass a *challenge* to -prove you control each of the domain names that will be listed in the certificate. A challenge is one of +prove you control each of the domain names that will be listed in the certificate. A challenge is one of three tasks that only someone who controls the domain should be able to accomplish: * Posting a specified file in a specified location on a web site (the HTTP-01 challenge) @@ -72,8 +72,8 @@ TLS-SNI-01 Challenge * When using the Apache plugin, make sure you are running Apache and no other web server on port 443. * When using the NGINX plugin, make sure you are running NGINX and no other web server on port 443. * With either the Apache or NGINX plugin, certbot modifies your web server configuration. If you get - an installation error then you have received a certificate but the plugin was unable to modify - your web server configuration, meaning that you'll have to install the certificate manually. + an error after successfully completing the challenge, then you have received a certificate but the + plugin was unable to modify your web server configuration, meaning that you'll have to install the certificate manually. In that case, please file a bug to help us improve certbot! * When using the Standalone plugin, make sure another program is not already listening to port 443 on the server. diff --git a/docs/using.rst b/docs/using.rst index ef81f400e..aae8efbf2 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -61,7 +61,7 @@ manual_ Y N | Helps you obtain a certificate by giving you instruction =========== ==== ==== =============================================================== ============================= Under the hood, plugins use one of several ACME protocol challenges_ to -prove you control a domain. The options are http-01_ (which uses port 80), +prove you control a domain. The options are http-01_ (which uses port 80), tls-sni-01_ (port 443) and dns-01_ (requiring configuration of a DNS server on port 53, though that's often not the same machine as your webserver). A few plugins support more than one challenge type, in which case you can choose one @@ -102,7 +102,7 @@ If you're getting a certificate for many domains at once, the plugin needs to know where each domain's files are served from, which could potentially be a separate directory for each domain. When requesting a certificate for multiple domains, each domain will use the most recently -specified ``--webroot-path``. So, for instance, +specified ``--webroot-path``. So, for instance, :: @@ -332,7 +332,7 @@ Example: .. code-block:: none - certbot --expand -d existing.com example.com,newdomain.com + certbot --expand -d existing.com,example.com,newdomain.com If you prefer, you can specify the domains individually like this: @@ -823,7 +823,7 @@ changed by passing the desired number to the command line flag Certbot command-line options ============================ -Certbot supports a lot of command line options. Here's the full list, from +Certbot supports a lot of command line options. Here's the full list, from ``certbot --help all``: .. literalinclude:: cli-help.txt From c314ec047436220529b083b316cabe167a4b3aab Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 30 Jun 2017 13:58:45 -0400 Subject: [PATCH 05/31] Correct --cert-name and --domains usage. * Revert "Mention that the domain is used to choose filename" This reverts commit 1c06144e18b379b4aa1fff67cdc2242419e9092f. * Correct --cert-name and --domains usage. * Clarify which paths --domains affects --- certbot/cli.py | 12 +++++++----- docs/cli-help.txt | 4 +--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/certbot/cli.py b/certbot/cli.py index d70a28242..4c5505506 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -867,9 +867,11 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis metavar="DOMAIN", action=_DomainsAction, default=[], help="Domain names to apply. For multiple domains you can use " "multiple -d flags or enter a comma separated list of domains " - "as a parameter. (default: Ask) Note: the first provided domain " - "will be most prominent in filenames and some software user " - "interfaces") + "as a parameter. The first provided domain will be used in " + "some software user interfaces and file paths for the " + "certificate and related material unless otherwise " + "specified or you already have a certificate for the same " + "domains. (default: Ask)") helpful.add( [None, "run", "certonly", "manage", "delete", "certificates"], "--cert-name", dest="certname", @@ -878,8 +880,8 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "and in file paths; it doesn't affect the content of the certificate itself. " "To see certificate names, run 'certbot certificates'. " "When creating a new certificate, specifies the new certificate's name. " - " (default: use the first of the domain names provided with -d or entered " - "interactively)") + "(default: the first provided domain or the name of an existing " + "certificate on your system for the same domains)") helpful.add( [None, "testing", "renew", "certonly"], "--dry-run", action="store_true", dest="dry_run", diff --git a/docs/cli-help.txt b/docs/cli-help.txt index f0c86f85c..4265056ce 100644 --- a/docs/cli-help.txt +++ b/docs/cli-help.txt @@ -50,9 +50,7 @@ optional arguments: -d DOMAIN, --domains DOMAIN, --domain DOMAIN Domain names to apply. For multiple domains you can use multiple -d flags or enter a comma separated list - of domains as a parameter. The first domain in the list - will be used to decide where to store the new certificate, - unless otherwise specified. (default: []) + of domains as a parameter. (default: Ask) --cert-name CERTNAME Certificate name to apply. Only one certificate name can be used per Certbot run. To see certificate names, run 'certbot certificates'. When creating a new From 43bea2edb3ecf86b759709cd343e4acb441d8c23 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 25 Jul 2017 11:43:23 -0700 Subject: [PATCH 06/31] Explicitly advise against using easy_install. --- docs/install.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/install.rst b/docs/install.rst index e75a8b3e2..fec556ec6 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -234,11 +234,10 @@ Installing from source Installation from source is only supported for developers and the whole process is described in the :doc:`contributing`. -.. warning:: Please do **not** use ``python setup.py install`` or - ``python pip install .``. Please do **not** attempt the - installation commands as superuser/root and/or without virtual - environment, e.g. ``sudo python setup.py install``, ``sudo pip - install``, ``sudo ./venv/bin/...``. These modes of operation might - corrupt your operating system and are **not supported** by the - Certbot team! +.. warning:: Please do **not** use ``python setup.py install``, ``python pip + install .``, or ``easy_install .``. Please do **not** attempt the + installation commands as superuser/root and/or without virtual environment, + e.g. ``sudo python setup.py install``, ``sudo pip install``, ``sudo + ./venv/bin/...``. These modes of operation might corrupt your operating + system and are **not supported** by the Certbot team! From 142ced234b7561c24f2fd089090cf16b64566ae8 Mon Sep 17 00:00:00 2001 From: r5d Date: Wed, 26 Jul 2017 16:16:20 -0400 Subject: [PATCH 07/31] Add cert name in renewal error messages (#4932) (#4957) * Add cert name in renewal error messages (#4932) * certbot: Fix error message in `handle_renewal_request`. --- certbot/renewal.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/certbot/renewal.py b/certbot/renewal.py index 5c6697941..f3131c06f 100644 --- a/certbot/renewal.py +++ b/certbot/renewal.py @@ -389,14 +389,16 @@ def handle_renewal_request(config): disp = zope.component.getUtility(interfaces.IDisplay) disp.notification("Processing " + renewal_file, pause=False) lineage_config = copy.deepcopy(config) + lineagename = storage.lineagename_for_filename(renewal_file) # Note that this modifies config (to add back the configuration # elements from within the renewal configuration file). try: renewal_candidate = _reconstitute(lineage_config, renewal_file) except Exception as e: # pylint: disable=broad-except - logger.warning("Renewal configuration file %s produced an " - "unexpected error: %s. Skipping.", renewal_file, e) + logger.warning("Renewal configuration file %s (cert: %s) " + "produced an unexpected error: %s. Skipping.", + renewal_file, lineagename, e) logger.debug("Traceback was:\n%s", traceback.format_exc()) parse_failures.append(renewal_file) continue @@ -422,8 +424,9 @@ def handle_renewal_request(config): renew_skipped.append(renewal_candidate.fullchain) except Exception as e: # pylint: disable=broad-except # obtain_cert (presumably) encountered an unanticipated problem. - logger.warning("Attempting to renew cert from %s produced an " - "unexpected error: %s. Skipping.", renewal_file, e) + logger.warning("Attempting to renew cert (%s) from %s produced an " + "unexpected error: %s. Skipping.", lineagename, + renewal_file, e) logger.debug("Traceback was:\n%s", traceback.format_exc()) renew_failures.append(renewal_candidate.fullchain) From 0321c0cb4cc1515efc1f787678c50874a911d38a Mon Sep 17 00:00:00 2001 From: ohemorange Date: Wed, 26 Jul 2017 13:57:25 -0700 Subject: [PATCH 08/31] Change add_server_directives replace=True behavior to attempt to replace, but append on failure to find. (#4956) * Change add_server_directives replace=True behavior to attempt to replace, but append on failure to find. * Remove try/except around add_server_directives --- certbot-nginx/certbot_nginx/configurator.py | 14 +--- certbot-nginx/certbot_nginx/parser.py | 80 +++++++++---------- .../certbot_nginx/tests/parser_test.py | 15 ++-- 3 files changed, 53 insertions(+), 56 deletions(-) diff --git a/certbot-nginx/certbot_nginx/configurator.py b/certbot-nginx/certbot_nginx/configurator.py index 63f659453..ec657a9db 100644 --- a/certbot-nginx/certbot_nginx/configurator.py +++ b/certbot-nginx/certbot_nginx/configurator.py @@ -198,16 +198,10 @@ class NginxConfigurator(common.Plugin): cert_directives = [['\n', 'ssl_certificate', ' ', fullchain_path], ['\n', 'ssl_certificate_key', ' ', key_path]] - try: - self.parser.add_server_directives(vhost, - cert_directives, replace=True) - logger.info("Deployed Certificate to VirtualHost %s for %s", - vhost.filep, vhost.names) - except errors.MisconfigurationError as error: - logger.debug(error) - # Presumably break here so that the virtualhost is not modified - raise errors.PluginError("Cannot find a cert or key directive in {0} for {1}. " - "VirtualHost was not modified.".format(vhost.filep, vhost.names)) + self.parser.add_server_directives(vhost, + cert_directives, replace=True) + logger.info("Deployed Certificate to VirtualHost %s for %s", + vhost.filep, vhost.names) self.save_notes += ("Changed vhost at %s with addresses of %s\n" % (vhost.filep, diff --git a/certbot-nginx/certbot_nginx/parser.py b/certbot-nginx/certbot_nginx/parser.py index 4e4aa36ca..158cb9929 100644 --- a/certbot-nginx/certbot_nginx/parser.py +++ b/certbot-nginx/certbot_nginx/parser.py @@ -278,8 +278,8 @@ class NginxParser(object): This method modifies vhost to be fully consistent with the new directives. - ..note :: If replace is True, this raises a misconfiguration error - if the directive does not already exist. + ..note :: If replace is True and the directive already exists, the first + instance will be replaced. Otherwise, the directive is added. ..note :: If replace is False nothing gets added if an identical block exists already. @@ -464,8 +464,9 @@ def _add_directives(block, directives, replace): When replace=False, it's an error to try and add a directive that already exists in the config block with a conflicting value. - When replace=True, a directive with the same name MUST already exist in the - config block, and the first instance will be replaced. + When replace=True and a directive with the same name already exists in the + config block, the first instance will be replaced. Otherwise, the directive + will be added to the config block. ..todo :: Find directives that are in included files. @@ -547,49 +548,46 @@ def _add_directive(block, directive, replace): location = find_location(directive) if replace: - if location is None: - raise errors.MisconfigurationError( - 'expected directive for {0} in the Nginx ' - 'config but did not find it.'.format(directive[0])) - block[location] = directive - _comment_directive(block, location) - else: - # Append directive. Fail if the name is not a repeatable directive name, - # and there is already a copy of that directive with a different value - # in the config file. + if location is not None: + block[location] = directive + _comment_directive(block, location) + return + # Append directive. Fail if the name is not a repeatable directive name, + # and there is already a copy of that directive with a different value + # in the config file. - # handle flat include files + # handle flat include files - directive_name = directive[0] - def can_append(loc, dir_name): - """ Can we append this directive to the block? """ - return loc is None or (isinstance(dir_name, str) and dir_name in REPEATABLE_DIRECTIVES) + directive_name = directive[0] + def can_append(loc, dir_name): + """ Can we append this directive to the block? """ + return loc is None or (isinstance(dir_name, str) and dir_name in REPEATABLE_DIRECTIVES) - err_fmt = 'tried to insert directive "{0}" but found conflicting "{1}".' + err_fmt = 'tried to insert directive "{0}" but found conflicting "{1}".' - # Give a better error message about the specific directive than Nginx's "fail to restart" - if directive_name == INCLUDE: - # in theory, we might want to do this recursively, but in practice, that's really not - # necessary because we know what file we're talking about (and if we don't recurse, we - # just give a worse error message) - included_directives = _parse_ssl_options(directive[1]) + # Give a better error message about the specific directive than Nginx's "fail to restart" + if directive_name == INCLUDE: + # in theory, we might want to do this recursively, but in practice, that's really not + # necessary because we know what file we're talking about (and if we don't recurse, we + # just give a worse error message) + included_directives = _parse_ssl_options(directive[1]) - for included_directive in included_directives: - included_dir_loc = find_location(included_directive) - included_dir_name = included_directive[0] - if not is_whitespace_or_comment(included_directive) \ - and not can_append(included_dir_loc, included_dir_name): - if block[included_dir_loc] != included_directive: - raise errors.MisconfigurationError(err_fmt.format(included_directive, - block[included_dir_loc])) - else: - _comment_out_directive(block, included_dir_loc, directive[1]) + for included_directive in included_directives: + included_dir_loc = find_location(included_directive) + included_dir_name = included_directive[0] + if not is_whitespace_or_comment(included_directive) \ + and not can_append(included_dir_loc, included_dir_name): + if block[included_dir_loc] != included_directive: + raise errors.MisconfigurationError(err_fmt.format(included_directive, + block[included_dir_loc])) + else: + _comment_out_directive(block, included_dir_loc, directive[1]) - if can_append(location, directive_name): - block.append(directive) - _comment_directive(block, len(block) - 1) - elif block[location] != directive: - raise errors.MisconfigurationError(err_fmt.format(directive, block[location])) + if can_append(location, directive_name): + block.append(directive) + _comment_directive(block, len(block) - 1) + elif block[location] != directive: + raise errors.MisconfigurationError(err_fmt.format(directive, block[location])) def _apply_global_addr_ssl(addr_to_ssl, parsed_server): """Apply global sslishness information to the parsed server block diff --git a/certbot-nginx/certbot_nginx/tests/parser_test.py b/certbot-nginx/certbot_nginx/tests/parser_test.py index 3877bf5d4..e655bc3e3 100644 --- a/certbot-nginx/certbot_nginx/tests/parser_test.py +++ b/certbot-nginx/certbot_nginx/tests/parser_test.py @@ -273,11 +273,16 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods ['server_name', 'example.*'], [] ]]]) mock_vhost.names = set(['foobar.com', 'example.*']) - self.assertRaises(errors.MisconfigurationError, - nparser.add_server_directives, - mock_vhost, - [['ssl_certificate', 'cert.pem']], - replace=True) + nparser.add_server_directives( + mock_vhost, [['ssl_certificate', 'cert.pem']], replace=True) + self.assertEqual( + nparser.parsed[filep], + [[['server'], [['listen', '69.50.225.155:9000'], + ['listen', '127.0.0.1'], + ['server_name', 'foobar.com'], ['#', COMMENT], + ['server_name', 'example.*'], [], + ['ssl_certificate', 'cert.pem'], ['#', COMMENT], [], + ]]]) def test_get_best_match(self): target_name = 'www.eff.org' From d6a7e2d1fec4c280956e8f2206ec017b33f4978f Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 28 Jul 2017 09:55:18 -0700 Subject: [PATCH 09/31] Bump cryptography to 2.0.2 (#4972) --- letsencrypt-auto-source/letsencrypt-auto | 50 ++++++++++++------- .../pieces/dependency-requirements.txt | 50 ++++++++++++------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 023d5044e..102e77790 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -770,25 +770,37 @@ ConfigArgParse==0.10.0 \ --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==1.9 \ - --hash=sha256:469a9d3d851038f1eb7d7f77bb08bb4775b41483372be450e25b293fe57bd59e \ - --hash=sha256:533143321d15c8743f91eec5c5f495c1b5cad9a25de8f6dab01eddd6b416903e \ - --hash=sha256:2230c186182d773064d06242e0fa604cd718bfff28aa9c5ae73d7e426e98a151 \ - --hash=sha256:3dc94ed5a26b8553a325767358f505c0a43e0c89df078647f77a4d022ddcdc57 \ - --hash=sha256:2eb8297b877cb6b56216750fa7017c9f5786bec8afd6a0f1aaace02cbfb6195f \ - --hash=sha256:025a96e48164106f2082b00f42bf430cf21f09e203e42585a712e420b75cbff0 \ - --hash=sha256:61eb3534f8ed2415dd708b28919205d523f220e4cd5b8165844edfdd4a649b8e \ - --hash=sha256:5474fe5ce6b517d3086e0231b6ad88f8978c551c4379f91c3d619c308490f0d7 \ - --hash=sha256:5ff169869624e23767d70db274f13a9ea4e97c029425a1224aa5e049e84ce2af \ - --hash=sha256:c26e057a2de13e97e708328d295c5ac4cd3eab4a5c42ce727dd1a53316034b8a \ - --hash=sha256:7db719432648f14ea33edffc5f75330c595804eac86ca916528b35ce50a8bfd6 \ - --hash=sha256:ca72537a7064bb80e34b6908e576ffc8e2c2cad29a7168f48d0999df089695c3 \ - --hash=sha256:2a5e577f5d2093e51486b4ec02b51bb5adb165b98fee99929d5af0813e90b469 \ - --hash=sha256:9d9da8bac2e31003d092f5ef6981a725c77c4e9a30638436884d61ad39f9a1ee \ - --hash=sha256:fab8ec6866e384d9827d5dc02a1383e991a6c05c54f818316c4b829e56ca2ba3 \ - --hash=sha256:365eb804362e581c9a02e7a610b30514f07dd77b2a38aed338eb5192446bbc58 \ - --hash=sha256:2908f709f02711dbb10561a9f154d2f7d1792385e2341e9708539cc4ecfb8667 \ - --hash=sha256:5518337022718029e367d982642f3e3523541e098ad671672a90b82474c84882 +cryptography==2.0.2 \ + --hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \ + --hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \ + --hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \ + --hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \ + --hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \ + --hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \ + --hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \ + --hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \ + --hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \ + --hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \ + --hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \ + --hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \ + --hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \ + --hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \ + --hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \ + --hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \ + --hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \ + --hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \ + --hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \ + --hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \ + --hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \ + --hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \ + --hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \ + --hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \ + --hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \ + --hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \ + --hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \ + --hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \ + --hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \ + --hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab enum34==1.1.2 \ --hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \ --hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501 diff --git a/letsencrypt-auto-source/pieces/dependency-requirements.txt b/letsencrypt-auto-source/pieces/dependency-requirements.txt index a8007ba3e..9f98c7520 100644 --- a/letsencrypt-auto-source/pieces/dependency-requirements.txt +++ b/letsencrypt-auto-source/pieces/dependency-requirements.txt @@ -62,25 +62,37 @@ ConfigArgParse==0.10.0 \ --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==1.9 \ - --hash=sha256:469a9d3d851038f1eb7d7f77bb08bb4775b41483372be450e25b293fe57bd59e \ - --hash=sha256:533143321d15c8743f91eec5c5f495c1b5cad9a25de8f6dab01eddd6b416903e \ - --hash=sha256:2230c186182d773064d06242e0fa604cd718bfff28aa9c5ae73d7e426e98a151 \ - --hash=sha256:3dc94ed5a26b8553a325767358f505c0a43e0c89df078647f77a4d022ddcdc57 \ - --hash=sha256:2eb8297b877cb6b56216750fa7017c9f5786bec8afd6a0f1aaace02cbfb6195f \ - --hash=sha256:025a96e48164106f2082b00f42bf430cf21f09e203e42585a712e420b75cbff0 \ - --hash=sha256:61eb3534f8ed2415dd708b28919205d523f220e4cd5b8165844edfdd4a649b8e \ - --hash=sha256:5474fe5ce6b517d3086e0231b6ad88f8978c551c4379f91c3d619c308490f0d7 \ - --hash=sha256:5ff169869624e23767d70db274f13a9ea4e97c029425a1224aa5e049e84ce2af \ - --hash=sha256:c26e057a2de13e97e708328d295c5ac4cd3eab4a5c42ce727dd1a53316034b8a \ - --hash=sha256:7db719432648f14ea33edffc5f75330c595804eac86ca916528b35ce50a8bfd6 \ - --hash=sha256:ca72537a7064bb80e34b6908e576ffc8e2c2cad29a7168f48d0999df089695c3 \ - --hash=sha256:2a5e577f5d2093e51486b4ec02b51bb5adb165b98fee99929d5af0813e90b469 \ - --hash=sha256:9d9da8bac2e31003d092f5ef6981a725c77c4e9a30638436884d61ad39f9a1ee \ - --hash=sha256:fab8ec6866e384d9827d5dc02a1383e991a6c05c54f818316c4b829e56ca2ba3 \ - --hash=sha256:365eb804362e581c9a02e7a610b30514f07dd77b2a38aed338eb5192446bbc58 \ - --hash=sha256:2908f709f02711dbb10561a9f154d2f7d1792385e2341e9708539cc4ecfb8667 \ - --hash=sha256:5518337022718029e367d982642f3e3523541e098ad671672a90b82474c84882 +cryptography==2.0.2 \ + --hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \ + --hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \ + --hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \ + --hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \ + --hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \ + --hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \ + --hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \ + --hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \ + --hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \ + --hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \ + --hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \ + --hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \ + --hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \ + --hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \ + --hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \ + --hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \ + --hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \ + --hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \ + --hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \ + --hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \ + --hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \ + --hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \ + --hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \ + --hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \ + --hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \ + --hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \ + --hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \ + --hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \ + --hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \ + --hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab enum34==1.1.2 \ --hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \ --hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501 From 7461bdbffd87dc54c0dd6b58f4b92ddf68cf036a Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 1 Aug 2017 10:18:11 -0700 Subject: [PATCH 10/31] Update pipstrap to version 1.3.0 (#4978) * Update pipstrap to version 1.2.0. * Update pipstrap to include Python 2.6 fix. * Bump pipstrap to 1.3.0. --- letsencrypt-auto-source/letsencrypt-auto | 31 +++++++++++++++++----- letsencrypt-auto-source/pieces/pipstrap.py | 31 +++++++++++++++++----- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 102e77790..7fe61a19c 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -946,6 +946,7 @@ anything goes wrong, it will exit with a non-zero status code. # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. from __future__ import print_function +from distutils.version import StrictVersion from hashlib import sha256 from os.path import join from pipes import quote @@ -980,12 +981,14 @@ except ImportError: from urllib.parse import urlparse # 3.4 -__version__ = 1, 1, 1 +__version__ = 1, 3, 0 +PIP_VERSION = '9.0.1' # wheel has a conditional dependency on argparse: maybe_argparse = ( - [('https://pypi.python.org/packages/source/a/argparse/' + [('https://pypi.python.org/packages/18/dd/' + 'e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/' 'argparse-1.4.0.tar.gz', '62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')] if version_info < (2, 7, 0) else []) @@ -993,13 +996,19 @@ maybe_argparse = ( PACKAGES = maybe_argparse + [ # Pip has no dependencies, as it vendors everything: - ('https://pypi.python.org/packages/source/p/pip/pip-8.0.3.tar.gz', - '30f98b66f3fe1069c529a491597d34a1c224a68640c82caf2ade5f88aa1405e8'), + ('https://pypi.python.org/packages/11/b6/' + 'abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/' + 'pip-{0}.tar.gz' + .format(PIP_VERSION), + '09f243e1a7b461f654c26a725fa373211bb7ff17a9300058b205c61658ca940d'), # This version of setuptools has only optional dependencies: - ('https://pypi.python.org/packages/source/s/setuptools/' + ('https://pypi.python.org/packages/69/65/' + '4c544cde88d4d876cdf5cbc5f3f15d02646477756d89547e9a7ecd6afa76/' 'setuptools-20.2.2.tar.gz', '24fcfc15364a9fe09a220f37d2dcedc849795e3de3e4b393ee988e66a9cbd85a'), - ('https://pypi.python.org/packages/source/w/wheel/wheel-0.29.0.tar.gz', + ('https://pypi.python.org/packages/c9/1d/' + 'bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/' + 'wheel-0.29.0.tar.gz', '1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648') ] @@ -1049,11 +1058,21 @@ def hashed_download(url, temp, digest): def main(): + pip_version = StrictVersion(check_output(['pip', '--version']) + .decode('utf-8').split()[1]) + min_pip_version = StrictVersion(PIP_VERSION) + if pip_version >= min_pip_version: + return 0 + has_pip_cache = pip_version >= StrictVersion('6.0') + temp = mkdtemp(prefix='pipstrap-') try: downloads = [hashed_download(url, temp, digest) for url, digest in PACKAGES] check_output('pip install --no-index --no-deps -U ' + + # Disable cache since we're not using it and it otherwise + # sometimes throws permission warnings: + ('--no-cache-dir ' if has_pip_cache else '') + ' '.join(quote(d) for d in downloads), shell=True) except HashError as exc: diff --git a/letsencrypt-auto-source/pieces/pipstrap.py b/letsencrypt-auto-source/pieces/pipstrap.py index 505f8ca72..78491b5e3 100755 --- a/letsencrypt-auto-source/pieces/pipstrap.py +++ b/letsencrypt-auto-source/pieces/pipstrap.py @@ -21,6 +21,7 @@ anything goes wrong, it will exit with a non-zero status code. # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. from __future__ import print_function +from distutils.version import StrictVersion from hashlib import sha256 from os.path import join from pipes import quote @@ -55,12 +56,14 @@ except ImportError: from urllib.parse import urlparse # 3.4 -__version__ = 1, 1, 1 +__version__ = 1, 3, 0 +PIP_VERSION = '9.0.1' # wheel has a conditional dependency on argparse: maybe_argparse = ( - [('https://pypi.python.org/packages/source/a/argparse/' + [('https://pypi.python.org/packages/18/dd/' + 'e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/' 'argparse-1.4.0.tar.gz', '62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')] if version_info < (2, 7, 0) else []) @@ -68,13 +71,19 @@ maybe_argparse = ( PACKAGES = maybe_argparse + [ # Pip has no dependencies, as it vendors everything: - ('https://pypi.python.org/packages/source/p/pip/pip-8.0.3.tar.gz', - '30f98b66f3fe1069c529a491597d34a1c224a68640c82caf2ade5f88aa1405e8'), + ('https://pypi.python.org/packages/11/b6/' + 'abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/' + 'pip-{0}.tar.gz' + .format(PIP_VERSION), + '09f243e1a7b461f654c26a725fa373211bb7ff17a9300058b205c61658ca940d'), # This version of setuptools has only optional dependencies: - ('https://pypi.python.org/packages/source/s/setuptools/' + ('https://pypi.python.org/packages/69/65/' + '4c544cde88d4d876cdf5cbc5f3f15d02646477756d89547e9a7ecd6afa76/' 'setuptools-20.2.2.tar.gz', '24fcfc15364a9fe09a220f37d2dcedc849795e3de3e4b393ee988e66a9cbd85a'), - ('https://pypi.python.org/packages/source/w/wheel/wheel-0.29.0.tar.gz', + ('https://pypi.python.org/packages/c9/1d/' + 'bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/' + 'wheel-0.29.0.tar.gz', '1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648') ] @@ -124,11 +133,21 @@ def hashed_download(url, temp, digest): def main(): + pip_version = StrictVersion(check_output(['pip', '--version']) + .decode('utf-8').split()[1]) + min_pip_version = StrictVersion(PIP_VERSION) + if pip_version >= min_pip_version: + return 0 + has_pip_cache = pip_version >= StrictVersion('6.0') + temp = mkdtemp(prefix='pipstrap-') try: downloads = [hashed_download(url, temp, digest) for url, digest in PACKAGES] check_output('pip install --no-index --no-deps -U ' + + # Disable cache since we're not using it and it otherwise + # sometimes throws permission warnings: + ('--no-cache-dir ' if has_pip_cache else '') + ' '.join(quote(d) for d in downloads), shell=True) except HashError as exc: From 314f4bbe225850a06b48a94f854c1c49159e5316 Mon Sep 17 00:00:00 2001 From: Zach Shepherd Date: Tue, 1 Aug 2017 11:34:35 -0700 Subject: [PATCH 11/31] client: allow callers to add information to the user agent (#4690) This change introduces a new flag to allow callers to add information to the user agent without replacing it entirely. This allows people re-packaging or wrapping Certbot to influence its user agent string. They may which to do this so that stats/metrics related to their distribution are available to boulder. This is beneficial for both the Certbot team and the party re-packaging Certbot as it allows the custom user agent to match the Certbot user agent as closely as possible, allowing data about use of the re-packaged version to be collected along side or separately from vanilla certbot. --- certbot/cli.py | 9 +++++++++ certbot/client.py | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/certbot/cli.py b/certbot/cli.py index eaafce762..7135f7600 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -1145,6 +1145,11 @@ def _create_subparsers(helpful): '(default: {0}). The flags encoded in the user agent are: ' '--duplicate, --force-renew, --allow-subset-of-names, -n, and ' 'whether any hooks are set.'.format(sample_user_agent())) + helpful.add( + None, "--user-agent-comment", default=None, type=_user_agent_comment_type, + help="Add a comment to the default user agent string. May be used when repackaging Certbot " + "or calling it from another tool to allow additional statistical data to be collected." + " Ignored if --user-agent is set. (Example: Foo-Wrapper/1.0)") helpful.add("certonly", "--csr", type=read_file, help="Path to a Certificate Signing Request (CSR) in DER or PEM format." @@ -1360,6 +1365,10 @@ def parse_preferred_challenges(pref_challs): "Unrecognized challenges: {0}".format(unrecognized)) return challs +def _user_agent_comment_type(value): + if "(" in value or ")" in value: + raise argparse.ArgumentTypeError("may not contain parentheses") + return value class _DeployHookAction(argparse.Action): """Action class for parsing deploy hooks.""" diff --git a/certbot/client.py b/certbot/client.py index 6010dd0a0..ed70fda71 100644 --- a/certbot/client.py +++ b/certbot/client.py @@ -58,11 +58,12 @@ def determine_user_agent(config): # policy, talk to a core Certbot team member before making any # changes here. if config.user_agent is None: - ua = ("CertbotACMEClient/{0} ({1}; {2}) Authenticator/{3} Installer/{4} " + ua = ("CertbotACMEClient/{0} ({1}; {2}{8}) Authenticator/{3} Installer/{4} " "({5}; flags: {6}) Py/{7}") ua = ua.format(certbot.__version__, cli.cli_command, util.get_os_info_ua(), config.authenticator, config.installer, config.verb, - ua_flags(config), platform.python_version()) + ua_flags(config), platform.python_version(), + "; " + config.user_agent_comment if config.user_agent_comment else "") else: ua = config.user_agent return ua From 912d235466669d516427b5db9997bb92705020f1 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 1 Aug 2017 17:01:07 -0700 Subject: [PATCH 12/31] Release 0.17.0 --- acme/setup.py | 2 +- certbot-apache/setup.py | 2 +- certbot-auto | 136 ++++++++++++------ certbot-compatibility-test/setup.py | 2 +- certbot-dns-cloudflare/setup.py | 2 +- certbot-dns-cloudxns/setup.py | 2 +- certbot-dns-digitalocean/setup.py | 2 +- certbot-dns-dnsimple/setup.py | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- certbot-dns-google/setup.py | 2 +- certbot-dns-luadns/setup.py | 2 +- certbot-dns-nsone/setup.py | 2 +- certbot-dns-rfc2136/setup.py | 2 +- certbot-dns-route53/setup.py | 2 +- certbot-nginx/setup.py | 2 +- certbot/__init__.py | 2 +- docs/cli-help.txt | 28 ++-- letsencrypt-auto | 136 ++++++++++++------ letsencrypt-auto-source/certbot-auto.asc | 14 +- letsencrypt-auto-source/letsencrypt-auto | 26 ++-- letsencrypt-auto-source/letsencrypt-auto.sig | Bin 256 -> 256 bytes .../pieces/certbot-requirements.txt | 24 ++-- 22 files changed, 253 insertions(+), 141 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index 0b166dd91..05480f5b0 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 7f61f9041..fa6268a4d 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.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-auto b/certbot-auto index 599538891..b935ed447 100755 --- a/certbot-auto +++ b/certbot-auto @@ -28,7 +28,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.16.0" +LE_AUTO_VERSION="0.17.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -200,6 +200,25 @@ ExperimentalBootstrap() { fi } +DeprecationBootstrap() { + # Arguments: Platform name, bootstrap function name + if [ "$DEBUG" = 1 ]; then + if [ "$2" != "" ]; then + BootstrapMessage $1 + $2 + fi + else + error "WARNING: certbot-auto support for this $1 is DEPRECATED!" + error "Please visit certbot.eff.org to learn how to download a version of" + error "Certbot that is packaged for your system. While an existing version" + error "of certbot-auto may work currently, we have stopped supporting updating" + error "system packages for your system. Please switch to a packaged version" + error "as soon as possible." + exit 1 + fi +} + + DeterminePythonVersion() { for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do # Break (while keeping the LE_PYTHON value) if found. @@ -630,11 +649,11 @@ Bootstrap() { elif [ -f /etc/manjaro-release ]; then ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon elif [ -f /etc/gentoo-release ]; then - ExperimentalBootstrap "Gentoo" BootstrapGentooCommon + DeprecationBootstrap "Gentoo" BootstrapGentooCommon elif uname | grep -iq FreeBSD ; then - ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd + DeprecationBootstrap "FreeBSD" BootstrapFreeBsd elif uname | grep -iq Darwin ; then - ExperimentalBootstrap "macOS" BootstrapMac + DeprecationBootstrap "macOS" BootstrapMac elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then @@ -751,25 +770,37 @@ ConfigArgParse==0.10.0 \ --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==1.9 \ - --hash=sha256:469a9d3d851038f1eb7d7f77bb08bb4775b41483372be450e25b293fe57bd59e \ - --hash=sha256:533143321d15c8743f91eec5c5f495c1b5cad9a25de8f6dab01eddd6b416903e \ - --hash=sha256:2230c186182d773064d06242e0fa604cd718bfff28aa9c5ae73d7e426e98a151 \ - --hash=sha256:3dc94ed5a26b8553a325767358f505c0a43e0c89df078647f77a4d022ddcdc57 \ - --hash=sha256:2eb8297b877cb6b56216750fa7017c9f5786bec8afd6a0f1aaace02cbfb6195f \ - --hash=sha256:025a96e48164106f2082b00f42bf430cf21f09e203e42585a712e420b75cbff0 \ - --hash=sha256:61eb3534f8ed2415dd708b28919205d523f220e4cd5b8165844edfdd4a649b8e \ - --hash=sha256:5474fe5ce6b517d3086e0231b6ad88f8978c551c4379f91c3d619c308490f0d7 \ - --hash=sha256:5ff169869624e23767d70db274f13a9ea4e97c029425a1224aa5e049e84ce2af \ - --hash=sha256:c26e057a2de13e97e708328d295c5ac4cd3eab4a5c42ce727dd1a53316034b8a \ - --hash=sha256:7db719432648f14ea33edffc5f75330c595804eac86ca916528b35ce50a8bfd6 \ - --hash=sha256:ca72537a7064bb80e34b6908e576ffc8e2c2cad29a7168f48d0999df089695c3 \ - --hash=sha256:2a5e577f5d2093e51486b4ec02b51bb5adb165b98fee99929d5af0813e90b469 \ - --hash=sha256:9d9da8bac2e31003d092f5ef6981a725c77c4e9a30638436884d61ad39f9a1ee \ - --hash=sha256:fab8ec6866e384d9827d5dc02a1383e991a6c05c54f818316c4b829e56ca2ba3 \ - --hash=sha256:365eb804362e581c9a02e7a610b30514f07dd77b2a38aed338eb5192446bbc58 \ - --hash=sha256:2908f709f02711dbb10561a9f154d2f7d1792385e2341e9708539cc4ecfb8667 \ - --hash=sha256:5518337022718029e367d982642f3e3523541e098ad671672a90b82474c84882 +cryptography==2.0.2 \ + --hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \ + --hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \ + --hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \ + --hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \ + --hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \ + --hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \ + --hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \ + --hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \ + --hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \ + --hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \ + --hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \ + --hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \ + --hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \ + --hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \ + --hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \ + --hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \ + --hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \ + --hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \ + --hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \ + --hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \ + --hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \ + --hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \ + --hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \ + --hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \ + --hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \ + --hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \ + --hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \ + --hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \ + --hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \ + --hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab enum34==1.1.2 \ --hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \ --hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501 @@ -876,18 +907,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.16.0 \ - --hash=sha256:e1cc2479f4f149a7128b67192c3f5f6c111b6b9ddcac421ebee8ac5030d5b09b \ - --hash=sha256:795801fd6b06b32060e364ac045312e6b26c6272d5ca32878277e5a2afdee186 -acme==0.16.0 \ - --hash=sha256:31592a744f7a6e7cbb4c5daf2deebc9af6b03997d6f80e5becc203ab8694edcf \ - --hash=sha256:538b69134cc50bdcdcc081b844c85158509022c61d7abc1f44216beeb95de9cd -certbot-apache==0.16.0 \ - --hash=sha256:337f84f391c7d7c31d84376e7a8c882ac119112a4aabceadd1a7de6a2f01ca06 \ - --hash=sha256:f1f37b56e1ceb0a28ccf51d54ca34444e6a708448845ef25372e223b9a82c4d4 -certbot-nginx==0.16.0 \ - --hash=sha256:1d57428202f8e7abdd99c3ddbcf374aad5f69c4262fe8dae53d2016e4ae04ded \ - --hash=sha256:77711655514d707ddf728195f00b2f6cdd1ad9db52440276b4a67664479c6954 +certbot==0.17.0 \ + --hash=sha256:64c25c7123357feffded6408660bc6f5c7d493dd635ae172081d21473075a86a \ + --hash=sha256:43f5b26c3f314d14babf79a3bdf3522e4fc9eef867a0681c426f113c650a669c +acme==0.17.0 \ + --hash=sha256:501710171633af13fc52aa61d0277a6fe335f7477db5810e72239aaf4f3a09e7 \ + --hash=sha256:3ccbe4aaeb98c77b98ee4093b4e4adb76a1a24cbdfec0130c489c206f1d9b66e +certbot-apache==0.17.0 \ + --hash=sha256:17a7e8d7526d838610e68b96cf052af17c4055655b76b06d1cbc74857d90a216 \ + --hash=sha256:29b9e7bc5eaaff6dc4bce8398e35eeacdf346126aad68cac3d41bb87df20a6b9 +certbot-nginx==0.17.0 \ + --hash=sha256:980c9a33a79ab839a089a0085ff0c5414f01f47b6db26ed342df25916658cec9 \ + --hash=sha256:e573f8b4283172755c07b9cca8a8da7ef2d31b4df763881394b5339b2d42994a UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -915,6 +946,7 @@ anything goes wrong, it will exit with a non-zero status code. # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. from __future__ import print_function +from distutils.version import StrictVersion from hashlib import sha256 from os.path import join from pipes import quote @@ -949,12 +981,14 @@ except ImportError: from urllib.parse import urlparse # 3.4 -__version__ = 1, 1, 1 +__version__ = 1, 3, 0 +PIP_VERSION = '9.0.1' # wheel has a conditional dependency on argparse: maybe_argparse = ( - [('https://pypi.python.org/packages/source/a/argparse/' + [('https://pypi.python.org/packages/18/dd/' + 'e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/' 'argparse-1.4.0.tar.gz', '62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')] if version_info < (2, 7, 0) else []) @@ -962,13 +996,19 @@ maybe_argparse = ( PACKAGES = maybe_argparse + [ # Pip has no dependencies, as it vendors everything: - ('https://pypi.python.org/packages/source/p/pip/pip-8.0.3.tar.gz', - '30f98b66f3fe1069c529a491597d34a1c224a68640c82caf2ade5f88aa1405e8'), + ('https://pypi.python.org/packages/11/b6/' + 'abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/' + 'pip-{0}.tar.gz' + .format(PIP_VERSION), + '09f243e1a7b461f654c26a725fa373211bb7ff17a9300058b205c61658ca940d'), # This version of setuptools has only optional dependencies: - ('https://pypi.python.org/packages/source/s/setuptools/' + ('https://pypi.python.org/packages/69/65/' + '4c544cde88d4d876cdf5cbc5f3f15d02646477756d89547e9a7ecd6afa76/' 'setuptools-20.2.2.tar.gz', '24fcfc15364a9fe09a220f37d2dcedc849795e3de3e4b393ee988e66a9cbd85a'), - ('https://pypi.python.org/packages/source/w/wheel/wheel-0.29.0.tar.gz', + ('https://pypi.python.org/packages/c9/1d/' + 'bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/' + 'wheel-0.29.0.tar.gz', '1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648') ] @@ -1018,11 +1058,21 @@ def hashed_download(url, temp, digest): def main(): + pip_version = StrictVersion(check_output(['pip', '--version']) + .decode('utf-8').split()[1]) + min_pip_version = StrictVersion(PIP_VERSION) + if pip_version >= min_pip_version: + return 0 + has_pip_cache = pip_version >= StrictVersion('6.0') + temp = mkdtemp(prefix='pipstrap-') try: downloads = [hashed_download(url, temp, digest) for url, digest in PACKAGES] check_output('pip install --no-index --no-deps -U ' + + # Disable cache since we're not using it and it otherwise + # sometimes throws permission warnings: + ('--no-cache-dir ' if has_pip_cache else '') + ' '.join(quote(d) for d in downloads), shell=True) except HashError as exc: @@ -1045,9 +1095,9 @@ UNLIKELY_EOF PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py" set +e if [ "$VERBOSE" = 1 ]; then - "$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" + "$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" else - PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` + PIP_OUT=`"$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` fi PIP_STATUS=$? set -e diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 071b97d22..4bb991f97 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.17.0.dev0' +version = '0.17.0' install_requires = [ 'certbot', diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index 7162a1dcf..2d264c100 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index 024e32918..6d8d57bad 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index dc09fdd0b..45ffbd060 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 98d3e0a25..dba26f0ac 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index a3ab24684..98c3cc7ce 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 4b7d21f2e..03e10f9d9 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index be0774e13..059fa0c7f 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index addb69b6d..fb7114d6b 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 3b5409602..f1dfca337 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index 7a69f9a13..ac01d8982 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -3,7 +3,7 @@ import sys from distutils.core import setup from setuptools import find_packages -version = '0.17.0.dev0' +version = '0.17.0' install_requires = [ 'acme=={0}'.format(version), diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index b501aecd9..5127f2f84 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.17.0.dev0' +version = '0.17.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot/__init__.py b/certbot/__init__.py index 23ed7eb7a..495da7a4c 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.17.0.dev0' +__version__ = '0.17.0' diff --git a/docs/cli-help.txt b/docs/cli-help.txt index 6ff284788..a00fe6c65 100644 --- a/docs/cli-help.txt +++ b/docs/cli-help.txt @@ -39,6 +39,12 @@ optional arguments: -v, --verbose This flag can be used multiple times to incrementally increase the verbosity of output, e.g. -vvv. (default: -2) + --max-log-backups MAX_LOG_BACKUPS + Specifies the maximum number of backup logs that + should be kept by Certbot's built in log rotation. + Setting this flag to 0 disables log rotation entirely, + causing Certbot to always append to the same log file. + (default: 1000) -n, --non-interactive, --noninteractive Run without ever asking for user input. This may require additional command line flags; the client will @@ -68,8 +74,8 @@ optional arguments: reloads webservers to deploy and then roll back those changes. It also calls --pre-hook and --post-hook commands if they are defined because they may be - necessary to accurately simulate renewal. --renew-hook - commands are not called. (default: False) + necessary to accurately simulate renewal. --deploy- + hook commands are not called. (default: False) --debug-challenges After setting up challenges, wait for user input before submitting to CA (default: False) --preferred-challenges PREF_CHALLS @@ -89,12 +95,18 @@ optional arguments: case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/0.16.0 (certbot; - Ubuntu 16.04.2 LTS) Authenticator/XXX Installer/YYY + "". (default: CertbotACMEClient/0.17.0 (certbot; + Ubuntu 16.04.3 LTS) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/2.7.12). The flags encoded in the user agent are: --duplicate, --force- renew, --allow-subset-of-names, -n, and whether any hooks are set. + --user-agent-comment USER_AGENT_COMMENT + Add a comment to the default user agent string. May be + used when repackaging Certbot or calling it from + another tool to allow additional statistical data to + be collected. Ignored if --user-agent is set. + (Example: Foo-Wrapper/1.0) (default: None) automation: Arguments for automating execution & other tweaks @@ -274,10 +286,10 @@ renew: attempt was made to obtain/renew a certificate. If multiple renewed certificates have identical post- hooks, only one will be run. (default: None) - --renew-hook RENEW_HOOK + --deploy-hook DEPLOY_HOOK Command to be run in a shell once for each - successfully renewed certificate. For this command, - the shell variable $RENEWED_LINEAGE will point to the + successfully issued certificate. For this command, the + shell variable $RENEWED_LINEAGE will point to the config live subdirectory (for example, "/etc/letsencrypt/live/example.com") containing the new certificates and keys; the shell variable @@ -286,7 +298,7 @@ renew: "example.com www.example.com" (default: None) --disable-hook-validation Ordinarily the commands specified for --pre-hook - /--post-hook/--renew-hook will be checked for + /--post-hook/--deploy-hook will be checked for validity, to see if the programs being run are in the $PATH, so that mistakes can be caught early, even when the hooks aren't being run just yet. The validation is diff --git a/letsencrypt-auto b/letsencrypt-auto index 599538891..b935ed447 100755 --- a/letsencrypt-auto +++ b/letsencrypt-auto @@ -28,7 +28,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.16.0" +LE_AUTO_VERSION="0.17.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -200,6 +200,25 @@ ExperimentalBootstrap() { fi } +DeprecationBootstrap() { + # Arguments: Platform name, bootstrap function name + if [ "$DEBUG" = 1 ]; then + if [ "$2" != "" ]; then + BootstrapMessage $1 + $2 + fi + else + error "WARNING: certbot-auto support for this $1 is DEPRECATED!" + error "Please visit certbot.eff.org to learn how to download a version of" + error "Certbot that is packaged for your system. While an existing version" + error "of certbot-auto may work currently, we have stopped supporting updating" + error "system packages for your system. Please switch to a packaged version" + error "as soon as possible." + exit 1 + fi +} + + DeterminePythonVersion() { for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do # Break (while keeping the LE_PYTHON value) if found. @@ -630,11 +649,11 @@ Bootstrap() { elif [ -f /etc/manjaro-release ]; then ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon elif [ -f /etc/gentoo-release ]; then - ExperimentalBootstrap "Gentoo" BootstrapGentooCommon + DeprecationBootstrap "Gentoo" BootstrapGentooCommon elif uname | grep -iq FreeBSD ; then - ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd + DeprecationBootstrap "FreeBSD" BootstrapFreeBsd elif uname | grep -iq Darwin ; then - ExperimentalBootstrap "macOS" BootstrapMac + DeprecationBootstrap "macOS" BootstrapMac elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then @@ -751,25 +770,37 @@ ConfigArgParse==0.10.0 \ --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==1.9 \ - --hash=sha256:469a9d3d851038f1eb7d7f77bb08bb4775b41483372be450e25b293fe57bd59e \ - --hash=sha256:533143321d15c8743f91eec5c5f495c1b5cad9a25de8f6dab01eddd6b416903e \ - --hash=sha256:2230c186182d773064d06242e0fa604cd718bfff28aa9c5ae73d7e426e98a151 \ - --hash=sha256:3dc94ed5a26b8553a325767358f505c0a43e0c89df078647f77a4d022ddcdc57 \ - --hash=sha256:2eb8297b877cb6b56216750fa7017c9f5786bec8afd6a0f1aaace02cbfb6195f \ - --hash=sha256:025a96e48164106f2082b00f42bf430cf21f09e203e42585a712e420b75cbff0 \ - --hash=sha256:61eb3534f8ed2415dd708b28919205d523f220e4cd5b8165844edfdd4a649b8e \ - --hash=sha256:5474fe5ce6b517d3086e0231b6ad88f8978c551c4379f91c3d619c308490f0d7 \ - --hash=sha256:5ff169869624e23767d70db274f13a9ea4e97c029425a1224aa5e049e84ce2af \ - --hash=sha256:c26e057a2de13e97e708328d295c5ac4cd3eab4a5c42ce727dd1a53316034b8a \ - --hash=sha256:7db719432648f14ea33edffc5f75330c595804eac86ca916528b35ce50a8bfd6 \ - --hash=sha256:ca72537a7064bb80e34b6908e576ffc8e2c2cad29a7168f48d0999df089695c3 \ - --hash=sha256:2a5e577f5d2093e51486b4ec02b51bb5adb165b98fee99929d5af0813e90b469 \ - --hash=sha256:9d9da8bac2e31003d092f5ef6981a725c77c4e9a30638436884d61ad39f9a1ee \ - --hash=sha256:fab8ec6866e384d9827d5dc02a1383e991a6c05c54f818316c4b829e56ca2ba3 \ - --hash=sha256:365eb804362e581c9a02e7a610b30514f07dd77b2a38aed338eb5192446bbc58 \ - --hash=sha256:2908f709f02711dbb10561a9f154d2f7d1792385e2341e9708539cc4ecfb8667 \ - --hash=sha256:5518337022718029e367d982642f3e3523541e098ad671672a90b82474c84882 +cryptography==2.0.2 \ + --hash=sha256:187ae17358436d2c760f28c2aeb02fefa3f37647a9c5b6f7f7c3e83cd1c5a972 \ + --hash=sha256:19e43a13bbf52028dd1e810c803f2ad8880d0692d772f98d42e1eaf34bdee3d6 \ + --hash=sha256:da9291502cbc87dc0284a20c56876e4d2e68deac61cc43df4aec934e44ca97b1 \ + --hash=sha256:0954f8813095f581669330e0a2d5e726c33ac7f450c1458fac58bab54595e516 \ + --hash=sha256:d68b0cc40a8432ed3fc84876c519de704d6001800ec22b136e75ae841910c45b \ + --hash=sha256:2f8ad9580ab4da645cfea52a91d2da99a49a1e76616d8be68441a986fad652b0 \ + --hash=sha256:cc00b4511294f5f6b65c4e77a1a9c62f52490a63d2c120f3872176b40a82351e \ + --hash=sha256:cf896020f6a9f095a547b3d672c8db1ef2ed71fca11250731fa1d4a4cb8b1590 \ + --hash=sha256:e0fdb8322206fa02aa38f71519ff75dce2eb481b7e1110e2936795cb376bb6ee \ + --hash=sha256:277538466657ca5d6637f80be100242f9831d75138b788d718edd3aab34621f8 \ + --hash=sha256:2c77eb0560f54ce654ab82d6b2a64327a71ee969b29022bf9746ca311c9f5069 \ + --hash=sha256:755a7853b679e79d0a799351c092a9b0271f95ff54c8dd8823d8b527a2926a86 \ + --hash=sha256:77197a2d525e761cdd4c771180b4bd0d80703654c6385e4311cbbbe2beb56fa1 \ + --hash=sha256:eb8bb79d0ab00c931c8333b745f06fec481a51c52d70acd4ee95d6093ba5c386 \ + --hash=sha256:131f61de82ef28f3e20beb4bfc24f9692d28cecfd704e20e6c7f070f7793013a \ + --hash=sha256:ac35435974b2e27cd4520f29c191d7da36f4189aa3264e52c4c6c6d089ab6142 \ + --hash=sha256:04b6ea99daa2a8460728794213d76d45ad58ea247dc7e7ff148d7dd726e87863 \ + --hash=sha256:2b9442f8b4c3d575f6cc3db0e856034e0f5a9d55ecd636f52d8c496795b26952 \ + --hash=sha256:b3d3b3ecba1fe1bdb6f180770a137f877c8f07571f7b2934bb269475bcf0e5e8 \ + --hash=sha256:670a58c0d75cb0e78e73dd003bd96d4440bbb1f2bc041dcf7b81767ca4fb0ce9 \ + --hash=sha256:5af84d23bdb86b5e90aca263df1424b43f1748480bfcde3ac2a3cbe622612468 \ + --hash=sha256:ba22e8eefabdd7aca37d0c0c00d2274000d2cebb5cce9e5a710cb55bf8797b31 \ + --hash=sha256:b798b22fa7e92b439547323b8b719d217f1e1b7677585cfeeedf3b55c70bb7fb \ + --hash=sha256:59cff28af8cce96cb7e94a459726e1d88f6f5fa75097f9dcbebd99118d64ea4c \ + --hash=sha256:fe859e445abc9ba9e97950ddafb904e23234c4ecb76b0fae6c86e80592ce464a \ + --hash=sha256:655f3c474067f1e277430f23cc0549f0b1dc99b82aec6e53f80b9b2db7f76f11 \ + --hash=sha256:0ebc2be053c9a03a2f3e20a466e87bf12a51586b3c79bd2a22171b073a805346 \ + --hash=sha256:01e6e60654df64cca53733cda39446d67100c819c181d403afb120e0d2a71e1b \ + --hash=sha256:d46f4e5d455cb5563685c52ef212696f0a6cc1ea627603218eabbd8a095291d8 \ + --hash=sha256:3780b2663ee7ebb37cb83263326e3cd7f8b2ea439c448539d4b87de12c8d06ab enum34==1.1.2 \ --hash=sha256:2475d7fcddf5951e92ff546972758802de5260bf409319a9f1934e6bbc8b1dc7 \ --hash=sha256:35907defb0f992b75ab7788f65fedc1cf20ffa22688e0e6f6f12afc06b3ea501 @@ -876,18 +907,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.16.0 \ - --hash=sha256:e1cc2479f4f149a7128b67192c3f5f6c111b6b9ddcac421ebee8ac5030d5b09b \ - --hash=sha256:795801fd6b06b32060e364ac045312e6b26c6272d5ca32878277e5a2afdee186 -acme==0.16.0 \ - --hash=sha256:31592a744f7a6e7cbb4c5daf2deebc9af6b03997d6f80e5becc203ab8694edcf \ - --hash=sha256:538b69134cc50bdcdcc081b844c85158509022c61d7abc1f44216beeb95de9cd -certbot-apache==0.16.0 \ - --hash=sha256:337f84f391c7d7c31d84376e7a8c882ac119112a4aabceadd1a7de6a2f01ca06 \ - --hash=sha256:f1f37b56e1ceb0a28ccf51d54ca34444e6a708448845ef25372e223b9a82c4d4 -certbot-nginx==0.16.0 \ - --hash=sha256:1d57428202f8e7abdd99c3ddbcf374aad5f69c4262fe8dae53d2016e4ae04ded \ - --hash=sha256:77711655514d707ddf728195f00b2f6cdd1ad9db52440276b4a67664479c6954 +certbot==0.17.0 \ + --hash=sha256:64c25c7123357feffded6408660bc6f5c7d493dd635ae172081d21473075a86a \ + --hash=sha256:43f5b26c3f314d14babf79a3bdf3522e4fc9eef867a0681c426f113c650a669c +acme==0.17.0 \ + --hash=sha256:501710171633af13fc52aa61d0277a6fe335f7477db5810e72239aaf4f3a09e7 \ + --hash=sha256:3ccbe4aaeb98c77b98ee4093b4e4adb76a1a24cbdfec0130c489c206f1d9b66e +certbot-apache==0.17.0 \ + --hash=sha256:17a7e8d7526d838610e68b96cf052af17c4055655b76b06d1cbc74857d90a216 \ + --hash=sha256:29b9e7bc5eaaff6dc4bce8398e35eeacdf346126aad68cac3d41bb87df20a6b9 +certbot-nginx==0.17.0 \ + --hash=sha256:980c9a33a79ab839a089a0085ff0c5414f01f47b6db26ed342df25916658cec9 \ + --hash=sha256:e573f8b4283172755c07b9cca8a8da7ef2d31b4df763881394b5339b2d42994a UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -915,6 +946,7 @@ anything goes wrong, it will exit with a non-zero status code. # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. from __future__ import print_function +from distutils.version import StrictVersion from hashlib import sha256 from os.path import join from pipes import quote @@ -949,12 +981,14 @@ except ImportError: from urllib.parse import urlparse # 3.4 -__version__ = 1, 1, 1 +__version__ = 1, 3, 0 +PIP_VERSION = '9.0.1' # wheel has a conditional dependency on argparse: maybe_argparse = ( - [('https://pypi.python.org/packages/source/a/argparse/' + [('https://pypi.python.org/packages/18/dd/' + 'e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/' 'argparse-1.4.0.tar.gz', '62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4')] if version_info < (2, 7, 0) else []) @@ -962,13 +996,19 @@ maybe_argparse = ( PACKAGES = maybe_argparse + [ # Pip has no dependencies, as it vendors everything: - ('https://pypi.python.org/packages/source/p/pip/pip-8.0.3.tar.gz', - '30f98b66f3fe1069c529a491597d34a1c224a68640c82caf2ade5f88aa1405e8'), + ('https://pypi.python.org/packages/11/b6/' + 'abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/' + 'pip-{0}.tar.gz' + .format(PIP_VERSION), + '09f243e1a7b461f654c26a725fa373211bb7ff17a9300058b205c61658ca940d'), # This version of setuptools has only optional dependencies: - ('https://pypi.python.org/packages/source/s/setuptools/' + ('https://pypi.python.org/packages/69/65/' + '4c544cde88d4d876cdf5cbc5f3f15d02646477756d89547e9a7ecd6afa76/' 'setuptools-20.2.2.tar.gz', '24fcfc15364a9fe09a220f37d2dcedc849795e3de3e4b393ee988e66a9cbd85a'), - ('https://pypi.python.org/packages/source/w/wheel/wheel-0.29.0.tar.gz', + ('https://pypi.python.org/packages/c9/1d/' + 'bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/' + 'wheel-0.29.0.tar.gz', '1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648') ] @@ -1018,11 +1058,21 @@ def hashed_download(url, temp, digest): def main(): + pip_version = StrictVersion(check_output(['pip', '--version']) + .decode('utf-8').split()[1]) + min_pip_version = StrictVersion(PIP_VERSION) + if pip_version >= min_pip_version: + return 0 + has_pip_cache = pip_version >= StrictVersion('6.0') + temp = mkdtemp(prefix='pipstrap-') try: downloads = [hashed_download(url, temp, digest) for url, digest in PACKAGES] check_output('pip install --no-index --no-deps -U ' + + # Disable cache since we're not using it and it otherwise + # sometimes throws permission warnings: + ('--no-cache-dir ' if has_pip_cache else '') + ' '.join(quote(d) for d in downloads), shell=True) except HashError as exc: @@ -1045,9 +1095,9 @@ UNLIKELY_EOF PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py" set +e if [ "$VERBOSE" = 1 ]; then - "$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" + "$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" else - PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` + PIP_OUT=`"$VENV_BIN/pip" install --disable-pip-version-check --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` fi PIP_STATUS=$? set -e diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc index aa713c8c0..36afe0eba 100644 --- a/letsencrypt-auto-source/certbot-auto.asc +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 -iQEcBAABCAAGBQJZXV5PAAoJEE0XyZXNl3Xy3IgH/1OiY21IcAGx13jW32KNIsf9 -/vqjR/fyPbraSzYDldCVIQxsaVA6oh2kNZgiB11OpPT20/WsDq1+Ymj+dMjonJfm -w3wjx5AnfR/YThQwNXUJ83XnPCA78CtYiXus9gyqk+10WpNXUkbdGOwM4eYOtb3o -fNjJXkA00pATIYXks6qV0WJVEDNYuHDfkDfxukVgU7HzjfayLQjo4Zbs7Qnp7oH9 -+Lizc11nTliUUo3hHyLziJsCfC+Irso5Q/fHM9rn9DS360PcW0uNjWeLQk0U1w1l -tuuObOsDi/7Rejk4uDu6qDVemdEoG1btCrZgzOvzi3NstWigrL76cZuoz0gaGu4= -=mN1c +iQEcBAABCAAGBQJZgRYdAAoJEE0XyZXNl3XyNskIAMh/M3tV8PTieSrMr3uzLua8 +R+tQJV31WlraoKGQAkZ9Ak+nEhJy0bOi3QAeOmEnS15sBM6ruD+UCfwUDrZxolfW +5Fnue2ocym+MhfDNKoerQNAmaaHY8sutoR+RNTegFyfyr92zMDZVzPm/DFAAHbK+ +eJltSx2Jleaig4V/RcKpkCwHErjQxn6Tn4jHlafAdNL28tEIGXcExpRj4raw3X1L +SoTq/yJiWe+M7t+1iBRVEMZHY1b47PbTo1ipKF/ZZ3Hrz5JKRhAKcA8diHlWp+1I +ujAfU4uu0hR+C3wcpeJ1i2YdS4S9y6uMGyIWU5toJfYdolTSGRZ2lPB+x5Um9pw= +=/7P7 -----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 7fe61a19c..b935ed447 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -28,7 +28,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.17.0.dev0" +LE_AUTO_VERSION="0.17.0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates @@ -907,18 +907,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.16.0 \ - --hash=sha256:e1cc2479f4f149a7128b67192c3f5f6c111b6b9ddcac421ebee8ac5030d5b09b \ - --hash=sha256:795801fd6b06b32060e364ac045312e6b26c6272d5ca32878277e5a2afdee186 -acme==0.16.0 \ - --hash=sha256:31592a744f7a6e7cbb4c5daf2deebc9af6b03997d6f80e5becc203ab8694edcf \ - --hash=sha256:538b69134cc50bdcdcc081b844c85158509022c61d7abc1f44216beeb95de9cd -certbot-apache==0.16.0 \ - --hash=sha256:337f84f391c7d7c31d84376e7a8c882ac119112a4aabceadd1a7de6a2f01ca06 \ - --hash=sha256:f1f37b56e1ceb0a28ccf51d54ca34444e6a708448845ef25372e223b9a82c4d4 -certbot-nginx==0.16.0 \ - --hash=sha256:1d57428202f8e7abdd99c3ddbcf374aad5f69c4262fe8dae53d2016e4ae04ded \ - --hash=sha256:77711655514d707ddf728195f00b2f6cdd1ad9db52440276b4a67664479c6954 +certbot==0.17.0 \ + --hash=sha256:64c25c7123357feffded6408660bc6f5c7d493dd635ae172081d21473075a86a \ + --hash=sha256:43f5b26c3f314d14babf79a3bdf3522e4fc9eef867a0681c426f113c650a669c +acme==0.17.0 \ + --hash=sha256:501710171633af13fc52aa61d0277a6fe335f7477db5810e72239aaf4f3a09e7 \ + --hash=sha256:3ccbe4aaeb98c77b98ee4093b4e4adb76a1a24cbdfec0130c489c206f1d9b66e +certbot-apache==0.17.0 \ + --hash=sha256:17a7e8d7526d838610e68b96cf052af17c4055655b76b06d1cbc74857d90a216 \ + --hash=sha256:29b9e7bc5eaaff6dc4bce8398e35eeacdf346126aad68cac3d41bb87df20a6b9 +certbot-nginx==0.17.0 \ + --hash=sha256:980c9a33a79ab839a089a0085ff0c5414f01f47b6db26ed342df25916658cec9 \ + --hash=sha256:e573f8b4283172755c07b9cca8a8da7ef2d31b4df763881394b5339b2d42994a UNLIKELY_EOF # ------------------------------------------------------------------------- diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig index 72ade22dc968edccc5def0ef8890ce432ac28c37..a8885d19a8a019fe066b56413c88c5b4c18fe480 100644 GIT binary patch literal 256 zcmV+b0ssD-;W!OOUZzGi_iFiTi<5HF*l62cevBJsaim8|jiad+GagzA1@*IAt80cZ~=?45o9pq~DzcX%?T+f76vxd1SH@e?cbnz9V7Gk{#$I_qlph1%RWSG-^`UlbnZuGSID1Xo%_C5H;Lh=+qz GN5G#rse^w2 diff --git a/letsencrypt-auto-source/pieces/certbot-requirements.txt b/letsencrypt-auto-source/pieces/certbot-requirements.txt index 3c91c6e76..808a6a8a5 100644 --- a/letsencrypt-auto-source/pieces/certbot-requirements.txt +++ b/letsencrypt-auto-source/pieces/certbot-requirements.txt @@ -1,12 +1,12 @@ -certbot==0.16.0 \ - --hash=sha256:e1cc2479f4f149a7128b67192c3f5f6c111b6b9ddcac421ebee8ac5030d5b09b \ - --hash=sha256:795801fd6b06b32060e364ac045312e6b26c6272d5ca32878277e5a2afdee186 -acme==0.16.0 \ - --hash=sha256:31592a744f7a6e7cbb4c5daf2deebc9af6b03997d6f80e5becc203ab8694edcf \ - --hash=sha256:538b69134cc50bdcdcc081b844c85158509022c61d7abc1f44216beeb95de9cd -certbot-apache==0.16.0 \ - --hash=sha256:337f84f391c7d7c31d84376e7a8c882ac119112a4aabceadd1a7de6a2f01ca06 \ - --hash=sha256:f1f37b56e1ceb0a28ccf51d54ca34444e6a708448845ef25372e223b9a82c4d4 -certbot-nginx==0.16.0 \ - --hash=sha256:1d57428202f8e7abdd99c3ddbcf374aad5f69c4262fe8dae53d2016e4ae04ded \ - --hash=sha256:77711655514d707ddf728195f00b2f6cdd1ad9db52440276b4a67664479c6954 +certbot==0.17.0 \ + --hash=sha256:64c25c7123357feffded6408660bc6f5c7d493dd635ae172081d21473075a86a \ + --hash=sha256:43f5b26c3f314d14babf79a3bdf3522e4fc9eef867a0681c426f113c650a669c +acme==0.17.0 \ + --hash=sha256:501710171633af13fc52aa61d0277a6fe335f7477db5810e72239aaf4f3a09e7 \ + --hash=sha256:3ccbe4aaeb98c77b98ee4093b4e4adb76a1a24cbdfec0130c489c206f1d9b66e +certbot-apache==0.17.0 \ + --hash=sha256:17a7e8d7526d838610e68b96cf052af17c4055655b76b06d1cbc74857d90a216 \ + --hash=sha256:29b9e7bc5eaaff6dc4bce8398e35eeacdf346126aad68cac3d41bb87df20a6b9 +certbot-nginx==0.17.0 \ + --hash=sha256:980c9a33a79ab839a089a0085ff0c5414f01f47b6db26ed342df25916658cec9 \ + --hash=sha256:e573f8b4283172755c07b9cca8a8da7ef2d31b4df763881394b5339b2d42994a From 744c9930407f22f1781032bc57d283f007787dad Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 1 Aug 2017 17:01:19 -0700 Subject: [PATCH 13/31] Bump version to 0.18.0 --- acme/setup.py | 2 +- certbot-apache/setup.py | 2 +- certbot-compatibility-test/setup.py | 2 +- certbot-dns-cloudflare/setup.py | 2 +- certbot-dns-cloudxns/setup.py | 2 +- certbot-dns-digitalocean/setup.py | 2 +- certbot-dns-dnsimple/setup.py | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- certbot-dns-google/setup.py | 2 +- certbot-dns-luadns/setup.py | 2 +- certbot-dns-nsone/setup.py | 2 +- certbot-dns-rfc2136/setup.py | 2 +- certbot-dns-route53/setup.py | 2 +- certbot-nginx/setup.py | 2 +- certbot/__init__.py | 2 +- letsencrypt-auto-source/letsencrypt-auto | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/acme/setup.py b/acme/setup.py index 05480f5b0..dad845c04 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.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 fa6268a4d..ea0085dfc 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.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 4bb991f97..9a348f1f9 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.17.0' +version = '0.18.0.dev0' install_requires = [ 'certbot', diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index 2d264c100..e301ae06f 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index 6d8d57bad..61e741600 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 45ffbd060..113936945 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index dba26f0ac..24d880bef 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 98c3cc7ce..cbae5303d 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 03e10f9d9..ad54b94a5 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 059fa0c7f..68061ced0 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index fb7114d6b..0a562afec 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index f1dfca337..f225e6a89 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -4,7 +4,7 @@ from setuptools import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index ac01d8982..46fff80c6 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -3,7 +3,7 @@ import sys from distutils.core import setup from setuptools import find_packages -version = '0.17.0' +version = '0.18.0.dev0' install_requires = [ 'acme=={0}'.format(version), diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 5127f2f84..f89307816 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.17.0' +version = '0.18.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ diff --git a/certbot/__init__.py b/certbot/__init__.py index 495da7a4c..6c5eff32b 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.17.0' +__version__ = '0.18.0.dev0' diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index b935ed447..3a929d036 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -28,7 +28,7 @@ if [ -z "$VENV_PATH" ]; then VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" fi VENV_BIN="$VENV_PATH/bin" -LE_AUTO_VERSION="0.17.0" +LE_AUTO_VERSION="0.18.0.dev0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates From 4f74b8eb7aa5ed2446cac552eb02f60e054de2b1 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 2 Aug 2017 12:06:02 -0700 Subject: [PATCH 14/31] Update changelog for 0.17.0 --- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a33b053a..bb8cafff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,45 @@ Certbot adheres to [Semantic Versioning](http://semver.org/). +## 0.17.0 - 2017-08-02 + +### Added + +* Support in our nginx plugin for modifying SSL server blocks that do + not contain certificate or key directives. +* A `--max-log-backups` flag to allow users to configure or even completely + disable Certbot's built in log rotation. +* A `--user-agent-comment` flag to allow people who build tools around Certbot + to differentiate their user agent string by adding a comment to its default + value. + +### Changed + +* Due to some awesome work by + [cryptography project](https://github.com/pyca/cryptography), compilation can + now be avoided on most systems when using certbot-auto. This eliminates many + problems people have had in the past such as running out of memory, having + invalid headers/libraries, and changes to the OS packages on their system + after compilation breaking Certbot. +* The `--renew-hook` flag has been hidden in favor of `--deploy-hook`. This new + flag works exactly the same way except it is always run when a certificate is + issued rather than just when it is renewed. +* We have started printing deprecation warnings in certbot-auto for + experimentally supported systems with OS packages available. +* A certificate lineage's name is included in error messages during renewal. + +### Fixed + +* Encoding errors that could occur when parsing error messages from the acme + server containing Unicode have been resolved. +* certbot-auto no longer prints misleading messages about their being a newer + pip version available when installation fails. +* Certbot's acme library now properly extracts domains from critical SAN + extensions. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.17.0+is%3Aclosed + ## 0.16.0 - 2017-07-05 ### Added From c0d10bba5a127e8010cd5df412555f952512c3a6 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 2 Aug 2017 12:11:19 -0700 Subject: [PATCH 15/31] typos and grammar --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb8cafff8..377c472f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,11 +31,11 @@ Certbot adheres to [Semantic Versioning](http://semver.org/). ### Fixed -* Encoding errors that could occur when parsing error messages from the acme +* Encoding errors that could occur when parsing error messages from the ACME server containing Unicode have been resolved. -* certbot-auto no longer prints misleading messages about their being a newer +* certbot-auto no longer prints misleading messages about there being a newer pip version available when installation fails. -* Certbot's acme library now properly extracts domains from critical SAN +* Certbot's ACME library now properly extracts domains from critical SAN extensions. More details about these changes can be found on our GitHub repo: From 5508d1dd125762fc907cc31cd5efab38dd0685b1 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 3 Aug 2017 13:45:55 -0700 Subject: [PATCH 16/31] Fix space in quiet check in BootstrapArchCommon --- letsencrypt-auto-source/letsencrypt-auto | 2 +- letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 7fe61a19c..4528a2bf3 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -492,7 +492,7 @@ BootstrapArchCommon() { fi if [ "$missing" ]; then - if [ "$QUIET" = 1]; then + if [ "$QUIET" = 1 ]; then $SUDO pacman -S --needed $missing $noconfirm > /dev/null else $SUDO pacman -S --needed $missing $noconfirm diff --git a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh index c3959484b..e9d91fe70 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh @@ -25,7 +25,7 @@ BootstrapArchCommon() { fi if [ "$missing" ]; then - if [ "$QUIET" = 1]; then + if [ "$QUIET" = 1 ]; then $SUDO pacman -S --needed $missing $noconfirm > /dev/null else $SUDO pacman -S --needed $missing $noconfirm From d4676610e9009397000522cc1fe5420242905e86 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 7 Aug 2017 08:36:41 -0700 Subject: [PATCH 17/31] Unhide Nginx (#4969) * Be careful with new interaction from enabling nginx * Fix py3 compataibility & better docs * Make minor changes to @pde's PR to unhide nginx * unhide nginx plugin * Only protect against nginx interaction in cb-auto --- certbot-nginx/certbot_nginx/configurator.py | 2 -- certbot/plugins/selection.py | 12 ++++++++-- certbot/plugins/selection_test.py | 25 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/certbot-nginx/certbot_nginx/configurator.py b/certbot-nginx/certbot_nginx/configurator.py index ec657a9db..fbe881bb0 100644 --- a/certbot-nginx/certbot_nginx/configurator.py +++ b/certbot-nginx/certbot_nginx/configurator.py @@ -87,8 +87,6 @@ class NginxConfigurator(common.Plugin): description = "Nginx Web Server plugin - Alpha" - hidden = True - DEFAULT_LISTEN_PORT = '80' @classmethod diff --git a/certbot/plugins/selection.py b/certbot/plugins/selection.py index fdfbf2b15..9e2ddf609 100644 --- a/certbot/plugins/selection.py +++ b/certbot/plugins/selection.py @@ -108,11 +108,19 @@ def choose_plugin(prepared, question): opts = [plugin_ep.description_with_name + (" [Misconfigured]" if plugin_ep.misconfigured else "") for plugin_ep in prepared] + names = set(plugin_ep.name for plugin_ep in prepared) while True: disp = z_util(interfaces.IDisplay) - code, index = disp.menu( - question, opts, force_interactive=True) + if "CERTBOT_AUTO" in os.environ and names == set(("apache", "nginx")): + # The possibility of being offered exactly apache and nginx here + # is new interactivity brought by https://github.com/certbot/certbot/issues/4079, + # so set apache as a default for those kinds of non-interactive use + # (the user will get a warning to set --non-interactive or --force-interactive) + apache_idx = [n for n, p in enumerate(prepared) if p.name == "apache"][0] + code, index = disp.menu(question, opts, default=apache_idx) + else: + code, index = disp.menu(question, opts, force_interactive=True) if code == display_util.OK: plugin_ep = prepared[index] diff --git a/certbot/plugins/selection_test.py b/certbot/plugins/selection_test.py index 9f0716905..4112810a2 100644 --- a/certbot/plugins/selection_test.py +++ b/certbot/plugins/selection_test.py @@ -1,4 +1,5 @@ """Tests for letsencrypt.plugins.selection""" +import os import sys import unittest @@ -115,6 +116,7 @@ class ChoosePluginTest(unittest.TestCase): False)) self.mock_apache = mock.Mock( description_with_name="a", misconfigured=True) + self.mock_apache.name = "apache" self.mock_stand = mock.Mock( description_with_name="s", misconfigured=False) self.mock_stand.init().more_info.return_value = "standalone" @@ -146,3 +148,26 @@ class ChoosePluginTest(unittest.TestCase): def test_no_choice(self, mock_util): mock_util().menu.return_value = (display_util.CANCEL, 0) self.assertTrue(self._call() is None) + + @test_util.patch_get_utility("certbot.plugins.selection.z_util") + def test_new_interaction_avoidance(self, mock_util): + mock_nginx = mock.Mock( + description_with_name="n", misconfigured=False) + mock_nginx.init().more_info.return_value = "nginx plugin" + mock_nginx.name = "nginx" + self.plugins[1] = mock_nginx + mock_util().menu.return_value = (display_util.CANCEL, 0) + + unset_cb_auto = os.environ.get("CERTBOT_AUTO") is None + if unset_cb_auto: + os.environ["CERTBOT_AUTO"] = "foo" + try: + self._call() + finally: + if unset_cb_auto: + del os.environ["CERTBOT_AUTO"] + + self.assertTrue("default" in mock_util().menu.call_args[1]) + +if __name__ == "__main__": + unittest.main() # pragma: no cover From f68fba2be2fc342dd72deaaf048ab79e5a8fc2be Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 7 Aug 2017 14:57:56 -0700 Subject: [PATCH 18/31] Fix oldest tests by pinning Google DNS deps (#5000) --- tox.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tox.ini b/tox.ini index 299b7f20f..dee14b8b3 100644 --- a/tox.ini +++ b/tox.ini @@ -85,11 +85,14 @@ deps = configobj==4.7.2 cryptography==1.2.3 enum34==0.9.23 + google-api-python-client==1.5 idna==2.0 ipaddress==1.0.16 mock==1.0.1 ndg-httpsclient==0.3.2 + oauth2client==2.0 parsedatetime==1.4 + pyasn1-modules==0.0.5 pyasn1==0.1.9 pyparsing==1.5.6 pyrfc3339==1.0 From 0ac21e47c76fa6bf612de005f286adec5f966c71 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 7 Aug 2017 17:12:49 -0700 Subject: [PATCH 19/31] Use #letsencrypt-dev instead of #letsencrypt (#4998) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8126b06b2..3edf9b167 100644 --- a/.travis.yml +++ b/.travis.yml @@ -169,7 +169,7 @@ notifications: email: false irc: channels: - - "chat.freenode.net#letsencrypt" + - "chat.freenode.net#letsencrypt-dev" on_success: never on_failure: always use_notice: true From f31cb5f8129201c8710d2802416bd1fbc540642e Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 7 Aug 2017 17:12:58 -0700 Subject: [PATCH 20/31] Put the minimum dep version in Google DNS setup.py (#5002) --- certbot-dns-google/setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index ad54b94a5..52ad15225 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -10,9 +10,11 @@ version = '0.18.0.dev0' install_requires = [ 'acme=={0}'.format(version), 'certbot=={0}'.format(version), - 'google-api-python-client', + # 1.5 is the first version that supports oauth2client>=2.0 + 'google-api-python-client>=1.5', 'mock', - 'oauth2client', + # for oauth2client.service_account.ServiceAccountCredentials + 'oauth2client>=2.0', # For pkg_resources. >=1.0 so pip resolves it to a version cryptography # will tolerate; see #2599: 'setuptools>=1.0', From f9ed53e6988f313d4e5f3fd817a17356ec445bb5 Mon Sep 17 00:00:00 2001 From: Noah Swartz Date: Mon, 7 Aug 2017 17:13:27 -0700 Subject: [PATCH 21/31] Revocation reason (#4987) * fix revocation reason help text * add it to the docs * move and expand revoke reason example --- certbot/cli.py | 5 +++-- docs/using.rst | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/certbot/cli.py b/certbot/cli.py index 7135f7600..e8b825a91 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -1156,9 +1156,10 @@ def _create_subparsers(helpful): " Currently --csr only works with the 'certonly' subcommand.") helpful.add("revoke", "--reason", dest="reason", - choices=CaseInsensitiveList(constants.REVOCATION_REASONS.keys()), + choices=CaseInsensitiveList(sorted(constants.REVOCATION_REASONS, + key=constants.REVOCATION_REASONS.get)), action=_EncodeReasonAction, default=0, - help="Specify reason for revoking certificate.") + help="Specify reason for revoking certificate. (default: unspecified)") helpful.add("rollback", "--checkpoints", type=int, metavar="N", default=flag_default("rollback_checkpoints"), diff --git a/docs/using.rst b/docs/using.rst index aae8efbf2..8d9a22847 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -383,6 +383,12 @@ use the ``revoke`` command to do so. Note that the ``revoke`` command takes the certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem +You can also specify the reason for revoking your certificate by using the ``reason`` flag. +Reasons include ``unspecified`` which is the default, as well as ``keycompromise``, +``affiliationchanged``, ``superseded``, and ``cessationofoperation``:: + + certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem --reason keycompromise + Additionally, if a certificate is a test certificate obtained via the ``--staging`` or ``--test-cert`` flag, that flag must be passed to the ``revoke`` subcommand. From 47b3d19170f20cbc22f54d82457c057dd6473f66 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 8 Aug 2017 12:03:48 -0700 Subject: [PATCH 22/31] Increase pinned configargparse version to 0.12.0. (#4995) --- letsencrypt-auto-source/letsencrypt-auto | 4 ++-- letsencrypt-auto-source/pieces/dependency-requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index e48785066..3c3227b41 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -766,8 +766,8 @@ cffi==1.10.0 \ --hash=sha256:285ab352552f52f1398c912556d4d36d4ea9b8450e5c65d03809bf9886755533 \ --hash=sha256:5576644b859197da7bbd8f8c7c2fb5dcc6cd505cadb42992d5f104c013f8a214 \ --hash=sha256:b3b02911eb1f6ada203b0763ba924234629b51586f72a21faacc638269f4ced5 -ConfigArgParse==0.10.0 \ - --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 +ConfigArgParse==0.12.0 \ + --hash=sha256:28cd7d67669651f2a4518367838c49539457504584a139709b2b8f6c208ef339 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 cryptography==2.0.2 \ diff --git a/letsencrypt-auto-source/pieces/dependency-requirements.txt b/letsencrypt-auto-source/pieces/dependency-requirements.txt index 9f98c7520..4b3da685c 100644 --- a/letsencrypt-auto-source/pieces/dependency-requirements.txt +++ b/letsencrypt-auto-source/pieces/dependency-requirements.txt @@ -58,8 +58,8 @@ cffi==1.10.0 \ --hash=sha256:285ab352552f52f1398c912556d4d36d4ea9b8450e5c65d03809bf9886755533 \ --hash=sha256:5576644b859197da7bbd8f8c7c2fb5dcc6cd505cadb42992d5f104c013f8a214 \ --hash=sha256:b3b02911eb1f6ada203b0763ba924234629b51586f72a21faacc638269f4ced5 -ConfigArgParse==0.10.0 \ - --hash=sha256:3b50a83dd58149dfcee98cb6565265d10b53e9c0a2bca7eeef7fb5f5524890a7 +ConfigArgParse==0.12.0 \ + --hash=sha256:28cd7d67669651f2a4518367838c49539457504584a139709b2b8f6c208ef339 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 cryptography==2.0.2 \ From 6c52cc49a7fdf05b00aaac2385c6f5d9c54b72ec Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 8 Aug 2017 15:31:41 -0700 Subject: [PATCH 23/31] Pin dependencies in compatibility tests. (#5004) We now use tools/pip_install_editable.sh which installs our packages using the pinned versions from certbot-auto. We also use letsencrypt-auto-source/letsencrypt-auto instead of certbot-auto in the root to: 1. Make sure OS bootstrappers are up to date with master. 2. Copy letsencrypt-auto-source into our tree so it can be used by tools/pip_install_editable.sh later. --- certbot-compatibility-test/Dockerfile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/certbot-compatibility-test/Dockerfile b/certbot-compatibility-test/Dockerfile index bb9359ce8..fe55a68a6 100644 --- a/certbot-compatibility-test/Dockerfile +++ b/certbot-compatibility-test/Dockerfile @@ -8,8 +8,8 @@ MAINTAINER Brad Warren # TODO: Install non-default Python versions for tox. # TODO: Install Apache/Nginx for plugin development. -COPY certbot-auto /opt/certbot/src/certbot-auto -RUN /opt/certbot/src/certbot-auto -n --os-packages-only +COPY letsencrypt-auto-source /opt/certbot/src/letsencrypt-auto-source +RUN /opt/certbot/src/letsencrypt-auto-source/letsencrypt-auto --os-packages-only # the above is not likely to change, so by putting it further up the # Dockerfile we make sure we cache as much as possible @@ -29,16 +29,18 @@ COPY acme /opt/certbot/src/acme/ COPY certbot-apache /opt/certbot/src/certbot-apache/ COPY certbot-nginx /opt/certbot/src/certbot-nginx/ COPY certbot-compatibility-test /opt/certbot/src/certbot-compatibility-test/ +COPY tools /opt/certbot/src/tools RUN virtualenv --no-site-packages -p python2 /opt/certbot/venv && \ /opt/certbot/venv/bin/pip install -U setuptools && \ - /opt/certbot/venv/bin/pip install -U pip && \ - /opt/certbot/venv/bin/pip install \ - -e /opt/certbot/src/acme \ - -e /opt/certbot/src \ - -e /opt/certbot/src/certbot-apache \ - -e /opt/certbot/src/certbot-nginx \ - -e /opt/certbot/src/certbot-compatibility-test + /opt/certbot/venv/bin/pip install -U pip +ENV PATH /opt/certbot/venv/bin:$PATH +RUN /opt/certbot/src/tools/pip_install_editable.sh \ + /opt/certbot/src/acme \ + /opt/certbot/src \ + /opt/certbot/src/certbot-apache \ + /opt/certbot/src/certbot-nginx \ + /opt/certbot/src/certbot-compatibility-test # install in editable mode (-e) to save space: it's not possible to # "rm -rf /opt/certbot/src" (it's stays in the underlaying image); @@ -46,5 +48,3 @@ RUN virtualenv --no-site-packages -p python2 /opt/certbot/venv && \ # bash" and investigate, apply patches, etc. WORKDIR /opt/certbot/src/certbot-compatibility-test/certbot_compatibility_test/testdata - -ENV PATH /opt/certbot/venv/bin:$PATH From 5e58580d130ee09657f9d752e7ffa6f566b45149 Mon Sep 17 00:00:00 2001 From: Bob Strecansky Date: Wed, 9 Aug 2017 12:12:36 -0400 Subject: [PATCH 24/31] [#4966] - Fedora 26 doesn't have development tools handy (#4997) --- letsencrypt-auto-source/letsencrypt-auto | 17 +++++++++++++++-- .../pieces/bootstrappers/rpm_common.sh | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 3c3227b41..39f8728e8 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -410,8 +410,7 @@ BootstrapRpmCommon() { ca-certificates " - # Some distros and older versions of current distros use a "python27" - # instead of "python" naming convention. Try both conventions. + # Most RPM distros use the "python" or "python-" naming convention. Let's try that first. if $SUDO $tool list python >/dev/null 2>&1; then pkgs="$pkgs python @@ -420,6 +419,20 @@ BootstrapRpmCommon() { python-tools python-pip " + # Fedora 26 starts to use the prefix python2 for python2 based packages. + # this elseif is theoretically for any Fedora over version 26: + elif $SUDO $tool list python2 >/dev/null 2>&1; then + pkgs="$pkgs + python2 + python2-libs + python2-setuptools + python2-devel + python2-virtualenv + python2-tools + python2-pip + " + # Some distros and older versions of current distros use a "python27" + # instead of the "python" or "python-" naming convention. else pkgs="$pkgs python27 diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh index dcd535292..965ee32f3 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh @@ -54,8 +54,7 @@ BootstrapRpmCommon() { ca-certificates " - # Some distros and older versions of current distros use a "python27" - # instead of "python" naming convention. Try both conventions. + # Most RPM distros use the "python" or "python-" naming convention. Let's try that first. if $SUDO $tool list python >/dev/null 2>&1; then pkgs="$pkgs python @@ -64,6 +63,20 @@ BootstrapRpmCommon() { python-tools python-pip " + # Fedora 26 starts to use the prefix python2 for python2 based packages. + # this elseif is theoretically for any Fedora over version 26: + elif $SUDO $tool list python2 >/dev/null 2>&1; then + pkgs="$pkgs + python2 + python2-libs + python2-setuptools + python2-devel + python2-virtualenv + python2-tools + python2-pip + " + # Some distros and older versions of current distros use a "python27" + # instead of the "python" or "python-" naming convention. else pkgs="$pkgs python27 From 48c890be61b26b4bf0b3767df994e036a14dda66 Mon Sep 17 00:00:00 2001 From: cj-dev Date: Wed, 9 Aug 2017 16:19:43 -0400 Subject: [PATCH 25/31] #4434 Test Config Base Class (#4974) * Addressing #4434 by implementing ConfigTestCase which mocks out a NamespaceConfig for consistent config use across tests * Refactor account_test.py for use with ConfigTestCase * Remove superfluous setup/teardown * Pylint oops. * Fix redundant inheritance class definitions * Separate ConfigTestCase's mocked directories * Module import style consistency * Refactor log_test.py for use with ConfigTestCase * Refactor eff_test.py for use with ConfigTestCase. Also tweak for import style consistency * Refactor reverter_test.py for use with ConfigTestCase * Refactor renewal_test.py for use with ConfigTestCase * Refactor main_test.py for use with ConfigTestCase * Refactor storage_test.py for use with ConfigTestCase * Refactor cert_manager_test.py for use with ConfigTestCase * Refactor client_test.py for use with ConfigTestCase * Refactor configuration_test.py for use with ConfigTestCase * Pylint! * Incorporating PR feedback * Remove comment --- certbot/tests/account_test.py | 15 +- certbot/tests/cert_manager_test.py | 158 ++++++++++----------- certbot/tests/client_test.py | 30 ++-- certbot/tests/configuration_test.py | 50 ++++--- certbot/tests/eff_test.py | 24 ++-- certbot/tests/log_test.py | 15 +- certbot/tests/main_test.py | 60 +++----- certbot/tests/renewal_test.py | 23 ++- certbot/tests/reverter_test.py | 23 +-- certbot/tests/storage_test.py | 211 +++++++++++++--------------- certbot/tests/util.py | 15 ++ 11 files changed, 284 insertions(+), 340 deletions(-) diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index 5950dcda9..575a40286 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -14,12 +14,10 @@ from acme import messages from certbot import errors -from certbot.tests import util - -from certbot.tests.util import TempDirTestCase +import certbot.tests.util as test_util -KEY = jose.JWKRSA.load(util.load_vector("rsa512_key_2.pem")) +KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key_2.pem")) class AccountTest(unittest.TestCase): @@ -58,12 +56,9 @@ class AccountTest(unittest.TestCase): self.assertTrue(repr(self.acc).startswith( " Date: Fri, 11 Aug 2017 01:51:19 +0200 Subject: [PATCH 26/31] Include plugin selection at the info logging level (#5010) * Plugin selection on INFO * Fixed lint errors * Fixed lint errors * record_chosen_plugin log plugin --- certbot/main.py | 2 ++ certbot/plugins/selection.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/certbot/main.py b/certbot/main.py index a6e630540..d1ed6fe2b 100644 --- a/certbot/main.py +++ b/certbot/main.py @@ -645,6 +645,7 @@ def renew_cert(config, plugins, lineage): except errors.PluginSelectionError as e: logger.info("Could not choose appropriate plugin: %s", e) raise + le_client = _init_le_client(config, auth, installer) _get_and_save_cert(le_client, config, lineage=lineage) @@ -673,6 +674,7 @@ def certonly(config, plugins): except errors.PluginSelectionError as e: logger.info("Could not choose appropriate plugin: %s", e) raise + le_client = _init_le_client(config, auth, installer) if config.csr: diff --git a/certbot/plugins/selection.py b/certbot/plugins/selection.py index 9e2ddf609..5b1953187 100644 --- a/certbot/plugins/selection.py +++ b/certbot/plugins/selection.py @@ -142,6 +142,8 @@ def record_chosen_plugins(config, plugins, auth, inst): "Update the config entries to reflect the plugins we actually selected." config.authenticator = plugins.find_init(auth).name if auth else "None" config.installer = plugins.find_init(inst).name if inst else "None" + logger.info("Plugins selected: Authenticator %s, Installer %s", + config.authenticator, config.installer) def choose_configurator_plugins(config, plugins, verb): From cd2e70e9cdd225bcdfe95357ee244f1dd1b27013 Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Mon, 21 Aug 2017 20:27:24 +0200 Subject: [PATCH 27/31] Redirect to zenhack/simp_le (#5025) Kuba's simp_le has been unmaintained for more than a year and is starting to break. zenhack's fork is actively maintained and available through PyPI. --- docs/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install.rst b/docs/install.rst index fec556ec6..2b12edb47 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -30,7 +30,7 @@ configurations (if you use the ``apache`` or ``nginx`` plugins). If none of these apply to you, it is theoretically possible to run without root privileges, but for most users who want to avoid running an ACME client as root, either `letsencrypt-nosudo `_ or -`simp_le `_ are more appropriate choices. +`simp_le `_ are more appropriate choices. The Apache plugin currently requires an OS with augeas version 1.0; currently `it supports From 56db211367d171aed5ee9aee1eccd87041e14de8 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 21 Aug 2017 12:23:09 -0700 Subject: [PATCH 28/31] Change certbot-auto's installation path to /opt (#4970) * Update comment about root usage. * run all of certbot-auto as root * remove other $SUDO uses from template * remove $SUDO usage from bootstrappers * default venv path = /opt/eff.org/certbot/venv * Create symlinks from old default venvs * Delete old venv path when it exists. Also, quote expansion of paths. * fix typo * Separate venv_dir and le_auto_path * Deduplicate code with test_dirs() * Ignore cleanup errors. This is caused by subdirectories being owned by root. * Split test into test_phase2_upgrade. * Rename test_dirs to temp_paths for clarity. * Check both venvs before bootstrapping again. * Use OLD_VENV_PATH/bin * Preserve environment with sudo. * Remove "esp. under sudo" comment. * Export *VENV_PATH. * Change check for OLD_VENV installation. This approach better handles manually set VENV_PATH values. * Remove SUDO_ENV. * Print message before requesting root privileges. * Make a function for selecting root auth method. * Address @erikrose's feedback. --- letsencrypt-auto-source/letsencrypt-auto | 179 ++++++++++-------- .../letsencrypt-auto.template | 129 +++++++------ .../pieces/bootstrappers/arch_common.sh | 6 +- .../pieces/bootstrappers/deb_common.sh | 10 +- .../pieces/bootstrappers/free_bsd.sh | 2 +- .../pieces/bootstrappers/gentoo_common.sh | 6 +- .../pieces/bootstrappers/mac.sh | 6 +- .../pieces/bootstrappers/mageia_common.sh | 4 +- .../pieces/bootstrappers/rpm_common.sh | 14 +- .../pieces/bootstrappers/suse_common.sh | 2 +- letsencrypt-auto-source/tests/auto_test.py | 79 ++++---- 11 files changed, 241 insertions(+), 196 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 39f8728e8..8ce3342be 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -23,9 +23,11 @@ fi if [ -z "$XDG_DATA_HOME" ]; then XDG_DATA_HOME=~/.local/share fi -VENV_NAME="letsencrypt" if [ -z "$VENV_PATH" ]; then - VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" + # We export these values so they are preserved properly if this script is + # rerun with sudo/su where $HOME/$XDG_DATA_HOME may have a different value. + export OLD_VENV_PATH="$XDG_DATA_HOME/letsencrypt" + export VENV_PATH="/opt/eff.org/certbot/venv" fi VENV_BIN="$VENV_PATH/bin" LE_AUTO_VERSION="0.18.0.dev0" @@ -49,6 +51,7 @@ Help for certbot itself cannot be provided until it is installed. implies --non-interactive All arguments are accepted and forwarded to the Certbot client when run." +export CERTBOT_AUTO="$0" for arg in "$@" ; do case "$arg" in @@ -119,16 +122,18 @@ else exit 1 fi -# certbot-auto needs root access to bootstrap OS dependencies, and -# certbot itself needs root access for almost all modes of operation -# The "normal" case is that sudo is used for the steps that need root, but -# this script *can* be run as root (not recommended), or fall back to using -# `su`. Auto-detection can be overridden by explicitly setting the -# environment variable LE_AUTO_SUDO to 'sudo', 'sudo_su' or '' as used below. +# Certbot itself needs root access for almost all modes of operation. +# certbot-auto needs root access to bootstrap OS dependencies and install +# Certbot at a protected path so it can be safely run as root. To accomplish +# this, this script will attempt to run itself as root if it doesn't have the +# necessary privileges by using `sudo` or falling back to `su` if it is not +# available. The mechanism used to obtain root access can be set explicitly by +# setting the environment variable LE_AUTO_SUDO to 'sudo', 'su', 'su_sudo', +# 'SuSudo', or '' as used below. # Because the parameters in `su -c` has to be a string, # we need to properly escape it. -su_sudo() { +SuSudo() { args="" # This `while` loop iterates over all parameters given to this function. # For each parameter, all `'` will be replace by `'"'"'`, and the escaped string @@ -147,34 +152,47 @@ su_sudo() { su root -c "$args" } -SUDO_ENV="" -export CERTBOT_AUTO="$0" -if [ -n "${LE_AUTO_SUDO+x}" ]; then - case "$LE_AUTO_SUDO" in - su_sudo|su) - SUDO=su_sudo - ;; - sudo) - SUDO=sudo - SUDO_ENV="CERTBOT_AUTO=$0" - ;; - '') ;; # Nothing to do for plain root method. - *) - error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'." - exit 1 - esac - say "Using preset root authorization mechanism '$LE_AUTO_SUDO'." -else - if test "`id -u`" -ne "0" ; then - if $EXISTS sudo 1>/dev/null 2>&1; then - SUDO=sudo - SUDO_ENV="CERTBOT_AUTO=$0" - else - say \"sudo\" is not available, will use \"su\" for installation steps... - SUDO=su_sudo - fi +# Sets the environment variable SUDO to be the name of the program or function +# to call to get root access. If this script already has root privleges, SUDO +# is set to an empty string. The value in SUDO should be run with the command +# to called with root privileges as arguments. +SetRootAuthMechanism() { + SUDO="" + if [ -n "${LE_AUTO_SUDO+x}" ]; then + case "$LE_AUTO_SUDO" in + SuSudo|su_sudo|su) + SUDO=SuSudo + ;; + sudo) + SUDO="sudo -E" + ;; + '') ;; # Nothing to do for plain root method. + *) + error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'." + exit 1 + esac + say "Using preset root authorization mechanism '$LE_AUTO_SUDO'." else - SUDO= + if test "`id -u`" -ne "0" ; then + if $EXISTS sudo 1>/dev/null 2>&1; then + SUDO="sudo -E" + else + say \"sudo\" is not available, will use \"su\" for installation steps... + SUDO=SuSudo + fi + fi + fi +} + +if [ "$1" = "--cb-auto-has-root" ]; then + shift 1 +elif [ "$1" != "--le-auto-phase2" ]; then + # if $1 is --le-auto-phase2, we've executed this branch before + SetRootAuthMechanism + if [ -n "$SUDO" ]; then + echo "Requesting to rerun $0 with root privileges..." + $SUDO "$0" --cb-auto-has-root "$@" + exit 0 fi fi @@ -261,7 +279,7 @@ BootstrapDebCommon() { QUIET_FLAG='-qq' fi - $SUDO apt-get $QUIET_FLAG update || error apt-get update hit problems but continuing anyway... + apt-get $QUIET_FLAG update || error apt-get update hit problems but continuing anyway... # virtualenv binary can be found in different packages depending on # distro version (#346) @@ -311,13 +329,13 @@ BootstrapDebCommon() { esac fi if [ "$add_backports" = 1 ]; then - $SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" - $SUDO apt-get $QUIET_FLAG update + sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" + apt-get $QUIET_FLAG update fi fi fi if [ "$add_backports" != 0 ]; then - $SUDO apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg + apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg augeas_pkg= fi } @@ -336,7 +354,7 @@ BootstrapDebCommon() { # XXX add a case for ubuntu PPAs fi - $SUDO apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \ + apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \ python \ python-dev \ $virtualenv \ @@ -380,9 +398,9 @@ BootstrapRpmCommon() { QUIET_FLAG='--quiet' fi - if ! $SUDO $tool list *virtualenv >/dev/null 2>&1; then + if ! $tool list *virtualenv >/dev/null 2>&1; then echo "To use Certbot, packages from the EPEL repository need to be installed." - if ! $SUDO $tool list epel-release >/dev/null 2>&1; then + if ! $tool list epel-release >/dev/null 2>&1; then error "Enable the EPEL repository and try running Certbot again." exit 1 fi @@ -394,7 +412,7 @@ BootstrapRpmCommon() { /bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 seconds..." sleep 1s fi - if ! $SUDO $tool install $yes_flag $QUIET_FLAG epel-release; then + if ! $tool install $yes_flag $QUIET_FLAG epel-release; then error "Could not enable EPEL. Aborting bootstrap!" exit 1 fi @@ -411,7 +429,7 @@ BootstrapRpmCommon() { " # Most RPM distros use the "python" or "python-" naming convention. Let's try that first. - if $SUDO $tool list python >/dev/null 2>&1; then + if $tool list python >/dev/null 2>&1; then pkgs="$pkgs python python-devel @@ -421,7 +439,7 @@ BootstrapRpmCommon() { " # Fedora 26 starts to use the prefix python2 for python2 based packages. # this elseif is theoretically for any Fedora over version 26: - elif $SUDO $tool list python2 >/dev/null 2>&1; then + elif $tool list python2 >/dev/null 2>&1; then pkgs="$pkgs python2 python2-libs @@ -443,13 +461,13 @@ BootstrapRpmCommon() { " fi - if $SUDO $tool list installed "httpd" >/dev/null 2>&1; then + if $tool list installed "httpd" >/dev/null 2>&1; then pkgs="$pkgs mod_ssl " fi - if ! $SUDO $tool install $yes_flag $QUIET_FLAG $pkgs; then + if ! $tool install $yes_flag $QUIET_FLAG $pkgs; then error "Could not install OS dependencies. Aborting bootstrap!" exit 1 fi @@ -467,7 +485,7 @@ BootstrapSuseCommon() { QUIET_FLAG='-qq' fi - $SUDO zypper $QUIET_FLAG $zypper_flags in $install_flags \ + zypper $QUIET_FLAG $zypper_flags in $install_flags \ python \ python-devel \ python-virtualenv \ @@ -498,7 +516,7 @@ BootstrapArchCommon() { " # pacman -T exits with 127 if there are missing dependencies - missing=$($SUDO pacman -T $deps) || true + missing=$(pacman -T $deps) || true if [ "$ASSUME_YES" = 1 ]; then noconfirm="--noconfirm" @@ -506,9 +524,9 @@ BootstrapArchCommon() { if [ "$missing" ]; then if [ "$QUIET" = 1 ]; then - $SUDO pacman -S --needed $missing $noconfirm > /dev/null + pacman -S --needed $missing $noconfirm > /dev/null else - $SUDO pacman -S --needed $missing $noconfirm + pacman -S --needed $missing $noconfirm fi fi } @@ -530,13 +548,13 @@ BootstrapGentooCommon() { case "$PACKAGE_MANAGER" in (paludis) - $SUDO cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x + cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x ;; (pkgcore) - $SUDO pmerge --noreplace --oneshot $ASK_OPTION $PACKAGES + pmerge --noreplace --oneshot $ASK_OPTION $PACKAGES ;; (portage|*) - $SUDO emerge --noreplace --oneshot $ASK_OPTION $PACKAGES + emerge --noreplace --oneshot $ASK_OPTION $PACKAGES ;; esac } @@ -546,7 +564,7 @@ BootstrapFreeBsd() { QUIET_FLAG="--quiet" fi - $SUDO pkg install -Ay $QUIET_FLAG \ + pkg install -Ay $QUIET_FLAG \ python \ py27-virtualenv \ augeas \ @@ -561,7 +579,7 @@ BootstrapMac() { elif hash port 2>/dev/null; then say "Using MacPorts to install dependencies..." pkgman=port - pkgcmd="$SUDO port install" + pkgcmd="port install" else say "No Homebrew/MacPorts; installing Homebrew..." ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" @@ -581,8 +599,8 @@ BootstrapMac() { # Workaround for _dlopen not finding augeas on macOS if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then say "Applying augeas workaround" - $SUDO mkdir -p /usr/local/lib/ - $SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/ + mkdir -p /usr/local/lib/ + ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/ fi if ! hash pip 2>/dev/null; then @@ -608,7 +626,7 @@ BootstrapMageiaCommon() { QUIET_FLAG='--quiet' fi - if ! $SUDO urpmi --force $QUIET_FLAG \ + if ! urpmi --force $QUIET_FLAG \ python \ libpython-devel \ python-virtualenv @@ -617,7 +635,7 @@ BootstrapMageiaCommon() { exit 1 fi - if ! $SUDO urpmi --force $QUIET_FLAG \ + if ! urpmi --force $QUIET_FLAG \ git \ gcc \ python-augeas \ @@ -1144,20 +1162,15 @@ UNLIKELY_EOF rm -rf "$VENV_PATH" exit 1 fi + + if [ -d "$OLD_VENV_PATH" -a ! -L "$OLD_VENV_PATH" ]; then + rm -rf "$OLD_VENV_PATH" + ln -s "$VENV_PATH" "$OLD_VENV_PATH" + fi + say "Installation succeeded." fi - if [ -n "$SUDO" ]; then - # SUDO is su wrapper or sudo - say "Requesting root privileges to run certbot..." - say " $VENV_BIN/letsencrypt" "$@" - fi - if [ -z "$SUDO_ENV" ] ; then - # SUDO is su wrapper / noop - $SUDO "$VENV_BIN/letsencrypt" "$@" - else - # sudo - $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" - fi + "$VENV_BIN/letsencrypt" "$@" else # Phase 1: Upgrade certbot-auto if necessary, then self-invoke. @@ -1168,12 +1181,14 @@ else # package). Phase 2 checks the version of the locally installed certbot. if [ ! -f "$VENV_BIN/letsencrypt" ]; then - if [ "$HELP" = 1 ]; then - echo "$USAGE" - exit 0 + if [ -z "$OLD_VENV_PATH" -o ! -f "$OLD_VENV_PATH/bin/letsencrypt" ]; then + if [ "$HELP" = 1 ]; then + echo "$USAGE" + exit 0 + fi + # If it looks like we've never bootstrapped before, bootstrap: + Bootstrap fi - # If it looks like we've never bootstrapped before, bootstrap: - Bootstrap fi if [ "$OS_PACKAGES_ONLY" = 1 ]; then say "OS packages installed." @@ -1333,13 +1348,13 @@ UNLIKELY_EOF say "Replacing certbot-auto..." # Clone permissions with cp. chmod and chown don't have a --reference # option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD: - $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" - $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" + cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" + cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" # Using mv rather than cp leaves the old file descriptor pointing to the # original copy so the shell can continue to read it unmolested. mv across # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the - # cp is unlikely to fail (esp. under sudo) if the rm doesn't. - $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" + # cp is unlikely to fail if the rm doesn't. + mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" fi # A newer version is available. fi # Self-upgrading is allowed. diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index 284241a82..29aaf1291 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -23,9 +23,11 @@ fi if [ -z "$XDG_DATA_HOME" ]; then XDG_DATA_HOME=~/.local/share fi -VENV_NAME="letsencrypt" if [ -z "$VENV_PATH" ]; then - VENV_PATH="$XDG_DATA_HOME/$VENV_NAME" + # We export these values so they are preserved properly if this script is + # rerun with sudo/su where $HOME/$XDG_DATA_HOME may have a different value. + export OLD_VENV_PATH="$XDG_DATA_HOME/letsencrypt" + export VENV_PATH="/opt/eff.org/certbot/venv" fi VENV_BIN="$VENV_PATH/bin" LE_AUTO_VERSION="{{ LE_AUTO_VERSION }}" @@ -49,6 +51,7 @@ Help for certbot itself cannot be provided until it is installed. implies --non-interactive All arguments are accepted and forwarded to the Certbot client when run." +export CERTBOT_AUTO="$0" for arg in "$@" ; do case "$arg" in @@ -119,16 +122,18 @@ else exit 1 fi -# certbot-auto needs root access to bootstrap OS dependencies, and -# certbot itself needs root access for almost all modes of operation -# The "normal" case is that sudo is used for the steps that need root, but -# this script *can* be run as root (not recommended), or fall back to using -# `su`. Auto-detection can be overridden by explicitly setting the -# environment variable LE_AUTO_SUDO to 'sudo', 'sudo_su' or '' as used below. +# Certbot itself needs root access for almost all modes of operation. +# certbot-auto needs root access to bootstrap OS dependencies and install +# Certbot at a protected path so it can be safely run as root. To accomplish +# this, this script will attempt to run itself as root if it doesn't have the +# necessary privileges by using `sudo` or falling back to `su` if it is not +# available. The mechanism used to obtain root access can be set explicitly by +# setting the environment variable LE_AUTO_SUDO to 'sudo', 'su', 'su_sudo', +# 'SuSudo', or '' as used below. # Because the parameters in `su -c` has to be a string, # we need to properly escape it. -su_sudo() { +SuSudo() { args="" # This `while` loop iterates over all parameters given to this function. # For each parameter, all `'` will be replace by `'"'"'`, and the escaped string @@ -147,34 +152,47 @@ su_sudo() { su root -c "$args" } -SUDO_ENV="" -export CERTBOT_AUTO="$0" -if [ -n "${LE_AUTO_SUDO+x}" ]; then - case "$LE_AUTO_SUDO" in - su_sudo|su) - SUDO=su_sudo - ;; - sudo) - SUDO=sudo - SUDO_ENV="CERTBOT_AUTO=$0" - ;; - '') ;; # Nothing to do for plain root method. - *) - error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'." - exit 1 - esac - say "Using preset root authorization mechanism '$LE_AUTO_SUDO'." -else - if test "`id -u`" -ne "0" ; then - if $EXISTS sudo 1>/dev/null 2>&1; then - SUDO=sudo - SUDO_ENV="CERTBOT_AUTO=$0" - else - say \"sudo\" is not available, will use \"su\" for installation steps... - SUDO=su_sudo - fi +# Sets the environment variable SUDO to be the name of the program or function +# to call to get root access. If this script already has root privleges, SUDO +# is set to an empty string. The value in SUDO should be run with the command +# to called with root privileges as arguments. +SetRootAuthMechanism() { + SUDO="" + if [ -n "${LE_AUTO_SUDO+x}" ]; then + case "$LE_AUTO_SUDO" in + SuSudo|su_sudo|su) + SUDO=SuSudo + ;; + sudo) + SUDO="sudo -E" + ;; + '') ;; # Nothing to do for plain root method. + *) + error "Error: unknown root authorization mechanism '$LE_AUTO_SUDO'." + exit 1 + esac + say "Using preset root authorization mechanism '$LE_AUTO_SUDO'." else - SUDO= + if test "`id -u`" -ne "0" ; then + if $EXISTS sudo 1>/dev/null 2>&1; then + SUDO="sudo -E" + else + say \"sudo\" is not available, will use \"su\" for installation steps... + SUDO=SuSudo + fi + fi + fi +} + +if [ "$1" = "--cb-auto-has-root" ]; then + shift 1 +elif [ "$1" != "--le-auto-phase2" ]; then + # if $1 is --le-auto-phase2, we've executed this branch before + SetRootAuthMechanism + if [ -n "$SUDO" ]; then + echo "Requesting to rerun $0 with root privileges..." + $SUDO "$0" --cb-auto-has-root "$@" + exit 0 fi fi @@ -385,20 +403,15 @@ UNLIKELY_EOF rm -rf "$VENV_PATH" exit 1 fi + + if [ -d "$OLD_VENV_PATH" -a ! -L "$OLD_VENV_PATH" ]; then + rm -rf "$OLD_VENV_PATH" + ln -s "$VENV_PATH" "$OLD_VENV_PATH" + fi + say "Installation succeeded." fi - if [ -n "$SUDO" ]; then - # SUDO is su wrapper or sudo - say "Requesting root privileges to run certbot..." - say " $VENV_BIN/letsencrypt" "$@" - fi - if [ -z "$SUDO_ENV" ] ; then - # SUDO is su wrapper / noop - $SUDO "$VENV_BIN/letsencrypt" "$@" - else - # sudo - $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" - fi + "$VENV_BIN/letsencrypt" "$@" else # Phase 1: Upgrade certbot-auto if necessary, then self-invoke. @@ -409,12 +422,14 @@ else # package). Phase 2 checks the version of the locally installed certbot. if [ ! -f "$VENV_BIN/letsencrypt" ]; then - if [ "$HELP" = 1 ]; then - echo "$USAGE" - exit 0 + if [ -z "$OLD_VENV_PATH" -o ! -f "$OLD_VENV_PATH/bin/letsencrypt" ]; then + if [ "$HELP" = 1 ]; then + echo "$USAGE" + exit 0 + fi + # If it looks like we've never bootstrapped before, bootstrap: + Bootstrap fi - # If it looks like we've never bootstrapped before, bootstrap: - Bootstrap fi if [ "$OS_PACKAGES_ONLY" = 1 ]; then say "OS packages installed." @@ -445,13 +460,13 @@ UNLIKELY_EOF say "Replacing certbot-auto..." # Clone permissions with cp. chmod and chown don't have a --reference # option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD: - $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" - $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" + cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" + cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" # Using mv rather than cp leaves the old file descriptor pointing to the # original copy so the shell can continue to read it unmolested. mv across # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the - # cp is unlikely to fail (esp. under sudo) if the rm doesn't. - $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" + # cp is unlikely to fail if the rm doesn't. + mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" fi # A newer version is available. fi # Self-upgrading is allowed. diff --git a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh index e9d91fe70..3983bc1d8 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh @@ -18,7 +18,7 @@ BootstrapArchCommon() { " # pacman -T exits with 127 if there are missing dependencies - missing=$($SUDO pacman -T $deps) || true + missing=$(pacman -T $deps) || true if [ "$ASSUME_YES" = 1 ]; then noconfirm="--noconfirm" @@ -26,9 +26,9 @@ BootstrapArchCommon() { if [ "$missing" ]; then if [ "$QUIET" = 1 ]; then - $SUDO pacman -S --needed $missing $noconfirm > /dev/null + pacman -S --needed $missing $noconfirm > /dev/null else - $SUDO pacman -S --needed $missing $noconfirm + pacman -S --needed $missing $noconfirm fi fi } diff --git a/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh index afd279ac2..12aa80d63 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh @@ -21,7 +21,7 @@ BootstrapDebCommon() { QUIET_FLAG='-qq' fi - $SUDO apt-get $QUIET_FLAG update || error apt-get update hit problems but continuing anyway... + apt-get $QUIET_FLAG update || error apt-get update hit problems but continuing anyway... # virtualenv binary can be found in different packages depending on # distro version (#346) @@ -71,13 +71,13 @@ BootstrapDebCommon() { esac fi if [ "$add_backports" = 1 ]; then - $SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" - $SUDO apt-get $QUIET_FLAG update + sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list" + apt-get $QUIET_FLAG update fi fi fi if [ "$add_backports" != 0 ]; then - $SUDO apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg + apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends -t "$BACKPORT_NAME" $augeas_pkg augeas_pkg= fi } @@ -96,7 +96,7 @@ BootstrapDebCommon() { # XXX add a case for ubuntu PPAs fi - $SUDO apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \ + apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \ python \ python-dev \ $virtualenv \ diff --git a/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh b/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh index f1bc00f3b..cfbd2b8b1 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh @@ -3,7 +3,7 @@ BootstrapFreeBsd() { QUIET_FLAG="--quiet" fi - $SUDO pkg install -Ay $QUIET_FLAG \ + pkg install -Ay $QUIET_FLAG \ python \ py27-virtualenv \ augeas \ diff --git a/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh index 86a1ec7d6..46543bab9 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh @@ -15,13 +15,13 @@ BootstrapGentooCommon() { case "$PACKAGE_MANAGER" in (paludis) - $SUDO cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x + cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x ;; (pkgcore) - $SUDO pmerge --noreplace --oneshot $ASK_OPTION $PACKAGES + pmerge --noreplace --oneshot $ASK_OPTION $PACKAGES ;; (portage|*) - $SUDO emerge --noreplace --oneshot $ASK_OPTION $PACKAGES + emerge --noreplace --oneshot $ASK_OPTION $PACKAGES ;; esac } diff --git a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh index b88e96999..b9f347f67 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh @@ -6,7 +6,7 @@ BootstrapMac() { elif hash port 2>/dev/null; then say "Using MacPorts to install dependencies..." pkgman=port - pkgcmd="$SUDO port install" + pkgcmd="port install" else say "No Homebrew/MacPorts; installing Homebrew..." ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" @@ -26,8 +26,8 @@ BootstrapMac() { # Workaround for _dlopen not finding augeas on macOS if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then say "Applying augeas workaround" - $SUDO mkdir -p /usr/local/lib/ - $SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/ + mkdir -p /usr/local/lib/ + ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/ fi if ! hash pip 2>/dev/null; then diff --git a/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh index 1c76bbcac..c9a540ce1 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh @@ -3,7 +3,7 @@ BootstrapMageiaCommon() { QUIET_FLAG='--quiet' fi - if ! $SUDO urpmi --force $QUIET_FLAG \ + if ! urpmi --force $QUIET_FLAG \ python \ libpython-devel \ python-virtualenv @@ -12,7 +12,7 @@ BootstrapMageiaCommon() { exit 1 fi - if ! $SUDO urpmi --force $QUIET_FLAG \ + if ! urpmi --force $QUIET_FLAG \ git \ gcc \ python-augeas \ diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh index 965ee32f3..129684338 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh @@ -24,9 +24,9 @@ BootstrapRpmCommon() { QUIET_FLAG='--quiet' fi - if ! $SUDO $tool list *virtualenv >/dev/null 2>&1; then + if ! $tool list *virtualenv >/dev/null 2>&1; then echo "To use Certbot, packages from the EPEL repository need to be installed." - if ! $SUDO $tool list epel-release >/dev/null 2>&1; then + if ! $tool list epel-release >/dev/null 2>&1; then error "Enable the EPEL repository and try running Certbot again." exit 1 fi @@ -38,7 +38,7 @@ BootstrapRpmCommon() { /bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 seconds..." sleep 1s fi - if ! $SUDO $tool install $yes_flag $QUIET_FLAG epel-release; then + if ! $tool install $yes_flag $QUIET_FLAG epel-release; then error "Could not enable EPEL. Aborting bootstrap!" exit 1 fi @@ -55,7 +55,7 @@ BootstrapRpmCommon() { " # Most RPM distros use the "python" or "python-" naming convention. Let's try that first. - if $SUDO $tool list python >/dev/null 2>&1; then + if $tool list python >/dev/null 2>&1; then pkgs="$pkgs python python-devel @@ -65,7 +65,7 @@ BootstrapRpmCommon() { " # Fedora 26 starts to use the prefix python2 for python2 based packages. # this elseif is theoretically for any Fedora over version 26: - elif $SUDO $tool list python2 >/dev/null 2>&1; then + elif $tool list python2 >/dev/null 2>&1; then pkgs="$pkgs python2 python2-libs @@ -87,13 +87,13 @@ BootstrapRpmCommon() { " fi - if $SUDO $tool list installed "httpd" >/dev/null 2>&1; then + if $tool list installed "httpd" >/dev/null 2>&1; then pkgs="$pkgs mod_ssl " fi - if ! $SUDO $tool install $yes_flag $QUIET_FLAG $pkgs; then + if ! $tool install $yes_flag $QUIET_FLAG $pkgs; then error "Could not install OS dependencies. Aborting bootstrap!" exit 1 fi diff --git a/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh index e60ca8628..56e7acda3 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh @@ -10,7 +10,7 @@ BootstrapSuseCommon() { QUIET_FLAG='-qq' fi - $SUDO zypper $QUIET_FLAG $zypper_flags in $install_flags \ + zypper $QUIET_FLAG $zypper_flags in $install_flags \ python \ python-devel \ python-virtualenv \ diff --git a/letsencrypt-auto-source/tests/auto_test.py b/letsencrypt-auto-source/tests/auto_test.py index 6f21c28d5..5c63325ee 100644 --- a/letsencrypt-auto-source/tests/auto_test.py +++ b/letsencrypt-auto-source/tests/auto_test.py @@ -4,7 +4,7 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from contextlib import contextmanager from functools import partial from json import dumps -from os import chmod, environ +from os import chmod, environ, makedirs from os.path import abspath, dirname, exists, join import re from shutil import copy, rmtree @@ -118,12 +118,13 @@ LE_AUTO_PATH = join(dirname(tests_dir()), 'letsencrypt-auto') @contextmanager -def ephemeral_dir(): +def temp_paths(): + """Creates and deletes paths for letsencrypt-auto and its venv.""" dir = mkdtemp(prefix='le-test-') try: - yield dir + yield join(dir, 'letsencrypt-auto'), join(dir, 'venv') finally: - rmtree(dir) + rmtree(dir, ignore_errors=True) def out_and_err(command, input=None, shell=False, env=None): @@ -160,21 +161,20 @@ def signed(content, private_key_name='signing.key'): return out -def install_le_auto(contents, venv_dir): +def install_le_auto(contents, install_path): """Install some given source code as the letsencrypt-auto script at the root level of a virtualenv. :arg contents: The contents of the built letsencrypt-auto script - :arg venv_dir: The path under which to install the script + :arg install_path: The path where to install the script """ - venv_le_auto_path = join(venv_dir, 'letsencrypt-auto') - with open(venv_le_auto_path, 'w') as le_auto: + with open(install_path, 'w') as le_auto: le_auto.write(contents) - chmod(venv_le_auto_path, S_IRUSR | S_IXUSR) + chmod(install_path, S_IRUSR | S_IXUSR) -def run_le_auto(venv_dir, base_url, **kwargs): +def run_le_auto(le_auto_path, venv_dir, base_url, **kwargs): """Run the prebuilt version of letsencrypt-auto, returning stdout and stderr strings. @@ -182,7 +182,7 @@ def run_le_auto(venv_dir, base_url, **kwargs): """ env = environ.copy() - d = dict(XDG_DATA_HOME=venv_dir, + d = dict(VENV_PATH=venv_dir, # URL to PyPI-style JSON that tell us the latest released version # of LE: LE_AUTO_JSON_URL=base_url + 'certbot/json', @@ -201,7 +201,7 @@ iQIDAQAB **kwargs) env.update(d) return out_and_err( - join(venv_dir, 'letsencrypt-auto') + ' --version', + le_auto_path + ' --version', shell=True, env=env) @@ -213,10 +213,12 @@ def set_le_script_version(venv_dir, version): print its version. """ - with open(join(venv_dir, 'letsencrypt', 'bin', 'letsencrypt'), 'w') as script: + letsencrypt_path = join(venv_dir, 'bin', 'letsencrypt') + with open(letsencrypt_path, 'w') as script: script.write("#!/usr/bin/env python\n" "from sys import stderr\n" "stderr.write('letsencrypt %s\\n')" % version) + chmod(letsencrypt_path, S_IRUSR | S_IXUSR) class AutoTests(TestCase): @@ -237,6 +239,11 @@ class AutoTests(TestCase): test suites. """ + NEW_LE_AUTO = build_le_auto( + version='99.9.9', + requirements='letsencrypt==99.9.9 --hash=sha256:1cc14d61ab424cdee446f51e50f1123f8482ec740587fe78626c933bba2873a0') + NEW_LE_AUTO_SIG = signed(NEW_LE_AUTO) + def test_successes(self): """Exercise most branches of letsencrypt-auto. @@ -252,20 +259,16 @@ class AutoTests(TestCase): the next, saving code. """ - NEW_LE_AUTO = build_le_auto( - version='99.9.9', - requirements='letsencrypt==99.9.9 --hash=sha256:1cc14d61ab424cdee446f51e50f1123f8482ec740587fe78626c933bba2873a0') - NEW_LE_AUTO_SIG = signed(NEW_LE_AUTO) - - with ephemeral_dir() as venv_dir: + with temp_paths() as (le_auto_path, venv_dir): # This serves a PyPI page with a higher version, a GitHub-alike # with a corresponding le-auto script, and a matching signature. resources = {'certbot/json': dumps({'releases': {'99.9.9': None}}), - 'v99.9.9/letsencrypt-auto': NEW_LE_AUTO, - 'v99.9.9/letsencrypt-auto.sig': NEW_LE_AUTO_SIG} + 'v99.9.9/letsencrypt-auto': self.NEW_LE_AUTO, + 'v99.9.9/letsencrypt-auto.sig': self.NEW_LE_AUTO_SIG} with serving(resources) as base_url: run_letsencrypt_auto = partial( run_le_auto, + le_auto_path, venv_dir, base_url, PIP_FIND_LINKS=join(tests_dir(), @@ -274,7 +277,7 @@ class AutoTests(TestCase): # Test when a phase-1 upgrade is needed, there's no LE binary # installed, and pip hashes verify: - install_le_auto(build_le_auto(version='50.0.0'), venv_dir) + install_le_auto(build_le_auto(version='50.0.0'), le_auto_path) out, err = run_letsencrypt_auto() ok_(re.match(r'letsencrypt \d+\.\d+\.\d+', err.strip().splitlines()[-1])) @@ -291,16 +294,28 @@ class AutoTests(TestCase): self.assertFalse('Upgrading certbot-auto ' in out) self.assertFalse('Creating virtual environment...' in out) - # Test when a phase-1 upgrade is not needed but a phase-2 - # upgrade is: + def test_phase2_upgrade(self): + """Test a phase-2 upgrade without a phase-1 upgrade.""" + with temp_paths() as (le_auto_path, venv_dir): + resources = {'certbot/json': dumps({'releases': {'99.9.9': None}}), + 'v99.9.9/letsencrypt-auto': self.NEW_LE_AUTO, + 'v99.9.9/letsencrypt-auto.sig': self.NEW_LE_AUTO_SIG} + with serving(resources) as base_url: + venv_bin = join(venv_dir, 'bin') + makedirs(venv_bin) set_le_script_version(venv_dir, '0.0.1') - out, err = run_letsencrypt_auto() + + install_le_auto(self.NEW_LE_AUTO, le_auto_path) + pip_find_links=join(tests_dir(), 'fake-letsencrypt', 'dist') + out, err = run_le_auto(le_auto_path, venv_dir, base_url, + PIP_FIND_LINKS=pip_find_links) + self.assertFalse('Upgrading certbot-auto ' in out) self.assertTrue('Creating virtual environment...' in out) def test_openssl_failure(self): """Make sure we stop if the openssl signature check fails.""" - with ephemeral_dir() as venv_dir: + with temp_paths() as (le_auto_path, venv_dir): # Serve an unrelated hash signed with the good key (easier than # making a bad key, and a mismatch is a mismatch): resources = {'': 'certbot/', @@ -308,9 +323,9 @@ class AutoTests(TestCase): 'v99.9.9/letsencrypt-auto': build_le_auto(version='99.9.9'), 'v99.9.9/letsencrypt-auto.sig': signed('something else')} with serving(resources) as base_url: - copy(LE_AUTO_PATH, venv_dir) + copy(LE_AUTO_PATH, le_auto_path) try: - out, err = run_le_auto(venv_dir, base_url) + out, err = run_le_auto(le_auto_path, venv_dir, base_url) except CalledProcessError as exc: eq_(exc.returncode, 1) self.assertTrue("Couldn't verify signature of downloaded " @@ -320,7 +335,7 @@ class AutoTests(TestCase): def test_pip_failure(self): """Make sure pip stops us if there is a hash mismatch.""" - with ephemeral_dir() as venv_dir: + with temp_paths() as (le_auto_path, venv_dir): resources = {'': 'certbot/', 'certbot/json': dumps({'releases': {'99.9.9': None}})} with serving(resources) as base_url: @@ -329,14 +344,14 @@ class AutoTests(TestCase): build_le_auto( version='99.9.9', requirements='configobj==5.0.6 --hash=sha256:badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb'), - venv_dir) + le_auto_path) try: - out, err = run_le_auto(venv_dir, base_url) + out, err = run_le_auto(le_auto_path, venv_dir, base_url) except CalledProcessError as exc: eq_(exc.returncode, 1) self.assertTrue("THESE PACKAGES DO NOT MATCH THE HASHES " "FROM THE REQUIREMENTS FILE" in exc.output) - ok_(not exists(join(venv_dir, 'letsencrypt')), + ok_(not exists(venv_dir), msg="The virtualenv was left around, even though " "installation didn't succeed. We shouldn't do " "this, as it foils our detection of whether we " From c33ee0e2df28b7bc5a8648468f2886a3d43ba5b9 Mon Sep 17 00:00:00 2001 From: Noah Swartz Date: Mon, 21 Aug 2017 12:30:04 -0700 Subject: [PATCH 29/31] add warnings and clarity to config documentation (#4991) --- docs/using.rst | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/using.rst b/docs/using.rst index 8d9a22847..11915d896 100644 --- a/docs/using.rst +++ b/docs/using.rst @@ -544,8 +544,15 @@ commands into your individual environment. Modifying the Renewal Configuration File ---------------------------------------- +When a certificate is issued, by default Certbot creates a renewal configuration file that +tracks the options that were selected when Certbot was run. This allows Certbot +to use those same options again when it comes time for renewal. These renewal +configuration files are located at ``/etc/letsencrypt/renewal/CERTNAME``. + For advanced certificate management tasks, it is possible to manually modify the certificate's -renewal configuration file, located at ``/etc/letsencrypt/renewal/CERTNAME``. +renewal configuration file, but this is discouraged since it can easily break Certbot's +ability to renew your certificates. If you choose to modify the renewal configuration file +we advise you to test its validity with the ``certbot renew --dry-run`` command. .. warning:: Modifying any files in ``/etc/letsencrypt`` can damage them so Certbot can no longer properly manage its certificates, and we do not recommend doing so. @@ -796,7 +803,12 @@ of Certbot that you would like to run. Configuration file ================== -It is possible to specify configuration file with +Certbot accepts a global configuration file that applies its options to all invocations +of Certbot. Certificate specific configuration choices should be set in the ``.conf`` +files that can be found in ``/etc/letsencrypt/renewal``. + +By default no cli.ini file is created, after creating one +it is possible to specify the location of this configuration file with ``certbot-auto --config cli.ini`` (or shorter ``-c cli.ini``). An example configuration file is shown below: @@ -810,6 +822,13 @@ By default, the following locations are searched: ``~/.config/letsencrypt/cli.ini`` if ``$XDG_CONFIG_HOME`` is not set). +Since this configuration file applies to all invocations of certbot it is incorrect +to list domains in it. Listing domains in cli.ini may prevent renewal from working. +Additionally due to how arguments in cli.ini are parsed, options which wish to +not be set should not be listed. Options set to false will instead be read +as being set to true by older versions of Certbot, since they have been listed +in the config file. + .. keep it up to date with constants.py .. _log-rotation: From 8ca36a0b629ff9e363df48e5b31320343574de7b Mon Sep 17 00:00:00 2001 From: Winston Smith Date: Wed, 23 Aug 2017 19:32:27 +0200 Subject: [PATCH 30/31] Organize + document `certbot/tests/testdata` directory (#4983) * wp organize keys documentation start * oganized testdata directory + readme * clean up doc * del acme change --- certbot/plugins/common_test.py | 4 +- certbot/tests/account_test.py | 8 +-- certbot/tests/cert_manager_test.py | 2 +- certbot/tests/client_test.py | 14 ++--- certbot/tests/crypto_util_test.py | 49 +++++++++--------- certbot/tests/main_test.py | 18 +++---- certbot/tests/storage_test.py | 15 ++++-- certbot/tests/testdata/README | 11 ++++ .../{cert-5sans.pem => cert-5sans_512.pem} | 0 .../{cert-san.pem => cert-san_512.pem} | 0 certbot/tests/testdata/cert.b64jose | 1 - certbot/tests/testdata/cert.der | Bin 377 -> 0 bytes .../{self_signed_cert.pem => cert_2048.pem} | 0 .../tests/testdata/{cert.pem => cert_512.pem} | 0 ...f_signed_cert_bad.pem => cert_512_bad.pem} | 0 ..._fullchain.pem => cert_fullchain_2048.pem} | 0 certbot/tests/testdata/csr-6sans.pem | 12 ----- certbot/tests/testdata/csr-6sans_512.conf | 29 +++++++++++ certbot/tests/testdata/csr-6sans_512.pem | 12 +++++ .../{csr-nonames.pem => csr-nonames_512.pem} | 0 certbot/tests/testdata/csr-nosans.pem | 8 --- certbot/tests/testdata/csr-nosans_512.conf | 16 ++++++ certbot/tests/testdata/csr-nosans_512.pem | 9 ++++ .../testdata/{csr-san.pem => csr-san_512.pem} | 0 .../tests/testdata/{csr.der => csr_512.der} | Bin .../tests/testdata/{csr.pem => csr_512.pem} | 0 certbot/tests/testdata/dsa512_key.pem | 14 ----- certbot/tests/testdata/dsa_cert.pem | 17 ------ certbot/tests/testdata/matching_cert.pem | 14 ----- certbot/tests/testdata/rsa512_key_2.pem | 9 ---- 30 files changed, 134 insertions(+), 128 deletions(-) create mode 100644 certbot/tests/testdata/README rename certbot/tests/testdata/{cert-5sans.pem => cert-5sans_512.pem} (100%) rename certbot/tests/testdata/{cert-san.pem => cert-san_512.pem} (100%) delete mode 100644 certbot/tests/testdata/cert.b64jose delete mode 100644 certbot/tests/testdata/cert.der rename certbot/tests/testdata/{self_signed_cert.pem => cert_2048.pem} (100%) rename certbot/tests/testdata/{cert.pem => cert_512.pem} (100%) rename certbot/tests/testdata/{self_signed_cert_bad.pem => cert_512_bad.pem} (100%) rename certbot/tests/testdata/{self_signed_fullchain.pem => cert_fullchain_2048.pem} (100%) delete mode 100644 certbot/tests/testdata/csr-6sans.pem create mode 100644 certbot/tests/testdata/csr-6sans_512.conf create mode 100644 certbot/tests/testdata/csr-6sans_512.pem rename certbot/tests/testdata/{csr-nonames.pem => csr-nonames_512.pem} (100%) delete mode 100644 certbot/tests/testdata/csr-nosans.pem create mode 100644 certbot/tests/testdata/csr-nosans_512.conf create mode 100644 certbot/tests/testdata/csr-nosans_512.pem rename certbot/tests/testdata/{csr-san.pem => csr-san_512.pem} (100%) rename certbot/tests/testdata/{csr.der => csr_512.der} (100%) rename certbot/tests/testdata/{csr.pem => csr_512.pem} (100%) delete mode 100644 certbot/tests/testdata/dsa512_key.pem delete mode 100644 certbot/tests/testdata/dsa_cert.pem delete mode 100644 certbot/tests/testdata/matching_cert.pem delete mode 100644 certbot/tests/testdata/rsa512_key_2.pem diff --git a/certbot/plugins/common_test.py b/certbot/plugins/common_test.py index 411cbe651..409c05946 100644 --- a/certbot/plugins/common_test.py +++ b/certbot/plugins/common_test.py @@ -202,7 +202,7 @@ class TLSSNI01Test(unittest.TestCase): achall.chall.encode.return_value = "token" key = test_util.load_pyopenssl_private_key("rsa512_key.pem") achall.response_and_validation.return_value = ( - response, (test_util.load_cert("cert.pem"), key)) + response, (test_util.load_cert("cert_512.pem"), key)) with mock.patch("certbot.plugins.common.open", mock_open, create=True): @@ -215,7 +215,7 @@ class TLSSNI01Test(unittest.TestCase): # pylint: disable=no-member mock_open.assert_called_once_with(self.sni.get_cert_path(achall), "wb") mock_open.return_value.write.assert_called_once_with( - test_util.load_vector("cert.pem")) + test_util.load_vector("cert_512.pem")) mock_safe_open.assert_called_once_with( self.sni.get_key_path(achall), "wb", chmod=0o400) mock_safe_open.return_value.write.assert_called_once_with( diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index 575a40286..7245ad6a1 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -17,7 +17,7 @@ from certbot import errors import certbot.tests.util as test_util -KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key_2.pem")) +KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) class AccountTest(unittest.TestCase): @@ -46,15 +46,15 @@ class AccountTest(unittest.TestCase): def test_id(self): self.assertEqual( - self.acc.id, "bca5889f66457d5b62fbba7b25f9ab6f") + self.acc.id, "7adac10320f585ddf118429c0c4af2cd") def test_slug(self): self.assertEqual( - self.acc.slug, "test.certbot.org@2015-07-04T14:04:10Z (bca5)") + self.acc.slug, "test.certbot.org@2015-07-04T14:04:10Z (7ada)") def test_repr(self): self.assertTrue(repr(self.acc).startswith( - " csr_X.der] + +and for the certificate: + + openssl req -new -out cert_X.pem -key rsaX_key.pem -subj '/CN=example.com' -x509 [-outform DER > cert_X.der] \ No newline at end of file diff --git a/certbot/tests/testdata/cert-5sans.pem b/certbot/tests/testdata/cert-5sans_512.pem similarity index 100% rename from certbot/tests/testdata/cert-5sans.pem rename to certbot/tests/testdata/cert-5sans_512.pem diff --git a/certbot/tests/testdata/cert-san.pem b/certbot/tests/testdata/cert-san_512.pem similarity index 100% rename from certbot/tests/testdata/cert-san.pem rename to certbot/tests/testdata/cert-san_512.pem diff --git a/certbot/tests/testdata/cert.b64jose b/certbot/tests/testdata/cert.b64jose deleted file mode 100644 index fa1abdb9f..000000000 --- a/certbot/tests/testdata/cert.b64jose +++ /dev/null @@ -1 +0,0 @@ -MIIB3jCCAYigAwIBAgICBTkwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1pY2hpZ2FuMRIwEAYDVQQHDAlBbm4gQXJib3IxKzApBgNVBAoMIlVuaXZlcnNpdHkgb2YgTWljaGlnYW4gYW5kIHRoZSBFRkYxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTE0MTIxMTIyMzQ0NVoXDTE0MTIxODIyMzQ0NVowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1pY2hpZ2FuMRIwEAYDVQQHDAlBbm4gQXJib3IxKzApBgNVBAoMIlVuaXZlcnNpdHkgb2YgTWljaGlnYW4gYW5kIHRoZSBFRkYxFDASBgNVBAMMC2V4YW1wbGUuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKx1c7RR7R_drnBSQ_zfx1vQLHUbFLh1AQQQ5R8DZUXd36efNK79vukFhN9HFoHZiUvOjm0c-pVE6K-EdE_twuUCAwEAATANBgkqhkiG9w0BAQsFAANBAC24z0IdwIVKSlntksllvr6zJepBH5fMndfk3XJp10jT6VE-14KNtjh02a56GoraAvJAT5_H67E8GvJ_ocNnB_o \ No newline at end of file diff --git a/certbot/tests/testdata/cert.der b/certbot/tests/testdata/cert.der deleted file mode 100644 index 5f1018505d81a50ed3239d829533deac5fcc2085..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 377 zcmXqLVk|XiVw7LN%*4pV#L2Ms(6oH-+lDa)ylk9WZ60mkc^MhGSs4t(3`Got*qB3E zn0dHUD-v@Ha#Hn@^K%X4#CZ)(4a|&;3``6RjLoCKTyr=Vr#=)57+D#Zy%`KVm>e0_ zlooFZd@FxGb01z;s66b16iPJW%*ddSVYv$pLpwieafaMs>~58{VWGc zu1@bVkOxUCvq%_-HDFi315zN&!fL?G$oL;EIG7z7c)I@!HO%vwut#mfG=7{>z}O6i?Kd^cJYN9>LqE5%h;CwZnWA40OQJj AMgRZ+ diff --git a/certbot/tests/testdata/self_signed_cert.pem b/certbot/tests/testdata/cert_2048.pem similarity index 100% rename from certbot/tests/testdata/self_signed_cert.pem rename to certbot/tests/testdata/cert_2048.pem diff --git a/certbot/tests/testdata/cert.pem b/certbot/tests/testdata/cert_512.pem similarity index 100% rename from certbot/tests/testdata/cert.pem rename to certbot/tests/testdata/cert_512.pem diff --git a/certbot/tests/testdata/self_signed_cert_bad.pem b/certbot/tests/testdata/cert_512_bad.pem similarity index 100% rename from certbot/tests/testdata/self_signed_cert_bad.pem rename to certbot/tests/testdata/cert_512_bad.pem diff --git a/certbot/tests/testdata/self_signed_fullchain.pem b/certbot/tests/testdata/cert_fullchain_2048.pem similarity index 100% rename from certbot/tests/testdata/self_signed_fullchain.pem rename to certbot/tests/testdata/cert_fullchain_2048.pem diff --git a/certbot/tests/testdata/csr-6sans.pem b/certbot/tests/testdata/csr-6sans.pem deleted file mode 100644 index 8f6b52bd7..000000000 --- a/certbot/tests/testdata/csr-6sans.pem +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBuzCCAWUCAQAweTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1pY2hpZ2FuMRIw -EAYDVQQHEwlBbm4gQXJib3IxDDAKBgNVBAoTA0VGRjEfMB0GA1UECxMWVW5pdmVy -c2l0eSBvZiBNaWNoaWdhbjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wXDANBgkqhkiG -9w0BAQEFAANLADBIAkEA9LYRcVE3Nr+qleecEcX8JwVDnjeG1X7ucsCasuuZM0e0 -9cmYuUzxIkMjO/9x4AVcvXXRXPEV+LzWWkfkTlzRMwIDAQABoIGGMIGDBgkqhkiG -9w0BCQ4xdjB0MHIGA1UdEQRrMGmCC2V4YW1wbGUuY29tggtleGFtcGxlLm9yZ4IL -ZXhhbXBsZS5uZXSCDGV4YW1wbGUuaW5mb4IVc3ViZG9tYWluLmV4YW1wbGUuY29t -ghtvdGhlci5zdWJkb21haW4uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADQQBd -k4BE5qvEvkYoZM/2++Xd9RrQ6wsdj0QiJQCozfsI4lQx6ZJnbtNc7HpDrX4W6XIv -IvzVBz/nD11drfz/RNuX ------END CERTIFICATE REQUEST----- diff --git a/certbot/tests/testdata/csr-6sans_512.conf b/certbot/tests/testdata/csr-6sans_512.conf new file mode 100644 index 000000000..fa7b3edc2 --- /dev/null +++ b/certbot/tests/testdata/csr-6sans_512.conf @@ -0,0 +1,29 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +C=US +C_default = US +ST=Michigan +ST_default=Michigan +L=Ann Arbor +L_default=Ann Arbor +O=EFF +O_default=EFF +OU=University of Michigan +OU_default=University of Michigan +CN=example.com +CN_default=example.com + + +[ v3_req ] +subjectAltName = @alt_names + +[alt_names] +DNS.1 = example.com +DNS.2 = example.org +DNS.3 = example.net +DNS.4 = example.info +DNS.5 = subdomain.example.com +DNS.6 = other.subdomain.example.com \ No newline at end of file diff --git a/certbot/tests/testdata/csr-6sans_512.pem b/certbot/tests/testdata/csr-6sans_512.pem new file mode 100644 index 000000000..f72c0541d --- /dev/null +++ b/certbot/tests/testdata/csr-6sans_512.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBuzCCAWUCAQAweTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1pY2hpZ2FuMRIw +EAYDVQQHDAlBbm4gQXJib3IxDDAKBgNVBAoMA0VGRjEfMB0GA1UECwwWVW5pdmVy +c2l0eSBvZiBNaWNoaWdhbjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wXDANBgkqhkiG +9w0BAQEFAANLADBIAkEArHVztFHtH92ucFJD/N/HW9AsdRsUuHUBBBDlHwNlRd3f +p580rv2+6QWE30cWgdmJS86ObRz6lUTor4R0T+3C5QIDAQABoIGGMIGDBgkqhkiG +9w0BCQ4xdjB0MHIGA1UdEQRrMGmCC2V4YW1wbGUuY29tggtleGFtcGxlLm9yZ4IL +ZXhhbXBsZS5uZXSCDGV4YW1wbGUuaW5mb4IVc3ViZG9tYWluLmV4YW1wbGUuY29t +ghtvdGhlci5zdWJkb21haW4uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADQQA+ +sU6T30n3SsdnHlj0Va8eECOWK7Lf8nUfxxgjPMQ7BoU8gbAnGfDmOlwDronTRqf1 +Me+nlYJU4TX1OiX10DYu +-----END CERTIFICATE REQUEST----- diff --git a/certbot/tests/testdata/csr-nonames.pem b/certbot/tests/testdata/csr-nonames_512.pem similarity index 100% rename from certbot/tests/testdata/csr-nonames.pem rename to certbot/tests/testdata/csr-nonames_512.pem diff --git a/certbot/tests/testdata/csr-nosans.pem b/certbot/tests/testdata/csr-nosans.pem deleted file mode 100644 index 813db67b0..000000000 --- a/certbot/tests/testdata/csr-nosans.pem +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBFTCBwAIBADBbMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh -MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDDAtleGFt -cGxlLm9yZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQD0thFxUTc2v6qV55wRxfwn -BUOeN4bVfu5ywJqy65kzR7T1yZi5TPEiQyM7/3HgBVy9ddFc8RX4vNZaR+ROXNEz -AgMBAAGgADANBgkqhkiG9w0BAQsFAANBAMikGL8Ch7hQCStXH7chhDp6+pt2+VSo -wgsrPQ2Bw4veDMlSemUrH+4e0TwbbntHfvXTDHWs9P3BiIDJLxFrjuA= ------END CERTIFICATE REQUEST----- diff --git a/certbot/tests/testdata/csr-nosans_512.conf b/certbot/tests/testdata/csr-nosans_512.conf new file mode 100644 index 000000000..1026cf9ad --- /dev/null +++ b/certbot/tests/testdata/csr-nosans_512.conf @@ -0,0 +1,16 @@ +[req] +distinguished_name = req_distinguished_name + +[req_distinguished_name] +C=US +C_default = US +ST=Michigan +ST_default=Michigan +L=Ann Arbor +L_default=Ann Arbor +O=EFF +O_default=EFF +OU=University of Michigan +OU_default=University of Michigan +CN=example.com +CN_default=example.com \ No newline at end of file diff --git a/certbot/tests/testdata/csr-nosans_512.pem b/certbot/tests/testdata/csr-nosans_512.pem new file mode 100644 index 000000000..5f02d7e97 --- /dev/null +++ b/certbot/tests/testdata/csr-nosans_512.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBMzCB3gIBADB5MQswCQYDVQQGEwJVUzERMA8GA1UECAwITWljaGlnYW4xEjAQ +BgNVBAcMCUFubiBBcmJvcjEMMAoGA1UECgwDRUZGMR8wHQYDVQQLDBZVbml2ZXJz +aXR5IHBmIE1pY2hpZ2FuMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBcMA0GCSqGSIb3 +DQEBAQUAA0sAMEgCQQCsdXO0Ue0f3a5wUkP838db0Cx1GxS4dQEEEOUfA2VF3d+n +nzSu/b7pBYTfRxaB2YlLzo5tHPqVROivhHRP7cLlAgMBAAGgADANBgkqhkiG9w0B +AQsFAANBAG06jIPvSC6wiGLy7sUTaEX4UCE6Cztp3vh/uXN7Q++CGn6KiXNs/BRW +eFlcFPbvxbVG/ZZFR5aPs+Oy6RhqOjg= +-----END CERTIFICATE REQUEST----- diff --git a/certbot/tests/testdata/csr-san.pem b/certbot/tests/testdata/csr-san_512.pem similarity index 100% rename from certbot/tests/testdata/csr-san.pem rename to certbot/tests/testdata/csr-san_512.pem diff --git a/certbot/tests/testdata/csr.der b/certbot/tests/testdata/csr_512.der similarity index 100% rename from certbot/tests/testdata/csr.der rename to certbot/tests/testdata/csr_512.der diff --git a/certbot/tests/testdata/csr.pem b/certbot/tests/testdata/csr_512.pem similarity index 100% rename from certbot/tests/testdata/csr.pem rename to certbot/tests/testdata/csr_512.pem diff --git a/certbot/tests/testdata/dsa512_key.pem b/certbot/tests/testdata/dsa512_key.pem deleted file mode 100644 index 78e164712..000000000 --- a/certbot/tests/testdata/dsa512_key.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN DSA PARAMETERS----- -MIGdAkEAwebEoGBfokKQeALHHnAZMQwYU35ILEBdV8oUmzv7qpSVUoHihyqfn6GC -OixAKSP8EJYcTilIqPbFbfFyOPlbLwIVANoFHEDiQgknAvKrG78pHzAJdQSPAkEA -qfka5Bnl+CeEMpzVZGrOVqZE/LFdZK9eT6YtWjzqtIkf3hwXUVxJsTnBG4xmrfvl -41pgNJpgu99YOYqPpS0g7A== ------END DSA PARAMETERS----- ------BEGIN DSA PRIVATE KEY----- -MIH5AgEAAkEAwebEoGBfokKQeALHHnAZMQwYU35ILEBdV8oUmzv7qpSVUoHihyqf -n6GCOixAKSP8EJYcTilIqPbFbfFyOPlbLwIVANoFHEDiQgknAvKrG78pHzAJdQSP -AkEAqfka5Bnl+CeEMpzVZGrOVqZE/LFdZK9eT6YtWjzqtIkf3hwXUVxJsTnBG4xm -rfvl41pgNJpgu99YOYqPpS0g7AJATQ2LUzjGQSM6UljcPY5I2OD9THkUR9kH2tth -zZd70UoI9btrVaTizgqYShuok94glSQNK0H92JgUk3scJPaAkAIVAMDn61h6vrCE -mNv063So6E+eYaIN ------END DSA PRIVATE KEY----- diff --git a/certbot/tests/testdata/dsa_cert.pem b/certbot/tests/testdata/dsa_cert.pem deleted file mode 100644 index ef94536e7..000000000 --- a/certbot/tests/testdata/dsa_cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICuDCCAnWgAwIBAgIJAPjmErVMzwVLMAsGCWCGSAFlAwQDAjB3MQswCQYDVQQG -EwJVUzERMA8GA1UECAwITWljaGlnYW4xEjAQBgNVBAcMCUFubiBBcmJvcjErMCkG -A1UECgwiVW5pdmVyc2l0eSBvZiBNaWNoaWdhbiBhbmQgdGhlIEVGRjEUMBIGA1UE -AwwLZXhhbXBsZS5jb20wHhcNMTUwNTEyMTUzOTQzWhcNMTUwNjExMTUzOTQzWjB3 -MQswCQYDVQQGEwJVUzERMA8GA1UECAwITWljaGlnYW4xEjAQBgNVBAcMCUFubiBB -cmJvcjErMCkGA1UECgwiVW5pdmVyc2l0eSBvZiBNaWNoaWdhbiBhbmQgdGhlIEVG -RjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wgfEwgakGByqGSM44BAEwgZ0CQQDB5sSg -YF+iQpB4AscecBkxDBhTfkgsQF1XyhSbO/uqlJVSgeKHKp+foYI6LEApI/wQlhxO -KUio9sVt8XI4+VsvAhUA2gUcQOJCCScC8qsbvykfMAl1BI8CQQCp+RrkGeX4J4Qy -nNVkas5WpkT8sV1kr15Ppi1aPOq0iR/eHBdRXEmxOcEbjGat++XjWmA0mmC731g5 -io+lLSDsA0MAAkBNDYtTOMZBIzpSWNw9jkjY4P1MeRRH2Qfa22HNl3vRSgj1u2tV -pOLOCphKG6iT3iCVJA0rQf3YmBSTexwk9oCQo1AwTjAdBgNVHQ4EFgQUZ2DlTDGU -PMwTUt0KztM6IyX61BcwHwYDVR0jBBgwFoAUZ2DlTDGUPMwTUt0KztM6IyX61Bcw -DAYDVR0TBAUwAwEB/zALBglghkgBZQMEAwIDMAAwLQIVAIbMgGx+KwBr4rgqZ2Lh -AAO8TegHAhQsuxpIIIphiReoWEtEJk4TqEIz/A== ------END CERTIFICATE----- diff --git a/certbot/tests/testdata/matching_cert.pem b/certbot/tests/testdata/matching_cert.pem deleted file mode 100644 index fda9cb1f4..000000000 --- a/certbot/tests/testdata/matching_cert.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICNzCCAeGgAwIBAgIJALizm9Y3q620MA0GCSqGSIb3DQEBCwUAMHcxCzAJBgNV -BAYTAlVTMREwDwYDVQQIDAhNaWNoaWdhbjESMBAGA1UEBwwJQW5uIEFyYm9yMSsw -KQYDVQQKDCJVbml2ZXJzaXR5IG9mIE1pY2hpZ2FuIGFuZCB0aGUgRUZGMRQwEgYD -VQQDDAtleGFtcGxlLmNvbTAeFw0xNTA1MDkwMDI0NTJaFw0xNjA1MDgwMDI0NTJa -MHcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNaWNoaWdhbjESMBAGA1UEBwwJQW5u -IEFyYm9yMSswKQYDVQQKDCJVbml2ZXJzaXR5IG9mIE1pY2hpZ2FuIGFuZCB0aGUg -RUZGMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC -QQD0thFxUTc2v6qV55wRxfwnBUOeN4bVfu5ywJqy65kzR7T1yZi5TPEiQyM7/3Hg -BVy9ddFc8RX4vNZaR+ROXNEzAgMBAAGjUDBOMB0GA1UdDgQWBBRJieHEVSHKmBk0 -mTExx1erzlylCjAfBgNVHSMEGDAWgBRJieHEVSHKmBk0mTExx1erzlylCjAMBgNV -HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EABT/nlpqOaanFSLZmWIrKv0zt63k4 -bmWNMA8fYT45KYpLomsW8qXdpC82IlVKfNk7fW0UYT3HOeDSJRcycxNCTQ== ------END CERTIFICATE----- diff --git a/certbot/tests/testdata/rsa512_key_2.pem b/certbot/tests/testdata/rsa512_key_2.pem deleted file mode 100644 index 709b6d8e3..000000000 --- a/certbot/tests/testdata/rsa512_key_2.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBAPS2EXFRNza/qpXnnBHF/CcFQ543htV+7nLAmrLrmTNHtPXJmLlM -8SJDIzv/ceAFXL110VzxFfi81lpH5E5c0TMCAwEAAQJBALmppYQ/JVARjWBcsEm/ -1/bXBJ127YLv4gQIY5baL4r6IdEE33OXMTTmD9wf+ajuq1eaH0htHkwhOvREu0sz -bskCIQD/Cg+xhEVLcwK3pFp3afPIhj1IPFiL3Uy/nqyMZ6O/RQIhAPWiDBofp7Cp -J4dGZs+hkRySq/IOeeRJlNK1Pq64nToXAiBZ7+te1100YSd5KT051SRB94zO13EG -SZESFduVW8rz3QIgK+tLiqg6TYYRQUi/PUTAM4GuKNuZw828RGiPyqHLywUCIQCd -pkZrNphL/y0D7HSbPIfZzD90M2V8tUjlK0BTqk1bHA== ------END RSA PRIVATE KEY----- From a5fae7eab5a284ae43e9807e83009b93205a2cf6 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 23 Aug 2017 11:01:20 -0700 Subject: [PATCH 31/31] certbot-auto OS dependency update system (#4971) * Add version number to bootstrap scripts. * Always determine Bootstrap function and version. * Write bootstrap version into venv. * Add PrevBootstrapVersion function. * Add OS bootstrapping check to phase 2. * Differentiate -n and renew when rebootstrapping. * Quote all environment variables. * Correct test condition * Add loud warning about hardcoded version list. * s/VENV_BOOTSTRAP_VERSION/BOOTSTRAP_VERSION_PATH * Properly handle noop bootstrap functions. --- letsencrypt-auto-source/letsencrypt-auto | 193 +++++++++++++++--- .../letsencrypt-auto.template | 157 +++++++++++--- .../pieces/bootstrappers/arch_common.sh | 4 + .../pieces/bootstrappers/deb_common.sh | 4 + .../pieces/bootstrappers/free_bsd.sh | 4 + .../pieces/bootstrappers/gentoo_common.sh | 4 + .../pieces/bootstrappers/mac.sh | 4 + .../pieces/bootstrappers/mageia_common.sh | 4 + .../pieces/bootstrappers/rpm_common.sh | 4 + .../pieces/bootstrappers/smartos.sh | 4 + .../pieces/bootstrappers/suse_common.sh | 4 + 11 files changed, 326 insertions(+), 60 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 8ce3342be..fe3f3b924 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -30,6 +30,7 @@ if [ -z "$VENV_PATH" ]; then export VENV_PATH="/opt/eff.org/certbot/venv" fi VENV_BIN="$VENV_PATH/bin" +BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" LE_AUTO_VERSION="0.18.0.dev0" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] @@ -80,7 +81,7 @@ for arg in "$@" ; do h) HELP=1;; n) - ASSUME_YES=1;; + NONINTERACTIVE=1;; q) QUIET=1;; v) @@ -96,8 +97,8 @@ if [ $BASENAME = "letsencrypt-auto" ]; then HELP=0 fi -# Set ASSUME_YES to 1 if QUIET (i.e. --quiet implies --non-interactive) -if [ "$QUIET" = 1 ]; then +# Set ASSUME_YES to 1 if QUIET or NONINTERACTIVE +if [ "$QUIET" = 1 -o "$NONINTERACTIVE" = 1 ]; then ASSUME_YES=1 fi @@ -256,6 +257,10 @@ DeterminePythonVersion() { fi } +# If new packages are installed by BootstrapDebCommon below, this version +# number must be increased. +BOOTSTRAP_DEB_COMMON_VERSION=1 + BootstrapDebCommon() { # Current version tested with: # @@ -372,6 +377,10 @@ BootstrapDebCommon() { fi } +# If new packages are installed by BootstrapRpmCommon below, this version +# number must be increased. +BOOTSTRAP_RPM_COMMON_VERSION=1 + BootstrapRpmCommon() { # Tested with: # - Fedora 20, 21, 22, 23 (x64) @@ -473,6 +482,10 @@ BootstrapRpmCommon() { fi } +# If new packages are installed by BootstrapSuseCommon below, this version +# number must be increased. +BOOTSTRAP_SUSE_COMMON_VERSION=1 + BootstrapSuseCommon() { # SLE12 don't have python-virtualenv @@ -496,6 +509,10 @@ BootstrapSuseCommon() { ca-certificates } +# If new packages are installed by BootstrapArchCommon below, this version +# number must be increased. +BOOTSTRAP_ARCH_COMMON_VERSION=1 + BootstrapArchCommon() { # Tested with: # - ArchLinux (x86_64) @@ -531,6 +548,10 @@ BootstrapArchCommon() { fi } +# If new packages are installed by BootstrapGentooCommon below, this version +# number must be increased. +BOOTSTRAP_GENTOO_COMMON_VERSION=1 + BootstrapGentooCommon() { PACKAGES=" dev-lang/python:2.7 @@ -559,6 +580,10 @@ BootstrapGentooCommon() { esac } +# If new packages are installed by BootstrapFreeBsd below, this version number +# must be increased. +BOOTSTRAP_FREEBSD_VERSION=1 + BootstrapFreeBsd() { if [ "$QUIET" = 1 ]; then QUIET_FLAG="--quiet" @@ -571,6 +596,10 @@ BootstrapFreeBsd() { libffi } +# If new packages are installed by BootstrapMac below, this version number must +# be increased. +BOOTSTRAP_MAC_VERSION=1 + BootstrapMac() { if hash brew 2>/dev/null; then say "Using Homebrew to install dependencies..." @@ -616,11 +645,19 @@ BootstrapMac() { fi } +# If new packages are installed by BootstrapSmartOS below, this version number +# must be increased. +BOOTSTRAP_SMARTOS_VERSION=1 + BootstrapSmartOS() { pkgin update pkgin -y install 'gcc49' 'py27-augeas' 'py27-virtualenv' } +# If new packages are installed by BootstrapMageiaCommon below, this version +# number must be increased. +BOOTSTRAP_MAGEIA_COMMON_VERSION=1 + BootstrapMageiaCommon() { if [ "$QUIET" = 1 ]; then QUIET_FLAG='--quiet' @@ -649,23 +686,41 @@ BootstrapMageiaCommon() { } -# Install required OS packages: -Bootstrap() { - if [ "$NO_BOOTSTRAP" = 1 ]; then - return - elif [ -f /etc/debian_version ]; then +# Set Bootstrap to the function that installs OS dependencies on this system +# and BOOTSTRAP_VERSION to the unique identifier for the current version of +# that function. If Bootstrap is set to a function that doesn't install any +# packages (either because --no-bootstrap was included on the command line or +# we don't know how to bootstrap on this system), BOOTSTRAP_VERSION is not set. +if [ "$NO_BOOTSTRAP" = 1 ]; then + Bootstrap() { + : + } +elif [ -f /etc/debian_version ]; then + Bootstrap() { BootstrapMessage "Debian-based OSes" BootstrapDebCommon - elif [ -f /etc/mageia-release ]; then - # Mageia has both /etc/mageia-release and /etc/redhat-release + } + BOOTSTRAP_VERSION="BootstrapDebCommon $BOOTSTRAP_DEB_COMMON_VERSION" +elif [ -f /etc/mageia-release ]; then + # Mageia has both /etc/mageia-release and /etc/redhat-release + Bootstrap() { ExperimentalBootstrap "Mageia" BootstrapMageiaCommon - elif [ -f /etc/redhat-release ]; then + } + BOOTSTRAP_VERSION="BootstrapMageiaCommon $BOOTSTRAP_MAGEIA_COMMON_VERSION" +elif [ -f /etc/redhat-release ]; then + Bootstrap() { BootstrapMessage "RedHat-based OSes" BootstrapRpmCommon - elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" +elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then + Bootstrap() { BootstrapMessage "openSUSE-based OSes" BootstrapSuseCommon - elif [ -f /etc/arch-release ]; then + } + BOOTSTRAP_VERSION="BootstrapSuseCommon $BOOTSTRAP_SUSE_COMMON_VERSION" +elif [ -f /etc/arch-release ]; then + Bootstrap() { if [ "$DEBUG" = 1 ]; then BootstrapMessage "Archlinux" BootstrapArchCommon @@ -677,25 +732,76 @@ Bootstrap() { error "--debug flag." exit 1 fi - elif [ -f /etc/manjaro-release ]; then + } + BOOTSTRAP_VERSION="BootstrapArchCommon $BOOTSTRAP_ARCH_COMMON_VERSION" +elif [ -f /etc/manjaro-release ]; then + Bootstrap() { ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon - elif [ -f /etc/gentoo-release ]; then + } + BOOTSTRAP_VERSION="BootstrapArchCommon $BOOTSTRAP_ARCH_COMMON_VERSION" +elif [ -f /etc/gentoo-release ]; then + Bootstrap() { DeprecationBootstrap "Gentoo" BootstrapGentooCommon - elif uname | grep -iq FreeBSD ; then + } + BOOTSTRAP_VERSION="BootstrapGentooCommon $BOOTSTRAP_GENTOO_COMMON_VERSION" +elif uname | grep -iq FreeBSD ; then + Bootstrap() { DeprecationBootstrap "FreeBSD" BootstrapFreeBsd - elif uname | grep -iq Darwin ; then + } + BOOTSTRAP_VERSION="BootstrapFreeBsd $BOOTSTRAP_FREEBSD_VERSION" +elif uname | grep -iq Darwin ; then + Bootstrap() { DeprecationBootstrap "macOS" BootstrapMac - elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then + } + BOOTSTRAP_VERSION="BootstrapMac $BOOTSTRAP_MAC_VERSION" +elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then + Bootstrap() { ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon - elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" +elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then + Bootstrap() { ExperimentalBootstrap "Joyent SmartOS Zone" BootstrapSmartOS - else + } + BOOTSTRAP_VERSION="BootstrapSmartOS $BOOTSTRAP_SMARTOS_VERSION" +else + Bootstrap() { error "Sorry, I don't know how to bootstrap Certbot on your operating system!" error error "You will need to install OS dependencies, configure virtualenv, and run pip install manually." error "Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites" error "for more info." exit 1 + } +fi + +# Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used +# to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set +# if it is unknown how OS dependencies were installed on this system. +SetPrevBootstrapVersion() { + if [ -f $BOOTSTRAP_VERSION_PATH ]; then + PREV_BOOTSTRAP_VERSION=$(cat "$BOOTSTRAP_VERSION_PATH") + # The list below only contains bootstrap version strings that existed before + # we started writing them to disk. + # + # DO NOT MODIFY THIS LIST UNLESS YOU KNOW WHAT YOU'RE DOING! + elif grep -Fqx "$BOOTSTRAP_VERSION" << "UNLIKELY_EOF" +BootstrapDebCommon 1 +BootstrapMageiaCommon 1 +BootstrapRpmCommon 1 +BootstrapSuseCommon 1 +BootstrapArchCommon 1 +BootstrapGentooCommon 1 +BootstrapFreeBsd 1 +BootstrapMac 1 +BootstrapSmartOS 1 +UNLIKELY_EOF + then + # If there's no bootstrap version saved to disk, but the currently selected + # bootstrap script is from before we started saving the version number, + # return the currently selected version to prevent us from rebootstrapping + # unnecessarily. + PREV_BOOTSTRAP_VERSION="$BOOTSTRAP_VERSION" fi } @@ -709,18 +815,39 @@ if [ "$1" = "--le-auto-phase2" ]; then # Phase 2: Create venv, install LE, and run. shift 1 # the --le-auto-phase2 arg - if [ -f "$VENV_BIN/letsencrypt" ]; then - # --version output ran through grep due to python-cryptography DeprecationWarnings - # grep for both certbot and letsencrypt until certbot and shim packages have been released - INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) - if [ -z "$INSTALLED_VERSION" ]; then - error "Error: couldn't get currently installed version for $VENV_BIN/letsencrypt: " 1>&2 - "$VENV_BIN/letsencrypt" --version - exit 1 + SetPrevBootstrapVersion + + INSTALLED_VERSION="none" + if [ -d "$VENV_PATH" ]; then + # If the selected Bootstrap function isn't a noop and it differs from the + # previously used version + if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then + # if non-interactive mode or stdin and stdout are connected to a terminal + if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then + rm -rf "$VENV_PATH" + "$0" "$@" + exit 0 + else + error "Skipping upgrade because new OS dependencies may need to be installed." + error + error "To upgrade to a newer version, please run this script again manually so you can" + error "approve changes or with --non-interactive on the command line to automatically" + error "install any required packages." + # Set INSTALLED_VERSION to be the same so we don't update the venv + INSTALLED_VERSION="$LE_AUTO_VERSION" + fi + elif [ -f "$VENV_BIN/letsencrypt" ]; then + # --version output ran through grep due to python-cryptography DeprecationWarnings + # grep for both certbot and letsencrypt until certbot and shim packages have been released + INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) + if [ -z "$INSTALLED_VERSION" ]; then + error "Error: couldn't get currently installed version for $VENV_BIN/letsencrypt: " 1>&2 + "$VENV_BIN/letsencrypt" --version + exit 1 + fi fi - else - INSTALLED_VERSION="none" fi + if [ "$LE_AUTO_VERSION" != "$INSTALLED_VERSION" ]; then say "Creating virtual environment..." DeterminePythonVersion @@ -731,6 +858,12 @@ if [ "$1" = "--le-auto-phase2" ]; then virtualenv --no-site-packages --python "$LE_PYTHON" "$VENV_PATH" > /dev/null fi + if [ -n "$BOOTSTRAP_VERSION" ]; then + echo "$BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH" + elif [ -n "$PREV_BOOTSTRAP_VERSION" ]; then + echo "$PREV_BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH" + fi + say "Installing Python packages..." TEMP_DIR=$(TempDir) trap 'rm -rf "$TEMP_DIR"' EXIT diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index 29aaf1291..eb2b82776 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -30,6 +30,7 @@ if [ -z "$VENV_PATH" ]; then export VENV_PATH="/opt/eff.org/certbot/venv" fi VENV_BIN="$VENV_PATH/bin" +BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" LE_AUTO_VERSION="{{ LE_AUTO_VERSION }}" BASENAME=$(basename $0) USAGE="Usage: $BASENAME [OPTIONS] @@ -80,7 +81,7 @@ for arg in "$@" ; do h) HELP=1;; n) - ASSUME_YES=1;; + NONINTERACTIVE=1;; q) QUIET=1;; v) @@ -96,8 +97,8 @@ if [ $BASENAME = "letsencrypt-auto" ]; then HELP=0 fi -# Set ASSUME_YES to 1 if QUIET (i.e. --quiet implies --non-interactive) -if [ "$QUIET" = 1 ]; then +# Set ASSUME_YES to 1 if QUIET or NONINTERACTIVE +if [ "$QUIET" = 1 -o "$NONINTERACTIVE" = 1 ]; then ASSUME_YES=1 fi @@ -266,23 +267,41 @@ DeterminePythonVersion() { {{ bootstrappers/smartos.sh }} {{ bootstrappers/mageia_common.sh }} -# Install required OS packages: -Bootstrap() { - if [ "$NO_BOOTSTRAP" = 1 ]; then - return - elif [ -f /etc/debian_version ]; then +# Set Bootstrap to the function that installs OS dependencies on this system +# and BOOTSTRAP_VERSION to the unique identifier for the current version of +# that function. If Bootstrap is set to a function that doesn't install any +# packages (either because --no-bootstrap was included on the command line or +# we don't know how to bootstrap on this system), BOOTSTRAP_VERSION is not set. +if [ "$NO_BOOTSTRAP" = 1 ]; then + Bootstrap() { + : + } +elif [ -f /etc/debian_version ]; then + Bootstrap() { BootstrapMessage "Debian-based OSes" BootstrapDebCommon - elif [ -f /etc/mageia-release ]; then - # Mageia has both /etc/mageia-release and /etc/redhat-release + } + BOOTSTRAP_VERSION="BootstrapDebCommon $BOOTSTRAP_DEB_COMMON_VERSION" +elif [ -f /etc/mageia-release ]; then + # Mageia has both /etc/mageia-release and /etc/redhat-release + Bootstrap() { ExperimentalBootstrap "Mageia" BootstrapMageiaCommon - elif [ -f /etc/redhat-release ]; then + } + BOOTSTRAP_VERSION="BootstrapMageiaCommon $BOOTSTRAP_MAGEIA_COMMON_VERSION" +elif [ -f /etc/redhat-release ]; then + Bootstrap() { BootstrapMessage "RedHat-based OSes" BootstrapRpmCommon - elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" +elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then + Bootstrap() { BootstrapMessage "openSUSE-based OSes" BootstrapSuseCommon - elif [ -f /etc/arch-release ]; then + } + BOOTSTRAP_VERSION="BootstrapSuseCommon $BOOTSTRAP_SUSE_COMMON_VERSION" +elif [ -f /etc/arch-release ]; then + Bootstrap() { if [ "$DEBUG" = 1 ]; then BootstrapMessage "Archlinux" BootstrapArchCommon @@ -294,25 +313,76 @@ Bootstrap() { error "--debug flag." exit 1 fi - elif [ -f /etc/manjaro-release ]; then + } + BOOTSTRAP_VERSION="BootstrapArchCommon $BOOTSTRAP_ARCH_COMMON_VERSION" +elif [ -f /etc/manjaro-release ]; then + Bootstrap() { ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon - elif [ -f /etc/gentoo-release ]; then + } + BOOTSTRAP_VERSION="BootstrapArchCommon $BOOTSTRAP_ARCH_COMMON_VERSION" +elif [ -f /etc/gentoo-release ]; then + Bootstrap() { DeprecationBootstrap "Gentoo" BootstrapGentooCommon - elif uname | grep -iq FreeBSD ; then + } + BOOTSTRAP_VERSION="BootstrapGentooCommon $BOOTSTRAP_GENTOO_COMMON_VERSION" +elif uname | grep -iq FreeBSD ; then + Bootstrap() { DeprecationBootstrap "FreeBSD" BootstrapFreeBsd - elif uname | grep -iq Darwin ; then + } + BOOTSTRAP_VERSION="BootstrapFreeBsd $BOOTSTRAP_FREEBSD_VERSION" +elif uname | grep -iq Darwin ; then + Bootstrap() { DeprecationBootstrap "macOS" BootstrapMac - elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then + } + BOOTSTRAP_VERSION="BootstrapMac $BOOTSTRAP_MAC_VERSION" +elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then + Bootstrap() { ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon - elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then + } + BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" +elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then + Bootstrap() { ExperimentalBootstrap "Joyent SmartOS Zone" BootstrapSmartOS - else + } + BOOTSTRAP_VERSION="BootstrapSmartOS $BOOTSTRAP_SMARTOS_VERSION" +else + Bootstrap() { error "Sorry, I don't know how to bootstrap Certbot on your operating system!" error error "You will need to install OS dependencies, configure virtualenv, and run pip install manually." error "Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites" error "for more info." exit 1 + } +fi + +# Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used +# to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set +# if it is unknown how OS dependencies were installed on this system. +SetPrevBootstrapVersion() { + if [ -f $BOOTSTRAP_VERSION_PATH ]; then + PREV_BOOTSTRAP_VERSION=$(cat "$BOOTSTRAP_VERSION_PATH") + # The list below only contains bootstrap version strings that existed before + # we started writing them to disk. + # + # DO NOT MODIFY THIS LIST UNLESS YOU KNOW WHAT YOU'RE DOING! + elif grep -Fqx "$BOOTSTRAP_VERSION" << "UNLIKELY_EOF" +BootstrapDebCommon 1 +BootstrapMageiaCommon 1 +BootstrapRpmCommon 1 +BootstrapSuseCommon 1 +BootstrapArchCommon 1 +BootstrapGentooCommon 1 +BootstrapFreeBsd 1 +BootstrapMac 1 +BootstrapSmartOS 1 +UNLIKELY_EOF + then + # If there's no bootstrap version saved to disk, but the currently selected + # bootstrap script is from before we started saving the version number, + # return the currently selected version to prevent us from rebootstrapping + # unnecessarily. + PREV_BOOTSTRAP_VERSION="$BOOTSTRAP_VERSION" fi } @@ -326,18 +396,39 @@ if [ "$1" = "--le-auto-phase2" ]; then # Phase 2: Create venv, install LE, and run. shift 1 # the --le-auto-phase2 arg - if [ -f "$VENV_BIN/letsencrypt" ]; then - # --version output ran through grep due to python-cryptography DeprecationWarnings - # grep for both certbot and letsencrypt until certbot and shim packages have been released - INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) - if [ -z "$INSTALLED_VERSION" ]; then - error "Error: couldn't get currently installed version for $VENV_BIN/letsencrypt: " 1>&2 - "$VENV_BIN/letsencrypt" --version - exit 1 + SetPrevBootstrapVersion + + INSTALLED_VERSION="none" + if [ -d "$VENV_PATH" ]; then + # If the selected Bootstrap function isn't a noop and it differs from the + # previously used version + if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then + # if non-interactive mode or stdin and stdout are connected to a terminal + if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then + rm -rf "$VENV_PATH" + "$0" "$@" + exit 0 + else + error "Skipping upgrade because new OS dependencies may need to be installed." + error + error "To upgrade to a newer version, please run this script again manually so you can" + error "approve changes or with --non-interactive on the command line to automatically" + error "install any required packages." + # Set INSTALLED_VERSION to be the same so we don't update the venv + INSTALLED_VERSION="$LE_AUTO_VERSION" + fi + elif [ -f "$VENV_BIN/letsencrypt" ]; then + # --version output ran through grep due to python-cryptography DeprecationWarnings + # grep for both certbot and letsencrypt until certbot and shim packages have been released + INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | grep "^certbot\|^letsencrypt" | cut -d " " -f 2) + if [ -z "$INSTALLED_VERSION" ]; then + error "Error: couldn't get currently installed version for $VENV_BIN/letsencrypt: " 1>&2 + "$VENV_BIN/letsencrypt" --version + exit 1 + fi fi - else - INSTALLED_VERSION="none" fi + if [ "$LE_AUTO_VERSION" != "$INSTALLED_VERSION" ]; then say "Creating virtual environment..." DeterminePythonVersion @@ -348,6 +439,12 @@ if [ "$1" = "--le-auto-phase2" ]; then virtualenv --no-site-packages --python "$LE_PYTHON" "$VENV_PATH" > /dev/null fi + if [ -n "$BOOTSTRAP_VERSION" ]; then + echo "$BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH" + elif [ -n "$PREV_BOOTSTRAP_VERSION" ]; then + echo "$PREV_BOOTSTRAP_VERSION" > "$BOOTSTRAP_VERSION_PATH" + fi + say "Installing Python packages..." TEMP_DIR=$(TempDir) trap 'rm -rf "$TEMP_DIR"' EXIT diff --git a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh index 3983bc1d8..5759336c5 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/arch_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapArchCommon below, this version +# number must be increased. +BOOTSTRAP_ARCH_COMMON_VERSION=1 + BootstrapArchCommon() { # Tested with: # - ArchLinux (x86_64) diff --git a/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh index 12aa80d63..eb22225e4 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapDebCommon below, this version +# number must be increased. +BOOTSTRAP_DEB_COMMON_VERSION=1 + BootstrapDebCommon() { # Current version tested with: # diff --git a/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh b/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh index cfbd2b8b1..a67c85619 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/free_bsd.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapFreeBsd below, this version number +# must be increased. +BOOTSTRAP_FREEBSD_VERSION=1 + BootstrapFreeBsd() { if [ "$QUIET" = 1 ]; then QUIET_FLAG="--quiet" diff --git a/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh index 46543bab9..e2d24b5fb 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/gentoo_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapGentooCommon below, this version +# number must be increased. +BOOTSTRAP_GENTOO_COMMON_VERSION=1 + BootstrapGentooCommon() { PACKAGES=" dev-lang/python:2.7 diff --git a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh index b9f347f67..9e26d3389 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/mac.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/mac.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapMac below, this version number must +# be increased. +BOOTSTRAP_MAC_VERSION=1 + BootstrapMac() { if hash brew 2>/dev/null; then say "Using Homebrew to install dependencies..." diff --git a/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh index c9a540ce1..dfa5b47f3 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/mageia_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapMageiaCommon below, this version +# number must be increased. +BOOTSTRAP_MAGEIA_COMMON_VERSION=1 + BootstrapMageiaCommon() { if [ "$QUIET" = 1 ]; then QUIET_FLAG='--quiet' diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh index 129684338..5b120a9e6 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapRpmCommon below, this version +# number must be increased. +BOOTSTRAP_RPM_COMMON_VERSION=1 + BootstrapRpmCommon() { # Tested with: # - Fedora 20, 21, 22, 23 (x64) diff --git a/letsencrypt-auto-source/pieces/bootstrappers/smartos.sh b/letsencrypt-auto-source/pieces/bootstrappers/smartos.sh index e721c1c0b..ac7c0ed4a 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/smartos.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/smartos.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapSmartOS below, this version number +# must be increased. +BOOTSTRAP_SMARTOS_VERSION=1 + BootstrapSmartOS() { pkgin update pkgin -y install 'gcc49' 'py27-augeas' 'py27-virtualenv' diff --git a/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh b/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh index 56e7acda3..c531cbe99 100755 --- a/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/suse_common.sh @@ -1,3 +1,7 @@ +# If new packages are installed by BootstrapSuseCommon below, this version +# number must be increased. +BOOTSTRAP_SUSE_COMMON_VERSION=1 + BootstrapSuseCommon() { # SLE12 don't have python-virtualenv