]>
git.proxmox.com Git - proxmox-acme.git/blob - src/proxmox-acme
007c58d0e51a77784490ddd39981ae543882d9c3
8 _debug3
"base64 multiline:'$1'"
9 ${ACME_OPENSSL_BIN:-openssl} base64
-e
11 _debug3
"base64 single line."
12 ${ACME_OPENSSL_BIN:-openssl} base64
-e |
tr -d '\r\n'
19 ${ACME_OPENSSL_BIN:-openssl} base64
-d -A
21 ${ACME_OPENSSL_BIN:-openssl} base64
-d
25 # Usage: hashalg [outputhex]
26 # Output Base64-encoded digest
29 if [ -z "$alg" ]; then
30 _usage
"Usage: _digest hashalg"
36 if [ "$alg" = "sha256" ] ||
[ "$alg" = "sha1" ] ||
[ "$alg" = "md5" ]; then
37 if [ "$outputhex" ]; then
38 ${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -hex | cut
-d = -f 2 |
tr -d ' '
40 ${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -binary | _base64
43 _err
"$alg is not supported yet"
50 # shellcheck disable=SC2018,SC2019
55 # shellcheck disable=SC2018,SC2019
62 echo "$_str" |
grep "^$_sub" >/dev
/null
2>&1
68 echo "$_str" |
grep -- "$_sub\$" >/dev
/null
2>&1
74 echo "$_str" |
grep -- "$_sub" >/dev
/null
2>&1
83 if [ -z "$_findex" ]; then
84 _usage
"Usage: str field [sep]"
88 if [ -z "$_sep" ]; then
93 while [ "$_ffi" -gt "0" ]; do
94 _fv
="$(echo "$_str" | cut -d "$_sep" -f "$_ffi")"
99 _ffi
="$(_math "$_ffi" - 1)"
102 printf -- "%s" "$_str"
108 if [ -z "$cmd" ]; then
109 _usage
"Usage: _exists cmd"
113 if eval type type >/dev
/null
2>&1; then
114 eval type "$cmd" >/dev
/null
2>&1
115 elif command >/dev
/null
2>&1; then
116 command -v "$cmd" >/dev
/null
2>&1
118 which "$cmd" >/dev
/null
2>&1
121 _debug3
"$cmd exists=$ret"
128 printf "%s" "$(($_m_opts))"
132 if ! egrep -o "$1" 2>/dev
/null
; then
133 sed -n 's/.*\('"$1"'\).*/\1/p'
139 if [ -z "$HTTP_HEADER" ] ||
! touch "$HTTP_HEADER"; then
140 HTTP_HEADER
="$(_mktemp)"
141 _debug2 HTTP_HEADER
"$HTTP_HEADER"
144 if [ "$__HTTP_INITIALIZED" ]; then
145 if [ "$_ACME_CURL$_ACME_WGET" ]; then
146 _debug2
"Http already initialized."
151 if [ -z "$_ACME_CURL" ] && _exists
"curl"; then
152 _ACME_CURL
="curl -L --silent --dump-header $HTTP_HEADER "
153 if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
154 _CURL_DUMP
="$(_mktemp)"
155 _ACME_CURL
="$_ACME_CURL --trace-ascii $_CURL_DUMP "
158 if [ "$CA_PATH" ]; then
159 _ACME_CURL
="$_ACME_CURL --capath $CA_PATH "
160 elif [ "$CA_BUNDLE" ]; then
161 _ACME_CURL
="$_ACME_CURL --cacert $CA_BUNDLE "
164 if _contains
"$(curl --help 2>&1)" "--globoff"; then
165 _ACME_CURL
="$_ACME_CURL -g "
169 if [ -z "$_ACME_WGET" ] && _exists
"wget"; then
171 if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
172 _ACME_WGET
="$_ACME_WGET -d "
174 if [ "$CA_PATH" ]; then
175 _ACME_WGET
="$_ACME_WGET --ca-directory=$CA_PATH "
176 elif [ "$CA_BUNDLE" ]; then
177 _ACME_WGET
="$_ACME_WGET --ca-certificate=$CA_BUNDLE "
181 #from wget 1.14: do not skip body on 404 error
182 if [ "$_ACME_WGET" ] && _contains
"$($_ACME_WGET --help 2>&1)" "--content-on-error"; then
183 _ACME_WGET
="$_ACME_WGET --content-on-error "
190 # body url [needbase64] [POST|PUT|DELETE] [ContentType]
196 _postContentType
="$5"
198 if [ -z "$httpmethod" ]; then
202 _debug
"_post_url" "$_post_url"
203 _debug2
"body" "$body"
204 _debug2
"_postContentType" "$_postContentType"
208 if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
210 if [ "$HTTPS_INSECURE" ]; then
211 _CURL
="$_CURL --insecure "
213 if [ "$httpmethod" = "HEAD" ]; then
216 _debug
"_CURL" "$_CURL"
217 if [ "$needbase64" ]; then
219 if [ "$_postContentType" ]; then
220 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type
: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
222 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
225 if [ "$_postContentType" ]; then
226 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type
: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)"
228 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)"
233 if [ "$_postContentType" ]; then
234 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type
: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
236 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
239 if [ "$_postContentType" ]; then
240 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type
: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")"
242 response
="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")"
247 if [ "$_ret" != "0" ]; then
248 _err
"Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
249 if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
250 _err
"Here is the curl dump log:"
251 _err
"$(cat "$_CURL_DUMP")"
254 elif [ "$_ACME_WGET" ]; then
256 if [ "$HTTPS_INSECURE" ]; then
257 _WGET
="$_WGET --no-check-certificate "
259 if [ "$httpmethod" = "HEAD" ]; then
260 _WGET
="$_WGET --read-timeout=3.0 --tries=2 "
262 _debug
"_WGET" "$_WGET"
263 if [ "$needbase64" ]; then
264 if [ "$httpmethod" = "POST" ]; then
265 if [ "$_postContentType" ]; then
266 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type
: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
268 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
271 if [ "$_postContentType" ]; then
272 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type
: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
274 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
278 if [ "$httpmethod" = "POST" ]; then
279 if [ "$_postContentType" ]; then
280 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type
: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
282 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
284 elif [ "$httpmethod" = "HEAD" ]; then
285 if [ "$_postContentType" ]; then
286 response
="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type
: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
288 response
="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
291 if [ "$_postContentType" ]; then
292 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type
: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
294 response
="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
299 if [ "$_ret" = "8" ]; then
301 _debug
"wget returns 8, the server returns a 'Bad request' response, lets process the response later."
303 if [ "$_ret" != "0" ]; then
304 _err
"Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
306 _sed_i
"s/^ *//g" "$HTTP_HEADER"
309 _err
"Neither curl nor wget is found, can not do $httpmethod."
311 _debug
"_ret" "$_ret"
312 printf "%s" "$response"
316 # url getheader timeout
327 if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
329 if [ "$HTTPS_INSECURE" ]; then
330 _CURL
="$_CURL --insecure "
333 _CURL
="$_CURL --connect-timeout $t"
335 _debug
"_CURL" "$_CURL"
336 if [ "$onlyheader" ]; then
337 $_CURL -I --user-agent "$USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url"
339 $_CURL --user-agent "$USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url"
342 if [ "$ret" != "0" ]; then
343 _err
"Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret"
344 if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
345 _err
"Here is the curl dump log:"
346 _err
"$(cat "$_CURL_DUMP")"
349 elif [ "$_ACME_WGET" ]; then
351 if [ "$HTTPS_INSECURE" ]; then
352 _WGET
="$_WGET --no-check-certificate "
355 _WGET
="$_WGET --timeout=$t"
357 _debug
"_WGET" "$_WGET"
358 if [ "$onlyheader" ]; then
359 $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev
/null
"$url" 2>&1 |
sed 's/^[ ]*//g'
361 $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url"
364 if [ "$ret" = "8" ]; then
366 _debug
"wget returns 8, the server returns a 'Bad request' response, lets process the response later."
368 if [ "$ret" != "0" ]; then
369 _err
"Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
373 _err
"Neither curl nor wget is found, can not do GET."
384 if ! tail -n "$1" 2>/dev
/null
; then
390 # stdin output hexstr splited by one space
392 # output: " 61 62 63"
395 od -A n
-v -t x1 |
tr -s " " |
sed 's/ $//' |
tr -d "\r\t\n"
396 elif _exists
hexdump; then
397 _debug3
"using hexdump"
398 hexdump -v -e '/1 ""' -e '/1 " %02x" ""'
399 elif _exists xxd
; then
401 xxd
-ps -c 20 -i |
sed "s/ 0x/ /g" |
tr -d ",\n" |
tr -s " "
403 _debug3
"using _ascii_hex"
411 _hex_str
=$
(_hex_dump
)
412 _debug3
"_url_encode"
413 _debug3
"_hex_str" "$_hex_str"
414 for _hex_code
in $_hex_str; do
416 case "${_hex_code}" in
620 printf '%%%s' "$_hex_code"
626 # Usage: hashalg secret_hex [outputhex]
633 if [ -z "$secret_hex" ]; then
634 _usage
"Usage: _hmac hashalg secret [outputhex]"
638 if [ "$alg" = "sha256" ] ||
[ "$alg" = "sha1" ]; then
639 if [ "$outputhex" ]; then
640 (${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -mac HMAC
-macopt "hexkey:$secret_hex" 2>/dev
/null ||
${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -hmac "$(printf "%s
" "$secret_hex" | _h2b)") | cut
-d = -f 2 |
tr -d ' '
642 ${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -mac HMAC
-macopt "hexkey:$secret_hex" -binary 2>/dev
/null ||
${ACME_OPENSSL_BIN:-openssl} dgst
-"$alg" -hmac "$(printf "%s
" "$secret_hex" | _h2b)" -binary
645 _err
"$alg is not supported yet"
654 _debug2 _is_idn_d
"$_is_idn_d"
655 _idn_temp
=$
(printf "%s" "$_is_idn_d" |
tr -d '0-9' |
tr -d 'a-z' |
tr -d 'A-Z' |
tr -d '*.,-_')
656 _debug2 _idn_temp
"$_idn_temp"
661 # aa.com,bb.com,cc.com
664 if ! _is_idn
"$__idn_d"; then
665 printf "%s" "$__idn_d"
670 if _contains
"$__idn_d" ','; then
672 for f
in $
(echo "$__idn_d" |
tr ',' ' '); do
673 [ -z "$f" ] && continue
674 if [ -z "$_i_first" ]; then
679 idn
--quiet "$f" |
tr -d "\r\n"
682 idn
"$__idn_d" |
tr -d "\r\n"
685 _err
"Please install idn to process IDN names."
690 sed "s/\" *: *\([\"{\[]\)/\":\1/g" |
sed "s/^ *\([^ ]\)/\1/" |
tr -d "\r\n"
697 if [ -z "$filename" ]; then
698 _usage
"Usage:_sed_i options filename"
701 _debug2 options
"$options"
702 if sed -h 2>&1 |
grep "\-i\[SUFFIX]" >/dev
/null
2>&1; then
703 _debug
"Using sed -i"
704 sed -i "$options" "$filename"
706 _debug
"No -i support in sed"
707 text
="$(cat "$filename")"
708 echo "$text" |
sed "$options" >"$filename"
715 if [ "$__INTERACTIVE" ]; then
716 _sleep_c
="$_sleep_sec"
717 while [ "$_sleep_c" -ge "0" ]; do
720 _sleep_c
="$(_math "$_sleep_c" - 1)"
731 if stat
-c '%U:%G' "$1" 2>/dev
/null
; then
736 if stat
-f '%Su:%Sg' "$1" 2>/dev
/null
; then
740 return 1 #error, 'stat' not found
749 date -u "+%Y-%m-%d %H:%M:%S"
754 if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
755 printf '\033[1;31;32m%b\033[0m' "$1"
762 if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
763 printf '\033[1;31;40m%b\033[0m' "$1"
770 [ -z "$LOG_FILE" ] && return
771 _printargs
"$@" >>"$LOG_FILE"
776 if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_INFO" ]; then
777 _syslog
"$SYSLOG_INFO" "$@"
783 _syslog
"$SYSLOG_ERROR" "$@"
785 if [ -z "$NO_TIMESTAMP" ] ||
[ "$NO_TIMESTAMP" = "0" ]; then
786 printf -- "%s" "[$(date)] " >&2
799 _read_conf
"$ACCOUNT_CONF_PATH" "$1"
803 _readaccountconf_mutable
() {
805 _readaccountconf
"SAVED_$_rac_key"