]>
Commit | Line | Data |
---|---|---|
1a8ba4f0 | 1 | #!/bin/bash |
92b88a9e | 2 | |
3f11a215 | 3 | VER=1.0 |
ece42f2f WL |
4 | |
5 | PROJECT_NAME="ProxmoxACME" | |
6 | ||
7 | USER_AGENT="$PROJECT_NAME/$VER" | |
8 | ||
9 | DNS_PLUGIN_PATH="/usr/share/proxmox-acme/dnsapi" | |
bb2e0864 WL |
10 | HTTP_HEADER="$(mktemp)" |
11 | ||
54fd0088 WL |
12 | DEBUG="0" |
13 | ||
92b88a9e | 14 | _base64() { |
bb2e0864 | 15 | openssl base64 -e | tr -d '\r\n' |
92b88a9e WL |
16 | } |
17 | ||
92b88a9e | 18 | _dbase64() { |
bb2e0864 | 19 | openssl base64 -d |
92b88a9e WL |
20 | } |
21 | ||
22 | # Usage: hashalg [outputhex] | |
23 | # Output Base64-encoded digest | |
24 | _digest() { | |
25 | alg="$1" | |
92b88a9e WL |
26 | |
27 | if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ] || [ "$alg" = "md5" ]; then | |
bb2e0864 WL |
28 | if [ "$2" ]; then |
29 | openssl dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' ' | |
92b88a9e | 30 | else |
bb2e0864 | 31 | openssl dgst -"$alg" -binary | _base64 |
92b88a9e | 32 | fi |
92b88a9e | 33 | fi |
92b88a9e WL |
34 | } |
35 | ||
79364a8c SI |
36 | _usage() { |
37 | __red "$@" >&2 | |
38 | printf "\n" >&2 | |
39 | } | |
40 | ||
92b88a9e WL |
41 | _upper_case() { |
42 | # shellcheck disable=SC2018,SC2019 | |
43 | tr 'a-z' 'A-Z' | |
44 | } | |
45 | ||
46 | _lower_case() { | |
47 | # shellcheck disable=SC2018,SC2019 | |
48 | tr 'A-Z' 'a-z' | |
49 | } | |
50 | ||
51 | _startswith() { | |
52 | _str="$1" | |
53 | _sub="$2" | |
54 | echo "$_str" | grep "^$_sub" >/dev/null 2>&1 | |
55 | } | |
56 | ||
57 | _endswith() { | |
58 | _str="$1" | |
59 | _sub="$2" | |
60 | echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1 | |
61 | } | |
62 | ||
63 | _contains() { | |
64 | _str="$1" | |
65 | _sub="$2" | |
66 | echo "$_str" | grep -- "$_sub" >/dev/null 2>&1 | |
67 | } | |
68 | ||
69 | # str index [sep] | |
70 | _getfield() { | |
71 | _str="$1" | |
72 | _findex="$2" | |
73 | _sep="$3" | |
74 | ||
92b88a9e WL |
75 | if [ -z "$_sep" ]; then |
76 | _sep="," | |
77 | fi | |
78 | ||
79 | _ffi="$_findex" | |
80 | while [ "$_ffi" -gt "0" ]; do | |
81 | _fv="$(echo "$_str" | cut -d "$_sep" -f "$_ffi")" | |
82 | if [ "$_fv" ]; then | |
83 | printf -- "%s" "$_fv" | |
84 | return 0 | |
85 | fi | |
86 | _ffi="$(_math "$_ffi" - 1)" | |
87 | done | |
88 | ||
89 | printf -- "%s" "$_str" | |
90 | ||
91 | } | |
92 | ||
93 | _exists() { | |
94 | cmd="$1" | |
92b88a9e | 95 | if eval type type >/dev/null 2>&1; then |
bb2e0864 WL |
96 | type "$cmd" >/dev/null 2>&1 |
97 | else command | |
92b88a9e | 98 | command -v "$cmd" >/dev/null 2>&1 |
92b88a9e WL |
99 | fi |
100 | ret="$?" | |
92b88a9e WL |
101 | return $ret |
102 | } | |
103 | ||
104 | # a + b | |
105 | _math() { | |
106 | _m_opts="$@" | |
107 | printf "%s" "$(($_m_opts))" | |
108 | } | |
109 | ||
110 | _egrep_o() { | |
111 | if ! egrep -o "$1" 2>/dev/null; then | |
112 | sed -n 's/.*\('"$1"'\).*/\1/p' | |
113 | fi | |
114 | } | |
115 | ||
79364a8c SI |
116 | _h2b() { |
117 | if _exists xxd; then | |
118 | if _contains "$(xxd --help 2>&1)" "assumes -c30"; then | |
119 | if xxd -r -p -c 9999 2>/dev/null; then | |
120 | return | |
121 | fi | |
122 | else | |
123 | if xxd -r -p 2>/dev/null; then | |
124 | return | |
125 | fi | |
126 | fi | |
127 | fi | |
128 | ||
129 | hex=$(cat) | |
130 | ic="" | |
131 | jc="" | |
132 | _debug2 _URGLY_PRINTF "$_URGLY_PRINTF" | |
133 | if [ -z "$_URGLY_PRINTF" ]; then | |
134 | if [ "$_ESCAPE_XARGS" ] && _exists xargs; then | |
135 | _debug2 "xargs" | |
136 | echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/g' | xargs printf | |
137 | else | |
138 | for h in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/ \1/g'); do | |
139 | if [ -z "$h" ]; then | |
140 | break | |
141 | fi | |
142 | printf "\x$h%s" | |
143 | done | |
144 | fi | |
145 | else | |
146 | for c in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\)/ \1/g'); do | |
147 | if [ -z "$ic" ]; then | |
148 | ic=$c | |
149 | continue | |
150 | fi | |
151 | jc=$c | |
152 | ic="$(_h_char_2_dec "$ic")" | |
153 | jc="$(_h_char_2_dec "$jc")" | |
154 | printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s" | |
155 | ic="" | |
156 | jc="" | |
157 | done | |
158 | fi | |
159 | ||
160 | } | |
161 | ||
162 | #Usage: keyfile hashalg | |
163 | #Output: Base64-encoded signature value | |
164 | _sign() { | |
165 | keyfile="$1" | |
166 | alg="$2" | |
167 | if [ -z "$alg" ]; then | |
168 | _usage "Usage: _sign keyfile hashalg" | |
169 | return 1 | |
170 | fi | |
171 | ||
172 | _sign_openssl="${ACME_OPENSSL_BIN:-openssl} dgst -sign $keyfile " | |
173 | ||
174 | if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || grep "BEGIN PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then | |
175 | $_sign_openssl -$alg | _base64 | |
176 | elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then | |
177 | if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then | |
178 | _err "Sign failed: $_sign_openssl" | |
179 | _err "Key file: $keyfile" | |
180 | _err "Key content:$(wc -l <"$keyfile") lines" | |
181 | return 1 | |
182 | fi | |
183 | _debug3 "_signedECText" "$_signedECText" | |
184 | _ec_r="$(echo "$_signedECText" | _head_n 2 | _tail_n 1 | cut -d : -f 4 | tr -d "\r\n")" | |
185 | _ec_s="$(echo "$_signedECText" | _head_n 3 | _tail_n 1 | cut -d : -f 4 | tr -d "\r\n")" | |
186 | if [ "$__ECC_KEY_LEN" -eq "256" ]; then | |
187 | while [ "${#_ec_r}" -lt "64" ]; do | |
188 | _ec_r="0${_ec_r}" | |
189 | done | |
190 | while [ "${#_ec_s}" -lt "64" ]; do | |
191 | _ec_s="0${_ec_s}" | |
192 | done | |
193 | fi | |
194 | if [ "$__ECC_KEY_LEN" -eq "384" ]; then | |
195 | while [ "${#_ec_r}" -lt "96" ]; do | |
196 | _ec_r="0${_ec_r}" | |
197 | done | |
198 | while [ "${#_ec_s}" -lt "96" ]; do | |
199 | _ec_s="0${_ec_s}" | |
200 | done | |
201 | fi | |
202 | if [ "$__ECC_KEY_LEN" -eq "512" ]; then | |
203 | while [ "${#_ec_r}" -lt "132" ]; do | |
204 | _ec_r="0${_ec_r}" | |
205 | done | |
206 | while [ "${#_ec_s}" -lt "132" ]; do | |
207 | _ec_s="0${_ec_s}" | |
208 | done | |
209 | fi | |
210 | _debug3 "_ec_r" "$_ec_r" | |
211 | _debug3 "_ec_s" "$_ec_s" | |
212 | printf "%s" "$_ec_r$_ec_s" | _h2b | _base64 | |
213 | else | |
214 | _err "Unknown key file format." | |
215 | return 1 | |
216 | fi | |
217 | ||
218 | } | |
219 | ||
220 | #dummy function because proxmox-acme does not call inithttp | |
221 | _resethttp() { | |
222 | : | |
223 | } | |
224 | ||
51b0ba75 SI |
225 | _HTTP_MAX_RETRY=8 |
226 | ||
92b88a9e WL |
227 | # body url [needbase64] [POST|PUT|DELETE] [ContentType] |
228 | _post() { | |
229 | body="$1" | |
230 | _post_url="$2" | |
231 | needbase64="$3" | |
232 | httpmethod="$4" | |
233 | _postContentType="$5" | |
51b0ba75 SI |
234 | _sleep_retry_sec=1 |
235 | _http_retry_times=0 | |
236 | _hcode=0 | |
237 | while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do | |
238 | [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] | |
239 | _lastHCode="$?" | |
240 | _debug "Retrying post" | |
241 | _post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode" | |
242 | _hcode="$?" | |
243 | _debug _hcode "$_hcode" | |
244 | if [ "$_hcode" = "0" ]; then | |
245 | break | |
246 | fi | |
247 | _http_retry_times=$(_math $_http_retry_times + 1) | |
248 | _sleep $_sleep_retry_sec | |
249 | done | |
250 | return $_hcode | |
251 | } | |
252 | ||
253 | # body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError] | |
254 | _post_impl() { | |
255 | body="$1" | |
256 | _post_url="$2" | |
257 | needbase64="$3" | |
258 | httpmethod="$4" | |
259 | _postContentType="$5" | |
260 | displayError="$6" | |
92b88a9e WL |
261 | |
262 | if [ -z "$httpmethod" ]; then | |
263 | httpmethod="POST" | |
264 | fi | |
92b88a9e | 265 | |
bb2e0864 WL |
266 | _CURL="curl -L --silent --dump-header $HTTP_HEADER -g " |
267 | if [ "$HTTPS_INSECURE" ]; then | |
268 | _CURL="$_CURL --insecure " | |
269 | fi | |
270 | if [ "$httpmethod" = "HEAD" ]; then | |
271 | _CURL="$_CURL -I " | |
272 | fi | |
273 | if [ "$needbase64" ]; then | |
274 | if [ "$body" ]; then | |
275 | if [ "$_postContentType" ]; then | |
276 | 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)" | |
92b88a9e | 277 | else |
bb2e0864 | 278 | response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)" |
92b88a9e WL |
279 | fi |
280 | else | |
bb2e0864 WL |
281 | if [ "$_postContentType" ]; then |
282 | 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)" | |
92b88a9e | 283 | else |
bb2e0864 | 284 | response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)" |
92b88a9e WL |
285 | fi |
286 | fi | |
bb2e0864 WL |
287 | else |
288 | if [ "$body" ]; then | |
289 | if [ "$_postContentType" ]; then | |
290 | 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")" | |
92b88a9e | 291 | else |
bb2e0864 | 292 | response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")" |
92b88a9e WL |
293 | fi |
294 | else | |
bb2e0864 WL |
295 | if [ "$_postContentType" ]; then |
296 | response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")" | |
92b88a9e | 297 | else |
bb2e0864 | 298 | response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")" |
92b88a9e WL |
299 | fi |
300 | fi | |
92b88a9e | 301 | fi |
bb2e0864 WL |
302 | _ret="$?" |
303 | if [ "$_ret" != "0" ]; then | |
51b0ba75 SI |
304 | if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then |
305 | _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" | |
306 | fi | |
bb2e0864 | 307 | fi |
92b88a9e WL |
308 | printf "%s" "$response" |
309 | return $_ret | |
310 | } | |
311 | ||
312 | # url getheader timeout | |
313 | _get() { | |
92b88a9e WL |
314 | url="$1" |
315 | onlyheader="$2" | |
316 | t="$3" | |
51b0ba75 SI |
317 | _sleep_retry_sec=1 |
318 | _http_retry_times=0 | |
319 | _hcode=0 | |
320 | while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do | |
321 | [ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ] | |
322 | _lastHCode="$?" | |
323 | _debug "Retrying GET" | |
324 | _get_impl "$url" "$onlyheader" "$t" "$_lastHCode" | |
325 | _hcode="$?" | |
326 | _debug _hcode "$_hcode" | |
327 | if [ "$_hcode" = "0" ]; then | |
328 | break | |
329 | fi | |
330 | _http_retry_times=$(_math $_http_retry_times + 1) | |
331 | _sleep $_sleep_retry_sec | |
332 | done | |
333 | return $_hcode | |
334 | } | |
335 | ||
336 | # url getheader timeout displayError | |
337 | _get_impl() { | |
338 | url="$1" | |
339 | onlyheader="$2" | |
340 | t="$3" | |
341 | displayError="$4" | |
92b88a9e | 342 | |
bb2e0864 WL |
343 | _CURL="curl -L --silent --dump-header $HTTP_HEADER -g " |
344 | if [ "$HTTPS_INSECURE" ]; then | |
345 | _CURL="$_CURL --insecure " | |
346 | fi | |
347 | if [ "$t" ]; then | |
348 | _CURL="$_CURL --connect-timeout $t" | |
349 | fi | |
350 | if [ "$onlyheader" ]; then | |
351 | $_CURL -I --user-agent "USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url" | |
92b88a9e | 352 | else |
bb2e0864 WL |
353 | $_CURL --user-agent "USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url" |
354 | fi | |
355 | ret=$? | |
356 | if [ "$ret" != "0" ]; then | |
51b0ba75 SI |
357 | if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then |
358 | _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" | |
359 | fi | |
92b88a9e | 360 | fi |
92b88a9e WL |
361 | return $ret |
362 | } | |
363 | ||
364 | _head_n() { | |
365 | head -n "$1" | |
366 | } | |
367 | ||
368 | _tail_n() { | |
bb2e0864 | 369 | tail -n "$1" |
92b88a9e WL |
370 | } |
371 | ||
372 | # stdin output hexstr splited by one space | |
373 | # input:"abc" | |
374 | # output: " 61 62 63" | |
375 | _hex_dump() { | |
bb2e0864 | 376 | od -A n -v -t x1 | tr -s " " | sed 's/ $//' | tr -d "\r\t\n" |
92b88a9e WL |
377 | } |
378 | ||
379 | # stdin stdout | |
380 | _url_encode() { | |
381 | _hex_str=$(_hex_dump) | |
92b88a9e WL |
382 | for _hex_code in $_hex_str; do |
383 | #upper case | |
384 | case "${_hex_code}" in | |
385 | "41") | |
386 | printf "%s" "A" | |
387 | ;; | |
388 | "42") | |
389 | printf "%s" "B" | |
390 | ;; | |
391 | "43") | |
392 | printf "%s" "C" | |
393 | ;; | |
394 | "44") | |
395 | printf "%s" "D" | |
396 | ;; | |
397 | "45") | |
398 | printf "%s" "E" | |
399 | ;; | |
400 | "46") | |
401 | printf "%s" "F" | |
402 | ;; | |
403 | "47") | |
404 | printf "%s" "G" | |
405 | ;; | |
406 | "48") | |
407 | printf "%s" "H" | |
408 | ;; | |
409 | "49") | |
410 | printf "%s" "I" | |
411 | ;; | |
412 | "4a") | |
413 | printf "%s" "J" | |
414 | ;; | |
415 | "4b") | |
416 | printf "%s" "K" | |
417 | ;; | |
418 | "4c") | |
419 | printf "%s" "L" | |
420 | ;; | |
421 | "4d") | |
422 | printf "%s" "M" | |
423 | ;; | |
424 | "4e") | |
425 | printf "%s" "N" | |
426 | ;; | |
427 | "4f") | |
428 | printf "%s" "O" | |
429 | ;; | |
430 | "50") | |
431 | printf "%s" "P" | |
432 | ;; | |
433 | "51") | |
434 | printf "%s" "Q" | |
435 | ;; | |
436 | "52") | |
437 | printf "%s" "R" | |
438 | ;; | |
439 | "53") | |
440 | printf "%s" "S" | |
441 | ;; | |
442 | "54") | |
443 | printf "%s" "T" | |
444 | ;; | |
445 | "55") | |
446 | printf "%s" "U" | |
447 | ;; | |
448 | "56") | |
449 | printf "%s" "V" | |
450 | ;; | |
451 | "57") | |
452 | printf "%s" "W" | |
453 | ;; | |
454 | "58") | |
455 | printf "%s" "X" | |
456 | ;; | |
457 | "59") | |
458 | printf "%s" "Y" | |
459 | ;; | |
460 | "5a") | |
461 | printf "%s" "Z" | |
462 | ;; | |
463 | ||
464 | #lower case | |
465 | "61") | |
466 | printf "%s" "a" | |
467 | ;; | |
468 | "62") | |
469 | printf "%s" "b" | |
470 | ;; | |
471 | "63") | |
472 | printf "%s" "c" | |
473 | ;; | |
474 | "64") | |
475 | printf "%s" "d" | |
476 | ;; | |
477 | "65") | |
478 | printf "%s" "e" | |
479 | ;; | |
480 | "66") | |
481 | printf "%s" "f" | |
482 | ;; | |
483 | "67") | |
484 | printf "%s" "g" | |
485 | ;; | |
486 | "68") | |
487 | printf "%s" "h" | |
488 | ;; | |
489 | "69") | |
490 | printf "%s" "i" | |
491 | ;; | |
492 | "6a") | |
493 | printf "%s" "j" | |
494 | ;; | |
495 | "6b") | |
496 | printf "%s" "k" | |
497 | ;; | |
498 | "6c") | |
499 | printf "%s" "l" | |
500 | ;; | |
501 | "6d") | |
502 | printf "%s" "m" | |
503 | ;; | |
504 | "6e") | |
505 | printf "%s" "n" | |
506 | ;; | |
507 | "6f") | |
508 | printf "%s" "o" | |
509 | ;; | |
510 | "70") | |
511 | printf "%s" "p" | |
512 | ;; | |
513 | "71") | |
514 | printf "%s" "q" | |
515 | ;; | |
516 | "72") | |
517 | printf "%s" "r" | |
518 | ;; | |
519 | "73") | |
520 | printf "%s" "s" | |
521 | ;; | |
522 | "74") | |
523 | printf "%s" "t" | |
524 | ;; | |
525 | "75") | |
526 | printf "%s" "u" | |
527 | ;; | |
528 | "76") | |
529 | printf "%s" "v" | |
530 | ;; | |
531 | "77") | |
532 | printf "%s" "w" | |
533 | ;; | |
534 | "78") | |
535 | printf "%s" "x" | |
536 | ;; | |
537 | "79") | |
538 | printf "%s" "y" | |
539 | ;; | |
540 | "7a") | |
541 | printf "%s" "z" | |
542 | ;; | |
bb2e0864 | 543 | |
92b88a9e WL |
544 | #numbers |
545 | "30") | |
546 | printf "%s" "0" | |
547 | ;; | |
548 | "31") | |
549 | printf "%s" "1" | |
550 | ;; | |
551 | "32") | |
552 | printf "%s" "2" | |
553 | ;; | |
554 | "33") | |
555 | printf "%s" "3" | |
556 | ;; | |
557 | "34") | |
558 | printf "%s" "4" | |
559 | ;; | |
560 | "35") | |
561 | printf "%s" "5" | |
562 | ;; | |
563 | "36") | |
564 | printf "%s" "6" | |
565 | ;; | |
566 | "37") | |
567 | printf "%s" "7" | |
568 | ;; | |
569 | "38") | |
570 | printf "%s" "8" | |
571 | ;; | |
572 | "39") | |
573 | printf "%s" "9" | |
574 | ;; | |
575 | "2d") | |
576 | printf "%s" "-" | |
577 | ;; | |
578 | "5f") | |
579 | printf "%s" "_" | |
580 | ;; | |
581 | "2e") | |
582 | printf "%s" "." | |
583 | ;; | |
584 | "7e") | |
585 | printf "%s" "~" | |
586 | ;; | |
bb2e0864 | 587 | |
92b88a9e WL |
588 | #other hex |
589 | *) | |
590 | printf '%%%s' "$_hex_code" | |
591 | ;; | |
592 | esac | |
593 | done | |
594 | } | |
595 | ||
596 | # Usage: hashalg secret_hex [outputhex] | |
597 | # Output binary hmac | |
598 | _hmac() { | |
599 | alg="$1" | |
600 | secret_hex="$2" | |
601 | outputhex="$3" | |
602 | ||
92b88a9e WL |
603 | if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ]; then |
604 | if [ "$outputhex" ]; then | |
bb2e0864 | 605 | (openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" 2>/dev/null || openssl dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)") | cut -d = -f 2 | tr -d ' ' |
92b88a9e | 606 | else |
bb2e0864 | 607 | openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary 2>/dev/null || openssl dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)" -binary |
92b88a9e | 608 | fi |
92b88a9e | 609 | fi |
92b88a9e WL |
610 | } |
611 | ||
612 | # domain | |
613 | _is_idn() { | |
614 | _is_idn_d="$1" | |
92b88a9e | 615 | _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_') |
92b88a9e WL |
616 | [ "$_idn_temp" ] |
617 | } | |
618 | ||
619 | # aa.com | |
92b88a9e WL |
620 | _idn() { |
621 | __idn_d="$1" | |
622 | if ! _is_idn "$__idn_d"; then | |
623 | printf "%s" "$__idn_d" | |
624 | return 0 | |
625 | fi | |
626 | ||
627 | if _exists idn; then | |
bb2e0864 | 628 | idn "$__idn_d" | tr -d "\r\n" |
92b88a9e WL |
629 | else |
630 | _err "Please install idn to process IDN names." | |
631 | fi | |
632 | } | |
633 | ||
634 | _normalizeJson() { | |
635 | sed "s/\" *: *\([\"{\[]\)/\":\1/g" | sed "s/^ *\([^ ]\)/\1/" | tr -d "\r\n" | |
636 | } | |
637 | ||
638 | # options file | |
639 | _sed_i() { | |
bb2e0864 | 640 | sed -i "$1" "$2" |
92b88a9e WL |
641 | } |
642 | ||
643 | # sleep sec | |
644 | _sleep() { | |
bb2e0864 | 645 | sleep "$1" |
92b88a9e WL |
646 | } |
647 | ||
648 | _stat() { | |
bb2e0864 | 649 | stat -c '%U:%G' "$1" 2>/dev/null |
92b88a9e WL |
650 | } |
651 | ||
92b88a9e WL |
652 | _time() { |
653 | date -u "+%s" | |
654 | } | |
655 | ||
656 | _utc_date() { | |
657 | date -u "+%Y-%m-%d %H:%M:%S" | |
658 | } | |
659 | ||
660 | # stubbed/aliased: | |
661 | __green() { | |
92b88a9e WL |
662 | printf -- "%b" "$1" |
663 | } | |
664 | ||
665 | __red() { | |
92b88a9e WL |
666 | printf -- "%b" "$1" |
667 | } | |
668 | ||
669 | _log() { | |
b0d717c7 | 670 | return 0 |
92b88a9e WL |
671 | } |
672 | ||
673 | _info() { | |
bb2e0864 WL |
674 | printf -- "%s" "[$(date)] " >&1 |
675 | echo "$1" | |
92b88a9e WL |
676 | } |
677 | ||
678 | _err() { | |
bb2e0864 | 679 | printf -- "%s" "[$(date)] " >&2 |
92b88a9e WL |
680 | if [ -z "$2" ]; then |
681 | __red "$1" >&2 | |
682 | else | |
683 | __red "$1='$2'" >&2 | |
684 | fi | |
685 | printf "\n" >&2 | |
686 | return 1 | |
687 | } | |
688 | ||
689 | # key | |
690 | _readaccountconf() { | |
1a8ba4f0 | 691 | echo "${!1}" |
92b88a9e WL |
692 | } |
693 | ||
694 | # key | |
695 | _readaccountconf_mutable() { | |
bb2e0864 WL |
696 | _readaccountconf "$1" |
697 | } | |
698 | ||
699 | # no-ops: | |
700 | _clearaccountconf() { | |
b0d717c7 | 701 | return 0 |
bb2e0864 WL |
702 | } |
703 | ||
704 | _cleardomainconf() { | |
b0d717c7 | 705 | return 0 |
bb2e0864 WL |
706 | } |
707 | ||
708 | _debug() { | |
54fd0088 WL |
709 | if [[ $DEBUG -eq 0 ]]; then |
710 | return | |
711 | fi | |
712 | printf -- "%s" "[$(date)] " >&1 | |
713 | echo "$1 $2" | |
bb2e0864 WL |
714 | } |
715 | ||
716 | _debug2() { | |
54fd0088 | 717 | _debug $1 $2 |
bb2e0864 WL |
718 | } |
719 | ||
720 | _debug3() { | |
54fd0088 | 721 | _debug $1 $2 |
bb2e0864 WL |
722 | } |
723 | ||
724 | _secure_debug() { | |
54fd0088 | 725 | _debug $1 $2 |
92b88a9e | 726 | } |
bb2e0864 WL |
727 | |
728 | _secure_debug2() { | |
54fd0088 | 729 | _debug $1 $2 |
bb2e0864 WL |
730 | } |
731 | ||
732 | _secure_debug3() { | |
54fd0088 | 733 | _debug $1 $2 |
bb2e0864 WL |
734 | } |
735 | ||
736 | _saveaccountconf() { | |
b0d717c7 | 737 | return 0 |
bb2e0864 WL |
738 | } |
739 | ||
740 | _saveaccountconf_mutable() { | |
b0d717c7 | 741 | return 0 |
bb2e0864 WL |
742 | } |
743 | ||
744 | _save_conf() { | |
b0d717c7 | 745 | return 0 |
bb2e0864 WL |
746 | } |
747 | ||
748 | _savedomainconf() { | |
b0d717c7 | 749 | return 0 |
bb2e0864 WL |
750 | } |
751 | ||
752 | _source_plugin_config() { | |
b0d717c7 | 753 | return 0 |
bb2e0864 WL |
754 | } |
755 | ||
216d4f1d WL |
756 | # Proxmox implementation to inject the DNSAPI variables |
757 | _load_plugin_config() { | |
13bc64ea FG |
758 | while IFS= read -r line; do |
759 | ADDR=(${line/=/ }) | |
216d4f1d WL |
760 | key="${ADDR[0]}" |
761 | value="${ADDR[1]}" | |
762 | ||
216d4f1d | 763 | # acme.sh uses eval insted of export |
13bc64ea FG |
764 | if [ -n "$key" ]; then |
765 | export "$key"="$value" | |
766 | fi | |
216d4f1d WL |
767 | done |
768 | } | |
ece42f2f WL |
769 | |
770 | # call setup and teardown direct | |
771 | # the parameter must be set in the correct order | |
772 | # $1 <String> DNS Plugin name | |
773 | # $2 <String> Fully Qualified Domain Name | |
774 | # $3 <String> value for TXT record | |
775 | # $4 <String> DNS plugin auth and config parameter separated by "," | |
54fd0088 | 776 | # $5 <Integer> 0 is off, and the default all others are on. |
ece42f2f WL |
777 | |
778 | setup() { | |
779 | dns_plugin="dns_$1" | |
780 | dns_plugin_path="${DNS_PLUGIN_PATH}/${dns_plugin}.sh" | |
781 | fqdn="_acme-challenge.$2" | |
13bc64ea FG |
782 | DEBUG=$3 |
783 | IFS= read -r txtvalue | |
ece42f2f WL |
784 | plugin_conf_string=$4 |
785 | ||
13bc64ea | 786 | _load_plugin_config |
ece42f2f WL |
787 | |
788 | if ! . "$dns_plugin_path"; then | |
789 | _err "Load file $dns_plugin error." | |
790 | return 1 | |
791 | fi | |
792 | ||
793 | addcommand="${dns_plugin}_add" | |
794 | if ! _exists "$addcommand"; then | |
795 | _err "It seems that your api file is not correct, it must have a function named: $addcommand" | |
796 | return 1 | |
797 | fi | |
798 | ||
799 | if ! $addcommand "$fqdn" "$txtvalue"; then | |
800 | _err "Error add txt for domain:$fulldomain" | |
801 | return 1 | |
802 | fi | |
803 | } | |
804 | ||
805 | teardown() { | |
806 | dns_plugin="dns_$1" | |
807 | dns_plugin_path="${DNS_PLUGIN_PATH}/${dns_plugin}.sh" | |
808 | fqdn="_acme-challenge.$2" | |
13bc64ea FG |
809 | DEBUG=$3 |
810 | IFS= read -r txtvalue | |
ece42f2f | 811 | |
13bc64ea | 812 | _load_plugin_config |
ece42f2f WL |
813 | |
814 | if ! . "$dns_plugin_path"; then | |
815 | _err "Load file $dns_plugin error." | |
816 | return 1 | |
817 | fi | |
818 | ||
819 | rmcommand="${dns_plugin}_rm" | |
820 | if ! _exists "$rmcommand"; then | |
821 | _err "It seems that your api file is not correct, it must have a function named: $rmcommand" | |
822 | return 1 | |
823 | fi | |
824 | ||
825 | if ! $rmcommand "$fqdn" "$txtvalue"; then | |
826 | _err "Error add txt for domain:$fulldomain" | |
827 | return 1 | |
828 | fi | |
829 | } | |
830 | ||
831 | "$@" |