From e963438c5a5d58ce3f997eef1e8e25f3cb4238d8 Mon Sep 17 00:00:00 2001 From: Lukas Schauer Date: Mon, 29 Mar 2021 19:14:03 +0200 Subject: [PATCH] make shellcheck happy again --- dehydrated | 112 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/dehydrated b/dehydrated index 8fe232b..b948c48 100755 --- a/dehydrated +++ b/dehydrated @@ -31,6 +31,22 @@ SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" BASEDIR="${SCRIPTDIR}" ORIGARGS=("${@}") +noglob_set() { + if [[ -n "${ZSH_VERSION:-}" ]]; then + set +o noglob + else + set +f + fi +} + +noglob_clear() { + if [[ -n "${ZSH_VERSION:-}" ]]; then + set -o noglob + else + set -f + fi +} + # Generate json.sh path matching string json_path() { if [ ! "${1}" = "-p" ]; then @@ -55,7 +71,6 @@ get_json_array_values() { # Get sub-dictionary from json get_json_dict_value() { local filter - echo "$(json_path "${1:-}" "${2:-}")" filter="$(printf 's/.*\[%s\][[:space:]]*\(.*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")" sed -n "${filter}" | jsonsh } @@ -103,13 +118,14 @@ jsonsh() { local ESCAPE local CHAR - if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + if echo "test string" | grep -Eao --color=never "test" >/dev/null 2>&1 then - GREP='egrep -ao --color=never' + GREP='grep -Eao --color=never' else - GREP='egrep -ao' + GREP='grep -Eao' fi + # shellcheck disable=SC2196 if echo "test string" | egrep -ao "test" >/dev/null 2>&1 then ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' @@ -126,10 +142,11 @@ jsonsh() { local SPACE='[[:space:]]+' # Force zsh to expand $A into multiple words - local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') - if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi - $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" - if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi + local is_wordsplit_disabled + is_wordsplit_disabled="$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')" + if [ "${is_wordsplit_disabled}" != "0" ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | grep -Ev "^$SPACE$" + if [ "${is_wordsplit_disabled}" != "0" ]; then unsetopt shwordsplit; fi } parse_array () { @@ -194,17 +211,14 @@ jsonsh() { } parse_value () { - local jpath="${1:+$1,}${2:-}" isleaf=0 isempty=0 print=0 + local jpath="${1:+$1,}${2:-}" case "$token" in '{') parse_object "$jpath" ;; '[') parse_array "$jpath" ;; # At this point, the only valid single-character tokens are digits. ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; - *) value=$token + *) value="${token/\\\///}" # replace solidus ("\/") in json strings with normalized value: "/" - value=$(echo "$value" | sed 's#\\/#/#g') - isleaf=1 - [ "$value" = '""' ] && isempty=1 ;; esac [ "$value" = '' ] && return @@ -229,8 +243,7 @@ jsonsh() { # Create (identifiable) temporary files _mktemp() { - # shellcheck disable=SC2068 - mktemp ${@:-} "${TMPDIR:-/tmp}/dehydrated-XXXXXX" + mktemp "${TMPDIR:-/tmp}/dehydrated-XXXXXX" } # Check for script dependencies @@ -385,7 +398,7 @@ load_config() { fi # Allow globbing - [[ -n "${ZSH_VERSION:-}" ]] && set +o noglob || set +f + noglob_set for check_config_d in "${CONFIG_D}"/*.sh; do if [[ -f "${check_config_d}" ]] && [[ -r "${check_config_d}" ]]; then @@ -398,7 +411,7 @@ load_config() { done # Disable globbing - [[ -n "${ZSH_VERSION:-}" ]] && set -o noglob || set -f + noglob_clear fi # Check for missing dependencies @@ -479,6 +492,7 @@ load_config() { fi fi + # shellcheck disable=SC1090 [[ -f "${ACCOUNTDIR}/${CAHASH}/config" ]] && . "${ACCOUNTDIR}/${CAHASH}/config" ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem" ACCOUNT_KEY_JSON="${ACCOUNTDIR}/${CAHASH}/registration_info.json" @@ -549,8 +563,8 @@ init_system() { grep -q newOrder <<< "${CA_DIRECTORY}" && API=2 || API=1 fi - if [[ ${API} -eq 1 ]]; then - # shellcheck disable=SC2015 + # shellcheck disable=SC2015 + if [[ "${API}" = "1" ]]; then CA_NEW_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-cert)" && CA_NEW_AUTHZ="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-authz)" && CA_NEW_REG="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-reg)" && @@ -561,7 +575,6 @@ init_system() { # Since reg URI is missing from directory we will assume it is the same as CA_NEW_REG without the new part CA_REG=${CA_NEW_REG/new-reg/reg} else - # shellcheck disable=SC2015 CA_NEW_ORDER="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newOrder)" && CA_NEW_NONCE="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newNonce)" && CA_NEW_ACCOUNT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newAccount)" && @@ -569,8 +582,6 @@ init_system() { CA_REQUIRES_EAB="$(printf "%s" "${CA_DIRECTORY}" | get_json_bool_value -p '"meta","externalAccountRequired"' || echo false)" && CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revokeCert)" || _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint." - # Since acct URI is missing from directory we will assume it is the same as CA_NEW_ACCOUNT without the new part - CA_ACCOUNT=${CA_NEW_ACCOUNT/new-acct/acct} fi # Export some environment variables to be used in hook script @@ -592,13 +603,14 @@ init_system() { if [[ ! "${PARAM_ACCEPT_TERMS:-}" = "yes" ]]; then printf '\n' >&2 printf 'To use dehydrated with this certificate authority you have to agree to their terms of service which you can find here: %s\n\n' "${CA_TERMS}" >&2 - printf 'To accept these terms of service run `%s --register --accept-terms`.\n' "${0}" >&2 + printf 'To accept these terms of service run "%s --register --accept-terms".\n' "${0}" >&2 exit 1 fi echo "+ Generating account key..." generated="true" - local tmp_account_key="$(_mktemp)" + local tmp_account_key + tmp_account_key="$(_mktemp)" _openssl genrsa -out "${tmp_account_key}" "${KEYSIZE}" cat "${tmp_account_key}" > "${ACCOUNT_KEY}" rm "${tmp_account_key}" @@ -702,11 +714,11 @@ init_system() { # Read account information or request from CA if missing if [[ -e "${ACCOUNT_KEY_JSON}" ]]; then if [[ ${API} -eq 1 ]]; then - ACCOUNT_ID="$(cat "${ACCOUNT_KEY_JSON}" | jsonsh | get_json_int_value id)" + ACCOUNT_ID="$(jsonsh < "${ACCOUNT_KEY_JSON}" | get_json_int_value id)" ACCOUNT_URL="${CA_REG}/${ACCOUNT_ID}" else if [[ -e "${ACCOUNT_ID_JSON}" ]]; then - ACCOUNT_URL="$(cat "${ACCOUNT_ID_JSON}" | jsonsh | get_json_string_value url)" + ACCOUNT_URL="$(jsonsh < "${ACCOUNT_ID_JSON}" | get_json_string_value url)" fi # if account URL is not storred, fetch it from the CA if [[ -z "${ACCOUNT_URL:-}" ]]; then @@ -772,7 +784,8 @@ deurlbase64() { # Convert hex string to binary data hex2bin() { # Remove spaces, add leading zero, escape as hex string and parse with printf - printf -- "$(cat | _sed -e 's/[[:space:]]//g' -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')" + # shellcheck disable=SC2059 + printf "%b" "$(cat | _sed -e 's/[[:space:]]//g' -e 's/^(.(.{2})*)$/0\1/' -e 's/(.{2})/\\x\1/g')" } # Convert binary data to hex string @@ -807,6 +820,7 @@ http_request() { fi set +e + # shellcheck disable=SC2086 if [[ "${1}" = "head" ]]; then statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)" curlret="${?}" @@ -846,8 +860,8 @@ http_request() { # An exclusive hook for the {1}-request error might be useful (e.g., for sending an e-mail to admins) if [[ -n "${HOOK}" ]]; then - errtxt="$(cat ${tempcont})" - errheaders="$(cat ${tempheaders})" + errtxt="$(cat "${tempcont}")" + errheaders="$(cat "${tempheaders}")" "${HOOK}" "request_failure" "${statuscode}" "${errtxt}" "${1}" "${errheaders}" || _exiterr 'request_failure hook returned with non-zero exit code' fi @@ -925,8 +939,7 @@ extract_altnames() { # SANs used, extract these altnames="$( <<<"${reqtext}" awk '/X509v3 Subject Alternative Name:/{print;getline;print;}' | tail -n1 )" # split to one per line: - # shellcheck disable=SC1003 - altnames="$( <<<"${altnames}" _sed -e 's/^[[:space:]]*//; s/, /\'$'\n''/g' )" + altnames="$( <<<"${altnames}" _sed -e 's/^[[:space:]]*//; s/, /'"'$'\n'"'/g' )" # we can only get DNS: ones signed if grep -qEv '^(DNS|othername):' <<<"${altnames}"; then _exiterr "Certificate signing request contains non-DNS Subject Alternative Names" @@ -1083,12 +1096,12 @@ sign_csr() { if [[ ${num_pending_challenges} -ne 0 ]]; then echo " + Deploying challenge tokens..." if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]]; then - "${HOOK}" "deploy_challenge" ${deploy_args[@]} || _exiterr 'deploy_challenge hook returned with non-zero exit code' + "${HOOK}" "deploy_challenge" "${deploy_args[@]}" || _exiterr 'deploy_challenge hook returned with non-zero exit code' elif [[ -n "${HOOK}" ]]; then # Run hook script to deploy the challenge token local idx=0 while [ ${idx} -lt ${num_pending_challenges} ]; do - "${HOOK}" "deploy_challenge" ${deploy_args[${idx}]} || _exiterr 'deploy_challenge hook returned with non-zero exit code' + "${HOOK}" "deploy_challenge" "${deploy_args[${idx}]}" || _exiterr 'deploy_challenge hook returned with non-zero exit code' idx=$((idx+1)) done fi @@ -1134,7 +1147,7 @@ sign_csr() { echo " + Cleaning challenge tokens..." # Clean challenge tokens using chained hook - [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && ("${HOOK}" "clean_challenge" ${deploy_args[@]} || _exiterr 'clean_challenge hook returned with non-zero exit code') + [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && ("${HOOK}" "clean_challenge" "${deploy_args[@]}" || _exiterr 'clean_challenge hook returned with non-zero exit code') # Clean remaining challenge tokens if validation has failed local idx=0 @@ -1144,7 +1157,7 @@ sign_csr() { # Delete alpn verification certificates [[ "${CHALLENGETYPE}" = "tls-alpn-01" ]] && rm -f "${ALPNCERTDIR}/${challenge_names[${idx}]}.crt.pem" "${ALPNCERTDIR}/${challenge_names[${idx}]}.key.pem" # Clean challenge token using non-chained hook - [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && ("${HOOK}" "clean_challenge" ${deploy_args[${idx}]} || _exiterr 'clean_challenge hook returned with non-zero exit code') + [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && ("${HOOK}" "clean_challenge" "${deploy_args[${idx}]}" || _exiterr 'clean_challenge hook returned with non-zero exit code') idx=$((idx+1)) done @@ -1192,7 +1205,7 @@ sign_csr() { foundaltchain=1 fi if [ "${foundaltchain}" = "0" ]; then - while read altcrturl; do + while read -r altcrturl; do if [ "${foundaltchain}" = "0" ]; then altcrt="$(signed_request "${altcrturl}" "")" altcn="$(get_last_cn "${altcrt}")" @@ -1292,7 +1305,7 @@ generate_alpn_certificate() { tmp_openssl_cnf="$(_mktemp)" cat "${OPENSSL_CNF}" > "${tmp_openssl_cnf}" printf "\n[SAN]\nsubjectAltName=DNS:%s\n" "${altname}" >> "${tmp_openssl_cnf}" - printf "1.3.6.1.5.5.7.1.31=critical,DER:04:20:${acmevalidation}\n" >> "${tmp_openssl_cnf}" + printf "1.3.6.1.5.5.7.1.31=critical,DER:04:20:%s\n" "${acmevalidation}" >> "${tmp_openssl_cnf}" SUBJ="/CN=${altname}/" [[ "${OSTYPE:0:5}" = "MINGW" ]] && SUBJ="/${SUBJ}" _openssl req -x509 -new -sha256 -nodes -newkey rsa:2048 -keyout "${alpncertdir}/${altname}.key.pem" -out "${alpncertdir}/${altname}.crt.pem" -subj "${SUBJ}" -extensions SAN -config "${tmp_openssl_cnf}" @@ -1326,7 +1339,8 @@ sign_domain() { if [[ ! -r "${certdir}/privkey.pem" ]] || [[ "${PRIVATE_KEY_RENEW}" = "yes" ]]; then echo " + Generating private key..." privkey="privkey-${timestamp}.pem" - local tmp_privkey="$(_mktemp)" + local tmp_privkey + tmp_privkey="$(_mktemp)" case "${KEY_ALGO}" in rsa) _openssl genrsa -out "${tmp_privkey}" "${KEYSIZE}";; prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${tmp_privkey}";; @@ -1440,6 +1454,7 @@ command_version() { revision="$(cd "${SCRIPTDIR}"; git rev-parse HEAD 2>/dev/null || echo "unknown")" echo "GIT-Revision: ${revision}" echo "" + # shellcheck disable=SC1091 if [[ "${OSTYPE}" =~ (BSD|Darwin) ]]; then echo "OS: $(uname -sr)" elif [[ -e /etc/os-release ]]; then @@ -1447,7 +1462,7 @@ command_version() { elif [[ -e /usr/lib/os-release ]]; then ( . /usr/lib/os-release && echo "OS: $PRETTY_NAME" ) else - echo "OS: $(cat /etc/issue | grep -v ^$ | head -n1 | _sed 's/\\(r|n|l) .*//g')" + echo "OS: $(grep -v '^$' /etc/issue | head -n1 | _sed 's/\\(r|n|l) .*//g')" fi echo "Used software:" [[ -n "${BASH_VERSION:-}" ]] && echo " bash: ${BASH_VERSION}" @@ -1549,9 +1564,9 @@ command_sign_domains() { if [[ -n "${PARAM_DOMAIN:-}" ]]; then DOMAINS_TXT="$(_mktemp)" if [[ -n "${PARAM_ALIAS:-}" ]]; then - printf -- "${PARAM_DOMAIN} > ${PARAM_ALIAS}" > "${DOMAINS_TXT}" + printf "%s > %s" "${PARAM_DOMAIN}" "${PARAM_ALIAS}" > "${DOMAINS_TXT}" else - printf -- "${PARAM_DOMAIN}" > "${DOMAINS_TXT}" + printf "%s" "${PARAM_DOMAIN}" > "${DOMAINS_TXT}" fi elif [[ -e "${DOMAINS_TXT}" ]]; then if [[ ! -r "${DOMAINS_TXT}" ]]; then @@ -1570,11 +1585,11 @@ command_sign_domains() { alias="$(grep -Eo '>[^ ]+' <<< "${line}" || true)" line="$(_sed -e 's/>[^ ]+[ ]*//g' <<< "${line}")" aliascount="$(grep -Eo '>' <<< "${alias}" | awk 'END {print NR}' || true )" - [ ${aliascount} -gt 1 ] && _exiterr "Only one alias per line is allowed in domains.txt!" + [ "${aliascount}" -gt 1 ] && _exiterr "Only one alias per line is allowed in domains.txt!" domain="$(printf '%s\n' "${line}" | cut -d' ' -f1)" morenames="$(printf '%s\n' "${line}" | cut -s -d' ' -f2-)" - [ ${aliascount} -lt 1 ] && alias="${domain}" || alias="${alias#>}" + [ "${aliascount}" -lt 1 ] && alias="${domain}" || alias="${alias#>}" export alias if [[ -z "${morenames}" ]];then @@ -1708,13 +1723,14 @@ command_sign_domains() { if [[ ! "${skip}" = "yes" ]]; then update_ocsp="yes" [[ -z "${csr}" ]] || printf "%s" "${csr}" > "${certdir}/cert-${timestamp}.csr" + # shellcheck disable=SC2086 if [[ "${PARAM_KEEP_GOING:-}" = "yes" ]]; then skip_exit_hook=yes - sign_domain "${certdir}" ${timestamp} ${domain} ${morenames} & + sign_domain "${certdir}" "${timestamp}" "${domain}" ${morenames} & wait $! || exit_with_errorcode=1 skip_exit_hook=no else - sign_domain "${certdir}" ${timestamp} ${domain} ${morenames} + sign_domain "${certdir}" "${timestamp}" "${domain}" ${morenames} fi fi @@ -1778,6 +1794,7 @@ command_sign_csr() { # gen cert certfile="$(_mktemp)" + # shellcheck disable=SC2086 sign_csr "${csr}" ${altnames} 3> "${certfile}" # print cert @@ -1882,7 +1899,7 @@ command_cleanup() { fi # Allow globbing - [[ -n "${ZSH_VERSION:-}" ]] && set +o noglob || set +f + noglob_set # Loop over all certificate directories for certdir in "${CERTDIR}/"*; do @@ -1995,8 +2012,7 @@ main() { fi } - # shellcheck disable=SC2199 - [[ -z "${@}" ]] && eval set -- "--help" + [[ -z "${*}" ]] && eval set -- "--help" while (( ${#} )); do case "${1}" in -- 2.39.5