From 434ca1985f26b08de18728e70e86813f357f6b65 Mon Sep 17 00:00:00 2001 From: Antonio Larrosa <33935697+antlarr-suse@users.noreply.github.com> Date: Fri, 8 Jan 2021 18:49:21 +0100 Subject: [PATCH 01/10] Change the SUSE override to use apachectl (#8592) For some time, SUSE distributions have had both an apachectl executable and an apache2ctl compat symlink so both could be used but apachectl is preferred since that's the official upstream name. This is currently the case in SLE 15 SP2 and openSUSE Leap 15.2 (and every release since SLE 12 SP1) OTOH, openSUSE Tumbleweed removed the apache2ctl compat symlink some weeks ago and both SLE/Leap will follow in one of the next releases so it's better to change certbot to use the official name, apachectl. --- certbot-apache/certbot_apache/_internal/override_suse.py | 8 ++++---- certbot/CHANGELOG.md | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/certbot-apache/certbot_apache/_internal/override_suse.py b/certbot-apache/certbot_apache/_internal/override_suse.py index eee9b0b64..afce98dfa 100644 --- a/certbot-apache/certbot_apache/_internal/override_suse.py +++ b/certbot-apache/certbot_apache/_internal/override_suse.py @@ -14,10 +14,10 @@ class OpenSUSEConfigurator(configurator.ApacheConfigurator): vhost_root="/etc/apache2/vhosts.d", vhost_files="*.conf", logs_root="/var/log/apache2", - ctl="apache2ctl", - version_cmd=['apache2ctl', '-v'], - restart_cmd=['apache2ctl', 'graceful'], - conftest_cmd=['apache2ctl', 'configtest'], + ctl="apachectl", + version_cmd=['apachectl', '-v'], + restart_cmd=['apachectl', 'graceful'], + conftest_cmd=['apachectl', 'configtest'], enmod="a2enmod", dismod="a2dismod", le_vhost_ext="-le-ssl.conf", diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index c01fe830c..efaa2f6be 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -14,7 +14,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Fixed -* +* Fixed the apache component on openSUSE Tumbleweed which no longer provides + an apache2ctl symlink and uses apachectl instead. More details about these changes can be found on our GitHub repo. From 42f20455cdde94d49892aec15f78ddbb9867e2a8 Mon Sep 17 00:00:00 2001 From: Daniel Almasi Date: Mon, 11 Jan 2021 21:40:12 +0000 Subject: [PATCH 02/10] Fix EC curve name typo in crypto_util (#8598) * Fix EC curve name typo in crypto_util Fix typo of secp521r1 in crypto util module. - secp521r1 is to be supported by certbot, but a typo of "SECP521R1" in the input validation section of the make_key function results in an error being thrown * Add myself to authors.md Add myself to authors.md ^^ * Add test for secp521r1 key generation Add test for secp521r1 key generation to cli-tests --- AUTHORS.md | 1 + .../certbot_tests/test_main.py | 15 +++++++++++---- certbot/CHANGELOG.md | 1 + certbot/certbot/crypto_util.py | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index ff5c61613..b00a90da3 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -60,6 +60,7 @@ Authors * [DanCld](https://github.com/DanCld) * [Daniel Albers](https://github.com/AID) * [Daniel Aleksandersen](https://github.com/da2x) +* [Daniel Almasi](https://github.com/almasen) * [Daniel Convissor](https://github.com/convissor) * [Daniel "Drex" Drexler](https://github.com/aeturnum) * [Daniel Huang](https://github.com/dhuang) diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py index 546f96305..28a728370 100644 --- a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py +++ b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py @@ -9,7 +9,7 @@ import shutil import subprocess import time -from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, SECP384R1 +from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, SECP384R1, SECP521R1 from cryptography.x509 import NameOID import pytest @@ -498,6 +498,13 @@ def test_renew_with_ec_keys(context): assert_elliptic_key(key2, SECP384R1) assert 280 < os.stat(key2).st_size < 320 # ec keys of 384 bits are ~310 bytes + context.certbot(['renew', '--elliptic-curve', 'secp521r1']) + + assert_cert_count_for_lineage(context.config_dir, certname, 3) + key3 = join(context.config_dir, 'archive', certname, 'privkey3.pem') + assert_elliptic_key(key3, SECP521R1) + assert 340 < os.stat(key3).st_size < 390 # ec keys of 521 bits are ~365 bytes + # We expect here that the command will fail because without --key-type specified, # Certbot must error out to prevent changing an existing certificate key type, # without explicit user consent (by specifying both --cert-name and --key-type). @@ -511,9 +518,9 @@ def test_renew_with_ec_keys(context): # We expect that the previous behavior of requiring both --cert-name and # --key-type to be set to not apply to the renew subcommand. context.certbot(['renew', '--force-renewal', '--key-type', 'rsa']) - assert_cert_count_for_lineage(context.config_dir, certname, 3) - key3 = join(context.config_dir, 'archive', certname, 'privkey3.pem') - assert_rsa_key(key3) + assert_cert_count_for_lineage(context.config_dir, certname, 4) + key4 = join(context.config_dir, 'archive', certname, 'privkey4.pem') + assert_rsa_key(key4) def test_ocsp_must_staple(context): diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index efaa2f6be..73e29ac45 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -16,6 +16,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). * Fixed the apache component on openSUSE Tumbleweed which no longer provides an apache2ctl symlink and uses apachectl instead. +* Fixed a typo in `certbot/crypto_util.py` causing an error upon attempting `secp521r1` key generation More details about these changes can be found on our GitHub repo. diff --git a/certbot/certbot/crypto_util.py b/certbot/certbot/crypto_util.py index 256454122..d511dfdb1 100644 --- a/certbot/certbot/crypto_util.py +++ b/certbot/certbot/crypto_util.py @@ -205,7 +205,7 @@ def make_key(bits=1024, key_type="rsa", elliptic_curve=None): elif key_type == 'ecdsa': try: name = elliptic_curve.upper() - if name in ('SECP256R1', 'SECP384R1', 'SECP512R1'): + if name in ('SECP256R1', 'SECP384R1', 'SECP521R1'): _key = ec.generate_private_key( curve=getattr(ec, elliptic_curve.upper(), None)(), backend=default_backend() From 7a02deeeba4e823c9b947a311fd85a5497a9dd30 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 11 Jan 2021 15:41:55 -0800 Subject: [PATCH 03/10] Modify release script to support yubikey sig (#8574) Using `tools/offline-sigrequest.sh` is annoying. A while ago I looked into how we could use our yubikeys for our Windows code signing signatures and in the process of doing that learned how to use them for the certbot-auto signature. The certbot-auto signature won't be needed once https://github.com/certbot/certbot/issues/8526 is resolved and we've implemented that plan which will hopefully be in 2-3 months, but despite that, doing this still felt worth it to me. The script still defaults to using `tools/offline-sign.sh`, but you can set an environment variable to use the yubikey instead. I tested both branches here and it worked. --- tools/_release.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/_release.sh b/tools/_release.sh index e17332f30..d1fe55ae9 100755 --- a/tools/_release.sh +++ b/tools/_release.sh @@ -216,8 +216,21 @@ fi # ensure we have the latest built version of leauto letsencrypt-auto-source/build.py -# and that it's signed correctly -tools/offline-sigrequest.sh || true +# Now we have to sign the built version of leauto. If +# RELEASE_OPENSSL_WITH_YUBIKEY is set, try to use the yubikey to sign +# letsencrypt-auto, otherwise, use tools/offline-sigrequest.sh. +if [ -n "$RELEASE_OPENSSL_WITH_YUBIKEY" ]; then + SignLEAuto() { + yubico-piv-tool -a verify-pin --sign -s 9c -i letsencrypt-auto-source/letsencrypt-auto -o letsencrypt-auto-source/letsencrypt-auto.sig + } +else + SignLEAuto() { + tools/offline-sigrequest.sh + } +fi + +# Loop until letsencrypt-auto is signed correctly. +SignLEAuto || true while ! openssl dgst -sha256 -verify $RELEASE_OPENSSL_PUBKEY -signature \ letsencrypt-auto-source/letsencrypt-auto.sig \ letsencrypt-auto-source/letsencrypt-auto ; do @@ -225,7 +238,7 @@ while ! openssl dgst -sha256 -verify $RELEASE_OPENSSL_PUBKEY -signature \ read -p "Would you like this script to try and sign it again [Y/n]?" response case $response in [yY][eE][sS]|[yY]|"") - tools/offline-sigrequest.sh || true;; + SignLEAuto || true;; *) ;; esac From b9de48e93ef885d2ce5f3a0ee3083777fc32ab1f Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Tue, 12 Jan 2021 13:45:26 -0800 Subject: [PATCH 04/10] Always sign certbot-auto with a yubikey (#8600) * always sign certbot-auto with the yubikey * remove tools/offline-sigrequest.sh --- tools/_release.sh | 16 +++--------- tools/offline-sigrequest.sh | 51 ------------------------------------- 2 files changed, 4 insertions(+), 63 deletions(-) delete mode 100755 tools/offline-sigrequest.sh diff --git a/tools/_release.sh b/tools/_release.sh index d1fe55ae9..e9e0e49f0 100755 --- a/tools/_release.sh +++ b/tools/_release.sh @@ -216,18 +216,10 @@ fi # ensure we have the latest built version of leauto letsencrypt-auto-source/build.py -# Now we have to sign the built version of leauto. If -# RELEASE_OPENSSL_WITH_YUBIKEY is set, try to use the yubikey to sign -# letsencrypt-auto, otherwise, use tools/offline-sigrequest.sh. -if [ -n "$RELEASE_OPENSSL_WITH_YUBIKEY" ]; then - SignLEAuto() { - yubico-piv-tool -a verify-pin --sign -s 9c -i letsencrypt-auto-source/letsencrypt-auto -o letsencrypt-auto-source/letsencrypt-auto.sig - } -else - SignLEAuto() { - tools/offline-sigrequest.sh - } -fi +# Now we have to sign the built version of leauto. +SignLEAuto() { + yubico-piv-tool -a verify-pin --sign -s 9c -i letsencrypt-auto-source/letsencrypt-auto -o letsencrypt-auto-source/letsencrypt-auto.sig +} # Loop until letsencrypt-auto is signed correctly. SignLEAuto || true diff --git a/tools/offline-sigrequest.sh b/tools/offline-sigrequest.sh deleted file mode 100755 index 6443ae8af..000000000 --- a/tools/offline-sigrequest.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -o errexit - -function sayhash { # $1 <-- HASH ; $2 <---SIGFILEBALL - while read -p "Press Enter to read the hash aloud or type 'done': " INP && [ "$INP" = "" ] ; do - if ! `which festival > /dev/null` ; then - echo \`festival\` is not installed! - echo Please install it to read the hash aloud - else - cat $1 | (echo "(Parameter.set 'Duration_Stretch 1.8)"; \ - echo -n '(SayText "'; \ - sha256sum | cut -c1-64 | fold -1 | sed 's/^a$/alpha/; s/^b$/bravo/; s/^c$/charlie/; s/^d$/delta/; s/^e$/echo/; s/^f$/foxtrot/'; \ - echo '")' ) | festival - fi - done - - echo 'Paste in the data from the QR code, then type Ctrl-D:' - cat > $2 -} - -function offlinesign { # $1 <-- INPFILE ; $2 <---SIGFILE - echo HASH FOR SIGNING: - SIGFILEBALL="$2.lzma.base64" - #echo "(place the resulting raw binary signature in $SIGFILEBALL)" - sha256sum $1 - echo metahash for confirmation only $(sha256sum $1 |cut -d' ' -f1 | tr -d '\n' | sha256sum | cut -c1-6) ... - echo - sayhash $1 $SIGFILEBALL -} - -function oncesigned { # $1 <-- INPFILE ; $2 <--SIGFILE - SIGFILEBALL="$2.lzma.base64" - cat $SIGFILEBALL | tr -d '\r' | base64 -d | unlzma -c > $2 || exit 1 - if ! [ -f $2 ] ; then - echo "Failed to find $2"'!' - exit 1 - fi - - if file $2 | grep -qv " data" ; then - echo "WARNING WARNING $2 does not look like a binary signature:" - echo `file $2` - exit 1 - fi -} - -HERE=`dirname $0` -LEAUTO="`realpath $HERE`/../letsencrypt-auto-source/letsencrypt-auto" -SIGFILE="$LEAUTO".sig -offlinesign $LEAUTO $SIGFILE -oncesigned $LEAUTO $SIGFILE From 13d4a992519c52b0771eb5015ce372b298fabc57 Mon Sep 17 00:00:00 2001 From: alexzorin Date: Wed, 13 Jan 2021 11:08:32 +1100 Subject: [PATCH 05/10] test: certbot-ci crash due to no p521 on boulder (#8602) * test: certbot-ci crash due to no p521 on boulder The bugfix in #8598 added an integration test to request a certificate for an EC P-521 key, which is unsupported when ACME_SERVER=boulder, failing our nightly integration tests. * add an integration test for all EC curves --- .../certbot_tests/test_main.py | 35 +++++++++++++------ certbot/tests/crypto_util_test.py | 10 +++--- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py index 28a728370..4296de6f8 100644 --- a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py +++ b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py @@ -476,6 +476,28 @@ def test_default_curve_type(context): assert_elliptic_key(key1, SECP256R1) +@pytest.mark.parametrize('curve,curve_cls,skip_servers', [ + # Curve name, Curve class, ACME servers to skip + ('secp256r1', SECP256R1, []), + ('secp384r1', SECP384R1, []), + ('secp521r1', SECP521R1, ['boulder-v1', 'boulder-v2'])] +) +def test_ecdsa_curves(context, curve, curve_cls, skip_servers): + """Test issuance for each supported ECDSA curve""" + if context.acme_server in skip_servers: + pytest.skip('ACME server {} does not support ECDSA curve {}' + .format(context.acme_server, curve)) + + domain = context.get_domain('curve') + context.certbot([ + 'certonly', + '--key-type', 'ecdsa', '--elliptic-curve', curve, + '--force-renewal', '-d', domain, + ]) + key = join(context.config_dir, "live", domain, 'privkey.pem') + assert_elliptic_key(key, curve_cls) + + def test_renew_with_ec_keys(context): """Test proper renew with updated private key complexity.""" certname = context.get_domain('renew') @@ -498,13 +520,6 @@ def test_renew_with_ec_keys(context): assert_elliptic_key(key2, SECP384R1) assert 280 < os.stat(key2).st_size < 320 # ec keys of 384 bits are ~310 bytes - context.certbot(['renew', '--elliptic-curve', 'secp521r1']) - - assert_cert_count_for_lineage(context.config_dir, certname, 3) - key3 = join(context.config_dir, 'archive', certname, 'privkey3.pem') - assert_elliptic_key(key3, SECP521R1) - assert 340 < os.stat(key3).st_size < 390 # ec keys of 521 bits are ~365 bytes - # We expect here that the command will fail because without --key-type specified, # Certbot must error out to prevent changing an existing certificate key type, # without explicit user consent (by specifying both --cert-name and --key-type). @@ -518,9 +533,9 @@ def test_renew_with_ec_keys(context): # We expect that the previous behavior of requiring both --cert-name and # --key-type to be set to not apply to the renew subcommand. context.certbot(['renew', '--force-renewal', '--key-type', 'rsa']) - assert_cert_count_for_lineage(context.config_dir, certname, 4) - key4 = join(context.config_dir, 'archive', certname, 'privkey4.pem') - assert_rsa_key(key4) + assert_cert_count_for_lineage(context.config_dir, certname, 3) + key3 = join(context.config_dir, 'archive', certname, 'privkey3.pem') + assert_rsa_key(key3) def test_ocsp_must_staple(context): diff --git a/certbot/tests/crypto_util_test.py b/certbot/tests/crypto_util_test.py index 37673db99..3861751eb 100644 --- a/certbot/tests/crypto_util_test.py +++ b/certbot/tests/crypto_util_test.py @@ -184,11 +184,13 @@ class MakeKeyTest(unittest.TestCase): def test_ec(self): # pylint: disable=no-self-use # ECDSA Key Type Tests from certbot.crypto_util import make_key - # Do not test larger keys as it takes too long. - # Try a good key size for ECDSA - OpenSSL.crypto.load_privatekey( - OpenSSL.crypto.FILETYPE_PEM, make_key(elliptic_curve="secp256r1", key_type='ecdsa')) + for (name, bits) in [('secp256r1', 256), ('secp384r1', 384), ('secp521r1', 521)]: + pkey = OpenSSL.crypto.load_privatekey( + OpenSSL.crypto.FILETYPE_PEM, + make_key(elliptic_curve=name, key_type='ecdsa') + ) + self.assertEqual(pkey.bits(), bits) def test_bad_key_sizes(self): from certbot.crypto_util import make_key From c0917a0302d10c9aca35f294b864499616b1af59 Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Wed, 13 Jan 2021 23:38:57 +0100 Subject: [PATCH 06/10] Use os.path.normcase to have Windows compatible challenge paths on Windows (#8599) * Use os.path.normcase to have Windows compatible challenge paths on Windows. * Add integration test and fix lint --- .../certbot_tests/test_main.py | 11 +++++++++++ certbot/certbot/_internal/plugins/webroot.py | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py index 4296de6f8..2d3d93669 100644 --- a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py +++ b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py @@ -148,6 +148,17 @@ def test_certonly(context): """Test the certonly verb on certbot.""" context.certbot(['certonly', '--cert-name', 'newname', '-d', context.get_domain('newname')]) + assert_cert_count_for_lineage(context.config_dir, 'newname', 1) + + +def test_certonly_webroot(context): + """Test the certonly verb with webroot plugin""" + with misc.create_http_server(context.http_01_port) as webroot: + certname = context.get_domain('webroot') + context.certbot(['certonly', '-a', 'webroot', '--webroot-path', webroot, '-d', certname]) + + assert_cert_count_for_lineage(context.config_dir, certname, 1) + def test_auth_and_install_with_csr(context): """Test certificate issuance and install using an existing CSR.""" diff --git a/certbot/certbot/_internal/plugins/webroot.py b/certbot/certbot/_internal/plugins/webroot.py index 484d209d6..88e02998d 100644 --- a/certbot/certbot/_internal/plugins/webroot.py +++ b/certbot/certbot/_internal/plugins/webroot.py @@ -157,7 +157,8 @@ to serve all files under specified web root ({0}).""" "--webroot-path and --domains, or --webroot-map. Run with " " --help webroot for examples.") for name, path in path_map.items(): - self.full_roots[name] = os.path.join(path, challenges.HTTP01.URI_ROOT_PATH) + self.full_roots[name] = os.path.join(path, os.path.normcase( + challenges.HTTP01.URI_ROOT_PATH)) logger.debug("Creating root challenges validation dir at %s", self.full_roots[name]) From 2fca48caaa8529432d003b0fdc880b673f6be1f5 Mon Sep 17 00:00:00 2001 From: Aaron Gable Date: Wed, 13 Jan 2021 17:12:48 -0800 Subject: [PATCH 07/10] --preferred-chain: only match root name (#8596) * --preferred-chain: only match root name Currently, when certbot is given the `--preferred-chain='Some Name'` flag, it iterates through all alternate chains offered by the ACME server until it finds any certificate which has `'Some Name'` as its Issuer Common Name. Unfortunately, this means that if the desired alternate chain is a strict subset of any earlier chain (e.g. the default chain is 'EE <-- Int <-- Root1 <-- Root2', but the desired chain is 'EE <-- Int <-- Root1'), there is no name which can be provided by the user which will allow the client to select the desired chain. This change makes it so that the `find_chain_with_issuer` logic only cares about the Issuer Common Name found in the last certificate in each chain. In the example above, the user would then be able to get their desired chain by specifying `--preferred-chain='Root1'`: although that name appears in the default chain, it does not appear in the highest certificate of that chain. This change is technically backwards-incompatible. However, the only advice that has been given to users of certbot (and the only usecase that we believe has existed so far) involved setting the flag to a value that is the name of a root, not an intermediate, so we don't expect any real-world configurations or use-cases to be broken. Fixes #8577 * Update interfaces.py --- AUTHORS.md | 1 + certbot/CHANGELOG.md | 5 ++++- certbot/certbot/crypto_util.py | 18 ++++++++---------- certbot/certbot/interfaces.py | 6 +++--- certbot/tests/crypto_util_test.py | 13 +++++++++++++ 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index b00a90da3..cb60bfd87 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,6 +1,7 @@ Authors ======= +* [Aaron Gable](https://github.com/aarongable) * [Aaron Zirbes](https://github.com/aaronzirbes) * Aaron Zuehlke * Ada Lovelace diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 73e29ac45..e51139225 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -10,7 +10,10 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Changed -* +* The `--preferred-chain` flag now only checks the Issuer Common Name of the + topmost (closest to the root) certificate in the chain, instead of checking + every certificate in the chain. + See [#8577](https://github.com/certbot/certbot/issues/8577). ### Fixed diff --git a/certbot/certbot/crypto_util.py b/certbot/certbot/crypto_util.py index d511dfdb1..edd4f9eb3 100644 --- a/certbot/certbot/crypto_util.py +++ b/certbot/certbot/crypto_util.py @@ -573,8 +573,9 @@ def get_serial_from_cert(cert_path): def find_chain_with_issuer(fullchains, issuer_cn, warn_on_no_match=False): - """Chooses the first certificate chain from fullchains which contains an - Issuer Subject Common Name matching issuer_cn. + """Chooses the first certificate chain from fullchains whose topmost + intermediate has an Issuer Common Name matching issuer_cn (in other words + the first chain which chains to a root whose name matches issuer_cn). :param fullchains: The list of fullchains in PEM chain format. :type fullchains: `list` of `str` @@ -585,14 +586,11 @@ def find_chain_with_issuer(fullchains, issuer_cn, warn_on_no_match=False): :rtype: `str` """ for chain in fullchains: - certs = [x509.load_pem_x509_certificate(cert, default_backend()) \ - for cert in CERT_PEM_REGEX.findall(chain.encode())] - # Iterate the fullchain beginning from the leaf. For each certificate encountered, - # match against Issuer Subject CN. - for cert in certs: - cert_issuer_cn = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME) - if cert_issuer_cn and cert_issuer_cn[0].value == issuer_cn: - return chain + certs = CERT_PEM_REGEX.findall(chain.encode()) + top_cert = x509.load_pem_x509_certificate(certs[-1], default_backend()) + top_issuer_cn = top_cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME) + if top_issuer_cn and top_issuer_cn[0].value == issuer_cn: + return chain # Nothing matched, return whatever was first in the list. if warn_on_no_match: diff --git a/certbot/certbot/interfaces.py b/certbot/certbot/interfaces.py index 6ba28bd56..28c6f2ac1 100644 --- a/certbot/certbot/interfaces.py +++ b/certbot/certbot/interfaces.py @@ -262,9 +262,9 @@ class IConfig(zope.interface.Interface): " with \"renew\" verb should be disabled.") preferred_chain = zope.interface.Attribute( - "If the CA offers multiple certificate chains, prefer the chain with " - "an issuer matching this Subject Common Name. If no match, the default " - "offered chain will be used." + "If the CA offers multiple certificate chains, prefer the chain whose " + "topmost certificate was issued from this Subject Common Name. " + "If no match, the default offered chain will be used." ) diff --git a/certbot/tests/crypto_util_test.py b/certbot/tests/crypto_util_test.py index 3861751eb..3b9c973f7 100644 --- a/certbot/tests/crypto_util_test.py +++ b/certbot/tests/crypto_util_test.py @@ -473,6 +473,19 @@ class FindChainWithIssuerTest(unittest.TestCase): matched = self._call(fullchains, "Pebble Root CA 0cc6f0") self.assertEqual(matched, fullchains[1]) + @mock.patch('certbot.crypto_util.logger.info') + def test_intermediate_match(self, mock_info): + """Don't pick a chain where only an intermediate matches""" + fullchains = self._all_fullchains() + # Make the second chain actually only contain "Pebble Root CA 0cc6f0" + # as an intermediate, not as the root. This wouldn't be a valid chain + # (the CERT_ISSUER cert didn't issue the CERT_ALT_ISSUER cert), but the + # function under test here doesn't care about that. + fullchains[1] = fullchains[1] + CERT_ISSUER.decode() + matched = self._call(fullchains, "Pebble Root CA 0cc6f0") + self.assertEqual(matched, fullchains[0]) + mock_info.assert_not_called() + @mock.patch('certbot.crypto_util.logger.info') def test_no_match(self, mock_info): fullchains = self._all_fullchains() From 261b5a76d8c000ce1354e0a0437b9c2f846fc6a3 Mon Sep 17 00:00:00 2001 From: Miltos Date: Thu, 14 Jan 2021 09:39:42 +0000 Subject: [PATCH 08/10] Minor fix to logging message (#8605) * Minor fix to logging message the `if socket_kwargs` will always evaluate to `true`. * Update acme/acme/crypto_util.py Co-authored-by: alexzorin --- acme/acme/crypto_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme/acme/crypto_util.py b/acme/acme/crypto_util.py index cabc7f4d1..4b58db328 100644 --- a/acme/acme/crypto_util.py +++ b/acme/acme/crypto_util.py @@ -166,7 +166,7 @@ def probe_sni(name, host, port=443, timeout=300, # pylint: disable=too-many-argu " from {0}:{1}".format( source_address[0], source_address[1] - ) if socket_kwargs else "" + ) if any(source_address) else "" ) socket_tuple = (host, port) # type: Tuple[str, int] sock = socket.create_connection(socket_tuple, **socket_kwargs) # type: ignore From adb7e5e62f4c96be678c5af3e55a82ddcc717590 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 15 Jan 2021 12:13:59 -0800 Subject: [PATCH 09/10] remove unused pyicu pinning (#8607) --- tools/oldest_constraints.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 5d1446005..27d5bf288 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -29,7 +29,6 @@ zope.interface==4.0.5 # Debian Jessie has reached end of life. However: # When it becomes necessary to upgrade any of these dependencies, you should only update them to the oldest version of the package found # in a non-EOL'd version of CentOS, Debian, or Ubuntu that has Certbot packages in their OS repositories. -PyICU==1.8 colorama==0.3.2 enum34==1.0.3 html5lib==0.999 From 00235d3807f298c3cee700ed946a2fc6c3bf8145 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Mon, 25 Jan 2021 12:59:14 -0800 Subject: [PATCH 10/10] Switch oldest tests to Python 3 (#8590) Fixes https://github.com/certbot/certbot/issues/8580. With this PR, it should now be possible to run the oldest tests natively on Linux, at least when using an older version of Python 3, which hasn't been possible in a long time. Unfortunately, this isn't possible on macOS which I opened https://github.com/certbot/certbot/issues/8589 to track. You can see the full test suite running with these changes at https://dev.azure.com/certbot/certbot/_build/results?buildId=3283&view=results. I took the version numbers for the packages I updated by searching for the oldest version of the dependency I think we should try and support based on the updated comments at the top of `oldest_constraints.txt`. While kind of annoying, I think it'd be a good idea for the reviewer to double check that I didn't make a mistake with the versions I used here. To find these versions, I used https://packages.ubuntu.com, https://packages.debian.org, and a CentOS 7 Docker image with EPEL 7 installed. For the latter, not all packages are available in Python 3 yet (which is something Certbot's EPEL package maintainers are working on) and in that case I didn't worry about the system because I think they can/will package the newest version available. If they end up hitting any issues here when trying to package Certbot on Python 3, we can always work with them to fix it. * remove py27 from oldest name * update min cryptography version * remove run_oldest_tests.sh * upgrade setuptools and pyopenssl * update cffi, pyparsing, and idna * expand oldest_constraints comments * clarify oldest comment * update min configobj version * update min parsedatetime version * quote tox env name * use Python 3.6 in the oldest tests * use Python 3.6 for oldest integration tests * properly pin asn1crypto * update min six version * set basepython for a nicer error message * remove outdated python 2 oldest constraints --- .../templates/jobs/extended-tests-jobs.yml | 4 ++ .../templates/jobs/standard-tests-jobs.yml | 6 ++- .../templates/steps/tox-steps.yml | 6 +-- acme/setup.py | 11 ++-- certbot-apache/setup.py | 2 +- certbot-dns-cloudflare/setup.py | 2 +- certbot-dns-cloudxns/setup.py | 2 +- certbot-dns-digitalocean/setup.py | 4 +- certbot-dns-dnsimple/setup.py | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- certbot-dns-gehirn/setup.py | 2 +- certbot-dns-google/setup.py | 2 +- certbot-dns-linode/setup.py | 2 +- certbot-dns-luadns/setup.py | 2 +- certbot-dns-nsone/setup.py | 2 +- certbot-dns-ovh/setup.py | 2 +- certbot-dns-rfc2136/setup.py | 2 +- certbot-dns-route53/setup.py | 2 +- certbot-dns-sakuracloud/setup.py | 2 +- certbot-nginx/setup.py | 6 +-- certbot/setup.py | 8 +-- tools/oldest_constraints.txt | 54 ++++++++++--------- tools/run_oldest_tests.sh | 37 ------------- tox.ini | 50 +++++++++++------ 24 files changed, 100 insertions(+), 114 deletions(-) delete mode 100755 tools/run_oldest_tests.sh diff --git a/.azure-pipelines/templates/jobs/extended-tests-jobs.yml b/.azure-pipelines/templates/jobs/extended-tests-jobs.yml index 0c92136e8..56e8d447e 100644 --- a/.azure-pipelines/templates/jobs/extended-tests-jobs.yml +++ b/.azure-pipelines/templates/jobs/extended-tests-jobs.yml @@ -22,15 +22,19 @@ jobs: TOXENV: py37 CERTBOT_NO_PIN: 1 linux-boulder-v1-integration-certbot-oldest: + PYTHON_VERSION: 3.6 TOXENV: integration-certbot-oldest ACME_SERVER: boulder-v1 linux-boulder-v2-integration-certbot-oldest: + PYTHON_VERSION: 3.6 TOXENV: integration-certbot-oldest ACME_SERVER: boulder-v2 linux-boulder-v1-integration-nginx-oldest: + PYTHON_VERSION: 3.6 TOXENV: integration-nginx-oldest ACME_SERVER: boulder-v1 linux-boulder-v2-integration-nginx-oldest: + PYTHON_VERSION: 3.6 TOXENV: integration-nginx-oldest ACME_SERVER: boulder-v2 linux-boulder-v1-py27-integration: diff --git a/.azure-pipelines/templates/jobs/standard-tests-jobs.yml b/.azure-pipelines/templates/jobs/standard-tests-jobs.yml index 2edd0c493..6865857dd 100644 --- a/.azure-pipelines/templates/jobs/standard-tests-jobs.yml +++ b/.azure-pipelines/templates/jobs/standard-tests-jobs.yml @@ -26,10 +26,12 @@ jobs: TOXENV: integration-certbot linux-oldest-tests-1: IMAGE_NAME: ubuntu-18.04 - TOXENV: py27-{acme,apache,apache-v2,certbot}-oldest + PYTHON_VERSION: 3.6 + TOXENV: '{acme,apache,apache-v2,certbot}-oldest' linux-oldest-tests-2: IMAGE_NAME: ubuntu-18.04 - TOXENV: py27-{dns,nginx}-oldest + PYTHON_VERSION: 3.6 + TOXENV: '{dns,nginx}-oldest' linux-py27: IMAGE_NAME: ubuntu-18.04 PYTHON_VERSION: 2.7 diff --git a/.azure-pipelines/templates/steps/tox-steps.yml b/.azure-pipelines/templates/steps/tox-steps.yml index a9f78d36b..ecf3d6032 100644 --- a/.azure-pipelines/templates/steps/tox-steps.yml +++ b/.azure-pipelines/templates/steps/tox-steps.yml @@ -45,11 +45,7 @@ steps: export TARGET_BRANCH="`echo "${BUILD_SOURCEBRANCH}" | sed -E 's!refs/(heads|tags)/!!g'`" [ -z "${SYSTEM_PULLREQUEST_TARGETBRANCH}" ] || export TARGET_BRANCH="${SYSTEM_PULLREQUEST_TARGETBRANCH}" env - if [[ "${TOXENV}" == *"oldest"* ]]; then - tools/run_oldest_tests.sh - else - python -m tox - fi + python -m tox env: AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) diff --git a/acme/setup.py b/acme/setup.py index 17a5af8d3..ddc8ce2ad 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -9,21 +9,18 @@ version = '1.12.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ - # load_pem_private/public_key (>=0.6) - # rsa_recover_prime_factors (>=0.8) - 'cryptography>=1.2.3', + 'cryptography>=2.1.4', # formerly known as acme.jose: # 1.1.0+ is required to avoid the warnings described at # https://github.com/certbot/josepy/issues/13. 'josepy>=1.1.0', - # Connection.set_tlsext_host_name (>=0.13) + matching Xenial requirements (>=0.15.1) - 'PyOpenSSL>=0.15.1', + 'PyOpenSSL>=17.3.0', 'pyrfc3339', 'pytz', 'requests[security]>=2.6.0', # security extras added in 2.4.1 'requests-toolbelt>=0.3.0', - 'setuptools', - 'six>=1.9.0', # needed for python_2_unicode_compatible + 'setuptools>=39.0.1', + 'six>=1.11.0', ] setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index aebd96b17..1a4f93765 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -13,7 +13,7 @@ install_requires = [ 'acme>=0.29.0', 'certbot>=1.6.0', 'python-augeas', - 'setuptools', + 'setuptools>=39.0.1', 'zope.component', 'zope.interface', ] diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index c5be8a49f..b308f0812 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'cloudflare>=1.5.1', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index ed9502970..8e37839e9 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 1a07ceae9..9bb59da49 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -12,8 +12,8 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'python-digitalocean>=1.11', - 'setuptools', - 'six', + 'setuptools>=39.0.1', + 'six>=1.11.0', 'zope.interface', ] diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 3cb6ca83b..d2a20c9be 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -11,7 +11,7 @@ version = '1.12.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 69fe0e384..5f1c214c3 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index 22c4d8e2b..906ab5a1f 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -11,7 +11,7 @@ version = '1.12.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'dns-lexicon>=2.1.22', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index aa2471a4b..333c33b94 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -13,7 +13,7 @@ version = '1.12.0.dev0' install_requires = [ 'google-api-python-client>=1.5.5', 'oauth2client>=4.0', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', # already a dependency of google-api-python-client, but added for consistency 'httplib2' diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index b1aa22b84..4f3c74be0 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -11,7 +11,7 @@ version = '1.12.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'dns-lexicon>=2.2.3', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 6eb633567..2ee1b6ff2 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index b21e7f38b..8e5e39052 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 954d8f011..8a79967fe 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 9acbeffda..f7a9c1f4c 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'dnspython', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index fea63db88..36298ed14 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -12,7 +12,7 @@ version = '1.12.0.dev0' # acme/certbot version. install_requires = [ 'boto3', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index bfb3deff8..f6a6c86a6 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -11,7 +11,7 @@ version = '1.12.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'dns-lexicon>=2.1.23', - 'setuptools', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 6e0bd8a96..2a15ed1d3 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -12,9 +12,9 @@ version = '1.12.0.dev0' install_requires = [ 'acme>=1.4.0', 'certbot>=1.6.0', - 'PyOpenSSL', - 'pyparsing>=1.5.5', # Python3 support - 'setuptools', + 'PyOpenSSL>=17.3.0', + 'pyparsing>=2.2.0', + 'setuptools>=39.0.1', 'zope.interface', ] diff --git a/certbot/setup.py b/certbot/setup.py index d2a372ce7..b5c9f8561 100644 --- a/certbot/setup.py +++ b/certbot/setup.py @@ -40,16 +40,16 @@ install_requires = [ # saying so here causes a runtime error against our temporary fork of 0.9.3 # in which we added 2.6 support (see #2243), so we relax the requirement. 'ConfigArgParse>=0.9.3', - 'configobj', - 'cryptography>=1.2.3', # load_pem_x509_certificate + 'configobj>=5.0.6', + 'cryptography>=2.1.4', 'distro>=1.0.1', # 1.1.0+ is required to avoid the warnings described at # https://github.com/certbot/josepy/issues/13. 'josepy>=1.1.0', - 'parsedatetime>=1.3', # Calendar.parseDT + 'parsedatetime>=2.4', 'pyrfc3339', 'pytz', - 'setuptools', + 'setuptools>=39.0.1', 'zope.component', 'zope.interface', ] diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 27d5bf288..1aabf6eeb 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -1,75 +1,79 @@ -# This file contains the oldest versions of our dependencies we say we require -# in our packages or versions we need to support to maintain compatibility with -# the versions included in the various Linux distros where we are packaged. +# This file contains the oldest versions of our dependencies we're trying to +# support. Usually these version numbers are taken from the packages of our +# dependencies available in popular LTS Linux distros. Keeping compatibility +# with those versions makes it much easier for OS maintainers to update their +# Certbot packages. +# +# When updating these dependencies, we should try to only update them to the +# oldest version of the package that is found in a non-EOL'd version of +# CentOS, Debian, or Ubuntu that has Certbot packages in their OS repositories +# using a version of Python we support. If the distro is EOL'd or using a +# version of Python we don't support, it can be ignored. # CentOS/RHEL 7 EPEL constraints -cffi==1.6.0 +# Some of these constraints may be stricter than necessary because they +# initially referred to the Python 2 packages in CentOS/RHEL 7 with EPEL. +cffi==1.9.1 chardet==2.2.1 -configobj==4.7.2 ipaddress==1.0.16 mock==1.0.1 ndg-httpsclient==0.3.2 ply==3.4 +pyOpenSSL==17.3.0 pyasn1==0.1.9 pycparser==2.14 pyRFC3339==1.0 python-augeas==0.5.0 oauth2client==4.0.0 -six==1.9.0 -# setuptools 0.9.8 is the actual version packaged, but some other dependencies -# in this file require setuptools>=1.0 and there are no relevant changes for us -# between these versions. -setuptools==1.0.0 urllib3==1.10.2 zope.component==4.1.0 zope.event==4.0.3 zope.interface==4.0.5 # Debian Jessie Backports constraints -# Debian Jessie has reached end of life. However: -# When it becomes necessary to upgrade any of these dependencies, you should only update them to the oldest version of the package found -# in a non-EOL'd version of CentOS, Debian, or Ubuntu that has Certbot packages in their OS repositories. +# Debian Jessie has reached end of life so these dependencies can probably be +# updated as needed or desired. colorama==0.3.2 enum34==1.0.3 html5lib==0.999 -idna==2.0 pbr==1.8.0 pytz==2012rc0 # Debian Buster constraints google-api-python-client==1.5.5 +pyparsing==2.2.0 # Our setup.py constraints apacheconfig==0.3.2 cloudflare==1.5.1 -cryptography==1.2.3 -parsedatetime==1.3 -pyparsing==1.5.5 python-digitalocean==1.11 requests[security]==2.6.0 # Ubuntu Xenial constraints +# Ubuntu Xenial only has versions of Python which we do not support available +# so these dependencies can probably be updated as needed or desired. ConfigArgParse==0.10.0 -pyOpenSSL==0.15.1 funcsigs==0.4 zope.hookable==4.0.4 # Ubuntu Bionic constraints. +cryptography==2.1.4 distro==1.0.1 # Lexicon oldest constraint is overridden appropriately on relevant DNS provider plugins # using their local-oldest-requirements.txt dns-lexicon==2.2.1 httplib2==0.9.2 +idna==2.6 +setuptools==39.0.1 +six==1.11.0 + +# Ubuntu Focal constraints +asn1crypto==0.24.0 +configobj==5.0.6 +parsedatetime==2.4 # Plugin constraints # These aren't necessarily the oldest versions we need to support # Tracking at https://github.com/certbot/certbot/issues/6473 boto3==1.4.7 botocore==1.7.41 - -# Old certbot[dev] constraints -# Old versions of certbot[dev] required ipdb and our normally pinned version of -# ipython which ipdb depends on doesn't support Python 2 so we pin an older -# version here to keep tests working while we have Python 2 support. -ipython==5.8.0 -prompt-toolkit==1.0.18 diff --git a/tools/run_oldest_tests.sh b/tools/run_oldest_tests.sh deleted file mode 100755 index 7bf9f2bc5..000000000 --- a/tools/run_oldest_tests.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -pushd "${DIR}/../" - -function cleanup() { - rm -f "${DOCKERFILE}" - popd -} - -trap cleanup EXIT - -DOCKERFILE=$(mktemp /tmp/Dockerfile.XXXXXX) - -cat << "EOF" >> "${DOCKERFILE}" -FROM ubuntu:16.04 -COPY letsencrypt-auto-source/pieces/dependency-requirements.txt /tmp/letsencrypt-auto-source/pieces/ -COPY tools/ /tmp/tools/ -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - python-dev python-pip python-setuptools \ - gcc libaugeas0 libssl-dev libffi-dev \ - git ca-certificates nginx-light openssl curl \ - && curl -fsSL https://get.docker.com | bash /dev/stdin \ - && python /tmp/tools/pipstrap.py \ - && python /tmp/tools/pip_install.py tox \ - && rm -rf /var/lib/apt/lists/* -EOF - -docker build -f "${DOCKERFILE}" -t oldest-worker . -docker run --rm --network=host -w "${PWD}" \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v "${PWD}:${PWD}" -v /tmp:/tmp \ - -e TOXENV -e ACME_SERVER -e PYTEST_ADDOPTS \ - oldest-worker python -m tox diff --git a/tox.ini b/tox.ini index 212d4ee76..94cd305aa 100644 --- a/tox.ini +++ b/tox.ini @@ -77,49 +77,65 @@ setenv = PYTEST_ADDOPTS = {env:PYTEST_ADDOPTS:--numprocesses auto} PYTHONHASHSEED = 0 -[testenv:py27-oldest] +[testenv:oldest] +# Setting basepython allows the tests to fail fast if that version of Python +# isn't available instead of potentially trying to use a newer version of +# Python which is unlikely to work. +basepython = python3.6 commands = {[testenv]commands} setenv = {[testenv]setenv} CERTBOT_OLDEST=1 -[testenv:py27-acme-oldest] +[testenv:acme-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} acme[dev] setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} -[testenv:py27-apache-oldest] +[testenv:apache-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} certbot-apache setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} -[testenv:py27-apache-v2-oldest] +[testenv:apache-v2-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} certbot-apache[dev] setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} -[testenv:py27-certbot-oldest] +[testenv:certbot-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} certbot[dev] setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} -[testenv:py27-dns-oldest] +[testenv:dns-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} {[base]dns_packages} setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} -[testenv:py27-nginx-oldest] +[testenv:nginx-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]install_and_test} certbot-nginx python tests/lock_test.py setenv = - {[testenv:py27-oldest]setenv} + {[testenv:oldest]setenv} [testenv:lint] basepython = python3 @@ -238,22 +254,26 @@ commands = passenv = DOCKER_* [testenv:integration-certbot-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]pip_install} certbot {[base]pip_install} certbot-ci pytest certbot-ci/certbot_integration_tests/certbot_tests \ --acme-server={env:ACME_SERVER:pebble} passenv = DOCKER_* -setenv = {[testenv:py27-oldest]setenv} +setenv = {[testenv:oldest]setenv} [testenv:integration-nginx-oldest] +basepython = + {[testenv:oldest]basepython} commands = {[base]pip_install} certbot-nginx {[base]pip_install} certbot-ci pytest certbot-ci/certbot_integration_tests/nginx_tests \ --acme-server={env:ACME_SERVER:pebble} passenv = DOCKER_* -setenv = {[testenv:py27-oldest]setenv} +setenv = {[testenv:oldest]setenv} [testenv:test-farm-tests-base] changedir = tests/letstest