266
266
# 2021-07-22 Only pass +noidnout param to dig/drill(#682)(2.38)
267
267
# 2021-07-25 Fix copy_file_to_location failures with ssh when suffix applied to file lacking an extension (tlhackque)(#686)
268
268
# 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)
269
+ # 2021-07-30 Prefer API V2 when both offered (tlhackque) (#690) (2.40)
270
+ # 2021-07-30 Run tests with -d to catch intermittent failures, Use fork's repo for upgrade tests. (tlhackque) (#692) (2.41)
269
271
# ----------------------------------------------------------------------------------------
270
272
271
273
case :$SHELLOPTS : in
274
276
275
277
PROGNAME=${0##*/ }
276
278
PROGDIR=" $( cd " $( dirname " $0 " ) " || exit ; pwd -P; ) "
277
- VERSION=" 2.39 "
279
+ VERSION=" 2.41 "
278
280
279
281
# defaults
280
282
ACCOUNT_KEY_LENGTH=4096
@@ -284,7 +286,11 @@ CA="https://acme-staging-v02.api.letsencrypt.org/directory"
284
286
CHALLENGE_CHECK_TYPE=" http"
285
287
CHECK_REMOTE_WAIT=0
286
288
CHECK_REMOTE=" true"
287
- CODE_LOCATION=" https://raw.githubusercontent.com/srvrco/getssl/master/getssl"
289
+ if [[ -n " ${GITHUB_REPOSITORY} " ]] ; then
290
+ CODE_LOCATION=" https://raw.githubusercontent.com/${GITHUB_REPOSITORY} /master/getssl"
291
+ else
292
+ CODE_LOCATION=" https://raw.githubusercontent.com/srvrco/getssl/master/getssl"
293
+ fi
288
294
CSR_SUBJECT=" /"
289
295
CURL_USERAGENT=" ${PROGNAME} /${VERSION} "
290
296
DEACTIVATE_AUTH=" false"
@@ -330,10 +336,12 @@ DNS_WAIT_RETRY_ADD="false" # Try the dns_add_command again if the DNS recor
330
336
# Private variables
331
337
_CHECK_ALL=0
332
338
_CREATE_CONFIG=0
339
+ _CURL_VERSION=" "
333
340
_FORCE_RENEW=0
334
341
_KEEP_VERSIONS=" "
335
342
_MUTE=0
336
343
_NOTIFY_VALID=0
344
+ _NOMETER=" "
337
345
_QUIET=0
338
346
_RECREATE_CSR=0
339
347
_REDIRECT_OUTPUT=" 1>/dev/null 2>&1"
@@ -562,15 +570,15 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
562
570
check_result=$( $DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT " ${rr} " " @${ns} " \
563
571
| grep -i " ^${rr} " \
564
572
| grep ' IN\WTXT' | awk -F' "' ' { print $2}' )
565
- debug " check_result=$check_result "
573
+ debug " check_result=\" $check_result \" "
566
574
if [[ -z " $check_result " ]]; then
567
575
# shellcheck disable=SC2086
568
576
debug " $DNS_CHECK_FUNC " $DNS_CHECK_OPTIONS ANY " ${rr} " " @${ns} "
569
577
# shellcheck disable=SC2086
570
578
check_result=$( $DNS_CHECK_FUNC $DNS_CHECK_OPTIONS ANY " ${rr} " " @${ns} " \
571
579
| grep -i " ^${rr} " \
572
580
| grep ' IN\WTXT' | awk -F' "' ' { print $2}' )
573
- debug " check_result=$check_result "
581
+ debug " check_result=\" $check_result \" "
574
582
fi
575
583
elif [[ " $DNS_CHECK_FUNC " == " host" ]]; then
576
584
check_result=$( $DNS_CHECK_FUNC -t TXT " ${rr} " " ${ns} " \
@@ -583,8 +591,8 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
583
591
| grep ' text =' | awk -F' "' ' { print $2}' )
584
592
fi
585
593
fi
586
- debug " expecting $auth_key "
587
- debug " ${ns} gave ... $check_result "
594
+ debug " expecting \" $auth_key \" "
595
+ debug " ${ns} gave ... \" $check_result \" "
588
596
589
597
if [[ " $check_result " == * " $auth_key " * ]]; then
590
598
check_dns=" success"
@@ -606,7 +614,7 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
606
614
debug " dns check failed - removing existing value"
607
615
del_dns_rr " ${d} " " ${auth_key} "
608
616
609
- error_exit " checking ${rr} gave $check_result not $auth_key "
617
+ error_exit " checking \" ${rr} \" gave \" $check_result \" not \" $auth_key \" "
610
618
fi
611
619
fi
612
620
done
@@ -758,7 +766,7 @@ check_getssl_upgrade() { # check if a more recent version of code is available a
758
766
if [ " $TEMP_UPGRADE_FILE " == " " ]; then
759
767
error_exit " mktemp failed"
760
768
fi
761
- curl --user-agent " $CURL_USERAGENT " --silent " $CODE_LOCATION " --output " $TEMP_UPGRADE_FILE "
769
+ curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --silent " $CODE_LOCATION " --output " $TEMP_UPGRADE_FILE "
762
770
errcode=$?
763
771
if [[ $errcode -eq 60 ]]; then
764
772
error_exit " curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)"
@@ -941,7 +949,7 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
941
949
fromfile=$( basename " $from " )
942
950
debug " davs user=$davsuser - pass=$davspass - host=$davshost port=$davsport dir=$davsdirn file=$davsfile "
943
951
debug " from dir=$fromdir file=$fromfile "
944
- curl -u " ${davsuser} :${davspass} " -T " ${fromdir} /${fromfile} " " https://${davshost} :${davsport}${davsdirn}${davsfile} "
952
+ curl ${_NOMETER} -u " ${davsuser} :${davspass} " -T " ${fromdir} /${fromfile} " " https://${davshost} :${davsport}${davsdirn}${davsfile} "
945
953
elif [[ " ${to: 0: 6} " == " ftpes:" ]] || [[ " ${to: 0: 5} " == " ftps:" ]] ; then
946
954
debug " using ftp to copy the file from $from "
947
955
ftpuser=$( echo " $to " | awk -F: ' {print $2}' )
@@ -956,10 +964,10 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
956
964
debug " from dir=$fromdir file=$fromfile "
957
965
if [[ " ${to: 0: 5} " == " ftps:" ]] ; then
958
966
# shellcheck disable=SC2086
959
- curl $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u " ${ftpuser} :${ftppass} " -T " ${fromdir} /${fromfile} " " ftp://${ftphost}${ftpdirn} :990/"
967
+ curl ${_NOMETER} $ FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u " ${ftpuser} :${ftppass} " -T " ${fromdir} /${fromfile} " " ftp://${ftphost}${ftpdirn} :990/"
960
968
else
961
969
# shellcheck disable=SC2086
962
- curl $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u " ${ftpuser} :${ftppass} " -T " ${fromdir} /${fromfile} " " ftp://${ftphost}${ftpdirn} /"
970
+ curl ${_NOMETER} $ FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u " ${ftpuser} :${ftppass} " -T " ${fromdir} /${fromfile} " " ftp://${ftphost}${ftpdirn} /"
963
971
fi
964
972
else
965
973
if ! mkdir -p " $( dirname " $to " ) " ; then
@@ -1377,7 +1385,7 @@ for d in "${alldomains[@]}"; do
1377
1385
# ACME only allows port 80 (http), but redirects may use https. --insecure is used in case
1378
1386
# those certificates are being renewed. Let's Encrypt does the same. In this case, we verify
1379
1387
# that the correct data is returned, so this is safe.
1380
- if [[ ! " $( curl --user-agent " $CURL_USERAGENT " --insecure --silent --location " $wellknown_url " ) " == " $keyauthorization " ]]; then
1388
+ if [[ ! " $( curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --insecure --silent --location " $wellknown_url " ) " == " $keyauthorization " ]]; then
1381
1389
error_exit " for some reason could not reach $wellknown_url - please check it manually"
1382
1390
fi
1383
1391
fi
@@ -1621,7 +1629,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
1621
1629
CertData=$( awk ' $1 ~ "^Location" {print $2}' " $CURL_HEADER " | tr -d ' \r' )
1622
1630
if [[ " $CertData " ]] ; then
1623
1631
echo -----BEGIN CERTIFICATE----- > " $gc_certfile "
1624
- curl --user-agent " $CURL_USERAGENT " --silent " $CertData " | openssl base64 -e >> " $gc_certfile "
1632
+ curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --silent " $CertData " | openssl base64 -e >> " $gc_certfile "
1625
1633
echo -----END CERTIFICATE----- >> " $gc_certfile "
1626
1634
info " Certificate saved in $CERT_FILE "
1627
1635
fi
@@ -1641,7 +1649,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
1641
1649
| sed ' s/>//g' )
1642
1650
if [[ " $IssuerData " ]] ; then
1643
1651
echo -----BEGIN CERTIFICATE----- > " $gc_cafile "
1644
- curl --user-agent " $CURL_USERAGENT " --silent " $IssuerData " | openssl base64 -e >> " $gc_cafile "
1652
+ curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --silent " $IssuerData " | openssl base64 -e >> " $gc_cafile "
1645
1653
echo -----END CERTIFICATE----- >> " $gc_cafile "
1646
1654
info " The intermediate CA cert is in $gc_cafile "
1647
1655
fi
@@ -1699,7 +1707,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
1699
1707
cp " $gc_certfile " " $gc_fullchain "
1700
1708
while [[ -n " $issuer_url " ]]; do
1701
1709
debug Fetching certificate issuer from " $issuer_url "
1702
- issuer_cert=$( curl --user-agent " $CURL_USERAGENT " --silent " $issuer_url " | openssl x509 -inform der -outform pem)
1710
+ issuer_cert=$( curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --silent " $issuer_url " | openssl x509 -inform der -outform pem)
1703
1711
debug Fetched issuer certificate " $( echo " $issuer_cert " | openssl x509 -inform pem -noout -text | awk ' BEGIN {FS="Subject: "} NF==2 {print $2; exit}' ) "
1704
1712
echo " $issuer_cert " >> " $gc_fullchain "
1705
1713
@@ -1714,7 +1722,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
1714
1722
get_cr () { # get curl response
1715
1723
url=" $1 "
1716
1724
debug url " $url "
1717
- response=$( curl --user-agent " $CURL_USERAGENT " --silent " $url " )
1725
+ response=$( curl ${_NOMETER} --user-agent " $CURL_USERAGENT " --silent " $url " )
1718
1726
ret=$?
1719
1727
debug response " ${response// [$'\t\r\n']} "
1720
1728
code=$( json_get " $response " status)
@@ -1797,7 +1805,7 @@ get_signing_params() { # get signing parameters from key
1797
1805
}
1798
1806
1799
1807
graceful_exit () { # normal exit function.
1800
- exit_code=$1
1808
+ exit_code=" ${1-0} "
1801
1809
clean_up
1802
1810
# shellcheck disable=SC2086
1803
1811
exit $exit_code
@@ -2055,7 +2063,7 @@ obtain_ca_resource_locations()
2055
2063
for suffix in " " " /directory" " /dir" ;
2056
2064
do
2057
2065
# Obtain CA resource locations
2058
- ca_all_loc=$( curl --user-agent " $CURL_USERAGENT " " ${CA}${suffix} " 2> /dev/null)
2066
+ ca_all_loc=$( curl ${_NOMETER} --user-agent " $CURL_USERAGENT " " ${CA}${suffix} " 2> /dev/null)
2059
2067
debug " ca_all_loc from ${CA}${suffix} gives $ca_all_loc "
2060
2068
# APIv1
2061
2069
URL_new_reg=$( echo " $ca_all_loc " | grep " new-reg" | awk -F' "' ' {print $4}' )
@@ -2072,10 +2080,11 @@ obtain_ca_resource_locations()
2072
2080
fi
2073
2081
done
2074
2082
2075
- if [[ -n " $URL_new_reg " ]]; then
2076
- API=1
2077
- elif [[ -n " $URL_newAccount " ]]; then
2083
+ # If a directory offers both versions, select V2.
2084
+ if [[ -n " $URL_newAccount " ]]; then
2078
2085
API=2
2086
+ elif [[ -n " $URL_new_reg " ]]; then
2087
+ API=1
2079
2088
else
2080
2089
error_exit " unknown API version"
2081
2090
fi
@@ -2236,9 +2245,9 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
2236
2245
CURL_HEADER=" $TEMP_DIR /curl.header"
2237
2246
dp=" $TEMP_DIR /curl.dump"
2238
2247
2239
- CURL=" curl "
2248
+ CURL=" curl ${_NOMETER} "
2240
2249
# shellcheck disable=SC2072
2241
- if [[ " $( $CURL -V | head -1 | cut -d ' ' -f2 ) " > " 7.33" ]]; then
2250
+ if [[ ! " ${_CURL_VERSION} " < " 7.33" ]]; then
2242
2251
CURL=" $CURL --http1.1 "
2243
2252
fi
2244
2253
@@ -2314,7 +2323,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
2314
2323
fi
2315
2324
2316
2325
if [[ $errcode -gt 0 || ( " $response " == " " && $url ! = * " revoke" * ) ]]; then
2317
- error_exit " ERROR curl \" $url \" failed with $errcode and returned $response "
2326
+ error_exit " ERROR curl \" $url \" failed with $errcode and returned \" $response \" "
2318
2327
fi
2319
2328
2320
2329
responseHeaders=$( cat " $CURL_HEADER " )
@@ -2414,13 +2423,14 @@ signal_exit() { # Handle trapped signals
2414
2423
}
2415
2424
2416
2425
traceback () { # Print function traceback
2417
- local i d=1 lbl=" called"
2418
- echo " Traceback" >&2
2419
- for (( i= $((${# FUNCNAME[@]} - 1 )) ; i> 0; i--)); do
2420
- if [[ ${i} -eq 1 ]] ; then lbl=" called traceback" ; fi
2421
- printf " %*s%s() line %d%s\n" " $d " ' ' " ${FUNCNAME[$i]} " " ${BASH_LINENO[$((i-1))]} " " $lbl " >&2
2422
- (( d++ ))
2423
- done
2426
+ local i d=1 lbl=" called"
2427
+ debug " Traceback"
2428
+ for (( i= $((${# FUNCNAME[@]} - 1 )) ; i> 0; i--)); do
2429
+ if [[ ${i} -eq 1 ]] ; then lbl=" called traceback" ; fi
2430
+ debug " $( printf " %*s%s() line %d%s\n" " $d " ' ' " ${FUNCNAME[$i]} " " ${BASH_LINENO[$((i-1))]} " " $lbl " ) "
2431
+ (( d++ ))
2432
+ done
2433
+ return 0
2424
2434
}
2425
2435
2426
2436
urlbase64 () { # urlbase64: base64 encoded string with '+' replaced with '-' and '/' replaced with '_'
@@ -2625,6 +2635,12 @@ write_openssl_conf() { # write out a minimal openssl conf
2625
2635
trap " signal_exit TERM" TERM HUP
2626
2636
trap " signal_exit INT" INT
2627
2637
2638
+ # When running tests, use debug mode to capture intermittent faults
2639
+ # Test harness will Save output in a temporary file, which is displayed if an error occurs
2640
+ if [[ ${_RUNNING_TEST} -eq 1 ]] ; then
2641
+ _USE_DEBUG=1
2642
+ fi
2643
+
2628
2644
# Parse command-line
2629
2645
while [[ -n ${1+defined} ]]; do
2630
2646
case $1 in
@@ -2720,6 +2736,17 @@ requires sed
2720
2736
requires sort
2721
2737
requires mktemp
2722
2738
2739
+ # Make sure cURL doesn't display a progress meter (if it's new enough)
2740
+ # --silent also does this, but suppresses warnings and informational messages too.
2741
+ # TODO: see where --silent can be removed (if _NOMETER defaults to --silent for old versions?)
2742
+ # This would help with debugging transfer errors.
2743
+
2744
+ _CURL_VERSION= " $( curl -V | head -1 | cut -d' ' -f2 ) "
2745
+ # shellcheck disable=SC2072
2746
+ if [[ ! " ${_CURL_VERSION} " < " 7.67" ]]; then
2747
+ _NOMETER=" --no-progress-meter"
2748
+ fi
2749
+
2723
2750
# Check if upgrades are available (unless they have specified -U to ignore Upgrade checks)
2724
2751
if [[ $_UPGRADE_CHECK -eq 1 ]]; then
2725
2752
check_getssl_upgrade
0 commit comments