From a83240400cfe4ce5f90dd71b2ba0c0f20a79b1db Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Wed, 25 Aug 2021 15:36:29 -0400 Subject: [PATCH 1/9] Use GitHub secrets for dynamic dns test credentials Note: To add the secrets to your repository on GitHub Goto Actions -> Settings -> Secrets New Repository Secret Add DUCKDNS_TOKEN Add DYNU_API_KEY --- .github/workflows/run-tests-staging-duckdns.yml | 2 ++ .github/workflows/run-tests-staging-dynu.yml | 2 ++ test/Dockerfile-centos7-duckdns | 2 +- test/Dockerfile-centos7-dynu | 2 +- test/Dockerfile-ubuntu-duckdns | 2 +- test/Dockerfile-ubuntu-dynu | 2 +- test/run-test.sh | 2 ++ 7 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-tests-staging-duckdns.yml b/.github/workflows/run-tests-staging-duckdns.yml index a6348bc..7647afe 100644 --- a/.github/workflows/run-tests-staging-duckdns.yml +++ b/.github/workflows/run-tests-staging-duckdns.yml @@ -8,6 +8,8 @@ on: pull_request: branches: - master +env: + DUCKDNS_TOKEN: ${{ secrets.DUCKDNS_TOKEN }} jobs: test-centos7-duckdns: runs-on: ubuntu-latest diff --git a/.github/workflows/run-tests-staging-dynu.yml b/.github/workflows/run-tests-staging-dynu.yml index 1f55bae..294faf5 100644 --- a/.github/workflows/run-tests-staging-dynu.yml +++ b/.github/workflows/run-tests-staging-dynu.yml @@ -8,6 +8,8 @@ on: pull_request: branches: - master +env: + DYNU_API_KEY: ${{ secrets.DYNU_API_KEY }} jobs: test-centos7-dynu: runs-on: ubuntu-latest diff --git a/test/Dockerfile-centos7-duckdns b/test/Dockerfile-centos7-duckdns index be26c79..96a5fab 100644 --- a/test/Dockerfile-centos7-duckdns +++ b/test/Dockerfile-centos7-duckdns @@ -14,7 +14,7 @@ ENV LC_ALL en_US.UTF-8 ENV staging "true" ENV dynamic_dns "dynu" -ENV DUCKDNS_TOKEN 1d616aa9-b8e4-4bb4-b312-3289de82badb +#ENV DUCKDNS_TOKEN WORKDIR /root RUN mkdir -p /etc/nginx/pki/private diff --git a/test/Dockerfile-centos7-dynu b/test/Dockerfile-centos7-dynu index 65c8051..09a1534 100644 --- a/test/Dockerfile-centos7-dynu +++ b/test/Dockerfile-centos7-dynu @@ -14,7 +14,7 @@ ENV LC_ALL en_US.UTF-8 ENV staging "true" ENV dynamic_dns "duckdns" -ENV DYNU_API_KEY 65cXefd35XbYf36546eg5dYcZT6X52Y2 +#ENV DYNU_API_KEY WORKDIR /root RUN mkdir /etc/nginx/pki diff --git a/test/Dockerfile-ubuntu-duckdns b/test/Dockerfile-ubuntu-duckdns index f0f2edd..c4fdc6a 100644 --- a/test/Dockerfile-ubuntu-duckdns +++ b/test/Dockerfile-ubuntu-duckdns @@ -8,7 +8,7 @@ ENV DEBIAN_FRONTEND noninteractive # Ensure tests in this image use the staging server ENV staging "true" ENV dynamic_dns "duckdns" -ENV DUCKDNS_TOKEN 1d616aa9-b8e4-4bb4-b312-3289de82badb +#ENV DUCKDNS_TOKEN # Update and install required software RUN apt-get update --fix-missing diff --git a/test/Dockerfile-ubuntu-dynu b/test/Dockerfile-ubuntu-dynu index b010293..68f5c06 100644 --- a/test/Dockerfile-ubuntu-dynu +++ b/test/Dockerfile-ubuntu-dynu @@ -8,7 +8,7 @@ ENV DEBIAN_FRONTEND noninteractive # Ensure tests in this image use the staging server ENV staging "true" ENV dynamic_dns "dynu" -ENV DYNU_API_KEY 65cXefd35XbYf36546eg5dYcZT6X52Y2 +#ENV DYNU_API_KEY # Update and install required software RUN apt-get update --fix-missing diff --git a/test/run-test.sh b/test/run-test.sh index 76a7555..d6156fb 100755 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -38,6 +38,8 @@ docker run \ --env GETSSL_IDN_HOST=$GETSSL_IDN_HOST \ --env GETSSL_OS=$GETSSL_OS \ --env GITHUB_REPOSITORY="${GITHUB_REPOSITORY}" \ + --env DUCKDNS_TOKEN="${DUCKDNS_TOKEN}" \ + --env DYNU_API_KEY="${DYNU_API_KEY}" \ -v "$(pwd)":/getssl \ --rm \ --network ${PWD##*/}_acmenet \ From 0a94644a7fa426ea8cdace8ce43261d9a515ff3e Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Wed, 25 Aug 2021 16:31:54 -0400 Subject: [PATCH 2/9] Fix "directory exists" test failures when setting up nginx Some versions of nginx create directories, so use -p with mkdir. --- test/Dockerfile-bash4-0 | 6 +++--- test/Dockerfile-bash4-2 | 6 +++--- test/Dockerfile-bash5-0 | 6 +++--- test/Dockerfile-centos7-dynu | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/Dockerfile-bash4-0 b/test/Dockerfile-bash4-0 index 9b1f790..0dae149 100644 --- a/test/Dockerfile-bash4-0 +++ b/test/Dockerfile-bash4-0 @@ -7,9 +7,9 @@ RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx l WORKDIR /root # Create nginx directories in standard places -RUN mkdir /run/nginx -RUN mkdir /etc/nginx/pki -RUN mkdir /etc/nginx/pki/private +RUN mkdir -p /run/nginx +RUN mkdir -p /etc/nginx/pki +RUN mkdir -p /etc/nginx/pki/private # Setup ftp ENV VSFTPD_CONF=/etc/vsftpd.conf diff --git a/test/Dockerfile-bash4-2 b/test/Dockerfile-bash4-2 index d9386f6..dd1cb11 100644 --- a/test/Dockerfile-bash4-2 +++ b/test/Dockerfile-bash4-2 @@ -7,9 +7,9 @@ RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx l WORKDIR /root # Create nginx directories in standard places -RUN mkdir /run/nginx -RUN mkdir /etc/nginx/pki -RUN mkdir /etc/nginx/pki/private +RUN mkdir -p /run/nginx +RUN mkdir -p /etc/nginx/pki +RUN mkdir -p /etc/nginx/pki/private # Setup ftp ENV VSFTPD_CONF=/etc/vsftpd.conf diff --git a/test/Dockerfile-bash5-0 b/test/Dockerfile-bash5-0 index 2d776eb..260290d 100644 --- a/test/Dockerfile-bash5-0 +++ b/test/Dockerfile-bash5-0 @@ -7,9 +7,9 @@ RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx l WORKDIR /root # Create nginx directories in standard places -RUN mkdir /run/nginx -RUN mkdir /etc/nginx/pki -RUN mkdir /etc/nginx/pki/private +RUN mkdir -p /run/nginx +RUN mkdir -p /etc/nginx/pki +RUN mkdir -p /etc/nginx/pki/private # Setup ftp ENV VSFTPD_CONF=/etc/vsftpd.conf diff --git a/test/Dockerfile-centos7-dynu b/test/Dockerfile-centos7-dynu index 09a1534..cabd7eb 100644 --- a/test/Dockerfile-centos7-dynu +++ b/test/Dockerfile-centos7-dynu @@ -17,8 +17,8 @@ ENV dynamic_dns "duckdns" #ENV DYNU_API_KEY WORKDIR /root -RUN mkdir /etc/nginx/pki -RUN mkdir /etc/nginx/pki/private +RUN mkdir -p /etc/nginx/pki +RUN mkdir -p /etc/nginx/pki/private COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf From 1511bc6f652c21feb2c631862b8e566c017d98cc Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Wed, 25 Aug 2021 16:53:54 -0400 Subject: [PATCH 3/9] Include repository name in dynamic DNS test domains For now, srvrco is excluded. The domain name will be --getssl. Must be added to accounts on these services. --- test/run-test.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/run-test.sh b/test/run-test.sh index d6156fb..e9aab38 100755 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -14,17 +14,27 @@ else COMMAND="bats /getssl/test --timing" fi +REPO="" +if [ -n "$GITHUB_REPOSITORY" ] ; then + REPO="$(echo "$GITHUB_REPOSITORY" | cut -d/ -f1)" + if [[ "$REPO" == "srvrco" ]] ; then + REPO="" + else + REPO="${REPO}-" + fi +fi + ALIAS="$OS.getssl.test" GETSSL_IDN_HOST="$OS.xn--t-r1a81lydm69gz81r.test" STAGING="" GETSSL_OS=$OS if [[ "$OS" == *"duckdns"* ]]; then - ALIAS="${OS%-duckdns}-getssl.duckdns.org" + ALIAS="${REPO}${OS%-duckdns}-getssl.duckdns.org" STAGING="--env STAGING=true --env dynamic_dns=duckdns" GETSSL_OS="${OS%-duckdns}" elif [[ "$OS" == *"dynu"* ]]; then - ALIAS="${OS%-dynu}-getssl.freeddns.org" + ALIAS="${REPO}${OS%-dynu}-getssl.freeddns.org" STAGING="--env STAGING=true --env dynamic_dns=dynu" GETSSL_OS="${OS%-dynu}" elif [[ "$OS" == "bash"* ]]; then From b2e4d73e9d3540de47e3d8451632b5e7d0b8b1a3 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Wed, 25 Aug 2021 17:39:38 -0400 Subject: [PATCH 4/9] Allow tests to run manually Avoids having to push, e.g. when adding a tag or updating credentials. --- .github/workflows/run-tests-pebble.yml | 3 +++ .github/workflows/run-tests-staging-duckdns.yml | 3 +++ .github/workflows/run-tests-staging-dynu.yml | 3 +++ .github/workflows/shellcheck.yml | 3 +++ 4 files changed, 12 insertions(+) diff --git a/.github/workflows/run-tests-pebble.yml b/.github/workflows/run-tests-pebble.yml index fe82ad6..65fed1c 100644 --- a/.github/workflows/run-tests-pebble.yml +++ b/.github/workflows/run-tests-pebble.yml @@ -8,6 +8,9 @@ on: pull_request: branches: - master + workflow_dispatch: + branches: + - master jobs: test-alpine: runs-on: ubuntu-latest diff --git a/.github/workflows/run-tests-staging-duckdns.yml b/.github/workflows/run-tests-staging-duckdns.yml index 7647afe..3a8efea 100644 --- a/.github/workflows/run-tests-staging-duckdns.yml +++ b/.github/workflows/run-tests-staging-duckdns.yml @@ -8,6 +8,9 @@ on: pull_request: branches: - master + workflow_dispatch: + branches: + - master env: DUCKDNS_TOKEN: ${{ secrets.DUCKDNS_TOKEN }} jobs: diff --git a/.github/workflows/run-tests-staging-dynu.yml b/.github/workflows/run-tests-staging-dynu.yml index 294faf5..2f9ec4f 100644 --- a/.github/workflows/run-tests-staging-dynu.yml +++ b/.github/workflows/run-tests-staging-dynu.yml @@ -8,6 +8,9 @@ on: pull_request: branches: - master + workflow_dispatch: + branches: + - master env: DYNU_API_KEY: ${{ secrets.DYNU_API_KEY }} jobs: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index baf6603..52873f6 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -7,6 +7,9 @@ on: branches: [ master ] pull_request: branches: [ master ] + workflow_dispatch: + branches: + - master jobs: lint: From 8747f91c2f0c451ac4b40e09edbc006b1af1972d Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Wed, 25 Aug 2021 18:36:45 -0400 Subject: [PATCH 5/9] Update test documentation with GitHub secrets Document the accounts and repo-specific domain names required to run the dynamic DNS tests. Also document the GitHub "secrets" that must be stored for CI testing to work. --- test/README-Testing.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/README-Testing.md b/test/README-Testing.md index d713914..5d67977 100644 --- a/test/README-Testing.md +++ b/test/README-Testing.md @@ -10,6 +10,23 @@ For continuous integration testing we have the following: 2. Then runs the `bats` test scripts (all the files with a ".bats" extension) for each OS (alpine, centos6, debian, ubuntu) 3. Runs the `bats` test script against the staging server (using ubuntu docker image and duckdns.org) +Tests can also be triggered manually from the GitHub website. + +For dynamic DNS tests, you need accounts on duckdns.org and dynu.com, and need to create 4 domain names in each account. + +For duckdns.org: +- Add DUCKDNS_TOKEN to your repository's environment secrets. The value is your account's token +- Add domains -centos7-getssl.duckdns.org, wild--centos7.duckdns.org, -ubuntu-getssl.duckdns.org, and wild--ubuntu-getssl.duckdns.org + +For dynu.com: + - Add DYNU_API_KEY to your repository's environment secrets. The value is your account's API Key. + - Add domains -centos7-getssl.freedns.org, wild--centos7.freedns.org, -ubuntu-getssl.freedns.org, and wild--ubuntu-getssl.freedns.org + +To run dynamic DNS tests outside the CI environment, you need accounts without in the domain names. Export the environment variable corresponding to the secrets (with the same values). + +For individual accounts, is your github account name. + + ## To run all the tests on a single OS 1. Start `pebble` and `challtestsrv` using ```docker-compose up -d --build``` From 6da313cedf4a9c003068d80b6c6856e8dc599f20 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Thu, 26 Aug 2021 14:00:50 -0400 Subject: [PATCH 6/9] Improve upgrades - use releases, do full install Use the GitHub release data to decide if an upgrade is available. Only download the release if a newer stable release is published. Install the full release - including the DNS scripts (requires "make") Don't check for upgrades when restarting. Remove --keep logic - only 1 old version is kept, only if make isn't available. Old versions are availablel from the repo; if you have local changes, --upgrade doesn't make sense. Can upgrade (or downgrade) to any tagged release with --experimental vx.yy Note that GitHub API requests are rate-limited; this shouldn't be an issue unless getssl is run more than ~60 times/hr. If the limit is exceeded, getssl will sleep until the limit is reset. The limit is per-IP address. The tests have been modified to only check for updates in the tests that verify the check for updates logic. This has the side effect of not doing MANY pointless checks for updates in the tests... --- README.md | 4 +- getssl | 241 +++++++++++++++++------- test/1-simple-http01.bats | 2 +- test/11-test--install.bats | 4 +- test/11-test-no-domain-storage.bats | 2 +- test/12-auto-upgrade-v1.bats | 10 +- test/13-notify-valid.bats | 4 +- test/14-test-revoke.bats | 2 +- test/15-test-revoke-no-suffix.bats | 2 +- test/17-test-spaces-in-sans-dns01.bats | 4 +- test/17-test-spaces-in-sans-http01.bats | 4 +- test/2-simple-dns01-dig.bats | 2 +- test/20-wildcard-simple.bats | 6 +- test/23-wildcard-check-globbing.bats | 2 +- test/25-wildcard-all.bats | 4 +- test/26-wildcard-revoke.bats | 2 +- test/27-wildcard-existing-cert.bats | 2 +- test/29-check-mktemp-failure.bats | 2 +- test/3-dual-rsa-ecdsa.bats | 6 +- test/31-test-posix-error.bats | 2 +- test/32-test-upgrade.bats | 63 +++++-- test/4-more-than-10-hosts.bats | 2 +- test/5-secp384-http01.bats | 4 +- test/8-staging-ecdsa.bats | 8 +- test/9-multiple-domains-dns01.bats | 2 +- test/9-test--all.bats | 2 +- test/Dockerfile-alpine | 2 +- test/Dockerfile-bash4-0 | 2 +- test/Dockerfile-bash4-2 | 2 +- test/Dockerfile-bash5-0 | 2 +- test/Dockerfile-centos6 | 2 +- test/Dockerfile-centos7 | 2 +- test/Dockerfile-centos7-duckdns | 2 +- test/Dockerfile-centos7-dynu | 2 +- test/Dockerfile-centos8 | 2 +- test/Dockerfile-debian | 2 +- test/Dockerfile-rockylinux8 | 2 +- test/Dockerfile-ubuntu | 2 +- test/Dockerfile-ubuntu-duckdns | 2 +- test/Dockerfile-ubuntu-dynu | 2 +- test/Dockerfile-ubuntu16 | 2 +- test/Dockerfile-ubuntu18 | 2 +- test/debug-test.sh | 4 +- test/test_helper.bash | 4 +- 44 files changed, 291 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 454a388..42dd5a9 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ sftp or ftp access to the remote server). getssl ver. 2.36 Obtain SSL certificates from the letsencrypt.org ACME server -Usage: getssl [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet] [-Q|--mute] [-u|--upgrade] [-k|--keep #] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir] [--preferred-chain chain] domain +Usage: getssl [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet] [-Q|--mute] [-u|--upgrade] [-X|--experimental tag] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir] [--preferred-chain chain] domain Options: -a, --all Check all certificates @@ -105,7 +105,7 @@ Options: -Q, --mute Like -q, but also mute notification about successful upgrade -r, --revoke "cert" "key" [CA_server] Revoke a certificate (the cert and key are required) -u, --upgrade Upgrade getssl if a more recent version is available - can be used with or without domain(s) - -k, --keep "#" Maximum number of old getssl versions to keep when upgrading + -X --experimental tag Allow upgrade to a specified version of getssl -U, --nocheck Do not check if a more recent version is available -v --version Display current version of getssl -w working_dir "Working directory" diff --git a/getssl b/getssl index 3bb6272..f7a58b9 100755 --- a/getssl +++ b/getssl @@ -268,6 +268,7 @@ # 2021-07-27 Support ftps://, FTPS_OPTIONS, remove default --insecure parameter to ftpes. Report caller(s) of error_exit in debug and test modes (tlhackque)(#687)(2.39) # 2021-07-30 Prefer API V2 when both offered (tlhackque) (#690) (2.40) # 2021-07-30 Run tests with -d to catch intermittent failures, Use fork's repo for upgrade tests. (tlhackque) (#692) (2.41) +# 2021-08-26 Improve upgrade check & make upgrade do a full install when possible (tlhackque) (#694) (2.42) # ---------------------------------------------------------------------------------------- case :$SHELLOPTS: in @@ -276,7 +277,7 @@ esac PROGNAME=${0##*/} PROGDIR="$(cd "$(dirname "$0")" || exit; pwd -P;)" -VERSION="2.41" +VERSION="2.42" # defaults ACCOUNT_KEY_LENGTH=4096 @@ -286,10 +287,11 @@ CA="https://acme-staging-v02.api.letsencrypt.org/directory" CHALLENGE_CHECK_TYPE="http" CHECK_REMOTE_WAIT=0 CHECK_REMOTE="true" +LIMIT_API="https://api.github.com/rate_limit" if [[ -n "${GITHUB_REPOSITORY}" ]] ; then - CODE_LOCATION="https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/master/getssl" + RELEASE_API="https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/latest" else - CODE_LOCATION="https://raw.githubusercontent.com/srvrco/getssl/master/getssl" + RELEASE_API="https://api.github.com/repos/srvrco/getssl/releases/latest" fi CSR_SUBJECT="/" CURL_USERAGENT="${PROGNAME}/${VERSION}" @@ -314,7 +316,7 @@ REUSE_PRIVATE_KEY="true" SERVER_TYPE="https" SKIP_HTTP_TOKEN_CHECK="false" SSLCONF="$(openssl version -d 2>/dev/null| cut -d\" -f2)/openssl.cnf" -TEMP_UPGRADE_FILE="" +TEMP_UPGRADE_DIR="" TOKEN_USER_ID="" USE_SINGLE_ACL="false" WORKING_DIR_CANDIDATES=("/etc/getssl" "${PROGDIR}/conf" "${PROGDIR}/.getssl" "${HOME}/.getssl") @@ -338,7 +340,6 @@ _CHECK_ALL=0 _CREATE_CONFIG=0 _CURL_VERSION="" _FORCE_RENEW=0 -_KEEP_VERSIONS="" _MUTE=0 _NOTIFY_VALID=0 _NOMETER="" @@ -351,6 +352,7 @@ _TEST_SKIP_CNAME_CALL=0 _TEST_SKIP_SOA_CALL=0 _UPGRADE=0 _UPGRADE_CHECK=1 +_UPGRADE_TO_TAG="" _USE_DEBUG=0 _ONLY_CHECK_CONFIG=0 config_errors="false" @@ -761,71 +763,165 @@ check_config() { # check the config files for all obvious errors debug "${DOMAIN}: check_config completed - all OK" } -check_getssl_upgrade() { # check if a more recent version of code is available available - TEMP_UPGRADE_FILE="$(mktemp 2>/dev/null || mktemp -t getssl.XXXXXX)" - if [ "$TEMP_UPGRADE_FILE" == "" ]; then - error_exit "mktemp failed" - fi - curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$CODE_LOCATION" --output "$TEMP_UPGRADE_FILE" +# Quota generally shouldn't be an issue - except for tests +# Rate limits are per-IP address +check_github_quota() { + local need remaining reset limits now + need="$1" + while true ; do + limits="$(curl ${_NOMETER:---silent} --user-agent "$CURL_USERAGENT" -H 'Accept: application/vnd.github.v3+json' "$LIMIT_API" | sed -e's/\("[^:]*": *\("[^""]*",\|[^,]*[,}]\)\)/\r\n\1/g' | sed -ne'/"core":/,/}/p')" + errcode=$? + if [[ $errcode -eq 60 ]]; then + error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)" + elif [[ $errcode -gt 0 ]]; then + error_exit "curl error checking releases: $errcode" + fi + limits="$(sed -e's/^ *//g' <<<"${limits}")" + remaining="$(sed -e'/^"remaining": *[0-9]/!d;s/^"remaining": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")" + reset="$(sed -e'/^"reset": *[0-9]/!d;s/^"reset": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")" + if [[ "$remaining" -ge "$need" ]] ; then return 0 ; fi + limit="$(sed -e'/^"limit": *[0-9]/!d;s/^"limit": *\([0-9][0-9]*\).*$/\1/' <<<"${limits}")" + if [[ "$limit" -lt "$need" ]] ; then + error_exit "GitHub API request $need exceeds limit $limit" + fi + now="$(date +%s)" + while [[ "$now" -lt "$reset" ]] ; do + info "sleeping $(( "$reset" - "$now" )) seconds for GitHub quota" + sleep "$(( "$reset" - "$now" ))" + now="$(date +%s)" + done + done +} +check_getssl_upgrade() { # check if a more recent release is available + check_github_quota 2 + # Check GitHub for latest stable release, or a specified tag + if [[ -n "$_UPGRADE_TO_TAG" ]]; then + RELEASE_API="$RELEASE_API/tags/$_UPGRADE_TO_TAG" + fi + local release_data release_tag release_ver local_ver release_desc release_url release_tar NEWCMD + debug "Checking for releases at $RELEASE_API" + # Sometimes the json is pretty-printed, sometimes not. Loosely tied to --user-agent, but not + # always. Normalize it enough to get the 3 elements necessary. Oh, for jq... + release_data="$(curl ${_NOMETER:---silent} --user-agent "$CURL_USERAGENT" -H 'Accept: application/vnd.github.v3+json' "$RELEASE_API" | sed -e's/\("[^:]*": *\("[^""]*",\|[^,]*[,}]\)\)/\r\n\1/g')" errcode=$? if [[ $errcode -eq 60 ]]; then error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)" elif [[ $errcode -gt 0 ]]; then - error_exit "curl error : $errcode" + error_exit "curl error checking releases: $errcode" + fi + debug "$release_data" + release_data="$(sed -e's/^ *//g' <<<"${release_data}")" + release_tag="$(sed -e'/^"tag_name": *"/!d;s/^"tag_name": *"\([^""]*\).*$/\1/' <<<"${release_data}")" + if [[ "${release_tag:0:1}" != 'v' ]] ; then + if [[ ${_MUTE} -eq 0 ]]; then + info "The current repository has no releases or is improperly tagged; can't check for upgrades: '$release_tag'" + fi + return 0 fi - latestversion=$(awk -F '"' '$1 == "VERSION=" {print $2}' "$TEMP_UPGRADE_FILE") - latestvdec=$(echo "$latestversion"| tr -d '.') - localvdec=$(echo "$VERSION"| tr -d '.' ) + release_ver="$( tr -d '.v' <<<"${release_tag}")" + local_ver="$( tr -d '.' <<<"${VERSION}")" debug "current code is version ${VERSION}" - debug "Most recent version is ${latestversion}" - # use a default of 0 for cases where the latest code has not been obtained. - if [[ "${latestvdec:-0}" -gt "$localvdec" ]]; then - if [[ ${_UPGRADE} -eq 1 ]]; then - if ! install "$0" "${0}.v${VERSION}"; then - error_exit "problem renaming old version while updating, check permissions" - fi - if ! install -m 700 "$TEMP_UPGRADE_FILE" "$0"; then - error_exit "problem installing new version while updating, check permissions" - fi - if [[ ${_MUTE} -eq 0 ]]; then - echo "Updated getssl from v${VERSION} to v${latestversion}" - echo "These update notifications can be turned off using the -Q option" - echo "" - echo "Updates are;" - awk "/\(${VERSION}\)$/ {s=1} s; /\(${latestversion}\)$/ || /^# ----/ {s=0}" "$TEMP_UPGRADE_FILE" | awk '{if(NR>1)print}' - echo "" - fi - if [[ -n "$_KEEP_VERSIONS" ]] && [[ "$_KEEP_VERSIONS" =~ ^[0-9]+$ ]]; then - # Obtain all locally stored old versions in getssl_versions - declare -a getssl_versions - shopt -s nullglob - for getssl_version in "$0".v*; do - getssl_versions[${#getssl_versions[@]}]="$getssl_version" - done - shopt -u nullglob - # Explicitly sort the getssl_versions array to make sure - shopt -s -o noglob - # shellcheck disable=SC2207 - IFS=$'\n' getssl_versions=($(sort <<< "${getssl_versions[*]}")) - shopt -u -o noglob - # Remove entries until given number of old versions to keep is reached - while [[ ${#getssl_versions[@]} -gt $_KEEP_VERSIONS ]]; do - debug "removing old version ${getssl_versions[0]}" - rm "${getssl_versions[0]}" - getssl_versions=("${getssl_versions[@]:1}") - done - fi - if ! eval "$ORIGCMD"; then - error_exit "Running upgraded getssl failed" - fi - graceful_exit - else + debug "Most recent version is ${release_tag:1}" + if [[ -z "$_UPGRADE_TO_TAG" ]] ; then + if [[ "$local_ver" -ge "$release_ver" ]] ; then return 0; fi + else + if [[ "$local_ver" -eq "$release_ver" ]] ; then return 0; fi + fi + if [[ ${_UPGRADE} -ne 1 ]]; then + if [[ ${_MUTE} -eq 0 ]]; then + release_desc="$(sed -e'/^"body": *"/!d;s/^"body": *"\([^""]*\).*$/\1/;s/\\r/\r/g;s/\\n/\n/g' <<<"$release_data")" info "" - info "A more recent version (v${latestversion}) of getssl is available, please update" + info "A more recent version (${release_tag}) than $VERSION of getssl is available, please update" info "The easiest way is to use the -u or --upgrade flag" info "" + info "Release ${release_tag} summary" + info "$release_desc" + info "" fi + return 0; + fi + # Find, download, and unpack the tarball containing the selected release + release_url="$(sed -e'/^"tarball_url": *"/!d;s/^"tarball_url": *"\([^""]*\).*$/\1/' <<<"${release_data}")" + debug "Release url '$release_url'" + requires tar + TEMP_UPGRADE_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t getssl.XXXXXXXX)" + if [ "$TEMP_UPGRADE_DIR" == "" ]; then + error_exit "mktemp failed" + fi + release_tar="$TEMP_UPGRADE_DIR/getssl-${release_tag}.tgz" + debug "Downloading release to $release_tar" + check_github_quota 1 + curl ${_NOMETER:---silent} -L --user-agent "$CURL_USERAGENT" -H 'Accept: application/vnd.github.v3+json' "$release_url" --output "$release_tar" + errcode=$? + if [[ $errcode -eq 60 ]]; then + error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)" + elif [[ $errcode -gt 0 ]]; then + error_exit "curl error downloading release: $errcode" + fi + if ! tar -C "${TEMP_UPGRADE_DIR}" --strip-components 1 -xzf "$release_tar" ; then + error_exit "failed to unpack release: $?" fi + # Inhibit check for upgrades when running the new version + NEWCMD="$(sed -e's/ -\(u\|-upgrade\|U\|-nocheck\)//g;s/^\([^ ]* \)/\1--nocheck /' <<<"$ORIGCMD")" + # Install everything with make - if it's available + if [ -n "$(command -v 'make' 2>/dev/null)" ]; then + if [[ "${0%/usr/bin/getssl}" != "$0" ]] ; then + export DESTDIR="${0%/usr/bin/getssl}" + fi + if [[ ${_MUTE} -eq 0 ]]; then + if ! make -C "${TEMP_UPGRADE_DIR}" "install" ; then + error_exit "Installation failed: $?" + fi + else + if ! make -s -C "${TEMP_UPGRADE_DIR}" "install" >/dev/null ; then + error_exit "Installation failed: $?" + fi + fi + clean_up + if [[ ${_MUTE} -eq 0 ]]; then + info "Installed $release_tag, restarting with $NEWCMD" + fi + if ! eval "$NEWCMD"; then + error_exit "Running upgraded getssl failed" + fi + graceful_exit + fi + # Fall back to 'install' and just the main script. + if [[ ${_MUTE} -eq 0 ]]; then + info "'make' is not available. getssl will be installed, but support scripts will not be upgraded" + info "To stay completely up-to-date, please install make" + fi + if ! install "$0" "${0}.v${VERSION}"; then + error_exit "problem renaming old version while updating, check permissions" + fi + if ! install -m 700 "$TEMP_UPGRADE_DIR/getssl" "$0"; then + error_exit "problem installing new version while updating, check permissions" + fi + if [[ ${_MUTE} -eq 0 ]]; then + echo "Updated getssl from v${VERSION} to $release_tag" + echo "The old version remains as ${0}.v${VERSION} and should be removed" + echo "" + fi + # This version can't be removed since disappearing can confuse bash. + declare -a getssl_versions + shopt -s nullglob + for getssl_version in "$0".v*; do + if [[ "$getssl_version" != "${0}.v${VERSION}" ]] ; then + getssl_versions[${#getssl_versions[@]}]="$getssl_version" + fi + done + shopt -u nullglob + if [[ -n "${getssl_versions[*]}" ]] ; then + rm "${getssl_versions[@]}" + fi + clean_up + if [[ ${_MUTE} -eq 0 ]]; then + info "Installed $release_tag, restarting with $NEWCMD" + fi + if ! eval "$NEWCMD"; then + error_exit "Running upgraded getssl failed" + fi + graceful_exit } clean_up() { # Perform pre-exit housekeeping @@ -848,8 +944,12 @@ clean_up() { # Perform pre-exit housekeeping rm -rf "${TEMP_DIR:?}" fi fi - if [[ -n "$TEMP_UPGRADE_FILE" ]] && [[ -f "$TEMP_UPGRADE_FILE" ]]; then - rm -f "$TEMP_UPGRADE_FILE" + if [[ -n "$TEMP_UPGRADE_DIR" ]] && [[ -d "$TEMP_UPGRADE_DIR" ]]; then + if [ "${TEMP_UPGRADE_DIR}" -ef "/tmp" ]; then + info "Not going to delete TEMP_UPGRADE_DIR ${TEMP_UPGRADE_DIR} as it appears to be /tmp" + else + rm -rf "${TEMP_UPGRADE_DIR:?}" + fi fi } @@ -1829,7 +1929,7 @@ help_message() { # print out the help message -Q, --mute Like -q, but also mute notification about successful upgrade -r, --revoke "cert" "key" [CA_server] Revoke a certificate (the cert and key are required) -u, --upgrade Upgrade getssl if a more recent version is available - can be used with or without domain(s) - -k, --keep "#" Maximum number of old getssl versions to keep when upgrading + -X, --experimental tag Upgrade to experimental releases, specified by tag (e.g. v9.43) -U, --nocheck Do not check if a more recent version is available -v --version Display current version of $PROGNAME -w working_dir "Working directory" @@ -2451,7 +2551,7 @@ urlbase64_decode() { usage() { # echos out the program usage echo "Usage: $PROGNAME [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet]"\ - "[-Q|--mute] [-u|--upgrade] [-k|--keep #] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir]"\ + "[-Q|--mute] [-u|--upgrade] [-X|--experimental tag] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir]"\ "[--preferred-chain chain] domain" } @@ -2660,7 +2760,8 @@ while [[ -n ${1+defined} ]]; do -a | --all) _CHECK_ALL=1 ;; -k | --keep) - shift; _KEEP_VERSIONS="$1";; + shift; + echo "--keep has no effect" ;; -q | --quiet) _QUIET=1 ;; -Q | --mute) @@ -2678,6 +2779,9 @@ while [[ -n ${1+defined} ]]; do REVOKE_REASON=0 ;; -u | --upgrade) _UPGRADE=1 ;; + -X | --experimental) + _UPGRADE_TO_TAG="$1" + shift ;; -U | --nocheck) _UPGRADE_CHECK=0 ;; -i | --install) @@ -2747,6 +2851,15 @@ if [[ ! "${_CURL_VERSION}" < "7.67" ]]; then _NOMETER="--no-progress-meter" fi +# Make sure mktemp works before going too far +MKDIR_TEST_FILE="$(mktemp 2>/dev/null || mktemp -t getssl.XXXXXX)" +if [ "$MKDIR_TEST_FILE" == "" ]; then + error_exit "mktemp failed" +else + rm "$MKDIR_TEST_FILE" +fi +unset MKDIR_TEST_FILE + # Check if upgrades are available (unless they have specified -U to ignore Upgrade checks) if [[ $_UPGRADE_CHECK -eq 1 ]]; then check_getssl_upgrade diff --git a/test/1-simple-http01.bats b/test/1-simple-http01.bats index 518f734..15205e1 100644 --- a/test/1-simple-http01.bats +++ b/test/1-simple-http01.bats @@ -33,7 +33,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment diff --git a/test/11-test--install.bats b/test/11-test--install.bats index 1ab1ca4..186e8c6 100644 --- a/test/11-test--install.bats +++ b/test/11-test--install.bats @@ -34,7 +34,7 @@ setup() { cp "${CODE_DIR}/test/test-config/getssl-etc-template.cfg" "/etc/getssl/getssl.cfg" # Run getssl - run ${CODE_DIR}/getssl "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d "$GETSSL_CMD_HOST" assert_success check_output_for_errors @@ -53,7 +53,7 @@ setup() { CONFIG_FILE="getssl-http01.cfg" # Run getssl - run ${CODE_DIR}/getssl --install "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --install "$GETSSL_CMD_HOST" assert_success check_output_for_errors diff --git a/test/11-test-no-domain-storage.bats b/test/11-test-no-domain-storage.bats index 9ad4aa4..f61db28 100644 --- a/test/11-test-no-domain-storage.bats +++ b/test/11-test-no-domain-storage.bats @@ -20,7 +20,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -a + run ${CODE_DIR}/getssl -U -d -a assert_success check_output_for_errors assert_line 'Not going to delete TEMP_DIR ///tmp as it appears to be /tmp' diff --git a/test/12-auto-upgrade-v1.bats b/test/12-auto-upgrade-v1.bats index 7554561..1dc5139 100644 --- a/test/12-auto-upgrade-v1.bats +++ b/test/12-auto-upgrade-v1.bats @@ -20,7 +20,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -d --check-config "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --check-config "$GETSSL_CMD_HOST" assert_success assert_line 'Using certificate issuer: https://pebble:14000/dir' } @@ -41,7 +41,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -d --check-config "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --check-config "$GETSSL_CMD_HOST" assert_success assert_line 'Using certificate issuer: https://acme-staging-v02.api.letsencrypt.org/directory' } @@ -62,7 +62,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -d --check-config "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --check-config "$GETSSL_CMD_HOST" assert_success assert_line 'Using certificate issuer: https://acme-v02.api.letsencrypt.org/directory' } @@ -83,7 +83,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -d --check-config "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --check-config "$GETSSL_CMD_HOST" assert_success assert_line 'Using certificate issuer: https://acme-staging-v02.api.letsencrypt.org/directory' } @@ -104,7 +104,7 @@ teardown() { setup_environment mkdir ${INSTALL_DIR}/.getssl cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/getssl.cfg" - run ${CODE_DIR}/getssl -d --check-config "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d --check-config "$GETSSL_CMD_HOST" assert_success assert_line 'Using certificate issuer: https://acme-v02.api.letsencrypt.org/directory' } diff --git a/test/13-notify-valid.bats b/test/13-notify-valid.bats index 6b66927..6c06123 100644 --- a/test/13-notify-valid.bats +++ b/test/13-notify-valid.bats @@ -33,7 +33,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d $GETSSL_HOST assert_success check_output_for_errors } @@ -43,7 +43,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl --notify-valid $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d --notify-valid $GETSSL_HOST assert [ $status == 2 ] check_output_for_errors cleanup_environment diff --git a/test/14-test-revoke.bats b/test/14-test-revoke.bats index fffe300..abc33cd 100644 --- a/test/14-test-revoke.bats +++ b/test/14-test-revoke.bats @@ -43,7 +43,7 @@ setup() { CERT=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt KEY=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.key - run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA + run ${CODE_DIR}/getssl -U -d --revoke $CERT $KEY $CA assert_success check_output_for_errors "debug" } diff --git a/test/15-test-revoke-no-suffix.bats b/test/15-test-revoke-no-suffix.bats index 3eb273c..1eaa060 100644 --- a/test/15-test-revoke-no-suffix.bats +++ b/test/15-test-revoke-no-suffix.bats @@ -49,7 +49,7 @@ setup() { CERT=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt KEY=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.key - run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA + run ${CODE_DIR}/getssl -U -d --revoke $CERT $KEY $CA assert_success check_output_for_errors "debug" } diff --git a/test/17-test-spaces-in-sans-dns01.bats b/test/17-test-spaces-in-sans-dns01.bats index 574866d..cc9efc7 100644 --- a/test/17-test-spaces-in-sans-dns01.bats +++ b/test/17-test-spaces-in-sans-dns01.bats @@ -41,7 +41,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment @@ -66,7 +66,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment diff --git a/test/17-test-spaces-in-sans-http01.bats b/test/17-test-spaces-in-sans-http01.bats index 0947e06..86df5dc 100644 --- a/test/17-test-spaces-in-sans-http01.bats +++ b/test/17-test-spaces-in-sans-http01.bats @@ -42,7 +42,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment @@ -67,7 +67,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment diff --git a/test/2-simple-dns01-dig.bats b/test/2-simple-dns01-dig.bats index c0edf7b..2e8199e 100644 --- a/test/2-simple-dns01-dig.bats +++ b/test/2-simple-dns01-dig.bats @@ -55,7 +55,7 @@ teardown() { } @test "Force renewal of certificate using DNS-01 (dig)" { - run ${CODE_DIR}/getssl -d -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success assert_output --partial "dig" check_output_for_errors "debug" diff --git a/test/20-wildcard-simple.bats b/test/20-wildcard-simple.bats index eb0544f..7b69f1f 100644 --- a/test/20-wildcard-simple.bats +++ b/test/20-wildcard-simple.bats @@ -35,7 +35,7 @@ setup() { skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl "*.$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d "*.$GETSSL_HOST" assert_success assert_line --partial "certificate is valid for more than" check_output_for_errors @@ -47,7 +47,7 @@ setup() { skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f "*.$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d -f "*.$GETSSL_HOST" assert_success refute_line --partial "certificate is valid for more than" check_output_for_errors @@ -61,7 +61,7 @@ setup() { echo "RENEW_ALLOW=2000" >> "${INSTALL_DIR}/.getssl/*.${GETSSL_HOST}/getssl.cfg" - run ${CODE_DIR}/getssl "*.$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d "*.$GETSSL_HOST" assert_success refute_line --partial "certificate is valid for more than" check_output_for_errors diff --git a/test/23-wildcard-check-globbing.bats b/test/23-wildcard-check-globbing.bats index bf74230..a075f5d 100644 --- a/test/23-wildcard-check-globbing.bats +++ b/test/23-wildcard-check-globbing.bats @@ -44,7 +44,7 @@ setup() { skip "Not trying on staging server yet" fi - run ${CODE_DIR}/getssl -f "*.$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d -f "*.$GETSSL_HOST" assert_success refute_line --partial "certificate is valid for more than" check_output_for_errors diff --git a/test/25-wildcard-all.bats b/test/25-wildcard-all.bats index 4a74912..a5e1c13 100644 --- a/test/25-wildcard-all.bats +++ b/test/25-wildcard-all.bats @@ -32,13 +32,13 @@ setup() { cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/*.${GETSSL_HOST}/getssl.cfg" # create another domain in the .getssl directory - run ${CODE_DIR}/getssl -c "a.${GETSSL_HOST}" + run ${CODE_DIR}/getssl -U -d -c "a.${GETSSL_HOST}" cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/a.${GETSSL_HOST}/getssl.cfg" # Create a directory in /root which looks like a domain so that if glob expansion is performed the wildcard certificate won't be created mkdir -p "${INSTALL_DIR}/a.${GETSSL_HOST}" - run ${CODE_DIR}/getssl --all + run ${CODE_DIR}/getssl -U -d --all assert_success assert_line --partial "Certificate saved in /root/.getssl/*.${GETSSL_HOST}/*.${GETSSL_HOST}" diff --git a/test/26-wildcard-revoke.bats b/test/26-wildcard-revoke.bats index e613c1e..5709cc7 100644 --- a/test/26-wildcard-revoke.bats +++ b/test/26-wildcard-revoke.bats @@ -39,7 +39,7 @@ setup() { CERT=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt KEY=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.key - run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA + run ${CODE_DIR}/getssl -U -d --revoke $CERT $KEY $CA assert_line "certificate revoked" assert_success check_output_for_errors "debug" diff --git a/test/27-wildcard-existing-cert.bats b/test/27-wildcard-existing-cert.bats index a9e83be..98c97e4 100644 --- a/test/27-wildcard-existing-cert.bats +++ b/test/27-wildcard-existing-cert.bats @@ -40,7 +40,7 @@ setup() { rm -r ${INSTALL_DIR}/.getssl # Create configuration - run ${CODE_DIR}/getssl -c "${GETSSL_CMD_HOST}" + run ${CODE_DIR}/getssl -U -d -c "${GETSSL_CMD_HOST}" # Assert that the newly created configuration contains the additional domain in SANS # if this fails then error in tests will be "grep failed" - this means SANS did not hold the expected value diff --git a/test/29-check-mktemp-failure.bats b/test/29-check-mktemp-failure.bats index 81b9ae4..1a00929 100644 --- a/test/29-check-mktemp-failure.bats +++ b/test/29-check-mktemp-failure.bats @@ -28,7 +28,7 @@ setup() { # set TMPDIR to an invalid directory and check for failure export TMPDIR=/getssl.invalid.directory setup_environment - run ${CODE_DIR}/getssl -c "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d -c "$GETSSL_CMD_HOST" assert_failure assert_line --partial "mktemp failed" } diff --git a/test/3-dual-rsa-ecdsa.bats b/test/3-dual-rsa-ecdsa.bats index df8a8fc..5babf8f 100644 --- a/test/3-dual-rsa-ecdsa.bats +++ b/test/3-dual-rsa-ecdsa.bats @@ -45,7 +45,7 @@ setup() { skip "Using staging server, skipping internal test" fi check_nginx - run ${CODE_DIR}/getssl -d $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d $GETSSL_HOST if [ "$OLD_NGINX" = "false" ]; then assert_line "certificate on server is same as the local cert" @@ -60,7 +60,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -f $GETSSL_HOST assert_success check_output_for_errors } @@ -94,7 +94,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -f $GETSSL_HOST assert_success check_output_for_errors cleanup_environment diff --git a/test/31-test-posix-error.bats b/test/31-test-posix-error.bats index 7623cae..87879b5 100644 --- a/test/31-test-posix-error.bats +++ b/test/31-test-posix-error.bats @@ -23,7 +23,7 @@ setup() { skip "Using staging server, skipping internal test" fi - run bash --posix "${CODE_DIR}/getssl" + run bash --posix "${CODE_DIR}/getssl" -U -d assert_failure assert_line "getssl: Running with POSIX mode enabled is not supported" check_output_for_errors diff --git a/test/32-test-upgrade.bats b/test/32-test-upgrade.bats index 1a311d7..fa000bb 100644 --- a/test/32-test-upgrade.bats +++ b/test/32-test-upgrade.bats @@ -5,9 +5,52 @@ load '/bats-assert/load.bash' load '/getssl/test/test_helper.bash' +setup_file() { + if [ -f $BATS_TMPDIR/failed.skip ]; then + echo "# Skipping setup due to previous test failure" >&3 + return 0 + fi + local n + # Not every tag reflects a stable release. Ask GitHub for the releases & identify the last two. + # This is sorted by creation date of the release tag, not the publication date. This matches + # GitHub's releases/latest, which is how getssl determines what's available. + # This is expensive, so do it only once + + . "${CODE_DIR}/getssl" -U --source + check_github_quota 1 + export RELEASES="$(mktemp 2>/dev/null || mktemp -t getssl.XXXXXX)" + if [ -z "$RELEASES" ]; then + echo "# mktemp failed" >&3 + return 1 + fi + if ! curl ${_NOMETER:---silent} --user-agent "$CURL_USERAGENT" \ + -H 'Accept: application/vnd.github.v3+json' "${RELEASE_API%/latest}" | \ + jq 'map(select((.draft or .prerelease)|not))|sort_by(.created_at)|reverse' >"$RELEASES" ; then + errcode="$?" + echo "# Failed to download release information from ${RELEASE_API%/latest} $errcode" >&3 + return "$errcode" + fi + n="$(jq '.|length' <$RELEASES)" + if [[ "$n" < 2 ]]; then + echo "# Fewer than 2 ($n) stable releases detected in ${RELEASE_API%/latest}, can not run upgrade tests" >&3 + return 0 + fi + CURRENT_TAG="$(jq -r '.[0].tag_name' <"$RELEASES")" + export CURRENT_TAG="${CURRENT_TAG:1}" + PREVIOUS_TAG="$(jq -r '.[1].tag_name' <"$RELEASES")" + export PREVIOUS_TAG="${PREVIOUS_TAG:1}" +} + +teardown_file() { + [ -n "$RELEASES" ] && rm -f "$RELEASES" + true +} + # This is run for every test setup() { [ ! -f $BATS_TMPDIR/failed.skip ] || skip "skipping tests after first failure" + [ -z "$PREVIOUS_TAG" ] && skip "Skipping upgrade test because no previous release detected" + export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt # Turn off warning about detached head @@ -19,13 +62,9 @@ setup() { fi run git clone "${_REPO}" "$INSTALL_DIR/upgrade-getssl" - # Don't do version arithmetics any longer, look what was the previous version by getting the last - # line (starting with v) and the one before that from the list of tags. + cd "$INSTALL_DIR/upgrade-getssl" - # This sets CURRENT_TAG and PREVIOUS_TAG bash variables - eval $(git tag -l | awk 'BEGIN {cur="?.??"};/^v/{prv=cur;cur=substr($1,2)};END{ printf("CURRENT_TAG=\"%s\";PREVIOUS_TAG=\"%s\"\n",cur,prv)}') - # The version in the file, which we will overwrite FILE_VERSION=$(awk -F'"' '/^VERSION=/{print $2}' "$CODE_DIR/getssl") # If FILE_VERSION > CURRENT_TAG then either we are testing a push to master or the last version wasn't released @@ -57,11 +96,11 @@ teardown() { cp "$CODE_DIR/getssl" "$INSTALL_DIR/upgrade-getssl/" sed -i -e "s/VERSION=\"${FILE_VERSION}\"/VERSION=\"${PREVIOUS_TAG}\"/" "$INSTALL_DIR/upgrade-getssl/getssl" - run "$INSTALL_DIR/upgrade-getssl/getssl" --check-config ${GETSSL_CMD_HOST} + run "$INSTALL_DIR/upgrade-getssl/getssl" -d --check-config ${GETSSL_CMD_HOST} assert_success # Check for current tag or file version otherwise push to master fails on a new version (or if the tag hasn't been updated) - assert_line --regexp "A more recent version \(v(${CURRENT_TAG}|${FILE_VERSION})\) of getssl is available, please update" + assert_line --regexp "A more recent version \(v(${CURRENT_TAG}|${FILE_VERSION})\) than .* of getssl is available, please update" check_output_for_errors } @@ -84,15 +123,17 @@ teardown() { cp "$CODE_DIR/getssl" "$INSTALL_DIR/upgrade-getssl/" sed -i -e "s/VERSION=\"${FILE_VERSION}\"/VERSION=\"${PREVIOUS_TAG}\"/" "$INSTALL_DIR/upgrade-getssl/getssl" - run "$INSTALL_DIR/upgrade-getssl/getssl" --check-config --upgrade ${GETSSL_CMD_HOST} + run "$INSTALL_DIR/upgrade-getssl/getssl" -d --check-config --upgrade ${GETSSL_CMD_HOST} assert_success # Check for current tag or file version otherwise push to master fails on a new version (or if the tag hasn't been updated) - assert_line --regexp "Updated getssl from v${PREVIOUS_TAG} to v(${CURRENT_TAG}|${FILE_VERSION})" + assert_line --regexp "Installed v(${CURRENT_TAG}|${FILE_VERSION}), restarting" } @test "Test that we can upgrade to the newer version when invoking as \"bash ./getssl\"" { + skip "Makefile doesn't support bash ./getssl" + # Note that `bash getssl` will fail if the CWD isn't in the PATH and an upgrade occurs if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" @@ -111,9 +152,9 @@ teardown() { cp "$CODE_DIR/getssl" "$INSTALL_DIR/upgrade-getssl/" sed -i -e "s/VERSION=\"${FILE_VERSION}\"/VERSION=\"${PREVIOUS_TAG}\"/" "$INSTALL_DIR/upgrade-getssl/getssl" - run bash ./getssl --check-config --upgrade ${GETSSL_CMD_HOST} + run bash ./getssl -d --check-config --upgrade ${GETSSL_CMD_HOST} assert_success # Check for current tag or file version otherwise push to master fails on a new version (or if the tag hasn't been updated) - assert_line --regexp "Updated getssl from v${PREVIOUS_TAG} to v(${CURRENT_TAG}|${FILE_VERSION})" + assert_line --regexp "Installed v(${CURRENT_TAG}|${FILE_VERSION}), restarting" } diff --git a/test/4-more-than-10-hosts.bats b/test/4-more-than-10-hosts.bats index f62d2e6..143afb4 100644 --- a/test/4-more-than-10-hosts.bats +++ b/test/4-more-than-10-hosts.bats @@ -39,7 +39,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors # Remove all the dns aliases diff --git a/test/5-secp384-http01.bats b/test/5-secp384-http01.bats index 5ddf0d6..a108c27 100644 --- a/test/5-secp384-http01.bats +++ b/test/5-secp384-http01.bats @@ -33,7 +33,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors } @@ -56,7 +56,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors } diff --git a/test/8-staging-ecdsa.bats b/test/8-staging-ecdsa.bats index 67e657a..797ce04 100644 --- a/test/8-staging-ecdsa.bats +++ b/test/8-staging-ecdsa.bats @@ -23,7 +23,7 @@ teardown() { setup_environment init_getssl sed -e 's/rsa/prime256v1/g' < "${CODE_DIR}/test/test-config/${CONFIG_FILE}" > "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" - run ${CODE_DIR}/getssl -d "$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d "$GETSSL_HOST" assert_success check_output_for_errors "debug" } @@ -40,7 +40,7 @@ teardown() { if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - run ${CODE_DIR}/getssl -d -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors "debug" cleanup_environment @@ -63,7 +63,7 @@ teardown() { setup_environment init_getssl sed -e 's/rsa/secp384r1/g' < "${CODE_DIR}/test/test-config/${CONFIG_FILE}" > "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" - run ${CODE_DIR}/getssl -d "$GETSSL_HOST" + run ${CODE_DIR}/getssl -U -d "$GETSSL_HOST" assert_success check_output_for_errors "debug" } @@ -80,7 +80,7 @@ teardown() { if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - run ${CODE_DIR}/getssl -d -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors "debug" cleanup_environment diff --git a/test/9-multiple-domains-dns01.bats b/test/9-multiple-domains-dns01.bats index 12bb2e1..c540d9a 100644 --- a/test/9-multiple-domains-dns01.bats +++ b/test/9-multiple-domains-dns01.bats @@ -39,7 +39,7 @@ setup() { if [ -n "$STAGING" ]; then skip "Using staging server, skipping internal test" fi - run ${CODE_DIR}/getssl -f $GETSSL_HOST + run ${CODE_DIR}/getssl -U -d -f $GETSSL_HOST assert_success check_output_for_errors # Remove all the dns aliases diff --git a/test/9-test--all.bats b/test/9-test--all.bats index 35697fd..bab1ced 100644 --- a/test/9-test--all.bats +++ b/test/9-test--all.bats @@ -29,7 +29,7 @@ setup() { cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" # Run test - run ${CODE_DIR}/getssl --all + run ${CODE_DIR}/getssl -U -d --all # Check success conditions assert_success diff --git a/test/Dockerfile-alpine b/test/Dockerfile-alpine index b0a0ae1..667512e 100644 --- a/test/Dockerfile-alpine +++ b/test/Dockerfile-alpine @@ -2,7 +2,7 @@ FROM alpine:latest # Note this image uses busybox awk instead of gawk -RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx bash lftp vsftpd openssh-server +RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx bash lftp vsftpd openssh-server jq WORKDIR /root diff --git a/test/Dockerfile-bash4-0 b/test/Dockerfile-bash4-0 index 0dae149..8c92f8e 100644 --- a/test/Dockerfile-bash4-0 +++ b/test/Dockerfile-bash4-0 @@ -2,7 +2,7 @@ FROM bash:4.0 # https://hub.docker.com/_/bash -RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server +RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server jq WORKDIR /root diff --git a/test/Dockerfile-bash4-2 b/test/Dockerfile-bash4-2 index dd1cb11..1f0f7f3 100644 --- a/test/Dockerfile-bash4-2 +++ b/test/Dockerfile-bash4-2 @@ -2,7 +2,7 @@ FROM bash:4.2 # https://hub.docker.com/_/bash -RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server +RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server jq WORKDIR /root diff --git a/test/Dockerfile-bash5-0 b/test/Dockerfile-bash5-0 index 260290d..a437388 100644 --- a/test/Dockerfile-bash5-0 +++ b/test/Dockerfile-bash5-0 @@ -2,7 +2,7 @@ FROM bash:5.0 # https://hub.docker.com/_/bash -RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server +RUN apk --no-cache add supervisor openssl git curl bind-tools drill wget nginx lftp vsftpd openssh-server jq WORKDIR /root diff --git a/test/Dockerfile-centos6 b/test/Dockerfile-centos6 index e16388f..f8d08b2 100644 --- a/test/Dockerfile-centos6 +++ b/test/Dockerfile-centos6 @@ -12,7 +12,7 @@ RUN sed -i 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf && # Update and install required software RUN yum -y install epel-release -RUN yum -y install git curl dnsutils ldns wget nginx +RUN yum -y install git curl dnsutils ldns wget nginx jq RUN yum -y install ftp vsftpd RUN yum -y install openssh-server diff --git a/test/Dockerfile-centos7 b/test/Dockerfile-centos7 index 56dff7d..400dcea 100644 --- a/test/Dockerfile-centos7 +++ b/test/Dockerfile-centos7 @@ -3,7 +3,7 @@ FROM centos:centos7 # Update and install required software RUN yum -y update RUN yum -y install epel-release -RUN yum -y install git curl ldns bind-utils wget which nginx +RUN yum -y install git curl ldns bind-utils wget which nginx jq RUN yum -y install ftp vsftpd RUN yum -y install openssh-server diff --git a/test/Dockerfile-centos7-duckdns b/test/Dockerfile-centos7-duckdns index 96a5fab..46bd254 100644 --- a/test/Dockerfile-centos7-duckdns +++ b/test/Dockerfile-centos7-duckdns @@ -5,7 +5,7 @@ FROM centos:centos7 # Update and install required software RUN yum -y update RUN yum -y install epel-release -RUN yum -y install git curl bind-utils ldns wget which nginx +RUN yum -y install git curl bind-utils ldns wget which nginx jq # Set locale ENV LANG en_US.UTF-8 diff --git a/test/Dockerfile-centos7-dynu b/test/Dockerfile-centos7-dynu index cabd7eb..f196c5d 100644 --- a/test/Dockerfile-centos7-dynu +++ b/test/Dockerfile-centos7-dynu @@ -5,7 +5,7 @@ FROM centos:centos7 # Update and install required software RUN yum -y update RUN yum -y install epel-release -RUN yum -y install git curl bind-utils ldns wget which nginx +RUN yum -y install git curl bind-utils ldns wget which nginx jq # Set locale ENV LANG en_US.UTF-8 diff --git a/test/Dockerfile-centos8 b/test/Dockerfile-centos8 index 4ac3114..552e1d9 100644 --- a/test/Dockerfile-centos8 +++ b/test/Dockerfile-centos8 @@ -5,7 +5,7 @@ FROM centos:centos8 # Update and install required software RUN yum -y update RUN yum -y install epel-release -RUN yum -y install git curl bind-utils wget which nginx +RUN yum -y install git curl bind-utils wget which nginx jq RUN yum -y install ftp vsftpd RUN yum -y install openssh-server diff --git a/test/Dockerfile-debian b/test/Dockerfile-debian index 1a57107..0deedff 100644 --- a/test/Dockerfile-debian +++ b/test/Dockerfile-debian @@ -4,7 +4,7 @@ FROM debian:latest # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light jq RUN apt-get install -y ftp vsftpd RUN apt-get install -y openssh-server RUN apt-get install -y locales # for idn testing diff --git a/test/Dockerfile-rockylinux8 b/test/Dockerfile-rockylinux8 index 4b7a135..37bff04 100644 --- a/test/Dockerfile-rockylinux8 +++ b/test/Dockerfile-rockylinux8 @@ -3,7 +3,7 @@ FROM rockylinux/rockylinux:8 # Update and install required software RUN yum -y update RUN yum -y install epel-release -RUN yum -y install git curl bind-utils wget which nginx +RUN yum -y install git curl bind-utils wget which nginx jq RUN yum -y install ftp vsftpd RUN yum -y install openssh-server RUN yum -y install glibc-locale-source glibc-langpack-en # for en_US.UTF-8 support diff --git a/test/Dockerfile-ubuntu b/test/Dockerfile-ubuntu index 5dee554..9ee83c6 100644 --- a/test/Dockerfile-ubuntu +++ b/test/Dockerfile-ubuntu @@ -7,7 +7,7 @@ ENV DEBIAN_FRONTEND noninteractive # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light jq RUN apt-get install -y vim dos2unix # for debugging RUN apt-get install -y ftp vsftpd RUN apt-get install -y openssh-server diff --git a/test/Dockerfile-ubuntu-duckdns b/test/Dockerfile-ubuntu-duckdns index c4fdc6a..783a151 100644 --- a/test/Dockerfile-ubuntu-duckdns +++ b/test/Dockerfile-ubuntu-duckdns @@ -12,7 +12,7 @@ ENV dynamic_dns "duckdns" # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light jq RUN apt-get install -y vim dos2unix # for debugging RUN apt-get install -y locales # for idn testing diff --git a/test/Dockerfile-ubuntu-dynu b/test/Dockerfile-ubuntu-dynu index 68f5c06..a84dc08 100644 --- a/test/Dockerfile-ubuntu-dynu +++ b/test/Dockerfile-ubuntu-dynu @@ -12,7 +12,7 @@ ENV dynamic_dns "dynu" # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light jq RUN apt-get install -y vim dos2unix # for debugging RUN apt-get install -y locales # for idn testing diff --git a/test/Dockerfile-ubuntu16 b/test/Dockerfile-ubuntu16 index 8e4ecae..396d13d 100644 --- a/test/Dockerfile-ubuntu16 +++ b/test/Dockerfile-ubuntu16 @@ -5,7 +5,7 @@ FROM ubuntu:xenial # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light jq RUN apt-get install -y ftp vsftpd RUN apt-get install -y openssh-server RUN apt-get install -y locales # for idn testing diff --git a/test/Dockerfile-ubuntu18 b/test/Dockerfile-ubuntu18 index 98b62d5..76ce362 100644 --- a/test/Dockerfile-ubuntu18 +++ b/test/Dockerfile-ubuntu18 @@ -5,7 +5,7 @@ FROM ubuntu:bionic # Update and install required software RUN apt-get update --fix-missing -RUN apt-get install -y git curl dnsutils ldnsutils wget gawk nginx-light +RUN apt-get install -y git curl dnsutils ldnsutils wget gawk nginx-light jq RUN apt-get install -y ftp vsftpd RUN apt-get install -y openssh-server RUN apt-get install -y locales # for idn testing diff --git a/test/debug-test.sh b/test/debug-test.sh index ac94b53..07e6cd6 100755 --- a/test/debug-test.sh +++ b/test/debug-test.sh @@ -24,7 +24,7 @@ if grep -q pebble "${CONFIG_FILE}"; then export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt fi -"${CODE_DIR}/getssl" -c "$GETSSL_HOST" 3>&1 +"${CODE_DIR}/getssl" -U -c "$GETSSL_HOST" 3>&1 cp "${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" # shellcheck disable=SC2086 -"${CODE_DIR}/getssl" ${DEBUG} -f "$GETSSL_HOST" 3>&1 +"${CODE_DIR}/getssl" -U ${DEBUG} -f "$GETSSL_HOST" 3>&1 diff --git a/test/test_helper.bash b/test/test_helper.bash index 0827adf..37f77cd 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -47,12 +47,12 @@ create_certificate() { # Create certificate cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl.cfg" # shellcheck disable=SC2086 - run ${CODE_DIR}/getssl -d "$@" "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d "$@" "$GETSSL_CMD_HOST" } init_getssl() { # Run initialisation (create account key, etc) - run ${CODE_DIR}/getssl -d -c "$GETSSL_CMD_HOST" + run ${CODE_DIR}/getssl -U -d -c "$GETSSL_CMD_HOST" assert_success [ -d "$INSTALL_DIR/.getssl" ] } From fa97be6a38174fca92fb3de69059de4ac28356b9 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Fri, 27 Aug 2021 11:14:40 -0400 Subject: [PATCH 7/9] Provide default credentials for srvrco (temporary) Use hard-coded default credentials for srvrco when GitHub secrets are not installed. This is a security issue for srvrco, but a fix seems to be difficult. --- .github/workflows/run-tests-staging-duckdns.yml | 2 +- .github/workflows/run-tests-staging-dynu.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests-staging-duckdns.yml b/.github/workflows/run-tests-staging-duckdns.yml index 3a8efea..87da158 100644 --- a/.github/workflows/run-tests-staging-duckdns.yml +++ b/.github/workflows/run-tests-staging-duckdns.yml @@ -12,7 +12,7 @@ on: branches: - master env: - DUCKDNS_TOKEN: ${{ secrets.DUCKDNS_TOKEN }} + DUCKDNS_TOKEN: ${{ secrets.DUCKDNS_TOKEN == '' && '1d616aa9-b8e4-4bb4-b312-3289de82badb' || secrets.DUCKDNS_TOKEN }} jobs: test-centos7-duckdns: runs-on: ubuntu-latest diff --git a/.github/workflows/run-tests-staging-dynu.yml b/.github/workflows/run-tests-staging-dynu.yml index 2f9ec4f..fde2ba2 100644 --- a/.github/workflows/run-tests-staging-dynu.yml +++ b/.github/workflows/run-tests-staging-dynu.yml @@ -12,7 +12,7 @@ on: branches: - master env: - DYNU_API_KEY: ${{ secrets.DYNU_API_KEY }} + DYNU_API_KEY: ${{ secrets.DYNU_API_KEY == '' && '65cXefd35XbYf36546eg5dYcZT6X52Y2' || secrets.DYNU_API_KEY }} jobs: test-centos7-dynu: runs-on: ubuntu-latest From 2f4523642317f73527d926c55f61e35c02fbf252 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Fri, 27 Aug 2021 14:18:00 -0400 Subject: [PATCH 8/9] Suppress test failure when release description contains "error" Upgrade test checks for "error" in output. But release descriptions can have "fix error in ..." Don't run this check. Checking that a new version is detected suffices. --- test/32-test-upgrade.bats | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/32-test-upgrade.bats b/test/32-test-upgrade.bats index fa000bb..823ec96 100644 --- a/test/32-test-upgrade.bats +++ b/test/32-test-upgrade.bats @@ -101,7 +101,8 @@ teardown() { # Check for current tag or file version otherwise push to master fails on a new version (or if the tag hasn't been updated) assert_line --regexp "A more recent version \(v(${CURRENT_TAG}|${FILE_VERSION})\) than .* of getssl is available, please update" - check_output_for_errors + # output can contain "error" in release description + # check_output_for_errors } From 01e3728d8430d0713421f8efbbe574ae13b1c381 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Thu, 2 Sep 2021 10:01:44 -0400 Subject: [PATCH 9/9] Compare version numbers properly getssl uses cURL's version to determine what command options are valid. The previous shortcuts will fail when curl V8.10 is released. (8.9 is greater than 8.10). V8 is planned for release, in part to avoid a minor version of 100, which also would fail. check_version() will compare full or partial version strings by component, and is true if $1 is at least $2. --- getssl | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/getssl b/getssl index f7a58b9..c8dfde7 100755 --- a/getssl +++ b/getssl @@ -269,6 +269,7 @@ # 2021-07-30 Prefer API V2 when both offered (tlhackque) (#690) (2.40) # 2021-07-30 Run tests with -d to catch intermittent failures, Use fork's repo for upgrade tests. (tlhackque) (#692) (2.41) # 2021-08-26 Improve upgrade check & make upgrade do a full install when possible (tlhackque) (#694) (2.42) +# 2021-09-02 Fix version compare - cURL v8 may have single digit minor numbers. (tlhackque) (2.43) # ---------------------------------------------------------------------------------------- case :$SHELLOPTS: in @@ -277,7 +278,7 @@ esac PROGNAME=${0##*/} PROGDIR="$(cd "$(dirname "$0")" || exit; pwd -P;)" -VERSION="2.42" +VERSION="2.43" # defaults ACCOUNT_KEY_LENGTH=4096 @@ -924,6 +925,27 @@ check_getssl_upgrade() { # check if a more recent release is available graceful_exit } +check_version() { # true if version string $1 >= $2 + local v1 v2 i n1 n2 n + # $1 and $2 can be different lengths, but all parts must be numeric + if [[ "$1" == "$2" ]] ; then return 0; fi + local IFS='.' + # shellcheck disable=SC2206 + v1=($1) + # shellcheck disable=SC2206 + v2=($2) + n1="${#v1[@]}" + n2="${#v2[@]}" + if [[ "$n1" -ge "$n2" ]] ; then n="$n1" ; else n="$n2" ; fi + for ((i=0; i