From 8881a9f40e1ae697ec0004670cda032c5a17f1a1 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:46:18 +0200 Subject: [PATCH 001/687] Add BookMyName API support --- dnsapi/dns_bookmyname.sh | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 dnsapi/dns_bookmyname.sh diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh new file mode 100644 index 00000000..188d93cb --- /dev/null +++ b/dnsapi/dns_bookmyname.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env sh + +#Here is a sample custom api script. +#This file name is "dns_bookmyname.sh" +#So, here must be a method dns_bookmyname_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: Neilpang +#Report Bugs here: https://github.com/acmesh-official/acme.sh +# +######## Public functions ##################### + +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + + +# BMN urls: +# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' +# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' + +# Output: +#good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX +#good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX + +# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised. + +# Usage: +# export BOOKMYNAME_USERNAME="ABCDE-FREE" +# export BOOKMYNAME_PASSWORD="MyPassword" +# /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld + + +#Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_bookmyname_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using bookmyname" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" + BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" + + if [ -z "$BOOKMYNAME_USERNAME" ] || [ -z "$BOOKMYNAME_PASSWORD" ]; then + BOOKMYNAME_USERNAME="" + BOOKMYNAME_PASSWORD="" + _err "You didn't specify BookMyName username and password yet." + _err "Please specify them and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME" + _saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD" + + + uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" + data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}" + result="$(_get "${uri}${data}")" + _debug "Result: $result" + + if ! _startswith "$result" 'good: update done, cid '; then + _err "Can't add $fulldomain" + return 1 + fi + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_bookmyname_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using bookmyname" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" + BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" + + + uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" + data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}" + result="$(_get "${uri}${data}")" + _debug "Result: $result" + + if ! _startswith "$result" 'good: remove done 1, cid '; then + _info "Can't remove $fulldomain" + fi + +} + +#################### Private functions below ################################## From 4ab5456a984eeafed71a6f56d1dda2830780c446 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:49:00 +0200 Subject: [PATCH 002/687] keep shfmt happy --- dnsapi/dns_bookmyname.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 188d93cb..99b3b680 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -13,7 +13,6 @@ # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - # BMN urls: # https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' # https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' @@ -29,7 +28,6 @@ # export BOOKMYNAME_PASSWORD="MyPassword" # /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld - #Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_bookmyname_add() { fulldomain=$1 @@ -53,7 +51,6 @@ dns_bookmyname_add() { _saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME" _saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD" - uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}" result="$(_get "${uri}${data}")" @@ -78,7 +75,6 @@ dns_bookmyname_rm() { BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}" BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}" - uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/" data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}" result="$(_get "${uri}${data}")" From 7eea866869031a7a02aea7ada5c27edc37470458 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:57:52 +0200 Subject: [PATCH 003/687] BMN -> BookMyName --- dnsapi/dns_bookmyname.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 99b3b680..7acdea02 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -21,7 +21,7 @@ #good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX #good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX -# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised. +# Be careful, BookMyName DNS servers can be slow to pick up changes; using dnssleep is thus advised. # Usage: # export BOOKMYNAME_USERNAME="ABCDE-FREE" From 4a60292f8284bc74c54d7f376bac70b2ded6ecd9 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Oct 2020 22:33:21 +0800 Subject: [PATCH 004/687] update freebsd --- .github/workflows/DNS.yml | 3 ++- .github/workflows/LetsEncrypt.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 976aff56..b06db229 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -183,10 +183,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl + usesh: true run: | if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} diff --git a/.github/workflows/LetsEncrypt.yml b/.github/workflows/LetsEncrypt.yml index ba5e933d..d71f3ac1 100644 --- a/.github/workflows/LetsEncrypt.yml +++ b/.github/workflows/LetsEncrypt.yml @@ -106,10 +106,11 @@ jobs: - uses: actions/checkout@v2 - name: Clone acmetest run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0.0.4 + - uses: vmactions/freebsd-vm@v0.0.5 with: envs: 'NGROK_TOKEN TEST_LOCAL' prepare: pkg install -y socat curl + usesh: true run: | cd ../acmetest && ./letest.sh From d76fb566a258ad1bdefe0d7629493ca85fbcf51d Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Sat, 10 Oct 2020 11:02:47 +0200 Subject: [PATCH 005/687] no private functions --- dnsapi/dns_bookmyname.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 7acdea02..79e6b14d 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -85,5 +85,3 @@ dns_bookmyname_rm() { fi } - -#################### Private functions below ################################## From b71a088da73f4ecc3a4d3e4a79de0e838f532e5e Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Sat, 10 Oct 2020 11:46:32 +0200 Subject: [PATCH 006/687] Revert "no private functions" This reverts commit d76fb566a258ad1bdefe0d7629493ca85fbcf51d. --- dnsapi/dns_bookmyname.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 79e6b14d..7acdea02 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -85,3 +85,5 @@ dns_bookmyname_rm() { fi } + +#################### Private functions below ################################## From 0781e8cf12f09fad71d0d63ce59c49c701b35d50 Mon Sep 17 00:00:00 2001 From: Marcel Waldvogel Date: Mon, 12 Oct 2020 13:52:57 +0200 Subject: [PATCH 007/687] Use random hour for cron job The hour for the cron job isn't really random (as is the minute), but assuming acme.sh installation times are not correlated, neither will be the resulting cron start times. --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 3be3849d..eb8aca49 100755 --- a/acme.sh +++ b/acme.sh @@ -5590,6 +5590,7 @@ installcronjob() { fi _t=$(_time) random_minute=$(_math $_t % 60) + random_hour=$(_math $_t / 60 % 24) if ! _exists "$_CRONTAB" && _exists "fcrontab"; then _CRONTAB="fcrontab" @@ -5616,12 +5617,12 @@ installcronjob() { if _exists uname && uname -a | grep SunOS >/dev/null; then $_CRONTAB -l | { cat - echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | $_CRONTAB -- else $_CRONTAB -l | { cat - echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | $_CRONTAB - fi fi From 92dbe6cdf8eb7d3b07b84876db79032c1d41f9c6 Mon Sep 17 00:00:00 2001 From: Marcel Waldvogel Date: Mon, 12 Oct 2020 14:20:40 +0200 Subject: [PATCH 008/687] Simplify and clarify SunOS crontab differences --- acme.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index eb8aca49..2ea5ccd7 100755 --- a/acme.sh +++ b/acme.sh @@ -5615,16 +5615,14 @@ installcronjob() { _info "Installing cron job" if ! $_CRONTAB -l | grep "$PROJECT_ENTRY --cron"; then if _exists uname && uname -a | grep SunOS >/dev/null; then - $_CRONTAB -l | { - cat - echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" - } | $_CRONTAB -- + _CRONTAB_STDIN="$_CRONTAB --" else - $_CRONTAB -l | { - cat - echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" - } | $_CRONTAB - + _CRONTAB_STDIN="$_CRONTAB -" fi + $_CRONTAB -l | { + cat + echo "$random_minute $random_hour * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" + } | $_CRONTAB_STDIN fi if [ "$?" != "0" ]; then _err "Install cron job failed. You need to manually renew your certs." From 20d23fcb92bcc58360089b8e0f3208c8291602aa Mon Sep 17 00:00:00 2001 From: fradev Date: Wed, 25 Aug 2021 16:55:36 +0200 Subject: [PATCH 009/687] Update ssh.sh Added scp mode for copy the certs --- deploy/ssh.sh | 229 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 201 insertions(+), 28 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 18de4aa6..b4a8140e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -23,6 +23,8 @@ # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value +# export DEPLOY_SSH_USE_SCP="" yes or no , default to no +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -T -q " # ######## Public functions ##################### @@ -73,6 +75,25 @@ ssh_deploy() { Le_Deploy_ssh_cmd="ssh -T" fi + # USE_SCP is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + Le_Deploy_ssh_use_scp="yes" + _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then + Le_Deploy_ssh_use_scp="" + _cleardomainconf Le_Deploy_ssh_use_scp + fi + + # SCP_CMD is optional. If not provided then use scp + if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then + Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" + _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then + Le_Deploy_ssh_scp_cmd="scp -T" + fi + + # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" @@ -99,6 +120,26 @@ ssh_deploy() { _cleardomainconf Le_Deploy_ssh_multi_call fi + # USE_SCP is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + Le_Deploy_ssh_use_scp="yes" + _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + Le_Deploy_ssh_multi_call="yes" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then + Le_Deploy_ssh_use_scp="" + _cleardomainconf Le_Deploy_ssh_use_scp + fi + + # SCP_CMD is optional. If not provided then use scp + if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then + Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" + _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then + Le_Deploy_ssh_scp_cmd="scp -T -q " + fi + _deploy_ssh_servers=$Le_Deploy_ssh_server for Le_Deploy_ssh_server in $_deploy_ssh_servers; do _ssh_deploy @@ -110,8 +151,16 @@ _ssh_deploy() { _cmdstr="" _backupprefix="" _backupdir="" + _local_cert_file="" + _local_ca_file="" + _local_full_file="" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + _info "Using scp as alternate method for copying files. Multicall Mode is implicit" + Le_Deploy_ssh_multi_call="yes" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + fi if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" else @@ -149,15 +198,30 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" - _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + + + # copy new key into file. + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + # scp the file + if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then + return $_err_code + fi + else + _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" + _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -172,18 +236,40 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_cert_file=$(_mktemp) + cat $_ckey > $_local_cert_file + cat $_ccert >> $_local_cert_file elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" - _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_cert_file ; then + if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" + _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -199,18 +285,47 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_ca_file=$(_mktemp) + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then + cat $_ckey >> $_local_ca_file + fi + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + cat $_ccert >> $_local_ca_file + fi + + cat $_cca >> $_local_ca_file + elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" - _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_ca_file ; then + if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" + _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi @@ -227,20 +342,63 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then # if filename is same as previous file then append. _pipe=">>" + _local_full_file=$(_mktemp) + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then + cat $_ckey >> $_local_full_file + fi + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then + cat $_ccert >> $_local_full_file + fi + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + cat $_cca >> $_local_full_file + fi + cat $_cfullchain >> $_local_full_file + elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" - _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + + if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if -n $_local_full_file ; then + if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then + return $_err_code + fi + else + if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then + return $_err_code + fi + fi + else + # copy new certificate into file. + _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" + _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" fi - _cmdstr="" fi fi + # cleanup local files if any + + if [ -n "$_local_cert_file" ]; then + rm $_local_cert_file > /dev/null 1>&2 + fi + if [ -n "$_local_ca_file" ]; then + rm $_local_ca_file > /dev/null 1>&2 + fi + if [ -n "$_local_full_file" ]; then + rm $_local_full_file > /dev/null 1>&2 + fi + # REMOTE_CMD is optional. # If provided then this command will be executed on remote host. @@ -265,6 +423,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d return $_err_code fi fi + # cleanup in case all is ok return 0 } @@ -284,3 +443,17 @@ _ssh_remote_cmd() { return $_err_code } + +# cmd scp +_scp_remote_cmd() { + _secure_debug "Remote scp source $1 and destination $2 using : $Le_Deploy_ssh_scp_cmd" + _info "Submitting secure copy command : $Le_Deploy_ssh_scp_cmd" + $Le_Deploy_ssh_scp_cmd "$1" "$Le_Deploy_ssh_user"@"$Le_Deploy_ssh_server":"$2" + _err_code="$?" + + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from scp" + fi + + return $_err_code +} From 613475ac264bf9cf48681bd11f72b4d2aa341e54 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:08:06 +0200 Subject: [PATCH 010/687] Update ssh.sh --- deploy/ssh.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b4a8140e..3424055f 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -237,8 +237,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_cert_file=$(_mktemp) - cat $_ckey > $_local_cert_file - cat $_ccert >> $_local_cert_file + cat "$_ckey" > "$_local_cert_file" + cat "$_ccert" >> "$_local_cert_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" @@ -344,15 +344,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _pipe=">>" _local_full_file=$(_mktemp) if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then - cat $_ckey >> $_local_full_file + cat "$_ckey" >> "$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat $_ccert >> $_local_full_file + cat "$_ccert" >> "$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat $_cca >> $_local_full_file + cat "$_cca" >> "$_local_full_file" fi - cat $_cfullchain >> $_local_full_file + cat "$_cfullchain" >> "$_local_full_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -390,13 +390,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # cleanup local files if any if [ -n "$_local_cert_file" ]; then - rm $_local_cert_file > /dev/null 1>&2 + rm "$_local_cert_file" > /dev/null 1>&2 fi if [ -n "$_local_ca_file" ]; then - rm $_local_ca_file > /dev/null 1>&2 + rm "$_local_ca_file" > /dev/null 1>&2 fi if [ -n "$_local_full_file" ]; then - rm $_local_full_file > /dev/null 1>&2 + rm "$_local_full_file" > /dev/null 1>&2 fi From 4cda54774aeaae0f58352cff18dc243a69bdb9e9 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:17:03 +0200 Subject: [PATCH 011/687] Update ssh.sh SC2086 and SC2215 --- deploy/ssh.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 3424055f..8b91a055 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -251,7 +251,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_cert_file ; then + if [ -n "$_local_cert_file" ]; then if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then return $_err_code fi @@ -287,13 +287,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _pipe=">>" _local_ca_file=$(_mktemp) if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then - cat $_ckey >> $_local_ca_file + cat "$_ckey" >> "$_local_ca_file" fi if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat $_ccert >> $_local_ca_file + cat "$_ccert" >> "$_local_ca_file" fi - cat $_cca >> $_local_ca_file + cat "$_cca" >> "$_local_ca_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -307,7 +307,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_ca_file ; then + if [ -n "$_local_ca_file" ]; then if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then return $_err_code fi @@ -366,7 +366,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if -n $_local_full_file ; then + if [ -n "$_local_full_file" ] ; then if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then return $_err_code fi From 08d60fcbf26172a3277a8785b9e161b8d1aa6c23 Mon Sep 17 00:00:00 2001 From: fradev Date: Mon, 30 Aug 2021 11:32:07 +0200 Subject: [PATCH 012/687] Update ssh.sh shfmt formatting --- deploy/ssh.sh | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 8b91a055..6039eefb 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -93,7 +93,6 @@ ssh_deploy() { Le_Deploy_ssh_scp_cmd="scp -T" fi - # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" @@ -206,12 +205,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # copy new key into file. if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then # scp the file if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then - return $_err_code + return $_err_code fi else _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" @@ -237,8 +235,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_cert_file=$(_mktemp) - cat "$_ckey" > "$_local_cert_file" - cat "$_ccert" >> "$_local_cert_file" + cat "$_ckey" >"$_local_cert_file" + cat "$_ccert" >>"$_local_cert_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" @@ -253,11 +251,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then if [ -n "$_local_cert_file" ]; then if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then - return $_err_code + return $_err_code fi fi else @@ -286,14 +284,14 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_ca_file=$(_mktemp) - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ; then - cat "$_ckey" >> "$_local_ca_file" + if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ]; then + cat "$_ckey" >>"$_local_ca_file" fi if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >> "$_local_ca_file" + cat "$_ccert" >>"$_local_ca_file" fi - cat "$_cca" >> "$_local_ca_file" + cat "$_cca" >>"$_local_ca_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -309,11 +307,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then if [ -n "$_local_ca_file" ]; then if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then - return $_err_code + return $_err_code fi fi else @@ -343,16 +341,16 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # if filename is same as previous file then append. _pipe=">>" _local_full_file=$(_mktemp) - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ; then - cat "$_ckey" >> "$_local_full_file" + if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ]; then + cat "$_ckey" >>"$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >> "$_local_full_file" + cat "$_ccert" >>"$_local_full_file" fi if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat "$_cca" >> "$_local_full_file" + cat "$_cca" >>"$_local_full_file" fi - cat "$_cfullchain" >> "$_local_full_file" + cat "$_cfullchain" >>"$_local_full_file" elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then # backup file we are about to overwrite. @@ -366,13 +364,13 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_full_file" ] ; then + if [ -n "$_local_full_file" ]; then if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then - return $_err_code + return $_err_code fi else if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then - return $_err_code + return $_err_code fi fi else @@ -390,16 +388,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # cleanup local files if any if [ -n "$_local_cert_file" ]; then - rm "$_local_cert_file" > /dev/null 1>&2 + rm "$_local_cert_file" >/dev/null 1>&2 fi if [ -n "$_local_ca_file" ]; then - rm "$_local_ca_file" > /dev/null 1>&2 + rm "$_local_ca_file" >/dev/null 1>&2 fi if [ -n "$_local_full_file" ]; then - rm "$_local_full_file" > /dev/null 1>&2 + rm "$_local_full_file" >/dev/null 1>&2 fi - # REMOTE_CMD is optional. # If provided then this command will be executed on remote host. if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then From bcf63b5d270a4535347e64e7f25f24970e474e6f Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:17:34 +0100 Subject: [PATCH 013/687] Add ArtFiles.de DNS API plugin --- dnsapi/dns_artfiles.sh | 176 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 dnsapi/dns_artfiles.sh diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh new file mode 100644 index 00000000..c857060a --- /dev/null +++ b/dnsapi/dns_artfiles.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env sh + +################################################################################ +# ACME.sh 3rd party DNS API plugin for ArtFiles.de +################################################################################ +# Author: Martin Arndt, https://troublezone.net/ +# Released: 2022-02-27 +# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX +################################################################################ +# Usage: +# 1. export AF_API_Username="api12345678" +# 2. export AF_API_Password="apiPassword" +# 3. acme.sh --issue -d example.com --dns dns_artfiles +################################################################################ + +########## API configuration ################################################### +AF_API_SUCCESS='status":"OK' +AF_URL_DCP='https://dcp.c.artfiles.de/api/' +AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain=' +AF_URL_DOMAINS=${AF_URL_BASE}'domain/get_domains.html' + +########## Public functions #################################################### + +# Adds a new TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_add() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS addition API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" + AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" + if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then + _err 'Missing ArtFiles.de username and/or password.' + _err 'Please ensure both are set via export command & try again.' + + return 1 + fi + + _saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME" + _saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD" + + _set_headers + _get_zone "$domain" + _dns 'GET' + if ! _contains "$response" 'TXT'; then + _err 'Retrieving TXT records failed.' + + return 1 + fi + + _clean_records + _dns 'SET' "$(printf -- '%s\n_acme-challenge "%s"' "$response" "$txtValue")" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Adding ACME challenge value failed.' + + return 1 + fi +} + +# Removes the existing TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_rm() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS removal API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + _set_headers + _get_zone "$domain" + if ! _dns 'GET'; then + return 1 + fi + + if ! _contains "$response" "$txtValue"; then + _err 'Retrieved TXT records are missing given ACME challenge value.' + + return 1 + fi + + _clean_records + response="$(printf -- '%s' "$response" | sed '$d')" + _dns 'SET' "$response" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Removing ACME challenge value failed.' + + return 1 + fi +} + +########## Private functions ################################################### + +# Cleans awful TXT records response of ArtFiles's API & pretty prints it. +# Usage: _clean_records +_clean_records() +{ + # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid + # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' + # from '\"' & turn '\n' into real LF characters. + # Yup, awful API to use - but that's all we got to get this working, so... ;) + _debug2 'Raw ' "$response" + response="$(printf -- '%s' "$response" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + _debug2 'Clean' "$response" +} + +# Executes an HTTP GET or POST request for getting or setting DNS records, +# containing given payload upon POST. +# Usage: _dns [GET | SET] [payload] +_dns() +{ + action="$1" + payload="$(printf -- '%s' "$2" | _url_encode)" + url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + + if [ "$action" = 'SET' ]; then + _debug2 'Payload' "$payload" + response="$(_post '' "$url&TXT=$payload" '' 'POST' 'application/x-www-form-urlencoded')" + else + response="$(_get "$url" '' 10)" + fi + + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err "DNS API error: $response" + + return 1 + fi + + _debug 'Response' "$response" + + return 0 +} + +# Gets the root domain zone for given domain. +# Usage: _get_zone _acme-challenge.www.example.com +_get_zone() +{ + _info 'Getting domain zone...' + _debug2 'Initial FQDN' "$1" + fqdn="$1" + fqdn="${fqdn#*.}" # Strip "_acme-challenge" right away + _debug2 'Reduced FQDN' "$fqdn" + + domains="$(_get "$AF_URL_DOMAINS" '' 10)" + while true; do + if _contains "$domains" "$fqdn"; then + domain="$fqdn" + _info "Found root domain zone: $domain" + break + else + fqdn="${fqdn#*.}" + _debug2 'FQDN' "$fqdn" + fi + done + + if [ "$domain" = "$fqdn" ]; then + return 0 + fi + + _err "Couldn't find root domain zone." + + return 1 +} + +# Adds the HTTP Authorization & Content-Type headers to a follow-up request. +# Usage: _set_headers +_set_headers() +{ + encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" + export _H1="Authorization: Basic $encoded" + export _H2='Content-Type: application/json' +} From 72d02f442e2e8528afb04a0e55c88185bb99a7e9 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:35:21 +0100 Subject: [PATCH 014/687] Fix formatting according to Shellcheck --- dnsapi/dns_artfiles.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index c857060a..4598854d 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -95,8 +95,7 @@ dns_artfiles_rm() { # Cleans awful TXT records response of ArtFiles's API & pretty prints it. # Usage: _clean_records -_clean_records() -{ +_clean_records() { # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' # from '\"' & turn '\n' into real LF characters. @@ -110,8 +109,7 @@ _clean_records() # Executes an HTTP GET or POST request for getting or setting DNS records, # containing given payload upon POST. # Usage: _dns [GET | SET] [payload] -_dns() -{ +_dns() { action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" @@ -137,8 +135,7 @@ _dns() # Gets the root domain zone for given domain. # Usage: _get_zone _acme-challenge.www.example.com -_get_zone() -{ +_get_zone() { _info 'Getting domain zone...' _debug2 'Initial FQDN' "$1" fqdn="$1" @@ -168,8 +165,7 @@ _get_zone() # Adds the HTTP Authorization & Content-Type headers to a follow-up request. # Usage: _set_headers -_set_headers() -{ +_set_headers() { encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" export _H1="Authorization: Basic $encoded" export _H2='Content-Type: application/json' From 0bea2e2b94e49f59e05c7507bcec548c50a4abac Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:37:22 +0100 Subject: [PATCH 015/687] Fix formatting according to Shellcheck 2/2 --- dnsapi/dns_artfiles.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 4598854d..f83ce64a 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -101,8 +101,9 @@ _clean_records() { # from '\"' & turn '\n' into real LF characters. # Yup, awful API to use - but that's all we got to get this working, so... ;) _debug2 'Raw ' "$response" - response="$(printf -- '%s' "$response" - \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + response="$( + printf -- '%s' "$response" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" _debug2 'Clean' "$response" } @@ -112,8 +113,9 @@ _clean_records() { _dns() { action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" - url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" - \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + url="$( + printf -- '%s%s' "$AF_URL_DNS" "$domain" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" if [ "$action" = 'SET' ]; then _debug2 'Payload' "$payload" From fb457968ecae380bc17914f22d134bcfba93d304 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:38:24 +0100 Subject: [PATCH 016/687] Fix formatting according to Shellcheck 3/3 --- dnsapi/dns_artfiles.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index f83ce64a..9c1a4338 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -103,7 +103,8 @@ _clean_records() { _debug2 'Raw ' "$response" response="$( printf -- '%s' "$response" - \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g')" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g' + )" _debug2 'Clean' "$response" } @@ -115,7 +116,8 @@ _dns() { payload="$(printf -- '%s' "$2" | _url_encode)" url="$( printf -- '%s%s' "$AF_URL_DNS" "$domain" - \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/' + )" if [ "$action" = 'SET' ]; then _debug2 'Payload' "$payload" From ed56d52af309a4d90747169a321dbd3698a4b71a Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 27 Feb 2022 15:12:05 +0100 Subject: [PATCH 017/687] Changed GitHub issues URL --- dnsapi/dns_artfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 9c1a4338..8e0a6151 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -5,7 +5,7 @@ ################################################################################ # Author: Martin Arndt, https://troublezone.net/ # Released: 2022-02-27 -# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX +# Issues: https://github.com/Eagle3386/acme.sh/issues ################################################################################ # Usage: # 1. export AF_API_Username="api12345678" From b37bf06de87ab41d495e0a3156f538c5baf9c679 Mon Sep 17 00:00:00 2001 From: fradev Date: Tue, 1 Mar 2022 17:57:59 +0100 Subject: [PATCH 018/687] Update ssh.sh --- deploy/ssh.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 604d8642..7d9e82e8 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -24,7 +24,7 @@ # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # export DEPLOY_SSH_USE_SCP="" yes or no , default to no -# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -T -q " +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q " # ######## Public functions ##################### @@ -53,7 +53,7 @@ ssh_deploy() { fi else Le_Deploy_ssh_user="$DEPLOY_SSH_USER" - _savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" + _savedeployconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" fi # SERVER is optional. If not provided then use _cdomain @@ -61,7 +61,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" if [ -n "$DEPLOY_SSH_SERVER" ]; then Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER" - _savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" + _savedeployconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" elif [ -z "$Le_Deploy_ssh_server" ]; then Le_Deploy_ssh_server="$_cdomain" fi @@ -71,7 +71,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" if [ -n "$DEPLOY_SSH_CMD" ]; then Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" - _savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" + _savedeployconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" elif [ -z "$Le_Deploy_ssh_cmd" ]; then Le_Deploy_ssh_cmd="ssh -T" fi @@ -80,7 +80,7 @@ ssh_deploy() { # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then Le_Deploy_ssh_use_scp="yes" - _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then Le_Deploy_ssh_use_scp="" _cleardomainconf Le_Deploy_ssh_use_scp @@ -89,9 +89,9 @@ ssh_deploy() { # SCP_CMD is optional. If not provided then use scp if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -T" + Le_Deploy_ssh_scp_cmd="scp -q" fi # BACKUP is optional. If not provided then default to previously saved value or yes. @@ -102,7 +102,7 @@ ssh_deploy() { elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then Le_Deploy_ssh_backup="yes" fi - _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + _savedeployconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy _getdeployconf DEPLOY_SSH_BACKUP_PATH @@ -112,7 +112,7 @@ ssh_deploy() { elif [ -z "$Le_Deploy_ssh_backup_path" ]; then Le_Deploy_ssh_backup_path=".acme_ssh_deploy" fi - _savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + _savedeployconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). @@ -120,7 +120,7 @@ ssh_deploy() { _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then Le_Deploy_ssh_multi_call="" _cleardomainconf Le_Deploy_ssh_multi_call @@ -130,9 +130,9 @@ ssh_deploy() { # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then Le_Deploy_ssh_use_scp="yes" - _savedomainconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" + _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then Le_Deploy_ssh_use_scp="" _cleardomainconf Le_Deploy_ssh_use_scp @@ -141,7 +141,7 @@ ssh_deploy() { # SCP_CMD is optional. If not provided then use scp if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedomainconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" + _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then Le_Deploy_ssh_scp_cmd="scp -T -q " fi @@ -165,7 +165,7 @@ _ssh_deploy() { if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then _info "Using scp as alternate method for copying files. Multicall Mode is implicit" Le_Deploy_ssh_multi_call="yes" - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" fi if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" @@ -200,7 +200,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" if [ -n "$DEPLOY_SSH_KEYFILE" ]; then Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE" - _savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" + _savedeployconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" fi if [ -n "$Le_Deploy_ssh_keyfile" ]; then if [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -238,7 +238,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" if [ -n "$DEPLOY_SSH_CERTFILE" ]; then Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" - _savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" + _savedeployconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" fi if [ -n "$Le_Deploy_ssh_certfile" ]; then _pipe=">" @@ -288,7 +288,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" if [ -n "$DEPLOY_SSH_CAFILE" ]; then Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE" - _savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" + _savedeployconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" fi if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" @@ -346,7 +346,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN" - _savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" + _savedeployconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" fi if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" @@ -418,7 +418,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD" - _savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" + _savedeployconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" fi if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" From ea3c37d754801b289fa6a5abcbeadea1c773b147 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Wed, 9 Mar 2022 01:36:06 +0100 Subject: [PATCH 019/687] Corrected use of Plesk API calls to fetch all domain for all Plesk editions This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains managed by the specific plesk instance. The existing implementation of the Plesk API uses the customer API. This brings two problems: 1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by administrative users. compare: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/ https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/ 2. The customer API is only available in the pro/admin editions. The most common license on VPS/Dedicated Servers is the web host edition. See: https://www.plesk.com/editions/ The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/ --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index f5986827..0f7dc241 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -41,7 +41,7 @@ pleskxml_init_checks_done=0 NEWLINE='\ ' -pleskxml_tplt_get_domains="" +pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. # No params. @@ -375,7 +375,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):' _debug "$output" From a6b58bc88d390a21baf3cf457f3d3daba314222b Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Wed, 9 Mar 2022 01:36:06 +0100 Subject: [PATCH 020/687] Corrected use of Plesk API calls to fetch all domain for all Plesk editions This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains ( of customers & administrative users) managed by the specific plesk instance. The previous implementation of the Plesk API uses the customer API. This brings two problems: 1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by administrative users. compare: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/ https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/ 2. The customer API is only available in the web pro/host editions. The most common license on VPS/Dedicated Servers is nowadays the web admin edition. See: https://www.plesk.com/editions/ The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API: https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/ This way is working for all plesk editions the same way. --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index f5986827..0f7dc241 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -41,7 +41,7 @@ pleskxml_init_checks_done=0 NEWLINE='\ ' -pleskxml_tplt_get_domains="" +pleskxml_tplt_get_domains="" # Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh # Also used to test credentials and URI. # No params. @@ -375,7 +375,7 @@ _pleskxml_get_root_domain() { # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' 'domain' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" _debug 'Domains managed by Plesk server are (ignore the hacked output):' _debug "$output" From 9fb5bb620d2ffa51eabb0354dfccc29ea9d88315 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:13:24 +0800 Subject: [PATCH 021/687] refact ssh hook to use deploy config --- acme.sh | 20 +++ deploy/ssh.sh | 414 +++++++++++++++++++++++--------------------------- 2 files changed, 210 insertions(+), 224 deletions(-) diff --git a/acme.sh b/acme.sh index 260733a2..37c625d2 100755 --- a/acme.sh +++ b/acme.sh @@ -2332,6 +2332,26 @@ _readdomainconf() { _read_conf "$DOMAIN_CONF" "$1" } +#_migratedomainconf oldkey newkey base64encode +_migratedomainconf() { + _old_key="$1" + _new_key="$2" + _b64encode="$3" + _value=$(_readdomainconf "$_old_key") + if [ -z "$_value" ]; then + return 1 # oldkey is not found + fi + _savedomainconf "$_new_key" "$_value" "$_b64encode" + _cleardomainconf "$_old_key" + _debug "Domain config $_old_key has been migrated to $_new_key" +} + +#_migratedeployconf oldkey newkey base64encode +_migratedeployconf() { + _migratedomainconf "$1" "SAVED_$2" "$3" || + _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found +} + #key value base64encode _savedeployconf() { _savedomainconf "SAVED_$1" "$2" "$3" diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 7d9e82e8..73d71597 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -23,8 +23,8 @@ # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value -# export DEPLOY_SSH_USE_SCP="" yes or no , default to no -# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q " +# export DEPLOY_SSH_USE_SCP="" yes or no, default to no +# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q" # ######## Public functions ##################### @@ -44,110 +44,134 @@ ssh_deploy() { _debug _cfullchain "$_cfullchain" # USER is required to login by SSH to remote host. + _migratedeployconf Le_Deploy_ssh_user DEPLOY_SSH_USER _getdeployconf DEPLOY_SSH_USER _debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER" if [ -z "$DEPLOY_SSH_USER" ]; then - if [ -z "$Le_Deploy_ssh_user" ]; then - _err "DEPLOY_SSH_USER not defined." - return 1 - fi - else - Le_Deploy_ssh_user="$DEPLOY_SSH_USER" - _savedeployconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user" + _err "DEPLOY_SSH_USER not defined." + return 1 fi + _savedeployconf DEPLOY_SSH_USER "$DEPLOY_SSH_USER" # SERVER is optional. If not provided then use _cdomain + _migratedeployconf Le_Deploy_ssh_server DEPLOY_SSH_SERVER _getdeployconf DEPLOY_SSH_SERVER _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" - if [ -n "$DEPLOY_SSH_SERVER" ]; then - Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER" - _savedeployconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server" - elif [ -z "$Le_Deploy_ssh_server" ]; then - Le_Deploy_ssh_server="$_cdomain" + if [ -z "$DEPLOY_SSH_SERVER" ]; then + DEPLOY_SSH_SERVER="$_cdomain" fi + _savedeployconf DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" # CMD is optional. If not provided then use ssh + _migratedeployconf Le_Deploy_ssh_cmd DEPLOY_SSH_CMD _getdeployconf DEPLOY_SSH_CMD _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" - if [ -n "$DEPLOY_SSH_CMD" ]; then - Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" - _savedeployconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" - elif [ -z "$Le_Deploy_ssh_cmd" ]; then - Le_Deploy_ssh_cmd="ssh -T" - fi - - # USE_SCP is optional. If not provided then default to previously saved - # value (which may be undefined... equivalent to "no"). - if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then - Le_Deploy_ssh_use_scp="yes" - _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" - elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then - Le_Deploy_ssh_use_scp="" - _cleardomainconf Le_Deploy_ssh_use_scp - fi - - # SCP_CMD is optional. If not provided then use scp - if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then - Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" - elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -q" + if [ -z "$DEPLOY_SSH_CMD" ]; then + DEPLOY_SSH_CMD="ssh -T" fi + _savedeployconf DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" # BACKUP is optional. If not provided then default to previously saved value or yes. + _migratedeployconf Le_Deploy_ssh_backup DEPLOY_SSH_BACKUP _getdeployconf DEPLOY_SSH_BACKUP _debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" - if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then - Le_Deploy_ssh_backup="no" - elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then - Le_Deploy_ssh_backup="yes" + if [ -z "$DEPLOY_SSH_BACKUP" ]; then + DEPLOY_SSH_BACKUP="yes" fi - _savedeployconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + _savedeployconf DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy + _migratedeployconf Le_Deploy_ssh_backup_path DEPLOY_SSH_BACKUP_PATH _getdeployconf DEPLOY_SSH_BACKUP_PATH _debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" - if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then - Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH" - elif [ -z "$Le_Deploy_ssh_backup_path" ]; then - Le_Deploy_ssh_backup_path=".acme_ssh_deploy" + if [ -z "$DEPLOY_SSH_BACKUP_PATH" ]; then + DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" fi - _savedeployconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + _savedeployconf DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). + _migratedeployconf Le_Deploy_ssh_multi_call DEPLOY_SSH_MULTI_CALL _getdeployconf DEPLOY_SSH_MULTI_CALL _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" - if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then - Le_Deploy_ssh_multi_call="" - _cleardomainconf Le_Deploy_ssh_multi_call + if [ -z "$DEPLOY_SSH_MULTI_CALL" ]; then + DEPLOY_SSH_MULTI_CALL="no" + fi + _savedeployconf DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" + + # KEYFILE is optional. + # If provided then private key will be copied to provided filename. + _migratedeployconf Le_Deploy_ssh_keyfile DEPLOY_SSH_KEYFILE + _getdeployconf DEPLOY_SSH_KEYFILE + _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" + if [ -n "$DEPLOY_SSH_KEYFILE" ]; then + _savedeployconf DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" + fi + + # CERTFILE is optional. + # If provided then certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_certfile DEPLOY_SSH_CERTFILE + _getdeployconf DEPLOY_SSH_CERTFILE + _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" + if [ -n "$DEPLOY_SSH_CERTFILE" ]; then + _savedeployconf DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" + fi + + # CAFILE is optional. + # If provided then CA intermediate certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_cafile DEPLOY_SSH_CAFILE + _getdeployconf DEPLOY_SSH_CAFILE + _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" + if [ -n "$DEPLOY_SSH_CAFILE" ]; then + _savedeployconf DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" + fi + + # FULLCHAIN is optional. + # If provided then fullchain certificate will be copied or appended to provided filename. + _migratedeployconf Le_Deploy_ssh_fullchain DEPLOY_SSH_FULLCHAIN + _getdeployconf DEPLOY_SSH_FULLCHAIN + _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" + if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then + _savedeployconf DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" + fi + + # REMOTE_CMD is optional. + # If provided then this command will be executed on remote host. + _migratedeployconf Le_Deploy_ssh_remote_cmd DEPLOY_SSH_REMOTE_CMD + _getdeployconf DEPLOY_SSH_REMOTE_CMD + _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" + if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then + _savedeployconf DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" fi # USE_SCP is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). - if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then - Le_Deploy_ssh_use_scp="yes" - _savedeployconf Le_Deploy_ssh_use_scp "$Le_Deploy_ssh_use_scp" - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - elif [ "$DEPLOY_SSH_USE_SCP" = "no" ]; then - Le_Deploy_ssh_use_scp="" - _cleardomainconf Le_Deploy_ssh_use_scp + _getdeployconf DEPLOY_SSH_USE_SCP + _debug2 DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP" + if [ -z "$DEPLOY_SSH_USE_SCP" ]; then + DEPLOY_SSH_USE_SCP="no" fi + _savedeployconf DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP" # SCP_CMD is optional. If not provided then use scp - if [ -n "$DEPLOY_SSH_SCP_CMD" ]; then - Le_Deploy_ssh_scp_cmd="$DEPLOY_SSH_SCP_CMD" - _savedeployconf Le_Deploy_ssh_scp_cmd "$Le_Deploy_ssh_scp_cmd" - elif [ -z "$Le_Deploy_ssh_scp_cmd" ]; then - Le_Deploy_ssh_scp_cmd="scp -T -q " + _getdeployconf DEPLOY_SSH_SCP_CMD + _debug2 DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD" + if [ -z "$DEPLOY_SSH_SCP_CMD" ]; then + DEPLOY_SSH_SCP_CMD="scp -q" + fi + _savedeployconf DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD" + + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + DEPLOY_SSH_MULTI_CALL="yes" + _info "Using scp as alternate method for copying files. Multicall Mode is implicit" + elif [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" + else + _info "Required commands batched and sent in single call to remote host" fi - _deploy_ssh_servers=$Le_Deploy_ssh_server - for Le_Deploy_ssh_server in $_deploy_ssh_servers; do + _deploy_ssh_servers=$DEPLOY_SSH_SERVER + for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do _ssh_deploy done } @@ -161,20 +185,10 @@ _ssh_deploy() { _local_ca_file="" _local_full_file="" - _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - _info "Using scp as alternate method for copying files. Multicall Mode is implicit" - Le_Deploy_ssh_multi_call="yes" - _savedeployconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" - fi - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then - _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" - else - _info "Required commands batched and sent in single call to remote host" - fi + _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" - if [ "$Le_Deploy_ssh_backup" = "yes" ]; then - _backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup" + if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then + _backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup" _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" # run cleanup on the backup directory, erase all older # than 180 days (15552000 seconds). @@ -186,7 +200,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -194,19 +208,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # KEYFILE is optional. - # If provided then private key will be copied to provided filename. - _getdeployconf DEPLOY_SSH_KEYFILE - _debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE" if [ -n "$DEPLOY_SSH_KEYFILE" ]; then - Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE" - _savedeployconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile" - fi - if [ -n "$Le_Deploy_ssh_keyfile" ]; then - if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_KEYFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -215,15 +221,16 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi # copy new key into file. - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then # scp the file - if ! _scp_remote_cmd "$_ckey" "$Le_Deploy_ssh_keyfile"; then + if ! _scp_remote_cmd "$_ckey" "$DEPLOY_SSH_KEYFILE"; then return $_err_code fi else - _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" - _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $DEPLOY_SSH_KEYFILE;" + _info "will copy private key to remote file $DEPLOY_SSH_KEYFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -232,26 +239,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # CERTFILE is optional. - # If provided then certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_CERTFILE - _debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE" if [ -n "$DEPLOY_SSH_CERTFILE" ]; then - Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" - _savedeployconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" - fi - if [ -n "$Le_Deploy_ssh_certfile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then + if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then # if filename is same as previous file then append. _pipe=">>" - _local_cert_file=$(_mktemp) - cat "$_ckey" >"$_local_cert_file" - cat "$_ccert" >>"$_local_cert_file" - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_CERTFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -259,21 +255,22 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_cert_file" ]; then - if ! _scp_remote_cmd "$_local_cert_file" "$Le_Deploy_ssh_certfile"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_ccert" "$Le_Deploy_ssh_certfile"; then - return $_err_code - fi + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file + _local_cert_file=$(_mktemp) + if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_cert_file" + fi + cat "$_ccert" >> "$_local_cert_file" + if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" - _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $DEPLOY_SSH_CERTFILE;" + _info "will copy certificate to remote file $DEPLOY_SSH_CERTFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -282,34 +279,16 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # CAFILE is optional. - # If provided then CA intermediate certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_CAFILE - _debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE" if [ -n "$DEPLOY_SSH_CAFILE" ]; then - Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE" - _savedeployconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile" - fi - if [ -n "$Le_Deploy_ssh_cafile" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] || - [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ] || + [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then # if filename is same as previous file then append. _pipe=">>" - _local_ca_file=$(_mktemp) - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ]; then - cat "$_ckey" >>"$_local_ca_file" - fi - if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >>"$_local_ca_file" - fi - - cat "$_cca" >>"$_local_ca_file" - - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_CAFILE $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -317,21 +296,25 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_ca_file" ]; then - if ! _scp_remote_cmd "$_local_ca_file" "$Le_Deploy_ssh_cafile"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_cca" "$Le_Deploy_ssh_cafile"; then - return $_err_code - fi + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file + _local_ca_file=$(_mktemp) + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_ca_file" + fi + if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then + cat "$_ccert" >> "$_local_ca_file" + fi + cat "$_cca" >>"$_local_ca_file" + if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" - _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $DEPLOY_SSH_CAFILE;" + _info "will copy CA file to remote file $DEPLOY_SSH_CAFILE" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -340,37 +323,17 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # FULLCHAIN is optional. - # If provided then fullchain certificate will be copied or appended to provided filename. - _getdeployconf DEPLOY_SSH_FULLCHAIN - _debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN" if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then - Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN" - _savedeployconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain" - fi - if [ -n "$Le_Deploy_ssh_fullchain" ]; then _pipe=">" - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] || - [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] || - [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ] || + [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ] || + [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then # if filename is same as previous file then append. _pipe=">>" - _local_full_file=$(_mktemp) - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ]; then - cat "$_ckey" >>"$_local_full_file" - fi - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ]; then - cat "$_ccert" >>"$_local_full_file" - fi - if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then - cat "$_cca" >>"$_local_full_file" - fi - cat "$_cfullchain" >>"$_local_full_file" - - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then + elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then # backup file we are about to overwrite. - _cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr cp $DEPLOY_SSH_FULLCHAIN $_backupdir >/dev/null;" + if [ "$DEPLOY_SSH_FULLCHAIN" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -378,21 +341,28 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - if [ "$Le_Deploy_ssh_use_scp" = "yes" ]; then - if [ -n "$_local_full_file" ]; then - if ! _scp_remote_cmd "$_local_full_file" "$Le_Deploy_ssh_fullchain"; then - return $_err_code - fi - else - if ! _scp_remote_cmd "$_cfullchain" "$Le_Deploy_ssh_fullchain"; then - return $_err_code - fi + # copy new certificate into file. + if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then + # scp the file + _local_full_file=$(_mktemp) + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then + cat "$_ckey" >> "$_local_full_file" + fi + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then + cat "$_ccert" >> "$_local_full_file" + fi + if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then + cat "$_cca" >> "$_local_full_file" + fi + cat "$_cfullchain" >> "$_local_full_file" + if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then + return $_err_code fi else - # copy new certificate into file. - _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" - _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + # ssh echo to the file + _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $DEPLOY_SSH_FULLCHAIN;" + _info "will copy fullchain to remote file $DEPLOY_SSH_FULLCHAIN" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -400,30 +370,22 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi fi - # cleanup local files if any - if [ -n "$_local_cert_file" ]; then - rm "$_local_cert_file" >/dev/null 1>&2 + # cleanup local files if any + if [ -f "$_local_cert_file" ]; then + rm -f "$_local_cert_file" fi - if [ -n "$_local_ca_file" ]; then - rm "$_local_ca_file" >/dev/null 1>&2 + if [ -f "$_local_ca_file" ]; then + rm -f "$_local_ca_file" fi - if [ -n "$_local_full_file" ]; then - rm "$_local_full_file" >/dev/null 1>&2 + if [ -f "$_local_full_file" ]; then + rm -f "$_local_full_file" fi - # REMOTE_CMD is optional. - # If provided then this command will be executed on remote host. - _getdeployconf DEPLOY_SSH_REMOTE_CMD - _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD" if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then - Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD" - _savedeployconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd" - fi - if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then - _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" - _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" - if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _cmdstr="$_cmdstr $DEPLOY_SSH_REMOTE_CMD;" + _info "Will execute remote command $DEPLOY_SSH_REMOTE_CMD" + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -445,10 +407,11 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _ssh_remote_cmd() { _cmd="$1" _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by ssh" + _info "Submitting sequence of commands to remote server by $DEPLOY_SSH_CMD" + # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + $DEPLOY_SSH_CMD "$DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then @@ -460,9 +423,12 @@ _ssh_remote_cmd() { # cmd scp _scp_remote_cmd() { - _secure_debug "Remote scp source $1 and destination $2 using : $Le_Deploy_ssh_scp_cmd" - _info "Submitting secure copy command : $Le_Deploy_ssh_scp_cmd" - $Le_Deploy_ssh_scp_cmd "$1" "$Le_Deploy_ssh_user"@"$Le_Deploy_ssh_server":"$2" + _src=$1 + _dest=$2 + _secure_debug "Remote copy source $_src to destination $_dest using: $DEPLOY_SSH_SCP_CMD" + _info "Submitting secure copy command: $DEPLOY_SSH_SCP_CMD" + + $DEPLOY_SSH_SCP_CMD "$_src" "$DEPLOY_SSH_USER"@"$DEPLOY_SSH_SERVER":"$_dest" _err_code="$?" if [ "$_err_code" != "0" ]; then From c8929ca0cb13abb2213cd5da7abd9bd1b140af9a Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:29:19 +0800 Subject: [PATCH 022/687] support specifying port for each host --- deploy/ssh.sh | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 73d71597..2de0d325 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -14,7 +14,7 @@ # The following examples are for QNAP NAS running QTS 4.2 # export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required -# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name +# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name, support multiple servers with optional port (eg. "host1 host2:8022") # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" @@ -185,7 +185,12 @@ _ssh_deploy() { _local_ca_file="" _local_full_file="" - _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" + case $DEPLOY_SSH_SERVER in + (*:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; + (*) _host=$DEPLOY_SSH_SERVER _port=;; + esac + + _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then _backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup" @@ -406,12 +411,18 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d #cmd _ssh_remote_cmd() { _cmd="$1" + + _ssh_cmd="$DEPLOY_SSH_CMD" + if [ -n "$_port" ]; then + _ssh_cmd="$_ssh_cmd -p $_port" + fi + _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by $DEPLOY_SSH_CMD" + _info "Submitting sequence of commands to remote server by $_ssh_cmd" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $DEPLOY_SSH_CMD "$DEPLOY_SSH_USER@$DEPLOY_SSH_SERVER" sh -c "'$_cmd'" + $_ssh_cmd "$DEPLOY_SSH_USER@$_host" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then @@ -425,10 +436,16 @@ _ssh_remote_cmd() { _scp_remote_cmd() { _src=$1 _dest=$2 - _secure_debug "Remote copy source $_src to destination $_dest using: $DEPLOY_SSH_SCP_CMD" - _info "Submitting secure copy command: $DEPLOY_SSH_SCP_CMD" - $DEPLOY_SSH_SCP_CMD "$_src" "$DEPLOY_SSH_USER"@"$DEPLOY_SSH_SERVER":"$_dest" + _scp_cmd="$DEPLOY_SSH_SCP_CMD" + if [ -n "$_port" ]; then + _scp_cmd="$_scp_cmd -P $_port" + fi + + _secure_debug "Remote copy source $_src to destination $_dest" + _info "Submitting secure copy by $_scp_cmd" + + $_scp_cmd "$_src" "$DEPLOY_SSH_USER"@"$_host":"$_dest" _err_code="$?" if [ "$_err_code" != "0" ]; then From f90cbb636a101625b118fbdb57b64f7d4d0bdabb Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:41:59 +0800 Subject: [PATCH 023/687] fix format --- acme.sh | 2 +- deploy/ssh.sh | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/acme.sh b/acme.sh index 37c625d2..4366501b 100755 --- a/acme.sh +++ b/acme.sh @@ -2349,7 +2349,7 @@ _migratedomainconf() { #_migratedeployconf oldkey newkey base64encode _migratedeployconf() { _migratedomainconf "$1" "SAVED_$2" "$3" || - _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found + _migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found } #key value base64encode diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 2de0d325..d40bba43 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -186,8 +186,8 @@ _ssh_deploy() { _local_full_file="" case $DEPLOY_SSH_SERVER in - (*:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; - (*) _host=$DEPLOY_SSH_SERVER _port=;; + *:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; + *) _host=$DEPLOY_SSH_SERVER _port=;; esac _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" @@ -265,9 +265,9 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_cert_file=$(_mktemp) if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_cert_file" + cat "$_ckey" >>"$_local_cert_file" fi - cat "$_ccert" >> "$_local_cert_file" + cat "$_ccert" >>"$_local_cert_file" if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then return $_err_code fi @@ -306,10 +306,10 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_ca_file=$(_mktemp) if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_ca_file" + cat "$_ckey" >>"$_local_ca_file" fi if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then - cat "$_ccert" >> "$_local_ca_file" + cat "$_ccert" >>"$_local_ca_file" fi cat "$_cca" >>"$_local_ca_file" if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then @@ -351,15 +351,15 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # scp the file _local_full_file=$(_mktemp) if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then - cat "$_ckey" >> "$_local_full_file" + cat "$_ckey" >>"$_local_full_file" fi if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then - cat "$_ccert" >> "$_local_full_file" + cat "$_ccert" >>"$_local_full_file" fi if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then - cat "$_cca" >> "$_local_full_file" + cat "$_cca" >>"$_local_full_file" fi - cat "$_cfullchain" >> "$_local_full_file" + cat "$_cfullchain" >>"$_local_full_file" if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then return $_err_code fi From 74f28021e701c53665774c4861d68863775bb206 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:49:40 +0800 Subject: [PATCH 024/687] fix format again --- deploy/ssh.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index d40bba43..074af84f 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -186,8 +186,14 @@ _ssh_deploy() { _local_full_file="" case $DEPLOY_SSH_SERVER in - *:*) _host=${DEPLOY_SSH_SERVER%:*} _port=${DEPLOY_SSH_SERVER##*:};; - *) _host=$DEPLOY_SSH_SERVER _port=;; + *:*) + _host=${DEPLOY_SSH_SERVER%:*} + _port=${DEPLOY_SSH_SERVER##*:} + ;; + *) + _host=$DEPLOY_SSH_SERVER + _port= + ;; esac _info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" From 3ce7d410c8ee18d4ed1049ccdc500a6624613df7 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Sat, 14 May 2022 22:59:02 +0800 Subject: [PATCH 025/687] improve doc comments --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 074af84f..1aed7d3e 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -14,7 +14,7 @@ # The following examples are for QNAP NAS running QTS 4.2 # export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required -# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name, support multiple servers with optional port (eg. "host1 host2:8022") +# export DEPLOY_SSH_SERVER="host1 host2:8022 192.168.0.1:9022" # defaults to domain name, support multiple servers with optional port # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" From d2a9d731edbc5d6dcfc434560ba605bef9039ed2 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 May 2022 22:25:44 +0800 Subject: [PATCH 026/687] Update ssh.sh --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 1aed7d3e..c66e2e19 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -170,7 +170,7 @@ ssh_deploy() { _info "Required commands batched and sent in single call to remote host" fi - _deploy_ssh_servers=$DEPLOY_SSH_SERVER + _deploy_ssh_servers="$DEPLOY_SSH_SERVER" for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do _ssh_deploy done From 13c71829485aac03e1d0da98784ea50e983e73cd Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sat, 18 Jun 2022 17:32:56 +0200 Subject: [PATCH 027/687] Fix usage docs in file's header comment --- dnsapi/dns_artfiles.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 8e0a6151..2f8e158f 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -8,8 +8,8 @@ # Issues: https://github.com/Eagle3386/acme.sh/issues ################################################################################ # Usage: -# 1. export AF_API_Username="api12345678" -# 2. export AF_API_Password="apiPassword" +# 1. export AF_API_USERNAME="api12345678" +# 2. export AF_API_PASSWORD="apiPassword" # 3. acme.sh --issue -d example.com --dns dns_artfiles ################################################################################ From 095697900b94e05f3ba8176c53632d6d3a7769e0 Mon Sep 17 00:00:00 2001 From: Marcel Hellkamp Date: Wed, 22 Jun 2022 17:54:49 +0200 Subject: [PATCH 028/687] fix: Challenge not skipped for pre-validated wildcard domain orders Some CAs auto-validate orders based on account-level rules and do not require a challenge at all. Sectigo introduced a non-standard challenges named 'sectigo-dns-01', presumably to work around this issue in certbot. This also works for non-wildcard domains in acme.sh, but wildcard domains are rejected because acme.sh hard-codes 'dns-01' as the only allowed challenge for wildcard domains, which is not offered by Sectigo. This change simply moves the '"status":"valid"' check up a bit and ignores challenge type mismatches or missing tokens if no challenge is needed anyway. --- acme.sh | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/acme.sh b/acme.sh index 260733a2..3210efd6 100755 --- a/acme.sh +++ b/acme.sh @@ -4600,28 +4600,26 @@ $_authorizations_map" thumbprint="$(__calc_account_thumbprint)" fi + keyauthorization="" + + if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then + _debug "$d is already valid." + keyauthorization="$STATE_VERIFIED" + _debug keyauthorization "$keyauthorization" + fi + entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" - keyauthorization="" - if [ -z "$entry" ]; then - if ! _startswith "$d" '*.'; then - _debug "Not a wildcard domain, lets check whether the validation is already valid." - if echo "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already valid." - keyauthorization="$STATE_VERIFIED" - _debug keyauthorization "$keyauthorization" - fi - fi - if [ -z "$keyauthorization" ]; then - _err "Error, can not get domain token entry $d for $vtype" - _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" - if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" - fi - _clearup - _on_issue_err "$_post_hook" - return 1 + + if [ -z "$keyauthorization" -a -z "$entry" ]; then + _err "Error, can not get domain token entry $d for $vtype" + _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" + if [ "$_supported_vtypes" ]; then + _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" fi + _clearup + _on_issue_err "$_post_hook" + return 1 fi if [ -z "$keyauthorization" ]; then @@ -4647,12 +4645,6 @@ $_authorizations_map" fi keyauthorization="$token.$thumbprint" _debug keyauthorization "$keyauthorization" - - if printf "%s" "$response" | grep '"status":"valid"' >/dev/null 2>&1; then - _debug "$d is already verified." - keyauthorization="$STATE_VERIFIED" - _debug keyauthorization "$keyauthorization" - fi fi dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot" From b3529dc7482e6a8d2bdbb0e77374d960b58974a1 Mon Sep 17 00:00:00 2001 From: seidler2547 Date: Mon, 27 Jun 2022 19:42:16 +0000 Subject: [PATCH 029/687] remove dns_do as it does not work anymore The API that it uses was shut down in May 2022 --- dnsapi/dns_do.sh | 148 ----------------------------------------------- 1 file changed, 148 deletions(-) delete mode 100755 dnsapi/dns_do.sh diff --git a/dnsapi/dns_do.sh b/dnsapi/dns_do.sh deleted file mode 100755 index 3850890c..00000000 --- a/dnsapi/dns_do.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env sh - -# DNS API for Domain-Offensive / Resellerinterface / Domainrobot - -# Report bugs at https://github.com/seidler2547/acme.sh/issues - -# set these environment variables to match your customer ID and password: -# DO_PID="KD-1234567" -# DO_PW="cdfkjl3n2" - -DO_URL="https://soap.resellerinterface.de/" - -######## Public functions ##################### - -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_do_add() { - fulldomain=$1 - txtvalue=$2 - if _dns_do_authenticate; then - _info "Adding TXT record to ${_domain} as ${fulldomain}" - _dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300 - if _contains "${response}" '>success<'; then - return 0 - fi - _err "Could not create resource record, check logs" - fi - return 1 -} - -#fulldomain -dns_do_rm() { - fulldomain=$1 - if _dns_do_authenticate; then - if _dns_do_list_rrs; then - _dns_do_had_error=0 - for _rrid in ${_rr_list}; do - _info "Deleting resource record $_rrid for $_domain" - _dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}" - if ! _contains "${response}" '>success<'; then - _dns_do_had_error=1 - _err "Could not delete resource record for ${_domain}, id ${_rrid}" - fi - done - return $_dns_do_had_error - fi - fi - return 1 -} - -#################### Private functions below ################################## -_dns_do_authenticate() { - _info "Authenticating as ${DO_PID}" - _dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}" - if _contains "${response}" '>success<'; then - _get_root "$fulldomain" - _debug "_domain $_domain" - return 0 - else - _err "Authentication failed, are DO_PID and DO_PW set correctly?" - fi - return 1 -} - -_dns_do_list_rrs() { - _dns_do_soap getRRList origin "${_domain}" - if ! _contains "${response}" 'SOAP-ENC:Array'; then - _err "getRRList origin ${_domain} failed" - return 1 - fi - _rr_list="$(echo "${response}" | - tr -d "\n\r\t" | - sed -e 's//\n/g' | - grep ">$(_regexcape "$fulldomain")" | - sed -e 's/<\/item>/\n/g' | - grep '>id[0-9]{1,16}<' | - tr -d '><')" - [ "${_rr_list}" ] -} - -_dns_do_soap() { - func="$1" - shift - # put the parameters to xml - body="" - while [ "$1" ]; do - _k="$1" - shift - _v="$1" - shift - body="$body<$_k>$_v" - done - body="$body" - _debug2 "SOAP request ${body}" - - # build SOAP XML - _xml=' - - '"$body"' -' - - # set SOAP headers - export _H1="SOAPAction: ${DO_URL}#${func}" - - if ! response="$(_post "${_xml}" "${DO_URL}")"; then - _err "Error <$1>" - return 1 - fi - _debug2 "SOAP response $response" - - # retrieve cookie header - _H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)" - export _H2 - - return 0 -} - -_get_root() { - domain=$1 - i=1 - - _dns_do_soap getDomainList - _all_domains="$(echo "${response}" | - tr -d "\n\r\t " | - _egrep_o 'domain]+>[^<]+' | - sed -e 's/^domain<\/key>]*>//g')" - - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - return 1 - fi - - if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then - _domain="$h" - return 0 - fi - - i=$(_math $i + 1) - done - _debug "$domain not found" - - return 1 -} - -_regexcape() { - echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g' -} From ba3e088b238382c76922fcf4a312819292bc75cb Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Thu, 7 Jul 2022 17:32:22 +0200 Subject: [PATCH 030/687] Improved error handling Improved error handling when result contains data-structure which might contain another status-flag that is related to the status of the related object and not the api call Revert "Improved error handling" This reverts commit fa6df1cfab134d38baad19fc1caa0842f00416d5. Revert "Revert "Improved error handling"" This reverts commit 5a4b78392f063863ee9f56686f5c429e9376af1b. --- dnsapi/dns_pleskxml.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 0f7dc241..e0b1724b 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -251,9 +251,12 @@ _call_api() { # Detect any that isn't "ok". None of the used calls should fail if the API is working correctly. # Also detect if there simply aren't any status lines (null result?) and report that, as well. + # Remove structure from result string, since it might contain values that are related to the status of the domain and not to the API request - statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *[^<]* *$')" - statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *ok *$')" + statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | sed '//,/<\/data>/d' | grep -c '^ *[^<]* *$')" + statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | sed '//,/<\/data>/d' | grep -c '^ *ok *$')" + _debug "statuslines_count_total=$statuslines_count_total." + _debug "statuslines_count_okay=$statuslines_count_okay." if [ -z "$statuslines_count_total" ]; then From b41d40da4010bc99bae3966dcc84df4b7b9abbd9 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sat, 9 Jul 2022 21:23:50 +0200 Subject: [PATCH 031/687] Extended debug logging in dns_pleskxml_rm() --- dnsapi/dns_pleskxml.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index e0b1724b..bcd72d9a 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -152,13 +152,23 @@ dns_pleskxml_rm() { _debug "Got list of DNS TXT records for root domain '$root_domain_name':" _debug "$reclist" - recid="$( + recline="$( _value "$reclist" | grep "${fulldomain}." | - grep "${txtvalue}" | + grep "${txtvalue}" + )" + + _debug "Got line for ${fulldomain}. and ${txtvalue}:" + _debug "$recline" + + recid="$( + _value "$recline" | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" + _debug "Got id from line:" + _debug $recid + if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." From 55a55e9f74a7c0842ed12d9e76d89b2c3232cdce Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sat, 9 Jul 2022 21:28:19 +0200 Subject: [PATCH 032/687] Fixed debug log to prevent globbing and word splitting. --- dnsapi/dns_pleskxml.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index bcd72d9a..56902e20 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -157,7 +157,7 @@ dns_pleskxml_rm() { grep "${fulldomain}." | grep "${txtvalue}" )" - + _debug "Got line for ${fulldomain}. and ${txtvalue}:" _debug "$recline" @@ -167,7 +167,7 @@ dns_pleskxml_rm() { )" _debug "Got id from line:" - _debug $recid + _debug "$recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" From bc7e02b47a7b04c367e08962a84a63170701f890 Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:11:27 +0200 Subject: [PATCH 033/687] Fixed removal of TXT record when subdomain is case-sensitive and improved debug logging Plesk SPI return domain names always lower-case. Therefore the search for domain names in the API response must be case-insensitve. Set debug logging to the values that are reallys used for the spi calls. added comment --- dnsapi/dns_pleskxml.sh | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 56902e20..a8f7f7be 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -145,32 +145,25 @@ dns_pleskxml_rm() { )" if [ -z "$reclist" ]; then - _err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting." + _err "No TXT records found for root domain $fulldomain (Plesk domain ID ${root_domain_id}). Exiting." return 1 fi - _debug "Got list of DNS TXT records for root domain '$root_domain_name':" + _debug "Got list of DNS TXT records for root Plesk domain ID ${root_domain_id} of root domain $fulldomain:" _debug "$reclist" - recline="$( - _value "$reclist" | - grep "${fulldomain}." | - grep "${txtvalue}" - )" - - _debug "Got line for ${fulldomain}. and ${txtvalue}:" - _debug "$recline" - + # Extracting the id of the TXT record for the full domain (NOT case-sensitive) and corresponding value recid="$( - _value "$recline" | + _value "$reclist" | + grep -i "${fulldomain}." | + grep "${txtvalue}" | sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" - _debug "Got id from line:" - _debug "$recid" + _debug "Got id from line: $recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then - _err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" + _err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" _err "Cannot delete TXT record. Exiting." return 1 fi From ca0981645fd0d855679e19565f59a40096c61fcf Mon Sep 17 00:00:00 2001 From: lufi42 <101186892+lufi42@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:34:30 +0200 Subject: [PATCH 034/687] Fixed shfmt error --- dnsapi/dns_pleskxml.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index a8f7f7be..799c374c 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -160,7 +160,7 @@ dns_pleskxml_rm() { sed 's/^.*\([0-9]\{1,\}\)<\/id>.*$/\1/' )" - _debug "Got id from line: $recid" + _debug "Got id from line: $recid" if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then _err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'" From d102943a324ba85992c8a7703152f2aedf35bbcc Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 7 Nov 2022 22:36:40 +0800 Subject: [PATCH 035/687] upgrade actions/checkout@v3 --- .github/workflows/DNS.yml | 16 ++++++++-------- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- .github/workflows/PebbleStrict.yml | 4 ++-- .github/workflows/Solaris.yml | 2 +- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- .github/workflows/dockerhub.yml | 2 +- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index dd031efd..17e98ae3 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -65,7 +65,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file @@ -113,7 +113,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install tools run: brew install socat - name: Clone acmetest @@ -164,7 +164,7 @@ jobs: - name: Set git to use LF run: | git config --global core.autocrlf false - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation @@ -223,7 +223,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/freebsd-vm@v0 @@ -274,7 +274,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/openbsd-vm@v0 @@ -325,7 +325,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/netbsd-vm@v0 @@ -377,7 +377,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/dragonflybsd-vm@v0 @@ -433,7 +433,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0 diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 2dff172a..46a572f0 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -45,7 +45,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index c9f1d623..d83c5d84 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -51,7 +51,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index d5c98a31..156fa5df 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -33,7 +33,7 @@ jobs: TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 TEST_ACME_Server: "LetsEncrypt.org_test" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Clone acmetest run: | cd .. \ diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index 1a0b4488..c1f29769 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -44,7 +44,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install tools run: brew install socat - name: Clone acmetest diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 136640a2..e0cb5586 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -45,7 +45,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index da46424a..f87ec207 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -51,7 +51,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 1740fc3f..9f3a98ce 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -33,7 +33,7 @@ jobs: TEST_CA: "Pebble Intermediate CA" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble @@ -58,7 +58,7 @@ jobs: TEST_IPCERT: 1 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 3488f78f..e1aea253 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -51,7 +51,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: vmactions/cf-tunnel@v0.0.3 id: tunnel with: diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 0a2ec971..a6ec714c 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -70,7 +70,7 @@ jobs: TestingDomain: ${{ matrix.TestingDomain }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install tools run: sudo apt-get install -y socat wget - name: Start StepCA diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index e5dfb172..c02e2f77 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -49,7 +49,7 @@ jobs: - name: Set git to use LF run: | git config --global core.autocrlf false - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 4d9f34b3..bd2c01aa 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -41,7 +41,7 @@ jobs: if: "contains(needs.CheckToken.outputs.hasToken, 'true')" steps: - name: checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx From 778ee02803098904be7dc5ec608665ad56060215 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Mon, 7 Nov 2022 23:43:37 +0100 Subject: [PATCH 036/687] update documentation for --cert-home Although the main use-case may be the --install command, this command also proves to be useful for the --signcsr and --issue commands. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d6d8e48c..9d6dfecc 100755 --- a/acme.sh +++ b/acme.sh @@ -6897,7 +6897,7 @@ Parameters: --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME. - --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. + --cert-home Specifies the home dir to save all the certs. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. -m, --email Specifies the account email, only valid for the '--install' and '--update-account' command. From 5a51454d136bb23eeb7d7fa6ca20bed00bfde7fd Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Thu, 17 Nov 2022 15:20:11 +0100 Subject: [PATCH 037/687] Update Alpine to 1.16.3 With #4399 applied we can pick minor versions safely. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 049649f6..79fd1d89 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16.3 RUN apk --no-cache add -f \ openssl \ From cdb238e41ce572647433880f3e3a4dd683990f3e Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:12:52 +0800 Subject: [PATCH 038/687] fix cf-tunnel --- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- .github/workflows/Solaris.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 46a572f0..6daa9be4 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -46,7 +46,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0 id: tunnel with: protocol: http diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index d83c5d84..0fa55fd4 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -52,7 +52,7 @@ jobs: ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0 id: tunnel with: protocol: http diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index e0cb5586..33bcf23c 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -46,7 +46,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0 id: tunnel with: protocol: http diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index f87ec207..7746645a 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -52,7 +52,7 @@ jobs: ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0 id: tunnel with: protocol: http diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index e1aea253..34d31a59 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -52,7 +52,7 @@ jobs: ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0.0.3 + - uses: vmactions/cf-tunnel@v0 id: tunnel with: protocol: http From 60315e5b91507802371253be2d4cf5c8ebc079fd Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:28:17 +0800 Subject: [PATCH 039/687] fix shellcheck warnings --- deploy/gitlab.sh | 2 +- dnsapi/dns_dynv6.sh | 8 ++++---- dnsapi/dns_edgedns.sh | 2 +- dnsapi/dns_infomaniak.sh | 4 ++-- dnsapi/dns_servercow.sh | 2 +- dnsapi/dns_vultr.sh | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index ba2d3122..d8a93ad2 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -67,7 +67,7 @@ gitlab_deploy() { error_response="error" - if test "${_response#*$error_response}" != "$_response"; then + if test ${_response#*"$error_response"} != "$_response"; then _err "Error in deploying certificate:" _err "$_response" return 1 diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 9efc9aeb..739eccf9 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -94,8 +94,8 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do #echo "host: $l" - if test "${_full_domain#*$l}" != "$_full_domain"; then - _record="${_full_domain%.$l}" + if test ${_full_domain#*"$l"} != "$_full_domain"; then + _record=${_full_domain%."$l"} _host=$l _debug "The host is $_host and the record $_record" return 0 @@ -143,7 +143,7 @@ _dns_dynv6_add_http() { return 1 fi _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" + record=${fulldomain%%."$_zone_name"} _set_record TXT "$record" "$txtvalue" if _contains "$response" "$txtvalue"; then _info "Successfully added record" @@ -161,7 +161,7 @@ _dns_dynv6_rm_http() { return 1 fi _get_zone_name "$_zone_id" - record="${fulldomain%%.$_zone_name}" + record=${fulldomain%%."$_zone_name"} _get_record_id "$_zone_id" "$record" "$txtvalue" _del_record "$_zone_id" "$_record_id" if [ -z "$response" ]; then diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 11c132fa..27650eb1 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -418,7 +418,7 @@ _edgedns_make_data_to_sign() { _secure_debug2 "hdr" "$hdr" _edgedns_make_content_hash path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')" - path="${path#*$AKAMAI_HOST}" + path=${path#*"$AKAMAI_HOST"} _debug "hier path" "$path" # dont expose headers to sign so use MT string _mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")" diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index 765cf39d..a005132c 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -76,7 +76,7 @@ dns_infomaniak_add() { domain_id=${zone_and_id#* } # extract first part of domain - key=${fulldomain%.$zone} + key=${fulldomain%."$zone"} _debug "zone:$zone id:$domain_id key:$key" @@ -149,7 +149,7 @@ dns_infomaniak_rm() { domain_id=${zone_and_id#* } # extract first part of domain - key=${fulldomain%.$zone} + key=${fulldomain%."$zone"} _debug "zone:$zone id:$domain_id key:$key" diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index f70a2294..52137905 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -53,7 +53,7 @@ dns_servercow_add() { if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then _info "A txt record with the same name already exists." # trim the string on the left - txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} + txtvalue_old=${response#*{\"name\":\""$_sub_domain"\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"} # trim the string on the right txtvalue_old=${txtvalue_old%%\"*} diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index bd925fdb..58f14be1 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -139,7 +139,7 @@ _vultr_rest() { data="$3" _debug "$ep" - api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"') + api_key_trimmed=$(echo "$VULTR_API_KEY" | tr -d '"') export _H1="Authorization: Bearer $api_key_trimmed" export _H2='Content-Type: application/json' From e275cb1efd295f3d688569fec2b467d894830b44 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:33:29 +0800 Subject: [PATCH 040/687] fix shellcheck warnings --- .github/workflows/shellcheck.yml | 2 +- deploy/gitlab.sh | 2 +- dnsapi/dns_dynv6.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index d628ea93..9beb5489 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -26,7 +26,7 @@ jobs: - name: Install Shellcheck run: sudo apt-get install -y shellcheck - name: DoShellcheck - run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" + run: shellcheck -V && shellcheck -e SC2181 -e SC2089 **/*.sh && echo "shellcheck OK" shfmt: runs-on: ubuntu-latest diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index d8a93ad2..595b6d20 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -67,7 +67,7 @@ gitlab_deploy() { error_response="error" - if test ${_response#*"$error_response"} != "$_response"; then + if test "${_response#*"$error_response"}" != "$_response"; then _err "Error in deploying certificate:" _err "$_response" return 1 diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 739eccf9..90814b1b 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -94,7 +94,7 @@ _get_domain() { _your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')" for l in $_your_hosts; do #echo "host: $l" - if test ${_full_domain#*"$l"} != "$_full_domain"; then + if test "${_full_domain#*"$l"}" != "$_full_domain"; then _record=${_full_domain%."$l"} _host=$l _debug "The host is $_host and the record $_record" From e684abdacde657ea2a22ecc627e4d63b209131d3 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:34:58 +0800 Subject: [PATCH 041/687] fix checkout --- .github/workflows/shellcheck.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 9beb5489..a5a08bbf 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -22,7 +22,7 @@ jobs: ShellCheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install Shellcheck run: sudo apt-get install -y shellcheck - name: DoShellcheck @@ -31,7 +31,7 @@ jobs: shfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install shfmt run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt From 3a1c6d84f0f4609e98239512357599cade4c807f Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:40:34 +0800 Subject: [PATCH 042/687] fix shellcheck warnings --- dnsapi/dns_oci.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 18d74410..3b81143f 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -265,6 +265,7 @@ _signed_request() { _response="$(_get "https://${_sig_host}${_sig_target}")" elif [ "$_curl_method" = "PATCH" ]; then export _H1="$_date_header" + # shellcheck disable=SC2090 export _H2="$_sig_body_sha256" export _H3="$_sig_body_type" export _H4="$_sig_body_length" From 7a756ebc4d08e60d5a127b220505d27fb54fe358 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:55:19 +0800 Subject: [PATCH 043/687] start v3.0.6 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d6d8e48c..4d4aceb1 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.5 +VER=3.0.6 PROJECT_NAME="acme.sh" From ec0e871592d286b8cd4e1d407411f0ba17c775e6 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2022 21:57:38 +0800 Subject: [PATCH 044/687] Use ec-256 as default key length fix https://github.com/acmesh-official/acme.sh/issues/2350#issuecomment-1324029469 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 4d4aceb1..c1a576a5 100755 --- a/acme.sh +++ b/acme.sh @@ -53,8 +53,8 @@ CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$ DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" -DEFAULT_ACCOUNT_KEY_LENGTH=2048 -DEFAULT_DOMAIN_KEY_LENGTH=2048 +DEFAULT_ACCOUNT_KEY_LENGTH=ec-256 +DEFAULT_DOMAIN_KEY_LENGTH=ec-256 DEFAULT_OPENSSL_BIN="openssl" From f4ed1b32b85d3cdf256168e698bc8e4261db7a3e Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Sat, 26 Nov 2022 18:12:11 +0330 Subject: [PATCH 045/687] Update dns_arvan.sh Update API URL --- dnsapi/dns_arvan.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 4c9217e5..2118883b 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -2,7 +2,7 @@ #Arvan_Token="Apikey xxxx" -ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" +ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains" #Author: Vahid Fardi #Report Bugs here: https://github.com/Neilpang/acme.sh # @@ -18,7 +18,7 @@ dns_arvan_add() { if [ -z "$Arvan_Token" ]; then _err "You didn't specify \"Arvan_Token\" token yet." - _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" + _err "You can get yours from here https://npanel.arvancloud.ir/profile/api-keys" return 1 fi #save the api token to the account conf file. From 9f942a6b65bda8c97dbd989549a0ced034cb6f42 Mon Sep 17 00:00:00 2001 From: Kiril Isakov Date: Sat, 26 Nov 2022 16:00:03 +0100 Subject: [PATCH 046/687] Trim trailing slash in `--home` argument's value # What's expected Since in `acme.sh` path strings are concatenated with a hardcoded slash in between, the left operand must never end with a trailing slash for the resulting path to be valid. Otherwise, obviously, the resulting path will have two adjacent slashes in the middle and will not be valid. # What actually happens Even though I cannot tell for each of the input params, I know this for sure for the the `--home` argument's value. If I run `acme.sh` with `--home` argument's value being a path ending in a trailing slash, ```sh acme.sh ... --debug ... --home /some/path/ ... -d somedomainna.me ... ``` I get the following (distinct) occurrencies of resulting invalid paths containing two adjacent slashes: ``` [...] Using config home:/some/path/ [...] DOMAIN_PATH='/some/path//somedomainna.me' [...] _CURL='curl --silent --dump-header /some/path//http.header -L -g ' [...] The domain key is here: /some/path//somedomainna.me/somedomainna.me.key [...] _CURL='curl --silent --dump-header /some/path//http.header -L -g -I ' [...] Your cert is in: /some/path//somedomainna.me/somedomainna.me.cer [...] Your cert key is in: /some/path//somedomainna.me/somedomainna.me.key [...] The intermediate CA cert is in: /some/path//somedomainna.me/ca.cer [...] And the full chain certs is there: /some/path//somedomainna.me/fullchain.cer ``` # Suggested fix Trim trailing slash in `--home` argument's value from the get-go. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d6d8e48c..77f0b8c1 100755 --- a/acme.sh +++ b/acme.sh @@ -7496,7 +7496,7 @@ _process() { shift ;; --home) - export LE_WORKING_DIR="$2" + export LE_WORKING_DIR="${2%/}" shift ;; --cert-home | --certhome) From ecf1f17cf4088cfab6e891a7002c445fa4bb6a8e Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 27 Nov 2022 11:10:14 +0800 Subject: [PATCH 047/687] update key type --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 30e6e554..15bc4089 100644 --- a/README.md +++ b/README.md @@ -361,10 +361,6 @@ Ok, it's done. # 10. Issue ECC certificates -`Let's Encrypt` can now issue **ECDSA** certificates. - -And we support them too! - Just set the `keylength` parameter with a prefix `ec-`. For example: @@ -385,10 +381,12 @@ Please look at the `keylength` parameter above. Valid values are: -1. **ec-256 (prime256v1, "ECDSA P-256")** +1. **ec-256 (prime256v1, "ECDSA P-256", which is the default key type)** 2. **ec-384 (secp384r1, "ECDSA P-384")** 3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)** - +4. **2048 (RSA2048)** +5. **3072 (RSA3072)** +6. **4096 (RSA4096)** # 11. Issue Wildcard certificates From 4610204c831d39716d792bd975dbbda65ac06699 Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Sun, 27 Nov 2022 10:21:24 +0330 Subject: [PATCH 048/687] Test CI --- dnsapi/dns_arvan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 2118883b..593e789f 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,10 +1,10 @@ #!/usr/bin/env sh -#Arvan_Token="Apikey xxxx" +# Arvan_Token="Apikey xxxx" ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains" -#Author: Vahid Fardi -#Report Bugs here: https://github.com/Neilpang/acme.sh +# Author: Vahid Fardi +# Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### From 264b9819ff92655c0714cc46e6a756201ffd9c9a Mon Sep 17 00:00:00 2001 From: Kiril Isakov Date: Sun, 27 Nov 2022 09:22:06 +0100 Subject: [PATCH 049/687] Replace the BASH parameter substitution mechanism (unsupported by sh) with standard commands (supported by sh) --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 77f0b8c1..714bd9bf 100755 --- a/acme.sh +++ b/acme.sh @@ -7496,7 +7496,7 @@ _process() { shift ;; --home) - export LE_WORKING_DIR="${2%/}" + export LE_WORKING_DIR="$(echo "$2" | sed 's|/$||')" shift ;; --cert-home | --certhome) From 04a5d794ac05acee31018a72d8e6df216a5f7e33 Mon Sep 17 00:00:00 2001 From: beartom <369622765@qq.com> Date: Sun, 27 Nov 2022 21:55:01 +0800 Subject: [PATCH 050/687] Update truenas.sh for certificate in chart release Update certificate in chart release of TrueCharts if any chart release Apps is using the same certificate as TrueNAS web UI. --- deploy/truenas.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 84cfd5f4..3f36a56e 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -184,6 +184,30 @@ truenas_deploy() { _info "S3 certificate is not configured or is not the same as TrueNAS web UI" fi + +_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" + if _exists jq; then + _info "Query all chart release" + _release_list=$(_get "$_api_url/chart/release") + _related_name_list=$(printf "%s" $_release_list | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") + _release_length=$(printf "%s" $_related_name_list | jq -r "length") + _info "Found $_release_length related chart release in list: $_related_name_list" + for i in $(seq 0 $((_release_length-1))); + do + _release_name=$(echo $_related_name_list | jq -r ".[$i]") + _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" + #Read the chart release configuration + _chart_config=$(printf "%s" $_release_list | jq -r ".[] | select(.name==\"$_release_name\")") + #Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress + _updated_chart_config=$(printf "%s" $_chart_config | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress " ) + _update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")" + _debug3 _update_chart_result "$_update_chart_result" + done + else + _info "Tool 'jq' does not exists, skip chart release checking" + fi + + _info "Deleting old certificate" _delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" From c07db3aa14e28689ee673832cf147494fb2ae2d4 Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Mon, 28 Nov 2022 16:09:17 +0330 Subject: [PATCH 051/687] add 'Accept' header --- dnsapi/dns_arvan.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 593e789f..b8c9da35 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -141,10 +141,11 @@ _arvan_rest() { response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" elif [ "$mtd" = "POST" ]; then export _H2="Content-Type: application/json" + export _H3="Accept: application/json" _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" else response="$(_get "$ARVAN_API_URL/$ep$data")" fi return 0 -} +} \ No newline at end of file From eab9603921789b541a8d8527b833a50f313f1381 Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Mon, 28 Nov 2022 16:11:17 +0330 Subject: [PATCH 052/687] Fix SH format --- dnsapi/dns_arvan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index b8c9da35..71ef2387 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -148,4 +148,4 @@ _arvan_rest() { response="$(_get "$ARVAN_API_URL/$ep$data")" fi return 0 -} \ No newline at end of file +} From 0c0d1d4e5210bd5b03f91df789f2471b09e849c7 Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Mon, 28 Nov 2022 16:22:25 +0330 Subject: [PATCH 053/687] Update duplicate message --- dnsapi/dns_arvan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 71ef2387..4ca5b685 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -40,7 +40,7 @@ dns_arvan_add() { _info "response id is $response" _info "Added, OK" return 0 - elif _contains "$response" "Record Data is Duplicated"; then + elif _contains "$response" "Record Data is duplicate"; then _info "Already exists, OK" return 0 else From bd2d0e6ad3c9dfad76cfe30e79d845fc62c8e228 Mon Sep 17 00:00:00 2001 From: beartom <369622765@qq.com> Date: Mon, 28 Nov 2022 20:59:10 +0800 Subject: [PATCH 054/687] Format Format --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 3f36a56e..6b299f3a 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -185,7 +185,7 @@ truenas_deploy() { fi -_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" + _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then _info "Query all chart release" _release_list=$(_get "$_api_url/chart/release") From 5a0225d03365d1bc36c4c18570d28d2ef97cc99e Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Tue, 29 Nov 2022 12:21:49 +0330 Subject: [PATCH 055/687] Fix export problem for special values --- .github/workflows/DNS.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 17e98ae3..55dec225 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -121,19 +121,19 @@ jobs: - name: Run acmetest run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh From 257de15c738d05780321fd5131671e59e1294931 Mon Sep 17 00:00:00 2001 From: Arash Hatami Date: Tue, 29 Nov 2022 13:45:04 +0330 Subject: [PATCH 056/687] Fix export problems --- .github/workflows/DNS.yml | 60 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 55dec225..615e5d8b 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -184,19 +184,19 @@ jobs: shell: bash run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh @@ -234,19 +234,19 @@ jobs: copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh @@ -285,19 +285,19 @@ jobs: copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh @@ -337,19 +337,19 @@ jobs: copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh @@ -389,19 +389,19 @@ jobs: copyback: false run: | if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh @@ -445,19 +445,19 @@ jobs: pkg set-mediator -v -I default@1.1 openssl export PATH=/usr/gnu/bin:$PATH if [ "${{ secrets.TokenName1}}" ] ; then - export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi if [ "${{ secrets.TokenName2}}" ] ; then - export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}} + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" fi if [ "${{ secrets.TokenName3}}" ] ; then - export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}} + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" fi if [ "${{ secrets.TokenName4}}" ] ; then - export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}} + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" fi if [ "${{ secrets.TokenName5}}" ] ; then - export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}} + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" fi cd ../acmetest ./letest.sh From 7d13146859552faf630205072a1fe337476436ba Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Tue, 29 Nov 2022 21:39:06 +0100 Subject: [PATCH 057/687] Added dns provider for ipv64.net --- dnsapi/dns_ipv64.sh | 150 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 dnsapi/dns_ipv64.sh diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh new file mode 100755 index 00000000..90207ba6 --- /dev/null +++ b/dnsapi/dns_ipv64.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env sh + +#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records +#2022/11/29 + +# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..." +# -- +# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa" +# -- +# + +IPv64_API="https://ipv64.net/api" + +######## Public functions ###################### + +#Usage: dns_ipv64_add _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_ipv64_add() { + fulldomain=$1 + txtvalue=$2 + + IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}" + if [ -z "$IPv64_Token" ]; then + _err "You must export variable: IPv64_Token" + _err "The API Key for your IPv64 account is necessary." + _err "You can look it up in your IPv64 account." + return 1 + fi + + # Now save the credentials. + _saveaccountconf_mutable IPv64_Token "$IPv64_Token" + + if ! _get_root "$fulldomain"; then + _err "invalid domain" "$fulldomain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # Now add the TXT record + _info "Trying to add TXT record" + if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then + _info "TXT record has been successfully added." + return 0 + else + _err "Errors happened during adding the TXT record, response=$_response" + return 1 + fi + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_ipv64_rm() { + fulldomain=$1 + txtvalue=$2 + + IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}" + if [ -z "$IPv64_Token" ]; then + _err "You must export variable: IPv64_Token" + _err "The API Key for your IPv64 account is necessary." + _err "You can look it up in your IPv64 account." + return 1 + fi + + if ! _get_root "$fulldomain"; then + _err "invalid domain" "$fulldomain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + # Now delete the TXT record + _info "Trying to delete TXT record" + if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then + _info "TXT record has been successfully deleted." + return 0 + else + _err "Errors happened during deleting the TXT record, response=$_response" + return 1 + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain="$1" + i=1 + p=1 + + _ipv64_get "get_domains" + domain_data=$_response + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + #if _contains "$domain_data" "\""$h"\"\:"; then + if _contains "$domain_data" "\"""$h""\"\:"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain="$h" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +#send get request to api +# $1 has to set the api-function +_ipv64_get() { + url="$IPv64_API?$1" + export _H1="Authorization: Bearer $IPv64_Token" + + _response=$(_get "$url") + _response="$(echo "$_response" | _normalizeJson)" + + if _contains "$_response" "429 Too Many Requests"; then + _info "API throttled, sleeping to reset the limit" + _sleep 10 + _response=$(_get "$url") + _response="$(echo "$_response" | _normalizeJson)" + fi +} + +_ipv64_rest() { + url="$IPv64_API" + export _H1="Authorization: Bearer $IPv64_Token" + export _H2="Content-Type: application/x-www-form-urlencoded" + _response=$(_post "$2" "$url" "" "$1") + + if _contains "$_response" "429 Too Many Requests"; then + _info "API throttled, sleeping to reset the limit" + _sleep 10 + _response=$(_post "$2" "$url" "" "$1") + fi + + if ! _contains "$_response" "\"info\":\"success\""; then + return 1 + fi + _debug2 response "$_response" + return 0 +} From 91e387e8b9deae01b4a7dd45c70c08bf35ee3574 Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Wed, 30 Nov 2022 08:55:27 +0100 Subject: [PATCH 058/687] added doc for dns_ipv64_rm --- dnsapi/dns_ipv64.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index 90207ba6..9979be42 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -49,6 +49,7 @@ dns_ipv64_add() { } #Usage: fulldomain txtvalue +#Usage: dns_ipv64_rm _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Remove the txt record after validation. dns_ipv64_rm() { fulldomain=$1 From a2af26635fe679af3892deffc671abe93c5f0b38 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Dec 2022 15:05:30 +0800 Subject: [PATCH 059/687] use ecc cert --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 0b5c1614..62add812 100755 --- a/acme.sh +++ b/acme.sh @@ -2857,7 +2857,8 @@ _initpath() { DOMAIN_PATH="$domainhomeecc" else if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then - _info "The domain '$domain' seems to have a ECC cert already, please add '$(__red "--ecc")' parameter if you want to use that cert." + _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert." + DOMAIN_PATH="$domainhomeecc" fi fi _debug DOMAIN_PATH "$DOMAIN_PATH" From 160513c67189b252434ddc52346a0d58843d004a Mon Sep 17 00:00:00 2001 From: Zachary Peschke Date: Fri, 9 Dec 2022 09:47:19 -0700 Subject: [PATCH 060/687] Minor grammar fixes for gd --- dnsapi/dns_gd.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 44c3d279..1729115e 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -22,8 +22,8 @@ dns_gd_add() { if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then GD_Key="" GD_Secret="" - _err "You don't specify godaddy api key and secret yet." - _err "Please create you key and try again." + _err "You didn't specify godaddy api key and secret yet." + _err "Please create your key and try again." return 1 fi @@ -46,7 +46,7 @@ dns_gd_add() { fi if _contains "$response" "$txtvalue"; then - _info "The record is existing, skip" + _info "This record already exists, skipping" return 0 fi From 764a4c99fac9f59f79638648d0499ef2e293ead5 Mon Sep 17 00:00:00 2001 From: plummer86 Date: Sun, 18 Dec 2022 22:32:49 +0000 Subject: [PATCH 061/687] Fix assignment to _wget_out --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d6d8e48c..02bc041c 100755 --- a/acme.sh +++ b/acme.sh @@ -2058,7 +2058,7 @@ _get() { fi _debug "_WGET" "$_WGET" if [ "$onlyheader" ]; then - _wget_out = "$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)" + _wget_out="$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)" if _contains "$_WGET" " -d "; then # Demultiplex wget debug output echo "$_wget_out" >&2 From 0cafc00c4fdac30032168450d97b468c23199f3c Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 17:22:12 +0800 Subject: [PATCH 062/687] append --fail-with-body argument to curl if supported --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index f4afa397..5d80399f 100755 --- a/acme.sh +++ b/acme.sh @@ -1855,6 +1855,11 @@ _inithttp() { if _contains "$(curl --help 2>&1)" "--globoff"; then _ACME_CURL="$_ACME_CURL -g " fi + + #from curl 7.76: return fail on HTTP errors but keep the body + if [ "$_ACME_CURL" ] && _contains "$($_ACME_CURL --help http)" "--fail-with-body"; then + _ACME_CURL="$_ACME_CURL --fail-with-body " + fi fi if [ -z "$_ACME_WGET" ] && _exists "wget"; then From 057c95bd1c0ebcfb30d0ab36aa267fcc544a87f7 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 17:24:34 +0800 Subject: [PATCH 063/687] improve `wget --content-on-error` condition --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 5d80399f..45dda74f 100755 --- a/acme.sh +++ b/acme.sh @@ -1877,11 +1877,11 @@ _inithttp() { elif [ "$CA_BUNDLE" ]; then _ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE " fi - fi - #from wget 1.14: do not skip body on 404 error - if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--content-on-error"; then - _ACME_WGET="$_ACME_WGET --content-on-error " + #from wget 1.14: do not skip body on 404 error + if _contains "$(wget --help 2>&1)" "--content-on-error"; then + _ACME_WGET="$_ACME_WGET --content-on-error " + fi fi __HTTP_INITIALIZED=1 From 7154c9ee5dd07d29d85a949e4853d3482333a360 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 17:42:27 +0800 Subject: [PATCH 064/687] improve `curl --help` predication --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 45dda74f..999ef563 100755 --- a/acme.sh +++ b/acme.sh @@ -1852,12 +1852,12 @@ _inithttp() { _ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE " fi - if _contains "$(curl --help 2>&1)" "--globoff"; then + if _contains "$(curl --help curl 2>&1)" "--globoff"; then _ACME_CURL="$_ACME_CURL -g " fi #from curl 7.76: return fail on HTTP errors but keep the body - if [ "$_ACME_CURL" ] && _contains "$($_ACME_CURL --help http)" "--fail-with-body"; then + if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then _ACME_CURL="$_ACME_CURL --fail-with-body " fi fi From fe1bfe9ae16b03e6647f47ee62809ed8641bf51c Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 16:34:18 +0800 Subject: [PATCH 065/687] improve vault and vault_api deployhooks --- deploy/vault.sh | 75 +++++++++++++++++++++++++++++++++++++-------- deploy/vault_cli.sh | 43 +++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 13 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 399abaee..2e4d0702 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -7,13 +7,16 @@ # # VAULT_PREFIX - this contains the prefix path in vault # VAULT_ADDR - vault requires this to find your vault server +# VAULT_SAVE_TOKEN - set to anything if you want to save the token +# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying +# VAULT_KV_V2 - set to anything if you are using v2 of the kv engine # # additionally, you need to ensure that VAULT_TOKEN is avialable # to access the vault server #returns 0 means success, otherwise error. -######## Public functions ##################### +######## Public functions ##################### #domain keyfile certfile cafile fullchain vault_deploy() { @@ -45,6 +48,24 @@ vault_deploy() { fi _savedeployconf VAULT_ADDR "$VAULT_ADDR" + _getdeployconf VAULT_SAVE_TOKEN + _savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN" + + _getdeployconf VAULT_RENEW_TOKEN + _savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN" + + _getdeployconf VAULT_KV_V2 + _savedeployconf VAULT_KV_V2 "$VAULT_KV_V2" + + _getdeployconf VAULT_TOKEN + if [ -z "$VAULT_TOKEN" ]; then + _err "VAULT_TOKEN needs to be defined" + return 1 + fi + if [ -n "$VAULT_SAVE_TOKEN" ]; then + _savedeployconf VAULT_TOKEN "$VAULT_TOKEN" + fi + # JSON does not allow multiline strings. # So replacing new-lines with "\n" here _ckey=$(sed -z 's/\n/\\n/g' <"$2") @@ -52,26 +73,56 @@ vault_deploy() { _cca=$(sed -z 's/\n/\\n/g' <"$4") _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") - URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" export _H1="X-Vault-Token: $VAULT_TOKEN" + if [ -n "$VAULT_RENEW_TOKEN" ]; then + URL="$VAULT_ADDR/v1/auth/token/renew-self" + _info "Renew the token to default TTL" + if ! _post "" "$URL" >/dev/null; then + _err "Failed to renew the token" + return 1 + fi + fi + + URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" + if [ -n "$FABIO" ]; then + _info "Writing certificate and key to $URL in Fabio mode" if [ -n "$VAULT_KV_V2" ]; then - _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" + _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1 else - _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" + _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1 fi else if [ -n "$VAULT_KV_V2" ]; then - _post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" - _post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" - _post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" - _post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" + _info "Writing certificate to $URL/cert.pem" + _post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1 + _info "Writing key to $URL/cert.key" + _post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1 + _info "Writing CA certificate to $URL/ca.pem" + _post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1 + _info "Writing full-chain certificate to $URL/fullchain.pem" + _post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1 else - _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" - _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" - _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" - _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" + _info "Writing certificate to $URL/cert.pem" + _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1 + _info "Writing key to $URL/cert.key" + _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1 + _info "Writing CA certificate to $URL/ca.pem" + _post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1 + _info "Writing full-chain certificate to $URL/fullchain.pem" + _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1 + fi + + # To make it compatible with the wrong ca path `chain.pem` which was used in former versions + if _get "$URL/chain.pem" >/dev/null; then + _err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning" + _info "Updating CA certificate to $URL/chain.pem for backward compatibility" + if [ -n "$VAULT_KV_V2" ]; then + _post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1 + else + _post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1 + fi fi fi diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index cbb8cc59..da6fe093 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -8,6 +8,8 @@ # # VAULT_PREFIX - this contains the prefix path in vault # VAULT_ADDR - vault requires this to find your vault server +# VAULT_SAVE_TOKEN - set to anything if you want to save the token +# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying # # additionally, you need to ensure that VAULT_TOKEN is avialable or # `vault auth` has applied the appropriate authorization for the vault binary @@ -33,15 +35,34 @@ vault_cli_deploy() { _debug _cfullchain "$_cfullchain" # validate required env vars + _getdeployconf VAULT_PREFIX if [ -z "$VAULT_PREFIX" ]; then _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" return 1 fi + _savedeployconf VAULT_PREFIX "$VAULT_PREFIX" + _getdeployconf VAULT_ADDR if [ -z "$VAULT_ADDR" ]; then _err "VAULT_ADDR needs to be defined (contains vault connection address)" return 1 fi + _savedeployconf VAULT_ADDR "$VAULT_ADDR" + + _getdeployconf VAULT_SAVE_TOKEN + _savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN" + + _getdeployconf VAULT_RENEW_TOKEN + _savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN" + + _getdeployconf VAULT_TOKEN + if [ -z "$VAULT_TOKEN" ]; then + _err "VAULT_TOKEN needs to be defined" + return 1 + fi + if [ -n "$VAULT_SAVE_TOKEN" ]; then + _savedeployconf VAULT_TOKEN "$VAULT_TOKEN" + fi VAULT_CMD=$(command -v vault) if [ ! $? ]; then @@ -49,13 +70,33 @@ vault_cli_deploy() { return 1 fi + if [ -n "$VAULT_RENEW_TOKEN" ]; then + _info "Renew the token to default TTL" + if ! $VAULT_CMD token renew; then + _err "Failed to renew the token" + return 1 + fi + fi + if [ -n "$FABIO" ]; then + _info "Writing certificate and key to $URL in Fabio mode" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 else + _info "Writing certificate to $URL/cert.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 + _info "Writing key to $URL/cert.key" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 - $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + _info "Writing CA certificate to $URL/ca.pem" + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1 + _info "Writing full-chain certificate to $URL/fullchain.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 + + # To make it compatible with the wrong ca path `chain.pem` which was used in former versions + if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then + _err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning" + _info "Updating CA certificate to $URL/chain.pem for backward compatibility" + $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 + fi fi } From b8d0d3c2429e2f33dceb9c94ad8e5273762be72a Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 19:17:37 +0800 Subject: [PATCH 066/687] improve chain.pem exists evaluating --- deploy/vault.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 2e4d0702..6c953fc6 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -115,7 +115,7 @@ vault_deploy() { fi # To make it compatible with the wrong ca path `chain.pem` which was used in former versions - if _get "$URL/chain.pem" >/dev/null; then + if _contains "$(_get "$URL/chain.pem")" "-----BEGIN CERTIFICATE-----"; then _err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning" _info "Updating CA certificate to $URL/chain.pem for backward compatibility" if [ -n "$VAULT_KV_V2" ]; then From ed63eb6833ab288b2a963255875bf9df99e39c79 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 23 Dec 2022 19:32:06 +0800 Subject: [PATCH 067/687] migrate FABIO to VAULT_FABIO_MODE and persist it --- deploy/vault.sh | 4 +++- deploy/vault_cli.sh | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 6c953fc6..30e825eb 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -66,6 +66,8 @@ vault_deploy() { _savedeployconf VAULT_TOKEN "$VAULT_TOKEN" fi + _migratedeployconf FABIO VAULT_FABIO_MODE + # JSON does not allow multiline strings. # So replacing new-lines with "\n" here _ckey=$(sed -z 's/\n/\\n/g' <"$2") @@ -86,7 +88,7 @@ vault_deploy() { URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" - if [ -n "$FABIO" ]; then + if [ -n "$VAULT_FABIO_MODE" ]; then _info "Writing certificate and key to $URL in Fabio mode" if [ -n "$VAULT_KV_V2" ]; then _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1 diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index da6fe093..ecbffd23 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -64,6 +64,8 @@ vault_cli_deploy() { _savedeployconf VAULT_TOKEN "$VAULT_TOKEN" fi + _migratedeployconf FABIO VAULT_FABIO_MODE + VAULT_CMD=$(command -v vault) if [ ! $? ]; then _err "cannot find vault binary!" @@ -78,7 +80,7 @@ vault_cli_deploy() { fi fi - if [ -n "$FABIO" ]; then + if [ -n "$VAULT_FABIO_MODE" ]; then _info "Writing certificate and key to $URL in Fabio mode" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 else From 7b623f85cd9dcf49958b0431d397ff75bda2a189 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 26 Dec 2022 21:43:02 +0800 Subject: [PATCH 068/687] minor --- .github/workflows/NetBSD.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 33bcf23c..25872c42 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -61,7 +61,6 @@ jobs: nat: | "8080": "80" prepare: | - export PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/" pkg_add curl socat usesh: true copyback: false From a2c64e79ff1b597b15d7bf7cb17aa627e7b7eb3f Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 26 Dec 2022 22:28:08 +0800 Subject: [PATCH 069/687] fix for openbsd --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index f4afa397..d8a46a6f 100755 --- a/acme.sh +++ b/acme.sh @@ -1637,7 +1637,7 @@ _stat() { #keyfile _isRSA() { keyfile=$1 - if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text | grep "^publicExponent:" >/dev/null 2>&1; then + if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text 2>&1 | grep "^publicExponent:" 2>&1 >/dev/null; then return 0 fi return 1 @@ -1646,7 +1646,7 @@ _isRSA() { #keyfile _isEcc() { keyfile=$1 - if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" >/dev/null 2>&1; then + if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" 2>&1 >/dev/null; then return 0 fi return 1 @@ -1744,7 +1744,7 @@ _calcjwk() { _debug3 x64 "$x64" xend=$(_math "$xend" + 1) - y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-10000)" + y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-2048)" _debug3 y "$y" y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)" From 1ccfa96c2e2c78aaca1ba92549e62b9f52fa9461 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Wed, 28 Dec 2022 02:47:49 +0800 Subject: [PATCH 070/687] improve logging --- deploy/vault.sh | 4 ++-- deploy/vault_cli.sh | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 30e825eb..569faba2 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -79,9 +79,9 @@ vault_deploy() { if [ -n "$VAULT_RENEW_TOKEN" ]; then URL="$VAULT_ADDR/v1/auth/token/renew-self" - _info "Renew the token to default TTL" + _info "Renew the Vault token to default TTL" if ! _post "" "$URL" >/dev/null; then - _err "Failed to renew the token" + _err "Failed to renew the Vault token" return 1 fi fi diff --git a/deploy/vault_cli.sh b/deploy/vault_cli.sh index ecbffd23..3ebb8074 100644 --- a/deploy/vault_cli.sh +++ b/deploy/vault_cli.sh @@ -73,30 +73,30 @@ vault_cli_deploy() { fi if [ -n "$VAULT_RENEW_TOKEN" ]; then - _info "Renew the token to default TTL" + _info "Renew the Vault token to default TTL" if ! $VAULT_CMD token renew; then - _err "Failed to renew the token" + _err "Failed to renew the Vault token" return 1 fi fi if [ -n "$VAULT_FABIO_MODE" ]; then - _info "Writing certificate and key to $URL in Fabio mode" + _info "Writing certificate and key to ${VAULT_PREFIX}/${_cdomain} in Fabio mode" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 else - _info "Writing certificate to $URL/cert.pem" + _info "Writing certificate to ${VAULT_PREFIX}/${_cdomain}/cert.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 - _info "Writing key to $URL/cert.key" + _info "Writing key to ${VAULT_PREFIX}/${_cdomain}/cert.key" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 - _info "Writing CA certificate to $URL/ca.pem" + _info "Writing CA certificate to ${VAULT_PREFIX}/${_cdomain}/ca.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1 - _info "Writing full-chain certificate to $URL/fullchain.pem" + _info "Writing full-chain certificate to ${VAULT_PREFIX}/${_cdomain}/fullchain.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 # To make it compatible with the wrong ca path `chain.pem` which was used in former versions if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then _err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning" - _info "Updating CA certificate to $URL/chain.pem for backward compatibility" + _info "Updating CA certificate to ${VAULT_PREFIX}/${_cdomain}/chain.pem for backward compatibility" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 fi fi From 27f30631ed48636a02aeb4cbe67de8a68e0e3615 Mon Sep 17 00:00:00 2001 From: Gavin Leo Date: Sun, 27 Nov 2022 21:32:20 +0800 Subject: [PATCH 071/687] Add gcore dns support. https://apidocs.gcore.com/dns --- dnsapi/dns_gcore.sh | 187 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100755 dnsapi/dns_gcore.sh diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh new file mode 100755 index 00000000..d549a650 --- /dev/null +++ b/dnsapi/dns_gcore.sh @@ -0,0 +1,187 @@ +#!/usr/bin/env sh + +# +#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb' +# + +GCORE_Api="https://api.gcorelabs.com/dns/v2" +GCORE_Doc="https://apidocs.gcore.com/dns" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_gcore_add() { + fulldomain=$1 + txtvalue=$2 + + GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}" + + if [ -z "$GCORE_Key" ]; then + GCORE_Key="" + _err "You didn't specify a Gcore api key yet." + _err "You can get yours from here $GCORE_Doc" + return 1 + fi + + #save the api key to the account conf file. + _saveaccountconf_mutable GCORE_Key "$GCORE_Key" + + _debug "First detect the zone name" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _zone_name "$_zone_name" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _gcore_rest GET "zones/$_zone_name/$fulldomain/TXT" + payload="" + + if echo "$response" | grep "record is not found" >/dev/null; then + _info "Record doesn't exists" + payload="{\"resource_records\":[{\"content\":[\"$txtvalue\"],\"enabled\":true}],\"ttl\":120}" + elif echo "$response" | grep "$txtvalue" >/dev/null; then + _info "Already exists, OK" + return 0 + elif echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then + _info "Record with mismatch txtvalue, try update it" + payload=$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/') + fi + + # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so + # we can not use updating anymore. + # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + # _debug count "$count" + # if [ "$count" = "0" ]; then + _info "Adding record" + if _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "rrset is already exists"; then + _info "Already exists, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 +} + +#fulldomain txtvalue +dns_gcore_rm() { + fulldomain=$1 + txtvalue=$2 + + GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _zone_name "$_zone_name" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _gcore_rest GET "zones/$_zone_name/$fulldomain/TXT" + + if echo "$response" | grep "record is not found" >/dev/null; then + _info "No such txt recrod" + return 0 + fi + + if ! echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then + _err "Error: $response" + return 1 + fi + + if ! echo "$response" | tr -d " " | grep \""$txtvalue"\" >/dev/null; then + _info "No such txt recrod" + return 0 + fi + + count="$(echo "$response" | grep -o "content" | wc -l)" + + if [ "$count" = "1" ]; then + if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT"; then + _err "Delete record error. $response" + return 1 + fi + return 0 + fi + + payload="$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//' | sed 's/\[,/\[/' | sed 's/,,/,/' | sed 's/,\]/\]/')" + if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then + _err "Delete record error. $response" + fi +} + +#################### Private functions below ################################## +#_acme-challenge.sub.domain.com +#returns +# _sub_domain=_acme-challenge.sub or _acme-challenge +# _domain=domain.com +# _zone_name=domain.com or sub.domain.com +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _gcore_rest GET "zones/$h"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\""; then + _zone_name=$h + if [ "$_zone_name" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_gcore_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + key_trimmed=$(echo "$GCORE_Key" | tr -d '"') + + export _H1="Content-Type: application/json" + export _H2="Authorization: APIKey $key_trimmed" + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$GCORE_Api/$ep" "" "$m")" + else + response="$(_get "$GCORE_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 1bfd3642e829bcd90b5c5e43371f975eb525165e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E9=9B=AA=E6=AE=87=E7=92=83=E9=99=8C=E6=A2=A6?= Date: Thu, 19 Jan 2023 10:19:05 +0800 Subject: [PATCH 072/687] Update gcore_cdn.sh --- deploy/gcore_cdn.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/deploy/gcore_cdn.sh b/deploy/gcore_cdn.sh index f573a3aa..fd17cc25 100644 --- a/deploy/gcore_cdn.sh +++ b/deploy/gcore_cdn.sh @@ -1,10 +1,11 @@ #!/usr/bin/env sh -# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). +# Here is the script to deploy the cert to G-Core CDN service (https://gcore.com/) using the G-Core Labs API (https://apidocs.gcore.com/cdn). # Returns 0 when success. # # Written by temoffey # Public domain, 2019 +# Update by DreamOfIce in 2023 #export DEPLOY_GCORE_CDN_USERNAME=myusername #export DEPLOY_GCORE_CDN_PASSWORD=mypassword @@ -56,7 +57,7 @@ gcore_cdn_deploy() { _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _debug _request "$_request" export _H1="Content-Type:application/json" - _response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login") + _response=$(_post "$_request" "https://api.gcore.com/auth/jwt/login") _debug _response "$_response" _regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$" _debug _regex "$_regex" @@ -69,8 +70,8 @@ gcore_cdn_deploy() { fi _info "Find CDN resource with cname $_cdomain" - export _H2="Authorization:Token $_token" - _response=$(_get "https://api.gcdn.co/resources") + export _H2="Authorization:Bearer $_token" + _response=$(_get "https://api.gcore.com/cdn/resources") _debug _response "$_response" _regex="\"primary_resource\":null}," _debug _regex "$_regex" @@ -102,7 +103,7 @@ gcore_cdn_deploy() { _date=$(date "+%d.%m.%Y %H:%M:%S") _request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}" _debug _request "$_request" - _response=$(_post "$_request" "https://api.gcdn.co/sslData") + _response=$(_post "$_request" "https://api.gcore.com/cdn/sslData") _debug _response "$_response" _regex=".*\"id\":\([0-9]*\).*$" _debug _regex "$_regex" @@ -117,7 +118,7 @@ gcore_cdn_deploy() { _info "Update CDN resource" _request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}" _debug _request "$_request" - _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") + _response=$(_post "$_request" "https://api.gcore.com/cdn/resources/$_resourceId" '' "PUT") _debug _response "$_response" _regex=".*\"sslData\":\([0-9]*\).*$" _debug _regex "$_regex" @@ -133,7 +134,7 @@ gcore_cdn_deploy() { _info "Not found old SSL certificate" else _info "Delete old SSL certificate" - _response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") + _response=$(_post '' "https://api.gcore.com/cdn/sslData/$_sslDataOld" '' "DELETE") _debug _response "$_response" fi From 7bbdd1f839c2bb1556a81b97636730f788457947 Mon Sep 17 00:00:00 2001 From: Vladislav Sharapov Date: Fri, 20 Jan 2023 23:43:15 +0400 Subject: [PATCH 073/687] fix(dns_openstack): fix argparse error Add equal sign to '--record' option to fix argparse error occurring when ACME token starts with '-'. --- dnsapi/dns_openstack.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_openstack.sh b/dnsapi/dns_openstack.sh index 38619e6f..fcc1dc2e 100755 --- a/dnsapi/dns_openstack.sh +++ b/dnsapi/dns_openstack.sh @@ -57,16 +57,16 @@ _dns_openstack_create_recordset() { if [ -z "$_recordset_id" ]; then _info "Creating a new recordset" - if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then + if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record="$txtvalue" "$_zone_id" "$fulldomain."); then _err "No recordset ID found after create" return 1 fi else _info "Updating existing recordset" - # Build new list of --record args for update - _record_args="--record $txtvalue" + # Build new list of --record= args for update + _record_args="--record=$txtvalue" for _rec in $_records; do - _record_args="$_record_args --record $_rec" + _record_args="$_record_args --record=$_rec" done # shellcheck disable=SC2086 if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then @@ -107,13 +107,13 @@ _dns_openstack_delete_recordset() { fi else _info "Found existing records, updating recordset" - # Build new list of --record args for update + # Build new list of --record= args for update _record_args="" for _rec in $_records; do if [ "$_rec" = "$txtvalue" ]; then continue fi - _record_args="$_record_args --record $_rec" + _record_args="$_record_args --record=$_rec" done # shellcheck disable=SC2086 if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then From bf50fce5bd2bcd58582e6768350de96aeb881d90 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 15:17:21 +0800 Subject: [PATCH 074/687] fix https://github.com/acmesh-official/acme.sh/issues/4470 --- acme.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index d8a46a6f..7683495b 100755 --- a/acme.sh +++ b/acme.sh @@ -2386,12 +2386,14 @@ _getdeployconf() { if [ "$_rac_value" ]; then if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then _debug2 "trim quotation marks" - eval "export $_rac_key=$_rac_value" + eval $_rac_key=$_rac_value + export $_rac_key fi return 0 # do nothing fi - _saved=$(_readdomainconf "SAVED_$_rac_key") - eval "export $_rac_key=\"\$_saved\"" + _saved="$(_readdomainconf "SAVED_$_rac_key")" + eval $_rac_key="$_saved" + export $_rac_key } #_saveaccountconf key value base64encode From 6c0a7144f677a0d3cc14c45e91c1104191e0dbe2 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 15:45:25 +0800 Subject: [PATCH 075/687] fix https://github.com/acmesh-official/acme.sh/issues/4445 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7683495b..cfef7ee6 100755 --- a/acme.sh +++ b/acme.sh @@ -7122,7 +7122,9 @@ _selectServer() { _getCAShortName() { caurl="$1" if [ -z "$caurl" ]; then - caurl="$DEFAULT_CA" + #use letsencrypt as default value if the Le_API is empty + #this case can only come from the old upgrading. + caurl="$CA_LETSENCRYPT_V2" fi if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then caurl="$CA_SSLCOM_RSA" #just hack to get the short name From b99c9980576a72c776e37aedaaea3ebd2f9e8f5d Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 16:13:42 +0800 Subject: [PATCH 076/687] fix https://github.com/acmesh-official/acme.sh/issues/4463 --- acme.sh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index cfef7ee6..c6c16056 100755 --- a/acme.sh +++ b/acme.sh @@ -6730,6 +6730,13 @@ _send_notify() { return 0 fi + _nsource="$NOTIFY_SOURCE" + if [ -z "$_nsource" ]; then + _nsource="$(hostname)" + fi + + _nsubject="$_nsubject by $_nsource" + _send_err=0 for _n_hook in $(echo "$_nhooks" | tr ',' " "); do _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" @@ -6784,11 +6791,12 @@ setnotify() { _nhook="$1" _nlevel="$2" _nmode="$3" + _nsource="$4" _initpath if [ -z "$_nhook$_nlevel$_nmode" ]; then - _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook ] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]" + _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook ] [--notify-level <0|1|2|3>] [--notify-mode <0|1>] [--notify-source ]" _usage "$_NOTIFY_WIKI" return 1 fi @@ -6805,6 +6813,12 @@ setnotify() { _saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE" fi + if [ "$_nsource" ]; then + _info "Set notify source to: $_nsource" + export "NOTIFY_SOURCE=$_nsource" + _saveaccountconf "NOTIFY_SOURCE" "$NOTIFY_SOURCE" + fi + if [ "$_nhook" ]; then _info "Set notify hook to: $_nhook" if [ "$_nhook" = "$NO_VALUE" ]; then @@ -6965,6 +6979,7 @@ Parameters: 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. --notify-hook Set the notify hook + --notify-source Set the server name in the notification message --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. See: $_REVOKE_WIKI @@ -7241,6 +7256,7 @@ _process() { _notify_hook="" _notify_level="" _notify_mode="" + _notify_source="" _revoke_reason="" _eab_kid="" _eab_hmac_key="" @@ -7733,6 +7749,15 @@ _process() { _notify_mode="$_nmode" shift ;; + --notify-source) + _nsource="$2" + if _startswith "$_nsource" "-"; then + _err "'$_nsource' is not valid host name for '$1'" + return 1 + fi + _notify_source="$_nsource" + shift + ;; --revoke-reason) _revoke_reason="$2" if _startswith "$_revoke_reason" "-"; then @@ -7887,7 +7912,7 @@ _process() { createCSR "$_domain" "$_altdomains" "$_ecc" ;; setnotify) - setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" + setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" "$_notify_source" ;; setdefaultca) setdefaultca From ab2305e259e1e0854ce096a6f84d6a82045f1137 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 16:42:10 +0800 Subject: [PATCH 077/687] fix stepca --- .github/workflows/Ubuntu.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index a6ec714c..df1a816b 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -80,8 +80,9 @@ jobs: -p 9000:9000 \ -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ + -e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \ --name stepca \ - smallstep/step-ca \ + smallstep/step-ca:0.23.1 \ && sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \ && docker exec stepca kill -1 1 \ && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" From 015a9b9271c956255879eb3320c9f99602056c22 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 16:45:12 +0800 Subject: [PATCH 078/687] fix notify --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c6c16056..74a855f9 100755 --- a/acme.sh +++ b/acme.sh @@ -6795,7 +6795,7 @@ setnotify() { _initpath - if [ -z "$_nhook$_nlevel$_nmode" ]; then + if [ -z "$_nhook$_nlevel$_nmode$_nsource" ]; then _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook ] [--notify-level <0|1|2|3>] [--notify-mode <0|1>] [--notify-source ]" _usage "$_NOTIFY_WIKI" return 1 From deb63b4adfe09f6603654d59a8c6ecc2af34e506 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 17:58:46 +0800 Subject: [PATCH 079/687] fix stepca --- .github/workflows/Ubuntu.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index df1a816b..22c8b2c5 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -81,9 +81,13 @@ jobs: -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ -e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \ + -e "DOCKER_STEPCA_INIT_PASSWORD=test" \ --name stepca \ - smallstep/step-ca:0.23.1 \ - && sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \ + smallstep/step-ca:0.23.1 + + sleep 5 + docker exec stepca bash -c "echo test >test" + docker exec -it stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \ && docker exec stepca kill -1 1 \ && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" - name: Clone acmetest From 6748c55c04109099c3755313801e8503615364d5 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 24 Jan 2023 18:00:09 +0800 Subject: [PATCH 080/687] fix stepca --- .github/workflows/Ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 22c8b2c5..4bf2ba29 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -86,8 +86,8 @@ jobs: smallstep/step-ca:0.23.1 sleep 5 - docker exec stepca bash -c "echo test >test" - docker exec -it stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \ + docker exec stepca bash -c "echo test >test" \ + && docker exec stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \ && docker exec stepca kill -1 1 \ && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" - name: Clone acmetest From 16bdc7d0a33a791e6629a4cb38e6b8ff6b6908d0 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 27 Jan 2023 11:44:06 +0800 Subject: [PATCH 081/687] fix from OpenAI https://github.com/acmesh-official/acme.sh/issues/992 https://github.com/acmesh-official/acme.sh/pull/2609 --- Dockerfile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 79fd1d89..7b50f080 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.16.3 +FROM alpine:3.17 RUN apk --no-cache add -f \ openssl \ @@ -12,7 +12,8 @@ RUN apk --no-cache add -f \ oath-toolkit-oathtool \ tar \ libidn \ - jq + jq \ + cronie ENV LE_CONFIG_HOME /acme.sh @@ -64,12 +65,10 @@ RUN for verb in help \ RUN printf "%b" '#!'"/usr/bin/env sh\n \ if [ \"\$1\" = \"daemon\" ]; then \n \ - trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \ - crond && sleep infinity &\n \ - wait \n \ + exec crond -n \n \ else \n \ exec -- \"\$@\"\n \ -fi" >/entry.sh && chmod +x /entry.sh +fi\n" >/entry.sh && chmod +x /entry.sh VOLUME /acme.sh From 5a59c3903650672d05cfc6ffdbf4d3bfae1b0c3a Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 15:24:21 +0800 Subject: [PATCH 082/687] fix format --- deploy/truenas.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 6b299f3a..60dbb1b5 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -184,22 +184,21 @@ truenas_deploy() { _info "S3 certificate is not configured or is not the same as TrueNAS web UI" fi - _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then _info "Query all chart release" _release_list=$(_get "$_api_url/chart/release") - _related_name_list=$(printf "%s" $_release_list | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") + _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") _release_length=$(printf "%s" $_related_name_list | jq -r "length") _info "Found $_release_length related chart release in list: $_related_name_list" for i in $(seq 0 $((_release_length-1))); do - _release_name=$(echo $_related_name_list | jq -r ".[$i]") + _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" #Read the chart release configuration - _chart_config=$(printf "%s" $_release_list | jq -r ".[] | select(.name==\"$_release_name\")") + _chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")") #Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress - _updated_chart_config=$(printf "%s" $_chart_config | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress " ) + _updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress " ) _update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")" _debug3 _update_chart_result "$_update_chart_result" done @@ -207,7 +206,6 @@ truenas_deploy() { _info "Tool 'jq' does not exists, skip chart release checking" fi - _info "Deleting old certificate" _delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" From 41b6f18a5d1b7805dc5c56ecb7abc2baa9a852f8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 15:25:50 +0800 Subject: [PATCH 083/687] fix format --- deploy/truenas.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 60dbb1b5..f9e540f7 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -191,14 +191,13 @@ truenas_deploy() { _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") _release_length=$(printf "%s" $_related_name_list | jq -r "length") _info "Found $_release_length related chart release in list: $_related_name_list" - for i in $(seq 0 $((_release_length-1))); - do + for i in $(seq 0 $((_release_length-1))); do _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" #Read the chart release configuration _chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")") #Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress - _updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress " ) + _updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ") _update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")" _debug3 _update_chart_result "$_update_chart_result" done From e3b688c9d87d74a493a189c874c1c3c6864b503d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 15:26:54 +0800 Subject: [PATCH 084/687] fix format --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index f9e540f7..88b24684 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -191,7 +191,7 @@ truenas_deploy() { _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") _release_length=$(printf "%s" $_related_name_list | jq -r "length") _info "Found $_release_length related chart release in list: $_related_name_list" - for i in $(seq 0 $((_release_length-1))); do + for i in $(seq 0 $((_release_length - 1))); do _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" #Read the chart release configuration From 2690c05781096875af7a30efd31c37a38ff8d84e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 15:28:06 +0800 Subject: [PATCH 085/687] fix format --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 88b24684..c79e6dac 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -189,7 +189,7 @@ truenas_deploy() { _info "Query all chart release" _release_list=$(_get "$_api_url/chart/release") _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") - _release_length=$(printf "%s" $_related_name_list | jq -r "length") + _release_length=$(printf "%s" "$_related_name_list" | jq -r "length") _info "Found $_release_length related chart release in list: $_related_name_list" for i in $(seq 0 $((_release_length - 1))); do _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") From aa9cbf7c551dfe75bc6b806c101ab004afe7b759 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 16:18:27 +0800 Subject: [PATCH 086/687] fix https://github.com/acmesh-official/acme.sh/issues/992 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7b50f080..d9c243b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -65,7 +65,7 @@ RUN for verb in help \ RUN printf "%b" '#!'"/usr/bin/env sh\n \ if [ \"\$1\" = \"daemon\" ]; then \n \ - exec crond -n \n \ + exec crond -n -s -m off \n \ else \n \ exec -- \"\$@\"\n \ fi\n" >/entry.sh && chmod +x /entry.sh From 01249d0cb9a43c528cb1e410ee50b68e292a4a0d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 16:24:27 +0800 Subject: [PATCH 087/687] fix warning --- .github/workflows/dockerhub.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index bd2c01aa..e60d6f7f 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -28,9 +28,9 @@ jobs: id: step_one run: | if [ "$DOCKER_PASSWORD" ] ; then - echo "::set-output name=hasToken::true" + echo "hasToken=true" >>$GITHUB_OUTPUT else - echo "::set-output name=hasToken::false" + echo "hasToken=false" >>$GITHUB_OUTPUT fi - name: Check the value run: echo ${{ steps.step_one.outputs.hasToken }} From a5b04a032896d92e2cd96d75d159e7471b0f7cb0 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Sat, 28 Jan 2023 17:19:04 +0800 Subject: [PATCH 088/687] ensure `curl --help` backward compatible --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 999ef563..c8a62f1d 100755 --- a/acme.sh +++ b/acme.sh @@ -1852,7 +1852,7 @@ _inithttp() { _ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE " fi - if _contains "$(curl --help curl 2>&1)" "--globoff"; then + if _contains "$(curl --help 2>&1)" "--globoff" || _contains "$(curl --help curl 2>&1)" "--globoff"; then _ACME_CURL="$_ACME_CURL -g " fi From ba9d146d6c615ab5ec4ede949602880246d17d05 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 28 Jan 2023 17:29:03 +0800 Subject: [PATCH 089/687] fix https://github.com/acmesh-official/acme.sh/issues/992 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d9c243b8..2ad50e6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ COPY ./ /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ -RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab - +RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null#> /proc/1/fd/1 2>/proc/1/fd/2#' | crontab - RUN for verb in help \ version \ From f537c606f730318021d6f297b59d6314ad9702e7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 Jan 2023 11:13:23 +0800 Subject: [PATCH 090/687] fix warnings --- .github/workflows/dockerhub.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index e60d6f7f..48c44429 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -43,9 +43,9 @@ jobs: - name: checkout code uses: actions/checkout@v3 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: login to docker hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin From c2344f3717d1c5d57a207c7cca2a60f97d4b48bf Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2023 14:39:03 +0800 Subject: [PATCH 091/687] add log for doh https://github.com/acmesh-official/acme.sh/issues/4481 --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 53387117..cd509cbc 100755 --- a/acme.sh +++ b/acme.sh @@ -4023,7 +4023,7 @@ _ns_purge_cf() { #checks if cf server is available _ns_is_available_cf() { - if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then + if _get "https://cloudflare-dns.com" "" 10 >/dev/null; then return 0 else return 1 @@ -4031,7 +4031,7 @@ _ns_is_available_cf() { } _ns_is_available_google() { - if _get "https://dns.google" "" 1 >/dev/null 2>&1; then + if _get "https://dns.google" "" 10 >/dev/null; then return 0 else return 1 @@ -4047,7 +4047,7 @@ _ns_lookup_google() { } _ns_is_available_ali() { - if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then + if _get "https://dns.alidns.com" "" 10 >/dev/null; then return 0 else return 1 @@ -4063,7 +4063,7 @@ _ns_lookup_ali() { } _ns_is_available_dp() { - if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then + if _get "https://doh.pub" "" 10 >/dev/null; then return 0 else return 1 From 7b5d94d0622e2fde9cacf7a18f578dabb5f559c9 Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Tue, 31 Jan 2023 11:10:42 +0100 Subject: [PATCH 092/687] convert domain and subdomain to lower case --- dnsapi/dns_ipv64.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index 9979be42..afa6df5a 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -36,6 +36,10 @@ dns_ipv64_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" + # convert to lower case + _domain = $(echo "$_domain" | tr '[:upper:]' '[:lower:]') + _sub_domain = $(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]') + # Now add the TXT record _info "Trying to add TXT record" if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then @@ -70,6 +74,10 @@ dns_ipv64_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" + # convert to lower case + _domain = $(echo "$_domain" | tr '[:upper:]' '[:lower:]') + _sub_domain = $(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]') + # Now delete the TXT record _info "Trying to delete TXT record" if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then From 553d861b8ae823f624a41979aec7965cbaefe921 Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Tue, 31 Jan 2023 11:17:33 +0100 Subject: [PATCH 093/687] fix shell check and formatting --- dnsapi/dns_ipv64.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index afa6df5a..489df5c9 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -37,9 +37,8 @@ dns_ipv64_add() { _debug _domain "$_domain" # convert to lower case - _domain = $(echo "$_domain" | tr '[:upper:]' '[:lower:]') - _sub_domain = $(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]') - + _domain="$(echo "$_domain" | tr '[:upper:]' '[:lower:]')" + _sub_domain="$(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]')" # Now add the TXT record _info "Trying to add TXT record" if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then @@ -75,9 +74,8 @@ dns_ipv64_rm() { _debug _domain "$_domain" # convert to lower case - _domain = $(echo "$_domain" | tr '[:upper:]' '[:lower:]') - _sub_domain = $(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]') - + _domain="$(echo "$_domain" | tr '[:upper:]' '[:lower:]')" + _sub_domain="$(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]')" # Now delete the TXT record _info "Trying to delete TXT record" if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then From 59dab6eac746946db8d846ba0edb565b88a22f41 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 3 Feb 2023 09:55:51 +0800 Subject: [PATCH 094/687] fix https://github.com/acmesh-official/acme.sh/issues/4485#issuecomment-1414022376 https://github.com/acmesh-official/acme.sh/issues/4483#issuecomment-1414460122 --- acme.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index cd509cbc..d9a8ea38 100755 --- a/acme.sh +++ b/acme.sh @@ -1856,10 +1856,11 @@ _inithttp() { _ACME_CURL="$_ACME_CURL -g " fi - #from curl 7.76: return fail on HTTP errors but keep the body - if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then - _ACME_CURL="$_ACME_CURL --fail-with-body " - fi + # don't use --fail-with-body + ##from curl 7.76: return fail on HTTP errors but keep the body + #if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then + # _ACME_CURL="$_ACME_CURL --fail-with-body " + #fi fi if [ -z "$_ACME_WGET" ] && _exists "wget"; then From 3cf8f7874542e31f339a2ee09ab85fac83862b37 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 3 Feb 2023 09:57:56 +0800 Subject: [PATCH 095/687] fix format --- acme.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index d9a8ea38..f512356a 100755 --- a/acme.sh +++ b/acme.sh @@ -1856,11 +1856,11 @@ _inithttp() { _ACME_CURL="$_ACME_CURL -g " fi - # don't use --fail-with-body - ##from curl 7.76: return fail on HTTP errors but keep the body - #if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then - # _ACME_CURL="$_ACME_CURL --fail-with-body " - #fi +#don't use --fail-with-body +##from curl 7.76: return fail on HTTP errors but keep the body +#if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then +# _ACME_CURL="$_ACME_CURL --fail-with-body " +#fi fi if [ -z "$_ACME_WGET" ] && _exists "wget"; then From a5fbf3fb806dd32fda16b7442b28e52dd20b58d8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 3 Feb 2023 09:59:42 +0800 Subject: [PATCH 096/687] fix format --- acme.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index f512356a..1df8a053 100755 --- a/acme.sh +++ b/acme.sh @@ -1856,11 +1856,11 @@ _inithttp() { _ACME_CURL="$_ACME_CURL -g " fi -#don't use --fail-with-body -##from curl 7.76: return fail on HTTP errors but keep the body -#if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then -# _ACME_CURL="$_ACME_CURL --fail-with-body " -#fi + #don't use --fail-with-body + ##from curl 7.76: return fail on HTTP errors but keep the body + #if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then + # _ACME_CURL="$_ACME_CURL --fail-with-body " + #fi fi if [ -z "$_ACME_WGET" ] && _exists "wget"; then From d6cf15368a3ee70845cd49b41dda0234bd04e1a8 Mon Sep 17 00:00:00 2001 From: Aleksandr Kunin Date: Wed, 24 Aug 2022 08:41:54 +0700 Subject: [PATCH 097/687] Vultr DNS: fix "grep: repetition-operator operand invalid" on FreeBSD --- dnsapi/dns_vultr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 58f14be1..54e5b6ce 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -78,7 +78,7 @@ dns_vultr_rm() { return 1 fi - _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)" + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2 | tr -d '"')" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." @@ -116,7 +116,7 @@ _get_root() { return 1 fi - if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then + if printf "%s\n" "$response" | grep -E '^\{.*\}' >/dev/null; then if _contains "$response" "\"domain\":\"$_domain\""; then _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" return 0 From 05a2eb3df46a3fcbdb59039ed35141a3d38e985e Mon Sep 17 00:00:00 2001 From: dharp Date: Tue, 21 Feb 2023 10:19:07 -0600 Subject: [PATCH 098/687] add additional debug statement for DOMAIN_CONF --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 1df8a053..76830473 100755 --- a/acme.sh +++ b/acme.sh @@ -5772,6 +5772,7 @@ deploy() { return 1 fi + _debug2 DOMAIN_CONF "$DOMAIN_CONF" . "$DOMAIN_CONF" _savedomainconf Le_DeployHook "$_hooks" From c0639c66087cb25a684dc3862d3c22ab7704bd1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=20=7C=20Anton=20R=C3=B6hm?= <18481195+AnTheMaker@users.noreply.github.com> Date: Thu, 23 Feb 2023 23:29:46 +0100 Subject: [PATCH 099/687] Create first version of Nanelo DNS API integration [create dnsapi/dns_nanelo.sh] --- dnsapi/dns_nanelo.sh | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 dnsapi/dns_nanelo.sh diff --git a/dnsapi/dns_nanelo.sh b/dnsapi/dns_nanelo.sh new file mode 100644 index 00000000..a3cea3b1 --- /dev/null +++ b/dnsapi/dns_nanelo.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh + +# Official DNS API for Nanelo.com + +# Provide the required API Key like this: +# NANELO_TOKEN="FmD408PdqT1E269gUK57" + +NANELO_API="https://api.nanelo.com/v1/" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_nanelo_add() { + fulldomain=$1 + txtvalue=$2 + + NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}" + if [ -z "$NANELO_TOKEN" ]; then + NANELO_TOKEN="" + _err "You didn't configure a Nanelo API Key yet." + _err "Please set NANELO_TOKEN and try again." + _err "Login to Nanelo.com and go to Settings > API Keys to get a Key" + return 1 + fi + _saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN" + + _info "Adding TXT record to ${fulldomain}" + response="$(_get "$NANELO_API$NANELO_TOKEN/dns/addrecord?type=TXT&name=${fulldomain}&value=${txtvalue}")" + if _contains "${response}" 'success'; then + return 0 + fi + _err "Could not create resource record, check logs" + _err "${response}" + return 1 +} + +dns_nanelo_rm() { + fulldomain=$1 + txtvalue=$2 + + NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}" + if [ -z "$NANELO_TOKEN" ]; then + NANELO_TOKEN="" + _err "You didn't configure a Nanelo API Key yet." + _err "Please set NANELO_TOKEN and try again." + _err "Login to Nanelo.com and go to Settings > API Keys to get a Key" + return 1 + fi + _saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN" + + _info "Deleting resource record $fulldomain" + response="$(_get "$NANELO_API$NANELO_TOKEN/dns/deleterecord?type=TXT&name=${fulldomain}&value=${txtvalue}")" + if _contains "${response}" 'success'; then + return 0 + fi + _err "Could not delete resource record, check logs" + _err "${response}" + return 1 +} From d3fefd223d5b7f9c4f1e43bea85d63ec1e532bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=20=7C=20Anton=20R=C3=B6hm?= <18481195+AnTheMaker@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:01:39 +0100 Subject: [PATCH 100/687] improve output --- dnsapi/dns_nanelo.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_nanelo.sh b/dnsapi/dns_nanelo.sh index a3cea3b1..2a22ecdb 100644 --- a/dnsapi/dns_nanelo.sh +++ b/dnsapi/dns_nanelo.sh @@ -9,7 +9,7 @@ NANELO_API="https://api.nanelo.com/v1/" ######## Public functions ##################### -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_nanelo_add() { fulldomain=$1 txtvalue=$2 @@ -29,7 +29,7 @@ dns_nanelo_add() { if _contains "${response}" 'success'; then return 0 fi - _err "Could not create resource record, check logs" + _err "Could not create resource record, please check the logs" _err "${response}" return 1 } @@ -53,7 +53,7 @@ dns_nanelo_rm() { if _contains "${response}" 'success'; then return 0 fi - _err "Could not delete resource record, check logs" + _err "Could not delete resource record, please check the logs" _err "${response}" return 1 } From 06e12a30e74042f3ee34a65b1197a3f20ca2adfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=20=7C=20Anton=20R=C3=B6hm?= <18481195+AnTheMaker@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:13:21 +0100 Subject: [PATCH 101/687] reduce nanelo dns ttl --- dnsapi/dns_nanelo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_nanelo.sh b/dnsapi/dns_nanelo.sh index 2a22ecdb..8ccc8c29 100644 --- a/dnsapi/dns_nanelo.sh +++ b/dnsapi/dns_nanelo.sh @@ -25,7 +25,7 @@ dns_nanelo_add() { _saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN" _info "Adding TXT record to ${fulldomain}" - response="$(_get "$NANELO_API$NANELO_TOKEN/dns/addrecord?type=TXT&name=${fulldomain}&value=${txtvalue}")" + response="$(_get "$NANELO_API$NANELO_TOKEN/dns/addrecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")" if _contains "${response}" 'success'; then return 0 fi @@ -49,7 +49,7 @@ dns_nanelo_rm() { _saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN" _info "Deleting resource record $fulldomain" - response="$(_get "$NANELO_API$NANELO_TOKEN/dns/deleterecord?type=TXT&name=${fulldomain}&value=${txtvalue}")" + response="$(_get "$NANELO_API$NANELO_TOKEN/dns/deleterecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")" if _contains "${response}" 'success'; then return 0 fi From 7dd12044dee65b3731d90e838a40afe21cef93a6 Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Sat, 25 Feb 2023 11:18:33 +0000 Subject: [PATCH 102/687] use _lower_case function --- dnsapi/dns_ipv64.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index 489df5c9..b50b8663 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -37,8 +37,8 @@ dns_ipv64_add() { _debug _domain "$_domain" # convert to lower case - _domain="$(echo "$_domain" | tr '[:upper:]' '[:lower:]')" - _sub_domain="$(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]')" + _domain="$(echo "$_domain" | _lower_case')" + _sub_domain="$(echo "$_sub_domain" | _lower_case)" # Now add the TXT record _info "Trying to add TXT record" if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then @@ -74,8 +74,8 @@ dns_ipv64_rm() { _debug _domain "$_domain" # convert to lower case - _domain="$(echo "$_domain" | tr '[:upper:]' '[:lower:]')" - _sub_domain="$(echo "$_sub_domain" | tr '[:upper:]' '[:lower:]')" + _domain="$(echo "$_domain" | _lower_case)" + _sub_domain="$(echo "$_sub_domain" | _lower_case)" # Now delete the TXT record _info "Trying to delete TXT record" if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then From df14b153974228d23ffe8396e8f2d32ab488ba9d Mon Sep 17 00:00:00 2001 From: Roman Lumetsberger Date: Sat, 25 Feb 2023 11:22:27 +0000 Subject: [PATCH 103/687] fix quote --- dnsapi/dns_ipv64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index b50b8663..54470119 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -37,7 +37,7 @@ dns_ipv64_add() { _debug _domain "$_domain" # convert to lower case - _domain="$(echo "$_domain" | _lower_case')" + _domain="$(echo "$_domain" | _lower_case)" _sub_domain="$(echo "$_sub_domain" | _lower_case)" # Now add the TXT record _info "Trying to add TXT record" From 1522b713da92e1f267208a4a35935e3abc687b15 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 28 Feb 2023 21:08:15 -0500 Subject: [PATCH 104/687] Use grep -E instead of expr expr was printing `expr: warning: '^.*[<>"]': using '^' as the first character of a basic regular expression is not portable;` --- notify/smtp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/smtp.sh b/notify/smtp.sh index 293c665e..f5ebebca 100644 --- a/notify/smtp.sh +++ b/notify/smtp.sh @@ -169,7 +169,7 @@ _clean_email_header() { # email _email_has_display_name() { _email="$1" - expr "$_email" : '^.*[<>"]' >/dev/null + echo "$_email" | grep -q -E '^.*[<>"]' } ## @@ -249,7 +249,7 @@ _mime_encoded_word() { _text="$1" # (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that) _ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-" - if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then + if echo "$_text" | grep -q -E "^.*[^$_ascii]"; then # At least one non-ASCII char; convert entire thing to encoded word printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?=" else From 15f96b72390c6137239e73fd81ec9f17fe33f6d1 Mon Sep 17 00:00:00 2001 From: Markus Hoffrogge Date: Thu, 2 Mar 2023 00:02:13 +0100 Subject: [PATCH 105/687] Fix to handle LE overload status 503 appropriately - LE HTTP response status 503 is not an error, it must be handled via sleep and retry - s. https://community.letsencrypt.org/t/new-service-busy-responses-beginning-during-high-load/184174 fixes #4530 --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index 1df8a053..af2d0dfb 100755 --- a/acme.sh +++ b/acme.sh @@ -2229,6 +2229,12 @@ _send_signed_request() { _debug3 _body "$_body" fi + if [ "$code" = '503' ]; then + _sleep_overload_retry_sec=3 + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _sleep $_sleep_overload_retry_sec + continue + fi if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." _CACHED_NONCE="" From 982c54b60504eb4cc83f31b651d936d4b04b1d75 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 2 Mar 2023 18:06:09 +0800 Subject: [PATCH 106/687] fix https://github.com/acmesh-official/acme.sh/issues/4530 --- acme.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index af2d0dfb..a6f3b905 100755 --- a/acme.sh +++ b/acme.sh @@ -2230,7 +2230,11 @@ _send_signed_request() { fi if [ "$code" = '503' ]; then - _sleep_overload_retry_sec=3 + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _sleep_overload_retry_sec=$_retryafter + if [ -z "$_sleep_overload_retry_sec" ]; then + _sleep_overload_retry_sec=5 + fi _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." _sleep $_sleep_overload_retry_sec continue From cb8b341fb4ded4c993c812b40441d3978eb73b0f Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 2 Mar 2023 18:10:38 +0800 Subject: [PATCH 107/687] fix https://github.com/acmesh-official/acme.sh/issues/4530 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index a6f3b905..f5f403ce 100755 --- a/acme.sh +++ b/acme.sh @@ -2229,8 +2229,8 @@ _send_signed_request() { _debug3 _body "$_body" fi - if [ "$code" = '503' ]; then - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + if [ "$code" = '503' ] || [ "$_retryafter" ]; then _sleep_overload_retry_sec=$_retryafter if [ -z "$_sleep_overload_retry_sec" ]; then _sleep_overload_retry_sec=5 From 20cfc4ac668b1ec360553ef5c86b0edeb0c69a30 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 4 Mar 2023 21:22:17 +0800 Subject: [PATCH 108/687] fix https://github.com/acmesh-official/acme.sh/issues/4535 --- acme.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f5f403ce..e2006868 100755 --- a/acme.sh +++ b/acme.sh @@ -2873,7 +2873,7 @@ _initpath() { if _isEccKey "$_ilength"; then DOMAIN_PATH="$domainhomeecc" - else + elif [ -z "$__SELECTED_RSA_KEY" ] if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert." DOMAIN_PATH="$domainhomeecc" @@ -7518,6 +7518,9 @@ _process() { --keylength | -k) _keylength="$2" shift + if [ "$_keylength" ] && ! _isEccKey "$_keylength"; then + export __SELECTED_RSA_KEY=1 + fi ;; -ak | --accountkeylength) _accountkeylength="$2" From ce629e8e70b6438573b97c4d3ffe2a6c87a4b295 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 4 Mar 2023 21:23:31 +0800 Subject: [PATCH 109/687] fix typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e2006868..5d73cdb6 100755 --- a/acme.sh +++ b/acme.sh @@ -2873,7 +2873,7 @@ _initpath() { if _isEccKey "$_ilength"; then DOMAIN_PATH="$domainhomeecc" - elif [ -z "$__SELECTED_RSA_KEY" ] + elif [ -z "$__SELECTED_RSA_KEY" ]; then if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert." DOMAIN_PATH="$domainhomeecc" From dde1bab1a83c17ceb69c453741de1b17e5576969 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:18:15 +0100 Subject: [PATCH 110/687] improve deletion of records --- dnsapi/dns_kas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 053abd21..87025fcf 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -215,7 +215,7 @@ _get_record_id() { return 1 fi - _record_id="$(echo "$response" | tr -d '\n\r' | sed "s//\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/record_id<\/key>/=>/g" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")" + _record_id="$(echo "$response" | tr -d '\n\r' | sed "s//\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/record_id<\/key>/=>/g" | grep -i "$_txtvalue" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")" _debug "[KAS] -> Record Id: " "$_record_id" return 0 } @@ -278,4 +278,4 @@ _callAPI() { response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")" _debug2 "[KAS] -> Response" "$response" echo "$response" -} +} \ No newline at end of file From dea8a08b64d8f7b51923bfe2ff01464f032e1928 Mon Sep 17 00:00:00 2001 From: Hobby-Student <6012744+Hobby-Student@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:36:53 +0100 Subject: [PATCH 111/687] added missing new line at EOF --- dnsapi/dns_kas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 87025fcf..1253cf27 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -278,4 +278,4 @@ _callAPI() { response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")" _debug2 "[KAS] -> Response" "$response" echo "$response" -} \ No newline at end of file +} From acbd8bce21a0f63cc9bdd4b87b3427355b5a5f5e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 09:48:13 +0800 Subject: [PATCH 112/687] feat: add retry count for removing record set This avoids infinite loop when something went wrong and throws a error --- dnsapi/dns_huaweicloud.sh | 60 ++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index ceda9258..b1bb61dc 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -98,19 +98,59 @@ dns_huaweicloud_rm() { fi _debug "Zone ID is:" "${zoneid}" + _recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}" + ret="$?" + if [ "${ret}" != "0" ]; then + _err "dns_api(dns_huaweicloud): Error removing record." + return 1 + fi + + return 0 +} + +################### Private functions below ################################## + + +# _recursive_rm_record +# remove all records from the record set +# +# _token=$1 +# _domain=$2 +# _zoneid=$3 +# _record_id=$4 +# +# Returns 0 on success +_recursive_rm_record() { + _token=$1 + _domain=$2 + _zoneid=$3 + _record_id=$4 + + # Most likely to have problems will huaweicloud side if more than 50 attempts but still cannot fully remove the record set + # Maybe can be removed manually in the dashboard + _retry_cnt=50 + # Remove all records # Therotically HuaweiCloud does not allow more than one record set # But remove them recurringly to increase robusty - while [ "${record_id}" != "0" ]; do + + while [ "${_record_id}" != "0" && "${_retry_cnt}" != "0" ]; do _debug "Removing Record" - _rm_record "${token}" "${zoneid}" "${record_id}" - record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + _retry_cnt=$((${_retry_cnt} - 1)) + _rm_record "${_token}" "${_zoneid}" "${_record_id}" + _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")" + _debug2 "Checking record exists: record_id=${_record_id}" done + + # Check if retry count is reached + if [ "${_retry_cnt}" == "0" ]; then + _debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard" + return 1 + fi + return 0 } -################### Private functions below ################################## - # _get_zoneid # # _token=$1 @@ -216,11 +256,11 @@ _add_record() { _debug "Record Set ID is:" "${_record_id}" # Remove all records - while [ "${_record_id}" != "0" ]; do - _debug "Removing Record" - _rm_record "${_token}" "${zoneid}" "${_record_id}" - _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" - done + _recursive_rm_record "${token}" "${_domain}" "${_zoneid}" "${_record_id}" + ret="$?" + if [ "${ret}" != "0" ]; then + return 1 + fi # Add brand new records with all old and new records export _H2="Content-Type: application/json" From 0cce2d60985b112fa4ef31672cec880ff4a01740 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 09:57:39 +0800 Subject: [PATCH 113/687] fix: fix shellcheck --- dnsapi/dns_huaweicloud.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index b1bb61dc..54f18226 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -98,6 +98,7 @@ dns_huaweicloud_rm() { fi _debug "Zone ID is:" "${zoneid}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" _recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}" ret="$?" if [ "${ret}" != "0" ]; then @@ -134,16 +135,16 @@ _recursive_rm_record() { # Therotically HuaweiCloud does not allow more than one record set # But remove them recurringly to increase robusty - while [ "${_record_id}" != "0" && "${_retry_cnt}" != "0" ]; do + while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do _debug "Removing Record" - _retry_cnt=$((${_retry_cnt} - 1)) + _retry_cnt=$((_retry_cnt - 1)) _rm_record "${_token}" "${_zoneid}" "${_record_id}" _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")" _debug2 "Checking record exists: record_id=${_record_id}" done # Check if retry count is reached - if [ "${_retry_cnt}" == "0" ]; then + if [ "${_retry_cnt}" = "0" ]; then _debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard" return 1 fi @@ -164,7 +165,7 @@ _get_zoneid() { i=1 while true; do - h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100) + h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 From 4dba84d09e129ea1a69c4158cbbce133e32e1562 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 10:01:20 +0800 Subject: [PATCH 114/687] fix: fix shfmt --- dnsapi/dns_huaweicloud.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 54f18226..1869a756 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -105,16 +105,15 @@ dns_huaweicloud_rm() { _err "dns_api(dns_huaweicloud): Error removing record." return 1 fi - + return 0 } ################### Private functions below ################################## - # _recursive_rm_record # remove all records from the record set -# +# # _token=$1 # _domain=$2 # _zoneid=$3 From e9366f8c7635858f0bf875786fb00e0df93b412a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 10:56:10 +0800 Subject: [PATCH 115/687] fix: fix huaweicloud existing record 400 --- dnsapi/dns_huaweicloud.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 1869a756..401390dc 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -246,8 +246,7 @@ _add_record() { \"type\": \"TXT\", \"ttl\": 1, \"records\": [ - ${_exist_record}, - \"\\\"${_txtvalue}\\\"\" + ${_exist_record},\"\\\"${_txtvalue}\\\"\" ] }" fi From bddde60522ebb25314568b157b56d7185a97bbca Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 11:27:08 +0800 Subject: [PATCH 116/687] fix: use update instead of remove then add --- dnsapi/dns_huaweicloud.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 401390dc..cad9f425 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -254,19 +254,16 @@ _add_record() { _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" _debug "Record Set ID is:" "${_record_id}" - # Remove all records - _recursive_rm_record "${token}" "${_domain}" "${_zoneid}" "${_record_id}" - ret="$?" - if [ "${ret}" != "0" ]; then - return 1 - fi - # Add brand new records with all old and new records export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" _debug2 "${_post_body}" - _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + if [ -z "${_exist_record}" ]; then + _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + else + _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/{$_record_id}" false "PUT" >/dev/null + fi _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" From 7560c64f46f3ad19ec185c7337241d1753f47d09 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 11:30:32 +0800 Subject: [PATCH 117/687] fix: fix typo --- dnsapi/dns_huaweicloud.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index cad9f425..766123c2 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -261,9 +261,9 @@ _add_record() { _debug2 "${_post_body}" if [ -z "${_exist_record}" ]; then _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null - else - _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/{$_record_id}" false "PUT" >/dev/null - fi + else + _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false "PUT" >/dev/null + fi _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" From 1f777a94a7cf22e95b6545c4ece8bbc1eea647a8 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 7 Mar 2023 17:50:44 +0800 Subject: [PATCH 118/687] fix: change some debug comments --- dnsapi/dns_huaweicloud.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 766123c2..c8601f34 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -175,11 +175,11 @@ _get_zoneid() { if _contains "${response}" '"id"'; then zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") - _debug2 "Return Zone ID(s):" "${zoneidlist}" - _debug2 "Return Zone Name(s):" "${zonenamelist}" + _debug2 "Returned Zone ID(s):" "${zoneidlist}" + _debug2 "Returned Zone Name(s):" "${zonenamelist}" zoneidnum=0 zoneidcount=$(echo "${zoneidlist}" | grep -c '^') - _debug "Retund Zone ID(s) Count:" "${zoneidcount}" + _debug "Returned Zone ID(s) Count:" "${zoneidcount}" while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do zoneidnum=$(_math "$zoneidnum" + 1) _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") From 70f4cad2ca9ed671c3a3d55a53913d8aed49871b Mon Sep 17 00:00:00 2001 From: Markus Hoffrogge Date: Tue, 7 Mar 2023 13:22:46 +0100 Subject: [PATCH 119/687] Fix Retry-After handling - closes #4543 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 5d73cdb6..b7d9129d 100755 --- a/acme.sh +++ b/acme.sh @@ -2229,8 +2229,8 @@ _send_signed_request() { _debug3 _body "$_body" fi - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') - if [ "$code" = '503' ] || [ "$_retryafter" ]; then + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + if [ "$code" = '503' ]; then _sleep_overload_retry_sec=$_retryafter if [ -z "$_sleep_overload_retry_sec" ]; then _sleep_overload_retry_sec=5 From 2d8c0c0131f56924aaee10078da9ca076fbf69f5 Mon Sep 17 00:00:00 2001 From: Alex Leigh Date: Tue, 7 Mar 2023 02:31:27 -0800 Subject: [PATCH 120/687] Add support for Google Domains DNS API. https://domains.google/learn/gts-acme/ This is an ACME API for Google Domains customers, which is different from the Google Cloud Domains API for Google Cloud customers. --- dnsapi/dns_googledomains.sh | 173 ++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100755 dnsapi/dns_googledomains.sh diff --git a/dnsapi/dns_googledomains.sh b/dnsapi/dns_googledomains.sh new file mode 100755 index 00000000..63e3073b --- /dev/null +++ b/dnsapi/dns_googledomains.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env sh + +# Author: Alex Leigh +# Created: 2023-03-02 + +#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx" +#GOOGLEDOMAINS_ZONE="xxxx" +GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets" + +######## Public functions ######## + +#Usage: dns_googledomains_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_googledomains_add() { + fulldomain=$1 + txtvalue=$2 + + _info "Invoking Google Domains ACME DNS API." + + if ! _dns_googledomains_setup; then + return 1 + fi + + zone="$(_dns_googledomains_get_zone "$fulldomain")" + if [ -z "$zone" ]; then + _err "Could not find a Google Domains-managed zone containing the requested domain." + return 1 + fi + + _debug zone "$zone" + _debug txtvalue "$txtvalue" + + _info "Adding TXT record for $fulldomain." + if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then + if _contains "$response" "$txtvalue"; then + _info "TXT record added." + return 0 + else + _err "Error adding TXT record." + return 1 + fi + fi + + _err "Error adding TXT record." + return 1 +} + +#Usage: dns_googledomains_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_googledomains_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Invoking Google Domains ACME DNS API." + + if ! _dns_googledomains_setup; then + return 1 + fi + + zone="$(_dns_googledomains_get_zone "$fulldomain")" + if [ -z "$zone" ]; then + _err "Could not find a Google Domains-managed domain based on request." + return 1 + fi + + _debug zone "$zone" + _debug txtvalue "$txtvalue" + + _info "Removing TXT record for $fulldomain." + if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then + if _contains "$response" "$txtvalue"; then + _err "Error removing TXT record." + return 1 + else + _info "TXT record removed." + return 0 + fi + fi + + _err "Error removing TXT record." + return 1 +} + +######## Private functions ######## + +_dns_googledomains_setup() { + if [ -n "$GOOGLEDOMAINS_SETUP_COMPLETED" ]; then + return 0 + fi + + GOOGLEDOMAINS_ACCESS_TOKEN="${GOOGLEDOMAINS_ACCESS_TOKEN:-$(_readaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN)}" + GOOGLEDOMAINS_ZONE="${GOOGLEDOMAINS_ZONE:-$(_readaccountconf_mutable GOOGLEDOMAINS_ZONE)}" + + if [ -z "$GOOGLEDOMAINS_ACCESS_TOKEN" ]; then + GOOGLEDOMAINS_ACCESS_TOKEN="" + _err "Google Domains access token was not specified." + _err "Please visit Google Domains Security settings to provision an ACME DNS API access token." + return 1 + fi + + if [ "$GOOGLEDOMAINS_ZONE" ]; then + _savedomainconf GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN" + _savedomainconf GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE" + else + _saveaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN" + _clearaccountconf_mutable GOOGLEDOMAINS_ZONE + _clearaccountconf GOOGLEDOMAINS_ZONE + fi + + _debug GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN" + _debug GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE" + + GOOGLEDOMAINS_SETUP_COMPLETED=1 + return 0 +} + +_dns_googledomains_get_zone() { + domain=$1 + + # Use zone directly if provided + if [ "$GOOGLEDOMAINS_ZONE" ]; then + if ! _dns_googledomains_api "$GOOGLEDOMAINS_ZONE"; then + return 1 + fi + + echo "$GOOGLEDOMAINS_ZONE" + return 0 + fi + + i=2 + while true; do + curr=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug curr "$curr" + + if [ -z "$curr" ]; then + return 1 + fi + + if _dns_googledomains_api "$curr"; then + echo "$curr" + return 0 + fi + + i=$(_math "$i" + 1) + done + + return 1 +} + +_dns_googledomains_api() { + zone=$1 + apimethod=$2 + data="$3" + + if [ -z "$data" ]; then + response="$(_get "$GOOGLEDOMAINS_API/$zone$apimethod")" + else + _debug data "$data" + export _H1="Content-Type: application/json" + response="$(_post "$data" "$GOOGLEDOMAINS_API/$zone$apimethod")" + fi + + _debug response "$response" + + if [ "$?" != "0" ]; then + _err "Error" + return 1 + fi + + if _contains "$response" "\"error\": {"; then + return 1 + fi + + return 0 +} From ae3e5dbf2c4c8f53f5705f00387f24d36abc7a06 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 12 Mar 2023 12:41:29 +0800 Subject: [PATCH 121/687] fix: fix DomainName not retreived properly Co-Authored-By: idawnlight --- dnsapi/dns_huaweicloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index c8601f34..b61c1d43 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -23,7 +23,7 @@ dns_huaweicloud_add() { HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" - HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}" # Check information if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then @@ -74,7 +74,7 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" - HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}" # Check information if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then From 42a5cd961dc22f655d732167aabebf8725a84784 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 17 Mar 2023 17:21:10 +0800 Subject: [PATCH 122/687] fix https://github.com/acmesh-official/acme.sh/issues/4530#issuecomment-1473395845 --- acme.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b7d9129d..e89662cd 100755 --- a/acme.sh +++ b/acme.sh @@ -2235,9 +2235,13 @@ _send_signed_request() { if [ -z "$_sleep_overload_retry_sec" ]; then _sleep_overload_retry_sec=5 fi - _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." - _sleep $_sleep_overload_retry_sec - continue + if [ $_sleep_overload_retry_sec -le 600 ]; then + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _sleep $_sleep_overload_retry_sec + continue + else + _info "The retryafter=$_retryafter is too large > 600, not retry anymore." + fi fi if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." From 7ef2533b98ae0566fc5775c32aa5ebfcfb3b724b Mon Sep 17 00:00:00 2001 From: imlonghao Date: Tue, 28 Mar 2023 22:34:04 +0800 Subject: [PATCH 123/687] fix(cloudns): fix grep when record start with hyphen symbol --- dnsapi/dns_cloudns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index b03fd579..8d7fd437 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -78,7 +78,7 @@ dns_cloudns_rm() { return 1 fi - for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do + for i in $(echo "$response" | tr '{' "\n" | grep -- "$record"); do record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g') if [ -n "$record_id" ]; then From 6ee72e119c421474f9d966af37422a186b6a5852 Mon Sep 17 00:00:00 2001 From: Paul Dee Date: Fri, 31 Mar 2023 01:13:41 +0200 Subject: [PATCH 124/687] Spelling / grammar --- dnsapi/dns_loopia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 399c7867..60d072e0 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -107,7 +107,7 @@ _loopia_load_config() { fi if _contains "$LOOPIA_Password" "'" || _contains "$LOOPIA_Password" '"'; then - _err "Password contains quoute or double quoute and this is not supported by dns_loopia.sh" + _err "Password contains a quotation mark or double quotation marks and this is not supported by dns_loopia.sh" return 1 fi From cbb7082afd25419779152faf7d35b664a09030b3 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Fri, 31 Mar 2023 00:33:44 +0000 Subject: [PATCH 125/687] Fixed bug with wildcard certs and ecc keys --- deploy/panos.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index ef622ded..3ee889b7 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -61,7 +61,7 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" fi #Close multipart content="$content${nl}--$delim--${nl}${nl}" @@ -92,9 +92,18 @@ deployer() { # This is the main function that will call the other functions to deploy everything. panos_deploy() { - _cdomain="$1" + _cdomain=${1//[*]/WILDCARD_} #Wildcard Safe filename _ckey="$2" _cfullchain="$5" + # VALID ECC KEY CHECK + if [[ "${_ckey: -8}" == "_ecc.key" ]] && [[ ! -f $_ckey ]]; then + _debug "The ECC key $_ckey doesn't exist. Attempting to strip _ecc from the filename" + _ckey="${_ckey:0:${#_ckey}-8}.key" + if [[ ! -f $_ckey ]]; then + _err "Still didn't work. Try issuing the certificate using RSA (non-ECC) encryption." + return 1 + fi + fi # PANOS ENV VAR check if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then _debug "No ENV variables found lets check for saved variables" From dc1f36da4348dfb9e737ad8121d5150c6e2c96d9 Mon Sep 17 00:00:00 2001 From: David Schramm Date: Sat, 1 Apr 2023 09:25:19 +0200 Subject: [PATCH 126/687] prevent whitespace splitting --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e89662cd..33721de5 100755 --- a/acme.sh +++ b/acme.sh @@ -2412,7 +2412,7 @@ _getdeployconf() { return 0 # do nothing fi _saved="$(_readdomainconf "SAVED_$_rac_key")" - eval $_rac_key="$_saved" + eval $_rac_key=\$_saved export $_rac_key } From dcdbe2fbb8d13579c0178b77822d29fc24520a4d Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 2 Apr 2023 12:04:58 +0800 Subject: [PATCH 127/687] fix https://github.com/acmesh-official/acme.sh/pull/4577 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e89662cd..fa350584 100755 --- a/acme.sh +++ b/acme.sh @@ -2412,7 +2412,7 @@ _getdeployconf() { return 0 # do nothing fi _saved="$(_readdomainconf "SAVED_$_rac_key")" - eval $_rac_key="$_saved" + eval $_rac_key=\"$_saved\" export $_rac_key } From a570fda1cb179476405370c94ddefa88dfd7a830 Mon Sep 17 00:00:00 2001 From: David Schramm Date: Sun, 2 Apr 2023 17:30:47 +0200 Subject: [PATCH 128/687] prevent whitespace splitting --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index fa350584..33721de5 100755 --- a/acme.sh +++ b/acme.sh @@ -2412,7 +2412,7 @@ _getdeployconf() { return 0 # do nothing fi _saved="$(_readdomainconf "SAVED_$_rac_key")" - eval $_rac_key=\"$_saved\" + eval $_rac_key=\$_saved export $_rac_key } From df753e2619f5e0069955ed07e32f6a340418126b Mon Sep 17 00:00:00 2001 From: sg1888 Date: Wed, 12 Apr 2023 22:00:53 +0000 Subject: [PATCH 129/687] Added functionality to save and reuse API key --- deploy/panos.sh | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 3ee889b7..8edf115b 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -25,15 +25,27 @@ parse_response() { else status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') + if [ "$type" = 'testkey' ] && [ "$status" != "success" ]; then + _debug "**** Saved API key is invalid ****" + unset _panos_key + fi fi return 0 } deployer() { content="" - type=$1 # Types are keygen, cert, key, commit - _debug "**** Deploying $type *****" + type=$1 # Types are testkey, keygen, cert, key, commit + _debug "**** Deploying $type ****" panos_url="https://$_panos_host/api/" + + #Test API Key by performing an empty commit. + if [ "$type" = 'testkey' ]; then + _H1="Content-Type: application/x-www-form-urlencoded" + content="type=commit&cmd=&key=$_panos_key" + fi + + # Generate API Key if [ "$type" = 'keygen' ]; then _H1="Content-Type: application/x-www-form-urlencoded" content="type=keygen&user=$_panos_user&password=$_panos_pass" @@ -134,8 +146,22 @@ panos_deploy() { _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST" return 1 else - _debug "Getting PANOS KEY" - deployer keygen + #Check for saved API Key + _getdeployconf PANOS_KEY + _panos_key=$PANOS_KEY + if [ "$_panos_key" ]; then + _debug "**** Testing Saved API KEY ****" + deployer testkey + fi + + # Generate a new API key if needed + if [ -z "$_panos_key" ]; then + _debug "**** Generating new PANOS API KEY ****" + deployer keygen + _savedeployconf PANOS_KEY "$_panos_key" 1 + fi + + # Recheck the key if [ -z "$_panos_key" ]; then _err "Missing apikey." return 1 From f66a29d1c3d450641f88c74de04a8967ef0d6cec Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 20 Apr 2023 18:07:59 +0800 Subject: [PATCH 130/687] fix https://github.com/acmesh-official/acme.sh/issues/4606 --- acme.sh | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/acme.sh b/acme.sh index 8b519f1f..d5caee4d 100755 --- a/acme.sh +++ b/acme.sh @@ -6146,8 +6146,22 @@ revoke() { uri="${ACME_REVOKE_CERT}" + _info "Try account key first." + if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then + if [ -z "$response" ]; then + _info "Revoke success." + rm -f "$CERT_PATH" + cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" + cat "$CSR_PATH" >"$CSR_PATH.revoked" + return 0 + else + _err "Revoke error." + _debug "$response" + fi + fi + if [ -f "$CERT_KEY_PATH" ]; then - _info "Try domain key first." + _info "Try domain key." if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then if [ -z "$response" ]; then _info "Revoke success." @@ -6163,21 +6177,6 @@ revoke() { else _info "Domain key file doesn't exist." fi - - _info "Try account key." - - if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then - if [ -z "$response" ]; then - _info "Revoke success." - rm -f "$CERT_PATH" - cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" - cat "$CSR_PATH" >"$CSR_PATH.revoked" - return 0 - else - _err "Revoke error." - _debug "$response" - fi - fi return 1 } From 84e4181ed74f26e2dbd78666f999eafa4642930f Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 20 Apr 2023 18:11:55 +0800 Subject: [PATCH 131/687] fix https://github.com/acmesh-official/acme.sh/issues/4604 --- dnsapi/dns_leaseweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 63f81869..4cd3a8f8 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -6,7 +6,7 @@ #See https://developer.leaseweb.com for more information. ######## Public functions ##################### -LSW_API="https://api.leaseweb.com/hosting/v2/domains/" +LSW_API="https://api.leaseweb.com/hosting/v2/domains" #Usage: dns_leaseweb_add _acme-challenge.www.domain.com dns_leaseweb_add() { From a7bc2293c0874129b3daf297905fa6c11eeb9d5b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 23 Apr 2023 13:16:12 +0800 Subject: [PATCH 132/687] fix https://github.com/acmesh-official/acme.sh/issues/4612#issuecomment-1518929996 --- deploy/docker.sh | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 3aa1b2cd..457e29ab 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -273,16 +273,27 @@ _check_curl_version() { _minor="$(_getfield "$_cversion" 2 '.')" _debug2 "_minor" "$_minor" - if [ "$_major$_minor" -lt "740" ]; then + if [ "$_major" -ge "8" ]; then + #ok + return 0; + fi + if [ "$_major" = "7" ]; then + if [ "$_minor" -lt "40" ]; then + _err "curl v$_cversion doesn't support unit socket" + _err "Please upgrade to curl 7.40 or later." + return 1 + fi + if [ "$_minor" -lt "50" ]; then + _debug "Use short host name" + export _CURL_NO_HOST=1 + else + export _CURL_NO_HOST= + fi + return 0 + else _err "curl v$_cversion doesn't support unit socket" _err "Please upgrade to curl 7.40 or later." return 1 fi - if [ "$_major$_minor" -lt "750" ]; then - _debug "Use short host name" - export _CURL_NO_HOST=1 - else - export _CURL_NO_HOST= - fi - return 0 + } From b937665b90d742ea5432c135b3cfc18eecf33014 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 23 Apr 2023 13:18:17 +0800 Subject: [PATCH 133/687] minor --- deploy/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 457e29ab..c9815d5b 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -275,7 +275,7 @@ _check_curl_version() { if [ "$_major" -ge "8" ]; then #ok - return 0; + return 0 fi if [ "$_major" = "7" ]; then if [ "$_minor" -lt "40" ]; then From 7623025b9007386281d64275978d41a0c52a1bf3 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Mon, 24 Apr 2023 18:45:50 +0000 Subject: [PATCH 134/687] Fixes for POSIX sh shell --- deploy/panos.sh | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 8edf115b..7fb0c9db 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -10,6 +10,7 @@ # export PANOS_USER="" # required # export PANOS_PASS="" # required # export PANOS_HOST="" # required +# export PANOS_KEY="" # optional # This function is to parse the XML parse_response() { @@ -25,7 +26,7 @@ parse_response() { else status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') - if [ "$type" = 'testkey' ] && [ "$status" != "success" ]; then + if [ "$type" = 'testkey' ] && [ "$status" != "success" ]; then _debug "**** Saved API key is invalid ****" unset _panos_key fi @@ -38,7 +39,7 @@ deployer() { type=$1 # Types are testkey, keygen, cert, key, commit _debug "**** Deploying $type ****" panos_url="https://$_panos_host/api/" - + #Test API Key by performing an empty commit. if [ "$type" = 'testkey' ]; then _H1="Content-Type: application/x-www-form-urlencoded" @@ -104,16 +105,17 @@ deployer() { # This is the main function that will call the other functions to deploy everything. panos_deploy() { - _cdomain=${1//[*]/WILDCARD_} #Wildcard Safe filename + _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename _ckey="$2" _cfullchain="$5" # VALID ECC KEY CHECK - if [[ "${_ckey: -8}" == "_ecc.key" ]] && [[ ! -f $_ckey ]]; then - _debug "The ECC key $_ckey doesn't exist. Attempting to strip _ecc from the filename" - _ckey="${_ckey:0:${#_ckey}-8}.key" - if [[ ! -f $_ckey ]]; then - _err "Still didn't work. Try issuing the certificate using RSA (non-ECC) encryption." - return 1 + keysuffix=$(printf '%s' "$_ckey" | tail -c 8) + if [ "$keysuffix" = "_ecc.key" ] && [ ! -f "$_ckey" ]; then + _debug "The ECC key $_ckey doesn't exist. Attempting to strip '_ecc' from the key name" + _ckey=$(echo "$_ckey" | sed 's/\(.*\)_ecc.key$/\1.key/g') + if [ ! -f "$_ckey" ]; then + _err "Unable to find a valid key. Try issuing the certificate using RSA (non-ECC) encryption." + return 1 fi fi # PANOS ENV VAR check @@ -122,9 +124,11 @@ panos_deploy() { _getdeployconf PANOS_USER _getdeployconf PANOS_PASS _getdeployconf PANOS_HOST + _getdeployconf PANOS_KEY _panos_user=$PANOS_USER _panos_pass=$PANOS_PASS _panos_host=$PANOS_HOST + _panos_key=$PANOS_KEY if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs." return 1 @@ -140,28 +144,33 @@ panos_deploy() { _panos_user="$PANOS_USER" _panos_pass="$PANOS_PASS" _panos_host="$PANOS_HOST" + if [ "$PANOS_KEY" ]; then + _savedeployconf PANOS_KEY "$PANOS_KEY" 1 + _panos_key="$PANOS_KEY" + else + _getdeployconf PANOS_KEY + _panos_key=$PANOS_KEY + fi fi _debug "Let's use username and pass to generate token." if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST" return 1 else - #Check for saved API Key - _getdeployconf PANOS_KEY - _panos_key=$PANOS_KEY + #Test API Key if [ "$_panos_key" ]; then _debug "**** Testing Saved API KEY ****" deployer testkey fi - # Generate a new API key if needed + # Generate a new API key if no valid key exists if [ -z "$_panos_key" ]; then _debug "**** Generating new PANOS API KEY ****" deployer keygen _savedeployconf PANOS_KEY "$_panos_key" 1 fi - # Recheck the key + # Confirm that a valid key was generated if [ -z "$_panos_key" ]; then _err "Missing apikey." return 1 From bb5f3cc32606507520f1705bb1a50334fc2796f5 Mon Sep 17 00:00:00 2001 From: Alexander Pushkarev Date: Mon, 1 May 2023 23:00:01 +0300 Subject: [PATCH 135/687] Add support for Mattermost notifications. --- notify/mattermost.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 notify/mattermost.sh diff --git a/notify/mattermost.sh b/notify/mattermost.sh new file mode 100644 index 00000000..9037ae0d --- /dev/null +++ b/notify/mattermost.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env sh + +# Support mattermost bots + +#MATTERMOST_API_URL="" +#MATTERMOST_CHANNEL_ID="" +#MATTERMOST_BOT_TOKEN="" + +mattermost_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + MATTERMOST_API_URL="${MATTERMOST_API_URL:-$(_readaccountconf_mutable MATTERMOST_API_URL)}" + if [ -z "$MATTERMOST_API_URL" ]; then + _err "You didn't specify a Mattermost API URL MATTERMOST_API_URL yet." + return 1 + fi + _saveaccountconf_mutable MATTERMOST_API_URL "$MATTERMOST_API_URL" + + MATTERMOST_CHANNEL_ID="${MATTERMOST_CHANNEL_ID:-$(_readaccountconf_mutable MATTERMOST_CHANNEL_ID)}" + if [ -z "$MATTERMOST_CHANNEL_ID" ]; then + _err "You didn't specify a Mattermost channel id MATTERMOST_CHANNEL_ID yet." + return 1 + fi + _saveaccountconf_mutable MATTERMOST_CHANNEL_ID "$MATTERMOST_CHANNEL_ID" + + MATTERMOST_BOT_TOKEN="${MATTERMOST_BOT_TOKEN:-$(_readaccountconf_mutable MATTERMOST_BOT_TOKEN)}" + if [ -z "$MATTERMOST_BOT_TOKEN" ]; then + _err "You didn't specify a Mattermost bot API token MATTERMOST_BOT_TOKEN yet." + return 1 + fi + _saveaccountconf_mutable MATTERMOST_BOT_TOKEN "$MATTERMOST_BOT_TOKEN" + + _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" + _data="{\"channel_id\": \"$MATTERMOST_CHANNEL_ID\", " + _data="$_data\"message\": \"$_content\"}" + + export _H1="Authorization: Bearer $MATTERMOST_BOT_TOKEN" + + if _post "$_data" "$MATTERMOST_API_URL" "" "POST" "application/json; charset=utf-8"; then + MATTERMOST_RESULT_OK=$(echo "$response" | _egrep_o 'create_at') + if [ "$?" = "0" ] && [ "$MATTERMOST_RESULT_OK" ]; then + _info "mattermost send success." + return 0 + fi + fi + _err "mattermost send error." + _err "$response" + return 1 +} From e6e22a1ca15cd7fc20242e3e8074858d9081d04f Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Tue, 9 May 2023 08:44:18 +0200 Subject: [PATCH 136/687] dnsapi: fix OPNsense script to be compatible with upcoming 23.1.8 The current script is already broken due to Bind 9.16 -> 9.18 changes due to their renaming scheme for primary/secondary so do not rely on the compat layer (which was also broken for other reasons). --- dnsapi/dns_opnsense.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index c2806a1b..d40cbe28 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -137,7 +137,7 @@ _get_root() { domain=$1 i=2 p=1 - if _opns_rest "GET" "/domain/searchMasterDomain"; then + if _opns_rest "GET" "/domain/searchPrimaryDomain"; then _domain_response="$response" else return 1 @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"primary\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) From af759f2330d5abe369871780eaf95972912c5351 Mon Sep 17 00:00:00 2001 From: gmanic <30374118+gmanic@users.noreply.github.com> Date: Sun, 14 May 2023 20:02:43 +0000 Subject: [PATCH 137/687] Enable additional command line parameters for nsupdate For being able to use e.g. "-v" to use TCP communication with the NSUPDATE_SERVER -> NSUPDATE_OPT has been added. NSUPDATE_OPT will be plainly added to the command line of nsupdate. NSUPDATE_OPT will also be saved to conf respectively read from conf --- dnsapi/dns_nsupdate.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index cd4b7140..569fc6a5 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -10,6 +10,7 @@ dns_nsupdate_add() { NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}" NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}" NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}" + NSUPDATE_OPT="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_OPT)}" _checkKeyFile || return 1 @@ -18,6 +19,7 @@ dns_nsupdate_add() { _saveaccountconf_mutable NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}" _saveaccountconf_mutable NSUPDATE_KEY "${NSUPDATE_KEY}" _saveaccountconf_mutable NSUPDATE_ZONE "${NSUPDATE_ZONE}" + _saveaccountconf_mutable NSUPDATE_OPT "${NSUPDATE_OPT}" [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost" [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53 @@ -26,13 +28,13 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then - nsupdate -k "${NSUPDATE_KEY}" $nsdebug < Date: Sun, 14 May 2023 20:20:22 +0000 Subject: [PATCH 138/687] Correct Typo, add -n test Added a test for non-zero-string, corrected type ZONE instead of OPT --- dnsapi/dns_nsupdate.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 569fc6a5..4161ad5b 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -10,7 +10,7 @@ dns_nsupdate_add() { NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}" NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}" NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}" - NSUPDATE_OPT="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_OPT)}" + NSUPDATE_OPT="${NSUPDATE_OPT:-$(_readaccountconf_mutable NSUPDATE_OPT)}" _checkKeyFile || return 1 @@ -23,6 +23,7 @@ dns_nsupdate_add() { [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost" [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53 + [ -n "${NSUPDATE_OPT}" ] || NSUPDATE_OPT="" _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\"" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" From f99d6dac084ad43cf559061f1cdf4ff0e0fc4885 Mon Sep 17 00:00:00 2001 From: gmanic <30374118+gmanic@users.noreply.github.com> Date: Sun, 14 May 2023 20:58:48 +0000 Subject: [PATCH 139/687] Push for actions --- dnsapi/dns_nsupdate.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 4161ad5b..77786a8c 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -3,6 +3,7 @@ ######## Public functions ##################### #Usage: dns_nsupdate_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# actions push dns_nsupdate_add() { fulldomain=$1 txtvalue=$2 From 0b0476e196ac38daeaba4a178617221f2d048fe7 Mon Sep 17 00:00:00 2001 From: gmanic <30374118+gmanic@users.noreply.github.com> Date: Sun, 14 May 2023 21:01:51 +0000 Subject: [PATCH 140/687] Update dns_nsupdate.sh --- dnsapi/dns_nsupdate.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 77786a8c..4161ad5b 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -3,7 +3,6 @@ ######## Public functions ##################### #Usage: dns_nsupdate_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -# actions push dns_nsupdate_add() { fulldomain=$1 txtvalue=$2 From a8fba65cbd06d2bf1a25895a24c17f3c04f2dbca Mon Sep 17 00:00:00 2001 From: sg1888 Date: Mon, 15 May 2023 01:43:54 +0000 Subject: [PATCH 141/687] Cleaned up verbiage. Added ability to store / update user variable. Added ability to use user/pass OR key --- deploy/panos.sh | 140 ++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 52 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 7fb0c9db..774060b0 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -7,10 +7,24 @@ # # Firewall admin with superuser and IP address is required. # -# export PANOS_USER="" # required -# export PANOS_PASS="" # required -# export PANOS_HOST="" # required -# export PANOS_KEY="" # optional +# You MUST include the following environment variable when first running +# the sccript (can be deleted afterwards): +# +# REQURED: +# export PANOS_HOST="" # required +# +# AND one of the two authenticiation methods: +# +# Method 1: Username & Password (RECOMMENDED) +# export PANOS_USER="" +# export PANOS_PASS="" +# +# Method 2: API KEY +# export PANOS_KEY="" +# +# +# The Username & Password method will automatically generate a new API key if +# no key is found, or if a saved key has expired or is invalid. # This function is to parse the XML parse_response() { @@ -26,8 +40,8 @@ parse_response() { else status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') - if [ "$type" = 'testkey' ] && [ "$status" != "success" ]; then - _debug "**** Saved API key is invalid ****" + if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then + _debug "**** API Key has EXPIRED or is INVALID ****" unset _panos_key fi fi @@ -36,25 +50,27 @@ parse_response() { deployer() { content="" - type=$1 # Types are testkey, keygen, cert, key, commit - _debug "**** Deploying $type ****" + type=$1 # Types are keytest, keygen, cert, key, commit panos_url="https://$_panos_host/api/" #Test API Key by performing an empty commit. - if [ "$type" = 'testkey' ]; then + if [ "$type" = 'keytest' ]; then + _debug "**** Testing saved API Key ****" _H1="Content-Type: application/x-www-form-urlencoded" content="type=commit&cmd=&key=$_panos_key" fi # Generate API Key if [ "$type" = 'keygen' ]; then + _debug "**** Generating new API Key ****" _H1="Content-Type: application/x-www-form-urlencoded" content="type=keygen&user=$_panos_user&password=$_panos_pass" # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" fi if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then - #Generate DEIM + _debug "**** Deploying $type ****" + #Generate DELIM delim="-----MultipartDelimiter$(date "+%s%N")" nl="\015\012" #Set Header @@ -83,8 +99,14 @@ deployer() { fi if [ "$type" = 'commit' ]; then + _debug "**** Committing changes ****" export _H1="Content-Type: application/x-www-form-urlencoded" - cmd=$(printf "%s" "<$_panos_user>" | _url_encode) + if [ "$_panos_user" ]; then + _commit_desc=$_panos_user + else + _commit_desc="acmesh" + fi + cmd=$(printf "%s" "<$_commit_desc>" | _url_encode) content="type=commit&key=$_panos_key&cmd=$cmd" fi response=$(_post "$content" "$panos_url" "" "POST") @@ -118,52 +140,66 @@ panos_deploy() { return 1 fi fi - # PANOS ENV VAR check - if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then - _debug "No ENV variables found lets check for saved variables" - _getdeployconf PANOS_USER - _getdeployconf PANOS_PASS - _getdeployconf PANOS_HOST - _getdeployconf PANOS_KEY - _panos_user=$PANOS_USER - _panos_pass=$PANOS_PASS - _panos_host=$PANOS_HOST - _panos_key=$PANOS_KEY - if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then - _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs." - return 1 - else - _debug "Using saved env variables." - fi + + # Environment Checks + + # PANOS_HOST + if [ "$PANOS_HOST" ]; then + _debug "Detected ENV variable PANOS_HOST. Saving to file." + _savedeployconf PANOS_HOST "$PANOS_HOST" 1 else - _debug "Detected ENV variables to be saved to the deploy conf." - # Encrypt and save user + _debug "Attempting to load variable PANOS_HOST from file." + _getdeployconf PANOS_HOST + fi + + # PANOS USER + if [ "$PANOS_USER" ]; then + _debug "Detected ENV variable PANOS_USER. Saving to file." _savedeployconf PANOS_USER "$PANOS_USER" 1 + else + _debug "Attempting to load variable PANOS_USER from file." + _getdeployconf PANOS_USER + fi + + # PANOS_KEY + if [ "$PANOS_PASS" ]; then + _debug "Detected ENV variable PANOS_PASS. Saving to file." _savedeployconf PANOS_PASS "$PANOS_PASS" 1 - _savedeployconf PANOS_HOST "$PANOS_HOST" 1 - _panos_user="$PANOS_USER" - _panos_pass="$PANOS_PASS" - _panos_host="$PANOS_HOST" - if [ "$PANOS_KEY" ]; then - _savedeployconf PANOS_KEY "$PANOS_KEY" 1 - _panos_key="$PANOS_KEY" - else - _getdeployconf PANOS_KEY - _panos_key=$PANOS_KEY - fi + else + _debug "Attempting to load variable PANOS_PASS from file." + _getdeployconf PANOS_PASS fi - _debug "Let's use username and pass to generate token." - if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then - _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST" - return 1 + + # PANOS_KEY + if [ "$PANOS_KEY" ]; then + _debug "Detected ENV variable PANOS_KEY. Saving to file." + _savedeployconf PANOS_KEY "$PANOS_KEY" 1 else - #Test API Key - if [ "$_panos_key" ]; then - _debug "**** Testing Saved API KEY ****" - deployer testkey - fi + _debug "Attempting to load variable PANOS_KEY from file." + _getdeployconf PANOS_KEY + fi + + #Store variables + _panos_host=$PANOS_HOST + _panos_key=$PANOS_KEY + _panos_user=$PANOS_USER + _panos_pass=$PANOS_PASS - # Generate a new API key if no valid key exists + #Test API Key if found. If the key is invalid, the variable panos_key will be unset. + if [ "$_panos_host" ] && [ "$_panos_key" ]; then + _debug "**** Testing API KEY ****" + deployer keytest + fi + + # Check for valid variables + if [ -z "$_panos_host" ]; then + _err "No host found. Please enter a valid host as environment variable PANOS_HOST." + return 1 + elif [ -z "$_panos_key" ] && { [ -z "$_panos_user" ] || [ -z "$_panos_pass" ]; }; then + _err "No user and pass OR valid API key found.. If this is the first time deploying please set PANOS_USER and PANOS_PASS -- AND/OR -- PANOS_KEY in environment variables. Delete them after you have succesfully deployed certs." + return 1 + else + # Generate a new API key if no valid API key is found if [ -z "$_panos_key" ]; then _debug "**** Generating new PANOS API KEY ****" deployer keygen @@ -172,7 +208,7 @@ panos_deploy() { # Confirm that a valid key was generated if [ -z "$_panos_key" ]; then - _err "Missing apikey." + _err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the credentials and try again" return 1 else deployer cert From 0ebc9f7a44f05f595084e55b83cff59b471b8d9f Mon Sep 17 00:00:00 2001 From: sg1888 Date: Mon, 15 May 2023 01:46:21 +0000 Subject: [PATCH 142/687] Fixed typo --- deploy/panos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 774060b0..755ad5c9 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -161,7 +161,7 @@ panos_deploy() { _getdeployconf PANOS_USER fi - # PANOS_KEY + # PANOS_PASS if [ "$PANOS_PASS" ]; then _debug "Detected ENV variable PANOS_PASS. Saving to file." _savedeployconf PANOS_PASS "$PANOS_PASS" 1 From 2e2e7cd05408f8bf98016c5c0c9762608cd4e681 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Wed, 17 May 2023 20:06:06 +0000 Subject: [PATCH 143/687] Added ability to force commit to firewall. Username is now also mandatory --- deploy/panos.sh | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 755ad5c9..2744ba6d 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -7,26 +7,24 @@ # # Firewall admin with superuser and IP address is required. # -# You MUST include the following environment variable when first running -# the sccript (can be deleted afterwards): -# # REQURED: # export PANOS_HOST="" # required +# export PANOS_USER="" # required # # AND one of the two authenticiation methods: # -# Method 1: Username & Password (RECOMMENDED) -# export PANOS_USER="" +# Method 1: Password (RECOMMENDED) # export PANOS_PASS="" # # Method 2: API KEY # export PANOS_KEY="" # # -# The Username & Password method will automatically generate a new API key if +# The Password method will automatically generate a new API key if # no key is found, or if a saved key has expired or is invalid. +# -# This function is to parse the XML +# This function is to parse the XML response from the firewall parse_response() { type=$2 if [ "$type" = 'keygen' ]; then @@ -48,6 +46,7 @@ parse_response() { return 0 } +#This function is used to deploy to the firewall deployer() { content="" type=$1 # Types are keytest, keygen, cert, key, commit @@ -68,6 +67,7 @@ deployer() { # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" fi + # Deploy Cert or Key if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then _debug "**** Deploying $type ****" #Generate DELIM @@ -98,17 +98,19 @@ deployer() { content=$(printf %b "$content") fi + # Commit changes if [ "$type" = 'commit' ]; then _debug "**** Committing changes ****" export _H1="Content-Type: application/x-www-form-urlencoded" - if [ "$_panos_user" ]; then - _commit_desc=$_panos_user + #Check for force commit + if [ "$FORCE" ]; then + cmd=$(printf "%s" "<$_panos_user>" | _url_encode) else - _commit_desc="acmesh" + cmd=$(printf "%s" "<$_panos_user>" | _url_encode) fi - cmd=$(printf "%s" "<$_commit_desc>" | _url_encode) content="type=commit&key=$_panos_key&cmd=$cmd" fi + response=$(_post "$content" "$panos_url" "" "POST") parse_response "$response" "$type" # Saving response to variables @@ -141,8 +143,6 @@ panos_deploy() { fi fi - # Environment Checks - # PANOS_HOST if [ "$PANOS_HOST" ]; then _debug "Detected ENV variable PANOS_HOST. Saving to file." @@ -193,10 +193,13 @@ panos_deploy() { # Check for valid variables if [ -z "$_panos_host" ]; then - _err "No host found. Please enter a valid host as environment variable PANOS_HOST." + _err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs." + return 1 + elif [ -z "$_panos_user" ]; then + _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed certs." return 1 elif [ -z "$_panos_key" ] && { [ -z "$_panos_user" ] || [ -z "$_panos_pass" ]; }; then - _err "No user and pass OR valid API key found.. If this is the first time deploying please set PANOS_USER and PANOS_PASS -- AND/OR -- PANOS_KEY in environment variables. Delete them after you have succesfully deployed certs." + _err "No pass OR valid API key found. If this is your first time deploying please set PANOS_PASS and/or PANOS_KEY in ENV variables. You can delete them after you have succesfully deployed certs." return 1 else # Generate a new API key if no valid API key is found @@ -208,7 +211,7 @@ panos_deploy() { # Confirm that a valid key was generated if [ -z "$_panos_key" ]; then - _err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the credentials and try again" + _err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the PANOS_USER and PANOS_PASS credentials and try again" return 1 else deployer cert From 126df9647b6ef11da3a7efe9897b453cf4e501d9 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Wed, 24 May 2023 18:51:57 +0000 Subject: [PATCH 144/687] Modified keytest to perform a partial empty commit --- deploy/panos.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 2744ba6d..880e4cec 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -56,7 +56,7 @@ deployer() { if [ "$type" = 'keytest' ]; then _debug "**** Testing saved API Key ****" _H1="Content-Type: application/x-www-form-urlencoded" - content="type=commit&cmd=&key=$_panos_key" + content="type=commit&key=$_panos_key&action=partial&cmd=acmekeytest" fi # Generate API Key @@ -132,6 +132,7 @@ panos_deploy() { _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename _ckey="$2" _cfullchain="$5" + # VALID ECC KEY CHECK keysuffix=$(printf '%s' "$_ckey" | tail -c 8) if [ "$keysuffix" = "_ecc.key" ] && [ ! -f "$_ckey" ]; then @@ -196,10 +197,10 @@ panos_deploy() { _err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs." return 1 elif [ -z "$_panos_user" ]; then - _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed certs." + _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs." return 1 elif [ -z "$_panos_key" ] && { [ -z "$_panos_user" ] || [ -z "$_panos_pass" ]; }; then - _err "No pass OR valid API key found. If this is your first time deploying please set PANOS_PASS and/or PANOS_KEY in ENV variables. You can delete them after you have succesfully deployed certs." + _err "No pass OR valid API key found. If this is your first time deploying please set PANOS_PASS and/or PANOS_KEY in ENV variables. You can delete them after you have succesfully deployed the certs." return 1 else # Generate a new API key if no valid API key is found From 623d615cd737de93b73e1c1a70dafb19b41d91f1 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 28 May 2023 21:42:53 +0200 Subject: [PATCH 145/687] Remove external OTP dependency from synology_dsm.sh Also adapt to DSM 7's API improvements. --- deploy/synology_dsm.sh | 142 +++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 63 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index c31a5df0..4e6ce661 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -1,34 +1,35 @@ -#!/usr/bin/env sh - -# Here is a script to deploy cert to Synology DSM -# -# It requires following environment variables: -# -# SYNO_Username - Synology Username to login (must be an administrator) -# SYNO_Password - Synology Password to login -# SYNO_Certificate - Certificate description to target for replacement -# -# The following environmental variables may be set if you don't like their -# default values: -# -# SYNO_Scheme - defaults to http -# SYNO_Hostname - defaults to localhost -# SYNO_Port - defaults to 5000 -# SYNO_DID - device ID to skip OTP - defaults to empty -# SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty -# +#!/bin/bash + +################################################################################ +# ACME.sh 3rd party deploy plugin for Synology DSM +################################################################################ +# Authors: Brian Hartvigsen (creator), https://github.com/tresni +# Martin Arndt (contributor), https://troublezone.net/ +# Updated: 2023-05-28 +# Issues: https://github.com/acmesh-official/acme.sh/issues/2727 +################################################################################ +# Usage: +# 1. export SYNO_Username="adminUser" +# 2. export SYNO_Password="adminPassword" +# Optional exports (shown values are the defaults): +# - export SYNO_Certificate="" to replace a specific certificate via description +# - export SYNO_Scheme="http" +# - export SYNO_Hostname="localhost" +# - export SYNO_Port="5000" +# - export SYNO_Device_Name="CertRenewal" - required for skipping 2FA-OTP +# - export SYNO_Device_ID="" - required for skipping 2FA-OTP +# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com +################################################################################ # Dependencies: -# ------------- -# - jq and curl -# - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set) -# -#returns 0 means success, otherwise error. - -######## Public functions ##################### +# - jq & curl +################################################################################ +# Return value: +# 0 means success, otherwise error. +################################################################################ +########## Public functions #################################################### #domain keyfile certfile cafile fullchain synology_dsm_deploy() { - _cdomain="$1" _ckey="$2" _ccert="$3" @@ -36,34 +37,39 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" - # Get Username and Password, but don't save until we successfully authenticate + # Get username & password, but don't save until we authenticated successfully _getdeployconf SYNO_Username _getdeployconf SYNO_Password _getdeployconf SYNO_Create - _getdeployconf SYNO_DID - _getdeployconf SYNO_TOTP_SECRET + _getdeployconf SYNO_Device_Name + _getdeployconf SYNO_Device_ID if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then _err "SYNO_Username & SYNO_Password must be set" return 1 fi + if [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then + _err "SYNO_Device_Name set, but SYNO_Device_ID is empty" + return 1 + fi _debug2 SYNO_Username "$SYNO_Username" _secure_debug2 SYNO_Password "$SYNO_Password" + _debug2 SYNO_Create "$SYNO_Create" + _debug2 SYNO_Device_Name "$SYNO_Device_Name" + _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" - # Optional scheme, hostname, and port for Synology DSM + # Optional scheme, hostname & port for Synology DSM _getdeployconf SYNO_Scheme _getdeployconf SYNO_Hostname _getdeployconf SYNO_Port - # default vaules for scheme, hostname, and port - # defaulting to localhost and http because it's localhost... + # Default values for scheme, hostname & port + # Defaulting to localhost & http, because it's localhost… [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Port}" ] || SYNO_Port="5000" - _savedeployconf SYNO_Scheme "$SYNO_Scheme" _savedeployconf SYNO_Hostname "$SYNO_Hostname" _savedeployconf SYNO_Port "$SYNO_Port" - _debug2 SYNO_Scheme "$SYNO_Scheme" _debug2 SYNO_Hostname "$SYNO_Hostname" _debug2 SYNO_Port "$SYNO_Port" @@ -87,49 +93,49 @@ synology_dsm_deploy() { _debug3 response "$response" _debug3 api_version "$api_version" - # Login, get the token from JSON and session id from cookie + # Login, get the session ID & SynoToken from JSON _info "Logging into $SYNO_Hostname:$SYNO_Port" encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" - otp_code="" - if [ -n "$SYNO_TOTP_SECRET" ]; then - if _exists oathtool; then - otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" - else - _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" - return 1 + # Get device ID if still empty first, otherwise log in right away + if [ -z "${SYNO_Device_ID:-}" ]; then + printf "Enter OTP code for user '%s': " "$SYNO_Username" + read -r otp_code + if [ -z "${SYNO_Device_Name:-}" ]; then + printf "Enter device name or leave empty for default (CertRenewal): " + read -r SYNO_Device_Name + [ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal" fi - fi - if [ -n "$SYNO_DID" ]; then - _H1="Cookie: did=$SYNO_DID" - export _H1 - _debug3 H1 "${_H1}" + response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") + _debug3 response "$response" + SYNO_Device_ID=$(echo "$response" | grep "device_id" | sed -n 's/.*"device_id" *: *"\([^"]*\).*/\1/p') + _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" + else + response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") + _debug3 response "$response" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') - _debug3 response "$response" - _debug token "$token" - - if [ -z "$token" ]; then - _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." - _err "Check your username and password." - _err "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET." + _debug Session ID "$sid" + _debug SynoToken "$token" + if [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then + _err "Unable to authenticate to $_base_url - check your username & password." + _err "If two-factor authentication is enabled for the user, set SYNO_Device_ID." return 1 fi - sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') _H1="X-SYNO-TOKEN: $token" export _H1 _debug2 H1 "${_H1}" - # Now that we know the username and password are good, save them + # Now that we know the username & password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" - _savedeployconf SYNO_DID "$SYNO_DID" - _savedeployconf SYNO_TOTP_SECRET "$SYNO_TOTP_SECRET" + _savedeployconf SYNO_Device_Name "$SYNO_Device_Name" + _savedeployconf SYNO_Device_ID "$SYNO_Device_ID" _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") @@ -140,7 +146,7 @@ synology_dsm_deploy() { _debug2 id "$id" if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then - _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set" + _err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set" return 1 fi @@ -171,13 +177,23 @@ synology_dsm_deploy() { if ! echo "$response" | grep '"error":' >/dev/null; then if echo "$response" | grep '"restart_httpd":true' >/dev/null; then - _info "http services were restarted" + _info "Restarting HTTP services succeeded" else - _info "http services were NOT restarted" + _info "Restarting HTTP services failed" fi + + _logout return 0 else _err "Unable to update certificate, error code $response" + _logout return 1 fi } + +#################### Private functions below ################################## +_logout() { + # Logout to not occupy a permanent session, e. g. in DSM's "Connected Users" widget + response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=logout") + _debug3 response "$response" +} From 0548ad2fc6b4febe557620ec2280bdec6b7ec304 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sun, 28 May 2023 22:33:15 +0200 Subject: [PATCH 146/687] Fix debug output of session ID --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 4e6ce661..f709e0fb 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -119,7 +119,7 @@ synology_dsm_deploy() { sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') - _debug Session ID "$sid" + _debug "Session ID" "$sid" _debug SynoToken "$token" if [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then _err "Unable to authenticate to $_base_url - check your username & password." From 63fca33b0459b1483c91c38a9ae3060bb6ef621a Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Mon, 29 May 2023 20:12:52 +0200 Subject: [PATCH 147/687] Fix retrieval of domain zone --- dnsapi/dns_artfiles.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 2f8e158f..703c02ac 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -140,14 +140,13 @@ _dns() { # Gets the root domain zone for given domain. # Usage: _get_zone _acme-challenge.www.example.com _get_zone() { - _info 'Getting domain zone...' - _debug2 'Initial FQDN' "$1" fqdn="$1" - fqdn="${fqdn#*.}" # Strip "_acme-challenge" right away - _debug2 'Reduced FQDN' "$fqdn" + domains="$(_get "$AF_URL_DOMAINS" "" 10)" + _info 'Getting domain zone...' + _debug2 'FQDN' "$fqdn" + _debug2 'Domains' "$domains" - domains="$(_get "$AF_URL_DOMAINS" '' 10)" - while true; do + while _contains "$fqdn" "."; do if _contains "$domains" "$fqdn"; then domain="$fqdn" _info "Found root domain zone: $domain" @@ -162,7 +161,7 @@ _get_zone() { return 0 fi - _err "Couldn't find root domain zone." + _err 'Couldn\'t find root domain zone.' return 1 } From fb33ea2a0b6fc8ff260da123709b0872c6b91e79 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Mon, 29 May 2023 20:21:16 +0200 Subject: [PATCH 148/687] Fix single quote escaping --- dnsapi/dns_artfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 703c02ac..ad547e3f 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -161,7 +161,7 @@ _get_zone() { return 0 fi - _err 'Couldn\'t find root domain zone.' + _err 'Couldn'\''t find root domain zone.' return 1 } From d108072bfbc057f895d29620a8ecd6752ebe47f6 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Tue, 30 May 2023 09:24:17 +0200 Subject: [PATCH 149/687] Add ArtFiles.de DNS API plugin --- dnsapi/dns_artfiles.sh | 175 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 dnsapi/dns_artfiles.sh diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh new file mode 100644 index 00000000..ad547e3f --- /dev/null +++ b/dnsapi/dns_artfiles.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env sh + +################################################################################ +# ACME.sh 3rd party DNS API plugin for ArtFiles.de +################################################################################ +# Author: Martin Arndt, https://troublezone.net/ +# Released: 2022-02-27 +# Issues: https://github.com/Eagle3386/acme.sh/issues +################################################################################ +# Usage: +# 1. export AF_API_USERNAME="api12345678" +# 2. export AF_API_PASSWORD="apiPassword" +# 3. acme.sh --issue -d example.com --dns dns_artfiles +################################################################################ + +########## API configuration ################################################### +AF_API_SUCCESS='status":"OK' +AF_URL_DCP='https://dcp.c.artfiles.de/api/' +AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain=' +AF_URL_DOMAINS=${AF_URL_BASE}'domain/get_domains.html' + +########## Public functions #################################################### + +# Adds a new TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_add() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS addition API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" + AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" + if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then + _err 'Missing ArtFiles.de username and/or password.' + _err 'Please ensure both are set via export command & try again.' + + return 1 + fi + + _saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME" + _saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD" + + _set_headers + _get_zone "$domain" + _dns 'GET' + if ! _contains "$response" 'TXT'; then + _err 'Retrieving TXT records failed.' + + return 1 + fi + + _clean_records + _dns 'SET' "$(printf -- '%s\n_acme-challenge "%s"' "$response" "$txtValue")" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Adding ACME challenge value failed.' + + return 1 + fi +} + +# Removes the existing TXT record for given ACME challenge value & domain. +# Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value" +dns_artfiles_rm() { + domain="$1" + txtValue="$2" + _info 'Using ArtFiles.de DNS removal API' + _debug 'Domain' "$domain" + _debug 'txtValue' "$txtValue" + + _set_headers + _get_zone "$domain" + if ! _dns 'GET'; then + return 1 + fi + + if ! _contains "$response" "$txtValue"; then + _err 'Retrieved TXT records are missing given ACME challenge value.' + + return 1 + fi + + _clean_records + response="$(printf -- '%s' "$response" | sed '$d')" + _dns 'SET' "$response" + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err 'Removing ACME challenge value failed.' + + return 1 + fi +} + +########## Private functions ################################################### + +# Cleans awful TXT records response of ArtFiles's API & pretty prints it. +# Usage: _clean_records +_clean_records() { + # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid + # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' + # from '\"' & turn '\n' into real LF characters. + # Yup, awful API to use - but that's all we got to get this working, so... ;) + _debug2 'Raw ' "$response" + response="$( + printf -- '%s' "$response" + \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g' + )" + _debug2 'Clean' "$response" +} + +# Executes an HTTP GET or POST request for getting or setting DNS records, +# containing given payload upon POST. +# Usage: _dns [GET | SET] [payload] +_dns() { + action="$1" + payload="$(printf -- '%s' "$2" | _url_encode)" + url="$( + printf -- '%s%s' "$AF_URL_DNS" "$domain" + \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/' + )" + + if [ "$action" = 'SET' ]; then + _debug2 'Payload' "$payload" + response="$(_post '' "$url&TXT=$payload" '' 'POST' 'application/x-www-form-urlencoded')" + else + response="$(_get "$url" '' 10)" + fi + + if ! _contains "$response" "$AF_API_SUCCESS"; then + _err "DNS API error: $response" + + return 1 + fi + + _debug 'Response' "$response" + + return 0 +} + +# Gets the root domain zone for given domain. +# Usage: _get_zone _acme-challenge.www.example.com +_get_zone() { + fqdn="$1" + domains="$(_get "$AF_URL_DOMAINS" "" 10)" + _info 'Getting domain zone...' + _debug2 'FQDN' "$fqdn" + _debug2 'Domains' "$domains" + + while _contains "$fqdn" "."; do + if _contains "$domains" "$fqdn"; then + domain="$fqdn" + _info "Found root domain zone: $domain" + break + else + fqdn="${fqdn#*.}" + _debug2 'FQDN' "$fqdn" + fi + done + + if [ "$domain" = "$fqdn" ]; then + return 0 + fi + + _err 'Couldn'\''t find root domain zone.' + + return 1 +} + +# Adds the HTTP Authorization & Content-Type headers to a follow-up request. +# Usage: _set_headers +_set_headers() { + encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" + export _H1="Authorization: Basic $encoded" + export _H2='Content-Type: application/json' +} From 6c8920f63eb59e554767e40dcefacec55ecf1396 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Mon, 5 Jun 2023 12:54:54 +0300 Subject: [PATCH 150/687] dns_ovh.sh Add ovh-us endpoint Remove discontinued runabove.com If any new env will be added then a user may spe Signed-off-by: Sergey Ponomarev --- dnsapi/dns_ovh.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 5e35011b..e1a958f6 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -14,6 +14,9 @@ #'ovh-eu' OVH_EU='https://eu.api.ovh.com/1.0' +#'ovh-us' +OVH_US='https://api.us.ovhcloud.com/1.0' + #'ovh-ca': OVH_CA='https://ca.api.ovh.com/1.0' @@ -29,9 +32,6 @@ SYS_EU='https://eu.api.soyoustart.com/1.0' #'soyoustart-ca' SYS_CA='https://ca.api.soyoustart.com/1.0' -#'runabove-ca' -RAV_CA='https://api.runabove.com/1.0' - wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-OVH-domain-api" ovh_success="https://github.com/acmesh-official/acme.sh/wiki/OVH-Success" @@ -45,6 +45,10 @@ _ovh_get_api() { printf "%s" $OVH_EU return ;; + ovh-us | ovhus) + printf "%s" $OVH_US + return + ;; ovh-ca | ovhca) printf "%s" $OVH_CA return @@ -65,14 +69,15 @@ _ovh_get_api() { printf "%s" $SYS_CA return ;; - runabove-ca | runaboveca) - printf "%s" $RAV_CA + # raw API url starts with https:// + https*) + printf "%s" "$1" return ;; *) - _err "Unknown parameter : $1" + _err "Unknown endpoint : $1" return 1 ;; esac From beab808b76fa49ab0eb2306b4b800acdb39e7f0e Mon Sep 17 00:00:00 2001 From: Justin Nogossek Date: Wed, 7 Jun 2023 23:35:47 +0200 Subject: [PATCH 151/687] Update URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15bc4089..d04d4d48 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) - [archlinux](https://www.archlinux.org/packages/community/any/acme.sh) - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) -- [CentOS Web Panel](http://centos-webpanel.com/) +- [CentOS Web Panel](https://control-webpanel.com) - [lnmp.org](https://lnmp.org/) - [more...](https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials) From caf23f9a0484c81ed9185e7ed479394d9736d3af Mon Sep 17 00:00:00 2001 From: Justin Nogossek Date: Wed, 7 Jun 2023 23:36:18 +0200 Subject: [PATCH 152/687] Remove not anymore exists tutorials and websites --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d04d4d48..73ff3321 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,10 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) - [ruby-china.org](https://ruby-china.org/topics/31983) - [Proxmox](https://pve.proxmox.com/wiki/Certificate_Management) - [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89) -- [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt) - [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty) - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709) - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html) - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) -- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh) - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) - [CentOS Web Panel](https://control-webpanel.com) - [lnmp.org](https://lnmp.org/) From 4c30250782ff7440ca5ceeddb066a67ca450fcc7 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Jun 2023 19:59:29 +0800 Subject: [PATCH 153/687] fix https://github.com/acmesh-official/acme.sh/issues/4659 --- acme.sh | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index 37d13662..df0bd27d 100755 --- a/acme.sh +++ b/acme.sh @@ -2884,6 +2884,7 @@ _initpath() { fi fi _debug DOMAIN_PATH "$DOMAIN_PATH" + export DOMAIN_PATH fi if [ -z "$DOMAIN_BACKUP_PATH" ]; then @@ -4952,18 +4953,6 @@ $_authorizations_map" if ! chmod a+r "$wellknown_path/$token"; then _debug "chmod failed, but we just continue." fi - if [ ! "$usingApache" ]; then - if webroot_owner=$(_stat "$_currentRoot"); then - _debug "Changing owner/group of .well-known to $webroot_owner" - if ! _exec "chown -R \"$webroot_owner\" \"$_currentRoot/.well-known\""; then - _debug "$(cat "$_EXEC_TEMP_ERR")" - _exec_err >/dev/null 2>&1 - fi - else - _debug "not changing owner/group of webroot" - fi - fi - fi elif [ "$vtype" = "$VTYPE_ALPN" ]; then acmevalidationv1="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" From 327e2fb0a4bdbe4b75339e1cad6d20bda29318d6 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 9 Jun 2023 20:18:38 +0800 Subject: [PATCH 154/687] remove all exec. https://github.com/acmesh-official/acme.sh/issues/4659 --- acme.sh | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/acme.sh b/acme.sh index df0bd27d..633eb9fa 100755 --- a/acme.sh +++ b/acme.sh @@ -2936,22 +2936,6 @@ _initpath() { } -_exec() { - if [ -z "$_EXEC_TEMP_ERR" ]; then - _EXEC_TEMP_ERR="$(_mktemp)" - fi - - if [ "$_EXEC_TEMP_ERR" ]; then - eval "$@ 2>>$_EXEC_TEMP_ERR" - else - eval "$@" - fi -} - -_exec_err() { - [ "$_EXEC_TEMP_ERR" ] && _err "$(cat "$_EXEC_TEMP_ERR")" && echo "" >"$_EXEC_TEMP_ERR" -} - _apachePath() { _APACHECTL="apachectl" if ! _exists apachectl; then @@ -2964,8 +2948,7 @@ _apachePath() { fi fi - if ! _exec $_APACHECTL -V >/dev/null; then - _exec_err + if ! $_APACHECTL -V >/dev/null; then return 1 fi @@ -3017,8 +3000,7 @@ _restoreApache() { cat "$APACHE_CONF_BACKUP_DIR/$httpdconfname" >"$httpdconf" _debug "Restored: $httpdconf." - if ! _exec $_APACHECTL -t; then - _exec_err + if ! $_APACHECTL -t; then _err "Sorry, restore apache config error, please contact me." return 1 fi @@ -3036,8 +3018,7 @@ _setApache() { #test the conf first _info "Checking if there is an error in the apache config file before starting." - if ! _exec "$_APACHECTL" -t >/dev/null; then - _exec_err + if ! $_APACHECTL -t >/dev/null; then _err "The apache config file has error, please fix it first, then try again." _err "Don't worry, there is nothing changed to your system." return 1 @@ -3098,8 +3079,7 @@ Allow from all chmod 755 "$ACME_DIR" fi - if ! _exec "$_APACHECTL" graceful; then - _exec_err + if ! $_APACHECTL graceful; then _err "$_APACHECTL graceful error, please contact me." _restoreApache return 1 @@ -3184,8 +3164,7 @@ _setNginx() { return 1 fi _info "Check the nginx conf before setting up." - if ! _exec "nginx -t" >/dev/null; then - _exec_err + if ! nginx -t >/dev/null; then return 1 fi @@ -3212,16 +3191,14 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { fi _debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)" _info "nginx conf is done, let's check it again." - if ! _exec "nginx -t" >/dev/null; then - _exec_err + if ! nginx -t >/dev/null; then _err "It seems that nginx conf was broken, let's restore." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi _info "Reload nginx" - if ! _exec "nginx -s reload" >/dev/null; then - _exec_err + if ! nginx -s reload >/dev/null; then _err "It seems that nginx reload error, let's restore." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 @@ -3346,8 +3323,7 @@ _restoreNginx() { done _info "Reload nginx" - if ! _exec "nginx -s reload" >/dev/null; then - _exec_err + if ! nginx -s reload >/dev/null; then _err "It seems that nginx reload error, please report bug." return 1 fi From f680ede9802fb7e1dfa5a68da53c50675bfa9607 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 10 Jun 2023 01:16:57 +0800 Subject: [PATCH 155/687] start 3.0.7 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 633eb9fa..0cc52131 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.6 +VER=3.0.7 PROJECT_NAME="acme.sh" From 0d0478245fe4ac60eec7ab1621fa47fda3bfd27a Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Sat, 26 Nov 2022 20:11:41 +0100 Subject: [PATCH 156/687] dns_1984hosting.sh: fix login with valid csrftoken and sessionid --- dnsapi/dns_1984hosting.sh | 156 ++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 72 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 6accc597..2c6b2e4f 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -1,46 +1,46 @@ #!/usr/bin/env sh -#This file name is "dns_1984hosting.sh" -#So, here must be a method dns_1984hosting_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. +# This file name is "dns_1984hosting.sh" +# So, here must be a method dns_1984hosting_add() +# Which will be called by acme.sh to add the txt record to your api system. +# returns 0 means success, otherwise error. -#Author: Adrian Fedoreanu -#Report Bugs here: https://github.com/acmesh-official/acme.sh +# Author: Adrian Fedoreanu +# Report Bugs here: https://github.com/acmesh-official/acme.sh # or here... https://github.com/acmesh-official/acme.sh/issues/2851 -# -######## Public functions ##################### + +######## Public functions ##################### # Export 1984HOSTING username and password in following variables # # One984HOSTING_Username=username # One984HOSTING_Password=password # -# sessionid cookie is saved in ~/.acme.sh/account.conf -# username/password need to be set only when changed. +# username/password and csrftoken/sessionid cookies are saved in ~/.acme.sh/account.conf -#Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Add a text record. dns_1984hosting_add() { fulldomain=$1 txtvalue=$2 - _info "Add TXT record using 1984Hosting" + _info "Add TXT record using 1984Hosting." _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" if ! _1984hosting_login; then - _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file" + _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file." return 1 fi - _debug "First detect the root zone" + _debug "First detect the root zone." if ! _get_root "$fulldomain"; then - _err "invalid domain" "$fulldomain" + _err "Invalid domain '$fulldomain'." return 1 fi _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Add TXT record $fulldomain with value '$txtvalue'" + _debug "Add TXT record $fulldomain with value '$txtvalue'." value="$(printf '%s' "$txtvalue" | _url_encode)" url="https://1984.hosting/domains/entry/" @@ -53,93 +53,97 @@ dns_1984hosting_add() { _debug2 postdata "$postdata" _authpost "$postdata" "$url" - response="$(echo "$_response" | _normalizeJson)" - _debug2 response "$response" - - if _contains "$response" '"haserrors": true'; then - _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post" + if _contains "$_response" '"haserrors": true'; then + _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post." return 1 - elif _contains "$response" "html>"; then - _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file" + elif _contains "$_response" "html>"; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file." return 1 - elif _contains "$response" '"auth": false'; then - _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie" + elif _contains "$_response" '"auth": false'; then + _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie." return 1 fi - _info "Added acme challenge TXT record for $fulldomain at 1984Hosting" + _info "Added acme challenge TXT record for $fulldomain at 1984Hosting." return 0 } -#Usage: fulldomain txtvalue -#Remove the txt record after validation. +# Usage: fulldomain txtvalue +# Remove the txt record after validation. dns_1984hosting_rm() { fulldomain=$1 txtvalue=$2 - _info "Delete TXT record using 1984Hosting" + _info "Delete TXT record using 1984Hosting." _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" if ! _1984hosting_login; then - _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file" + _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file." return 1 fi - _debug "First detect the root zone" + _debug "First detect the root zone." if ! _get_root "$fulldomain"; then - _err "invalid domain" "$fulldomain" + _err "Invalid domain '$fulldomain'." return 1 fi _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Delete $fulldomain TXT record" + _debug "Delete $fulldomain TXT record." url="https://1984.hosting/domains" if ! _get_zone_id "$url" "$_domain"; then - _err "invalid zone" "$_domain" + _err "Invalid zone '$_domain'." return 1 fi _htmlget "$url/$_zone_id" "$txtvalue" - _debug2 _response "$_response" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" _debug2 entry_id "$entry_id" if [ -z "$entry_id" ]; then - _err "Error getting TXT entry_id for $1" + _err "Error getting TXT entry_id for $1." return 1 fi _authpost "entry=$entry_id" "$url/delentry/" - response="$(echo "$_response" | _normalizeJson)" - _debug2 response "$response" - - if ! _contains "$response" '"ok": true'; then - _err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post" + if ! _contains "$_response" '"ok": true'; then + _err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post." return 1 fi - _info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting" + _info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting." return 0 } #################### Private functions below ################################## - -# usage: _1984hosting_login username password -# returns 0 success _1984hosting_login() { if ! _check_credentials; then return 1; fi if _check_cookies; then - _debug "Already logged in" + _debug "Already logged in." return 0 fi - _debug "Login to 1984Hosting as user $One984HOSTING_Username" + _debug "Login to 1984Hosting as user $One984HOSTING_Username." username=$(printf '%s' "$One984HOSTING_Username" | _url_encode) password=$(printf '%s' "$One984HOSTING_Password" | _url_encode) url="https://1984.hosting/accounts/checkuserauth/" + _get "https://1984.hosting/accounts/login/" | grep "csrfmiddlewaretoken" + csrftoken="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')" + sessionid="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')" + + if [ -z "$csrftoken" ] || [ -z "$sessionid" ]; then + _err "One or more cookies are empty: '$csrftoken', '$sessionid'." + return 1 + fi + + export _H1="Cookie: $csrftoken; $sessionid" + export _H2="Referer: https://1984.hosting/accounts/login/" + csrf_header=$(echo "$csrftoken" | sed 's/csrftoken=//' | _head_n 1) + export _H3="X-CSRFToken: $csrf_header" + response="$(_post "username=$username&password=$password&otpkey=" $url)" response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" @@ -149,6 +153,8 @@ _1984hosting_login() { One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')" export One984HOSTING_SESSIONID_COOKIE export One984HOSTING_CSRFTOKEN_COOKIE + _saveaccountconf_mutable One984HOSTING_Username "$One984HOSTING_Username" + _saveaccountconf_mutable One984HOSTING_Password "$One984HOSTING_Password" _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE" return 0 @@ -157,9 +163,13 @@ _1984hosting_login() { } _check_credentials() { + One984HOSTING_Username="${One984HOSTING_Username:-$(_readaccountconf_mutable One984HOSTING_Username)}" + One984HOSTING_Password="${One984HOSTING_Password:-$(_readaccountconf_mutable One984HOSTING_Password)}" if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then One984HOSTING_Username="" One984HOSTING_Password="" + _clearaccountconf_mutable One984HOSTING_Username + _clearaccountconf_mutable One984HOSTING_Password _err "You haven't specified 1984Hosting username or password yet." _err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again." return 1 @@ -171,42 +181,43 @@ _check_cookies() { One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}" One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}" if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then - _debug "No cached cookie(s) found" + _debug "No cached cookie(s) found." return 1 fi _authget "https://1984.hosting/accounts/loginstatus/" - if _contains "$response" '"ok": true'; then - _debug "Cached cookies still valid" + if _contains "$_response" '"ok": true'; then + _debug "Cached cookies still valid." return 0 fi - _debug "Cached cookies no longer valid" + + _debug "Cached cookies no longer valid. Clearing cookies." One984HOSTING_SESSIONID_COOKIE="" One984HOSTING_CSRFTOKEN_COOKIE="" - _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" - _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE" + _clearaccountconf_mutable One984HOSTING_SESSIONID_COOKIE + _clearaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE return 1 } -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com +# _acme-challenge.www.domain.com +# Returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com _get_root() { domain="$1" i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + # not valid if [ -z "$h" ]; then - #not valid return 1 fi _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." if _contains "$_response" "serial" && ! _contains "$_response" "null"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi @@ -216,46 +227,47 @@ _get_root() { return 1 } -#usage: _get_zone_id url domain.com -#returns zone id for domain.com +# Usage: _get_zone_id url domain.com +# Returns zone id for domain.com _get_zone_id() { url=$1 domain=$2 _htmlget "$url" "$domain" - _debug2 _response "$_response" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)" _debug2 _zone_id "$_zone_id" if [ -z "$_zone_id" ]; then - _err "Error getting _zone_id for $2" + _err "Error getting _zone_id for $2." return 1 fi return 0 } -# add extra headers to request +# Add extra headers to request _authget() { - export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | _normalizeJson) _debug2 _response "$_response" } -# truncate huge HTML response -# echo: Argument list too long +# Truncate huge HTML response +# Echo: Argument list too long _htmlget() { - export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2") if _contains "$_response" "@$2"; then _response=$(echo "$_response" | grep -v "[@]" | _head_n 1) fi + _debug2 _response "$_response" } -# add extra headers to request +# Add extra headers to request _authpost() { url="https://1984.hosting/domains" _get_zone_id "$url" "$_domain" csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")" - export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE" + export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" export _H2="Referer: https://1984.hosting/domains/$_zone_id" export _H3="X-CSRFToken: $csrf_header" - _response=$(_post "$1" "$2") + _response="$(_post "$1" "$2" | _normalizeJson)" + _debug2 _response "$_response" } From db3f131dfc92022fda39386b6b2f2ac33a29e010 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Tue, 4 Jul 2023 15:47:19 +0200 Subject: [PATCH 157/687] Re-add deprecated SYNO_TOTP_SECRET part for legacy compatibility As requested in acmesh-official/acme.sh/pull/4646 by Neil Pang --- deploy/synology_dsm.sh | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index f709e0fb..406c6ac0 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -5,7 +5,7 @@ ################################################################################ # Authors: Brian Hartvigsen (creator), https://github.com/tresni # Martin Arndt (contributor), https://troublezone.net/ -# Updated: 2023-05-28 +# Updated: 2023-07-03 # Issues: https://github.com/acmesh-official/acme.sh/issues/2727 ################################################################################ # Usage: @@ -41,6 +41,8 @@ synology_dsm_deploy() { _getdeployconf SYNO_Username _getdeployconf SYNO_Password _getdeployconf SYNO_Create + _getdeployconf SYNO_DID + _getdeployconf SYNO_TOTP_SECRET _getdeployconf SYNO_Device_Name _getdeployconf SYNO_Device_ID if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then @@ -74,7 +76,7 @@ synology_dsm_deploy() { _debug2 SYNO_Hostname "$SYNO_Hostname" _debug2 SYNO_Port "$SYNO_Port" - # Get the certificate description, but don't save it until we verfiy it's real + # Get the certificate description, but don't save it until we verify it's real _getdeployconf SYNO_Certificate _debug SYNO_Certificate "${SYNO_Certificate:-}" @@ -97,9 +99,31 @@ synology_dsm_deploy() { _info "Logging into $SYNO_Hostname:$SYNO_Port" encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" + + # START - DEPRECATED, only kept for legacy compatibility reasons + if [ -n "$SYNO_TOTP_SECRET" ]; then + _info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" + _info " See synology_dsm.sh script or ACME.sh Wiki page for details:" + _info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide" + DEPRECATED_otp_code="" + if _exists oathtool; then + DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" + else + _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" + return 1 + fi + if [ -n "$SYNO_DID" ]; then + _H1="Cookie: did=$SYNO_DID" + export _H1 + _debug3 H1 "${_H1}" + fi + + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + _debug3 response "$response" + # END - DEPRECATED, only kept for legacy compatibility reasons # Get device ID if still empty first, otherwise log in right away - if [ -z "${SYNO_Device_ID:-}" ]; then + elif [ -z "${SYNO_Device_ID:-}" ]; then printf "Enter OTP code for user '%s': " "$SYNO_Username" read -r otp_code if [ -z "${SYNO_Device_Name:-}" ]; then @@ -121,7 +145,7 @@ synology_dsm_deploy() { token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug "Session ID" "$sid" _debug SynoToken "$token" - if [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then + if [ -z "$SYNO_DID" && -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then _err "Unable to authenticate to $_base_url - check your username & password." _err "If two-factor authentication is enabled for the user, set SYNO_Device_ID." return 1 @@ -150,7 +174,7 @@ synology_dsm_deploy() { return 1 fi - # we've verified this certificate description is a thing, so save it + # We've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64" _info "Generate form POST request" @@ -162,10 +186,10 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then - _debug2 default "this is the default certificate" + _debug2 default "This is the default certificate" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true" else - _debug2 default "this is NOT the default certificate" + _debug2 default "This is NOT the default certificate" fi content="$content${nl}--$delim--${nl}" content="$(printf "%b_" "$content")" @@ -193,7 +217,7 @@ synology_dsm_deploy() { #################### Private functions below ################################## _logout() { - # Logout to not occupy a permanent session, e. g. in DSM's "Connected Users" widget + # Logout to not occupy a permanent session, e.g. in DSM's "Connected Users" widget response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=logout") _debug3 response "$response" } From 0c9e4f67a89bfbc6ee14802139324c3b80c3ac03 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Tue, 4 Jul 2023 15:55:44 +0200 Subject: [PATCH 158/687] Update synology_dsm.sh Split "[ && ]" into "[ ] && [ ]" to make ShellCheck happy --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 406c6ac0..04d59e55 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -145,7 +145,7 @@ synology_dsm_deploy() { token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug "Session ID" "$sid" _debug SynoToken "$token" - if [ -z "$SYNO_DID" && -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then + if [ -z "$SYNO_DID" ] && [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then _err "Unable to authenticate to $_base_url - check your username & password." _err "If two-factor authentication is enabled for the user, set SYNO_Device_ID." return 1 From 0d7b831661dc01ba28d8b461c930049cea3e6ea4 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Tue, 4 Jul 2023 16:58:14 +0200 Subject: [PATCH 159/687] Fix variable initialization --- deploy/synology_dsm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 04d59e55..7398b350 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -99,7 +99,8 @@ synology_dsm_deploy() { _info "Logging into $SYNO_Hostname:$SYNO_Port" encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" - + + otp_code="" # START - DEPRECATED, only kept for legacy compatibility reasons if [ -n "$SYNO_TOTP_SECRET" ]; then _info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" @@ -119,7 +120,7 @@ synology_dsm_deploy() { _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") _debug3 response "$response" # END - DEPRECATED, only kept for legacy compatibility reasons # Get device ID if still empty first, otherwise log in right away From e0d96bcb3928fda0c8e40ffa189578250822323a Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Tue, 4 Jul 2023 21:54:49 -0400 Subject: [PATCH 160/687] Add initial AWS SES support Copied most of the v4 api stuff from DNS_AWS hook (Thanks!) New tokens added: AWS_SES_ACCESS_KEY_ID AWS_SES_SECRET_ACCESS_KEY AWS_SES_REGION AWS_SES_TO AWS_SES_FROM AWS_SES_FROM_NAME (Optional) --- notify/aws_ses.sh | 226 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 notify/aws_ses.sh diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh new file mode 100644 index 00000000..0741ca81 --- /dev/null +++ b/notify/aws_ses.sh @@ -0,0 +1,226 @@ +#!/usr/bin/env sh + +# +#AWS_SES_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +# +#AWS_SES_SECRET_ACCESS_KEY="xxxxxxx" +# +#AWS_SES_REGION="us-east-1" +# +#AWS_SES_TO="xxxx@xxx.com" +# +#AWS_SES_FROM="xxxx@cccc.com" +# +#AWS_SES_FROM_NAME="Something something" +#This is the Amazon SES api wrapper for acme.sh +AWS_WIKI="https://docs.aws.amazon.com/ses/latest/dg/send-email-api.html" + +aws_ses_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + AWS_SES_ACCESS_KEY_ID="${AWS_SES_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_SES_ACCESS_KEY_ID)}" + AWS_SES_SECRET_ACCESS_KEY="${AWS_SES_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SES_SECRET_ACCESS_KEY)}" + AWS_SES_REGION="${AWS_SES_REGION:-$(_readaccountconf_mutable AWS_SES_REGION)}" + + + if [ -z "$AWS_SES_ACCESS_KEY_ID" ] || [ -z "$AWS_SES_SECRET_ACCESS_KEY" ]; then + _use_container_role || _use_instance_role + fi + + if [ -z "$AWS_SES_ACCESS_KEY_ID" ] || [ -z "$AWS_SES_SECRET_ACCESS_KEY" ]; then + AWS_SES_ACCESS_KEY_ID="" + AWS_SES_SECRET_ACCESS_KEY="" + _err "You haven't specified the aws SES api key id and and api key secret yet." + _err "Please create your key and try again. see $(__green $AWS_WIKI)" + return 1 + fi + + if [ -z "$AWS_SES_REGION" ]; then + AWS_SES_REGION="" + _err "You haven't specified the aws SES api region yet." + _err "Please specify your region and try again. see https://docs.aws.amazon.com/general/latest/gr/ses.html" + return 1 + fi + + #save for future use, unless using a role which will be fetched as needed + if [ -z "$_using_role" ]; then + _saveaccountconf_mutable AWS_SES_ACCESS_KEY_ID "$AWS_SES_ACCESS_KEY_ID" + _saveaccountconf_mutable AWS_SES_SECRET_ACCESS_KEY "$AWS_SES_SECRET_ACCESS_KEY" + fi + + AWS_SES_TO="${AWS_SES_TO:-$(_readaccountconf_mutable AWS_SES_TO)}" + if [ -z "$AWS_SES_TO" ]; then + AWS_SES_TO="" + _err "You didn't specify an email to AWS_SES_TO receive messages." + return 1 + fi + _saveaccountconf_mutable AWS_SES_TO "$AWS_SES_TO" + + AWS_SES_FROM="${AWS_SES_FROM:-$(_readaccountconf_mutable AWS_SES_FROM)}" + if [ -z "$AWS_SES_FROM" ]; then + AWS_SES_FROM="" + _err "You didn't specify an email to AWS_SES_FROM receive messages." + return 1 + fi + _saveaccountconf_mutable AWS_SES_FROM "$AWS_SES_FROM" + + AWS_SES_FROM_NAME="${AWS_SES_FROM_NAME:-$(_readaccountconf_mutable AWS_SES_FROM_NAME)}" + _saveaccountconf_mutable AWS_SES_FROM_NAME "$AWS_SES_FROM_NAME" + + AWS_SES_SENDFROM="$AWS_SES_FROM_NAME <$AWS_SES_FROM>" + + AWS_SES_ACTION="Action=SendEmail" + AWS_SES_SOURCE="Source=$AWS_SES_SENDFROM" + AWS_SES_TO="Destination.ToAddresses.member.1=$AWS_SES_TO" + AWS_SES_SUBJECT="Message.Subject.Data=$_subject" + AWS_SES_MESSAGE="Message.Body.Text.Data=$_content" + + _data="${AWS_SES_ACTION}&${AWS_SES_SOURCE}&${AWS_SES_TO}&${AWS_SES_SUBJECT}&${AWS_SES_MESSAGE}" + + response="$(aws_rest POST "" "" "$_data")" +} + +_use_metadata() { + _aws_creds="$( + _get "$1" "" 1 | + _normalizeJson | + tr '{,}' '\n' | + while read -r _line; do + _key="$(echo "${_line%%:*}" | tr -d '"')" + _value="${_line#*:}" + _debug3 "_key" "$_key" + _secure_debug3 "_value" "$_value" + case "$_key" in + AccessKeyId) echo "AWS_SES_ACCESS_KEY_ID=$_value" ;; + SecretAccessKey) echo "AWS_SES_SECRET_ACCESS_KEY=$_value" ;; + Token) echo "AWS_SESSION_TOKEN=$_value" ;; + esac + done | + paste -sd' ' - + )" + _secure_debug "_aws_creds" "$_aws_creds" + + if [ -z "$_aws_creds" ]; then + return 1 + fi + + eval "$_aws_creds" + _using_role=true +} + +#method uri qstr data +aws_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + CanonicalURI="/$ep" + _debug2 CanonicalURI "$CanonicalURI" + + CanonicalQueryString="$qsr" + _debug2 CanonicalQueryString "$CanonicalQueryString" + + RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")" + _debug2 RequestDate "$RequestDate" + + #RequestDate="20161120T141056Z" ############## + + export _H1="x-amz-date: $RequestDate" + + aws_host="email.$AWS_SES_REGION.amazonaws.com" + CanonicalHeaders="host:$aws_host\nx-amz-date:$RequestDate\n" + SignedHeaders="host;x-amz-date" + if [ -n "$AWS_SESSION_TOKEN" ]; then + export _H3="x-amz-security-token: $AWS_SESSION_TOKEN" + CanonicalHeaders="${CanonicalHeaders}x-amz-security-token:$AWS_SESSION_TOKEN\n" + SignedHeaders="${SignedHeaders};x-amz-security-token" + fi + _debug2 CanonicalHeaders "$CanonicalHeaders" + _debug2 SignedHeaders "$SignedHeaders" + + RequestPayload="$data" + _debug2 RequestPayload "$RequestPayload" + + Hash="sha256" + + CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$(printf "%s" "$RequestPayload" | _digest "$Hash" hex)" + _debug2 CanonicalRequest "$CanonicalRequest" + + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" + _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" + + Algorithm="AWS4-HMAC-SHA256" + _debug2 Algorithm "$Algorithm" + + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)" + _debug2 RequestDateOnly "$RequestDateOnly" + + Region="$AWS_SES_REGION" + Service="ses" + + CredentialScope="$RequestDateOnly/$Region/$Service/aws4_request" + _debug2 CredentialScope "$CredentialScope" + + StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest" + + _debug2 StringToSign "$StringToSign" + + kSecret="AWS4$AWS_SES_SECRET_ACCESS_KEY" + + #kSecret="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" ############################ + + _secure_debug2 kSecret "$kSecret" + + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" + _secure_debug2 kSecretH "$kSecretH" + + kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" + _debug2 kDateH "$kDateH" + + kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)" + _debug2 kRegionH "$kRegionH" + + kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)" + _debug2 kServiceH "$kServiceH" + + kSigningH="$(printf "%s" "aws4_request" | _hmac "$Hash" "$kServiceH" hex)" + _debug2 kSigningH "$kSigningH" + + signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" + _debug2 signature "$signature" + + Authorization="$Algorithm Credential=$AWS_SES_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + _debug2 Authorization "$Authorization" + + _H2="Authorization: $Authorization" + _debug _H2 "$_H2" + + url="https://$aws_host/$ep" + if [ "$qsr" ]; then + url="https://$aws_host/$ep?$qsr" + fi + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + response="$(_post "$data" "$url")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" = "0" ]; then + if _contains "$response" " Date: Tue, 4 Jul 2023 22:14:17 -0400 Subject: [PATCH 161/687] Add newline at end of file to satisfy shfmt's "No newline at end of file" error --- notify/aws_ses.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 0741ca81..3d4de630 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -223,4 +223,4 @@ aws_rest() { return 1 fi fi -} \ No newline at end of file +} From 8d136c6a25484687cc802b1425c48cbe6f63982d Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Tue, 4 Jul 2023 22:15:53 -0400 Subject: [PATCH 162/687] Add newline at end of file to satisfy shfmt's "extra line" error --- notify/aws_ses.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 3d4de630..1060763d 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -25,7 +25,6 @@ aws_ses_send() { AWS_SES_SECRET_ACCESS_KEY="${AWS_SES_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SES_SECRET_ACCESS_KEY)}" AWS_SES_REGION="${AWS_SES_REGION:-$(_readaccountconf_mutable AWS_SES_REGION)}" - if [ -z "$AWS_SES_ACCESS_KEY_ID" ] || [ -z "$AWS_SES_SECRET_ACCESS_KEY" ]; then _use_container_role || _use_instance_role fi From a6b5f0c9d41a514929bf503bd830244785f9ce95 Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Tue, 4 Jul 2023 22:31:30 -0400 Subject: [PATCH 163/687] Fix variable naming to make the access key and secret key consistent with Route53. --- notify/aws_ses.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 1060763d..571fd392 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -1,9 +1,9 @@ #!/usr/bin/env sh # -#AWS_SES_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" # -#AWS_SES_SECRET_ACCESS_KEY="xxxxxxx" +#AWS_SECRET_ACCESS_KEY="xxxxxxx" # #AWS_SES_REGION="us-east-1" # @@ -21,17 +21,17 @@ aws_ses_send() { _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" - AWS_SES_ACCESS_KEY_ID="${AWS_SES_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_SES_ACCESS_KEY_ID)}" - AWS_SES_SECRET_ACCESS_KEY="${AWS_SES_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SES_SECRET_ACCESS_KEY)}" + AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}" + AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}" AWS_SES_REGION="${AWS_SES_REGION:-$(_readaccountconf_mutable AWS_SES_REGION)}" - if [ -z "$AWS_SES_ACCESS_KEY_ID" ] || [ -z "$AWS_SES_SECRET_ACCESS_KEY" ]; then + if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then _use_container_role || _use_instance_role fi - if [ -z "$AWS_SES_ACCESS_KEY_ID" ] || [ -z "$AWS_SES_SECRET_ACCESS_KEY" ]; then - AWS_SES_ACCESS_KEY_ID="" - AWS_SES_SECRET_ACCESS_KEY="" + if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then + AWS_ACCESS_KEY_ID="" + AWS_SECRET_ACCESS_KEY="" _err "You haven't specified the aws SES api key id and and api key secret yet." _err "Please create your key and try again. see $(__green $AWS_WIKI)" return 1 @@ -46,8 +46,8 @@ aws_ses_send() { #save for future use, unless using a role which will be fetched as needed if [ -z "$_using_role" ]; then - _saveaccountconf_mutable AWS_SES_ACCESS_KEY_ID "$AWS_SES_ACCESS_KEY_ID" - _saveaccountconf_mutable AWS_SES_SECRET_ACCESS_KEY "$AWS_SES_SECRET_ACCESS_KEY" + _saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID" + _saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY" fi AWS_SES_TO="${AWS_SES_TO:-$(_readaccountconf_mutable AWS_SES_TO)}" @@ -93,8 +93,8 @@ _use_metadata() { _debug3 "_key" "$_key" _secure_debug3 "_value" "$_value" case "$_key" in - AccessKeyId) echo "AWS_SES_ACCESS_KEY_ID=$_value" ;; - SecretAccessKey) echo "AWS_SES_SECRET_ACCESS_KEY=$_value" ;; + AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; + SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; Token) echo "AWS_SESSION_TOKEN=$_value" ;; esac done | @@ -173,7 +173,7 @@ aws_rest() { _debug2 StringToSign "$StringToSign" - kSecret="AWS4$AWS_SES_SECRET_ACCESS_KEY" + kSecret="AWS4$AWS_SECRET_ACCESS_KEY" #kSecret="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" ############################ @@ -197,7 +197,7 @@ aws_rest() { signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" _debug2 signature "$signature" - Authorization="$Algorithm Credential=$AWS_SES_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + Authorization="$Algorithm Credential=$AWS_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" _debug2 Authorization "$Authorization" _H2="Authorization: $Authorization" From db8a2d0c653ba19df024c8289942166d7e5bb025 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:05:06 +0200 Subject: [PATCH 164/687] Fix & improve DNS API for ArtFiles.de --- dnsapi/dns_artfiles.sh | 80 ++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index ad547e3f..6224c416 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -5,40 +5,34 @@ ################################################################################ # Author: Martin Arndt, https://troublezone.net/ # Released: 2022-02-27 -# Issues: https://github.com/Eagle3386/acme.sh/issues +# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX ################################################################################ # Usage: -# 1. export AF_API_USERNAME="api12345678" -# 2. export AF_API_PASSWORD="apiPassword" +# 1. export AF_API_USERNAME='api12345678' +# 2. export AF_API_PASSWORD='apiPassword' # 3. acme.sh --issue -d example.com --dns dns_artfiles ################################################################################ ########## API configuration ################################################### + AF_API_SUCCESS='status":"OK' AF_URL_DCP='https://dcp.c.artfiles.de/api/' AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain=' -AF_URL_DOMAINS=${AF_URL_BASE}'domain/get_domains.html' +AF_URL_DOMAINS=${AF_URL_DCP}'domain/get_domains.html' ########## Public functions #################################################### # Adds a new TXT record for given ACME challenge value & domain. # Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value" -dns_artfiles_add() { +dns_artfiles_add() +{ domain="$1" txtValue="$2" - _info 'Using ArtFiles.de DNS addition API' + _info 'Using ArtFiles.de DNS addition API…' _debug 'Domain' "$domain" _debug 'txtValue' "$txtValue" - AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" - AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" - if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then - _err 'Missing ArtFiles.de username and/or password.' - _err 'Please ensure both are set via export command & try again.' - - return 1 - fi - + _set_credentials _saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME" _saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD" @@ -62,13 +56,15 @@ dns_artfiles_add() { # Removes the existing TXT record for given ACME challenge value & domain. # Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value" -dns_artfiles_rm() { +dns_artfiles_rm() +{ domain="$1" txtValue="$2" - _info 'Using ArtFiles.de DNS removal API' + _info 'Using ArtFiles.de DNS removal API…' _debug 'Domain' "$domain" _debug 'txtValue' "$txtValue" + _set_credentials _set_headers _get_zone "$domain" if ! _dns 'GET'; then @@ -95,29 +91,28 @@ dns_artfiles_rm() { # Cleans awful TXT records response of ArtFiles's API & pretty prints it. # Usage: _clean_records -_clean_records() { +_clean_records() +{ + _info 'Cleaning TXT records…' # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' # from '\"' & turn '\n' into real LF characters. - # Yup, awful API to use - but that's all we got to get this working, so... ;) + # Yup, awful API to use - but that's all we got to get this working, so… ;) _debug2 'Raw ' "$response" - response="$( - printf -- '%s' "$response" - \ | sed 's/^\(.*TXT":"\)\([^,}]*\)\(.*\)$/\2/;s/.$//;s/\\"/"/g;s/\\n/\n/g' - )" + + response="$(printf -- '%s' "$response" | sed 's/^.*TXT":"\([^}]*\).*$/\1/;s/,".*$//;s/.$//;s/\\"/"/g;s/\\n/\n/g')" _debug2 'Clean' "$response" } # Executes an HTTP GET or POST request for getting or setting DNS records, # containing given payload upon POST. # Usage: _dns [GET | SET] [payload] -_dns() { +_dns() +{ + _info 'Executing HTTP request…' action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" - url="$( - printf -- '%s%s' "$AF_URL_DNS" "$domain" - \ | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/' - )" + url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')" if [ "$action" = 'SET' ]; then _debug2 'Payload' "$payload" @@ -139,10 +134,11 @@ _dns() { # Gets the root domain zone for given domain. # Usage: _get_zone _acme-challenge.www.example.com -_get_zone() { +_get_zone() +{ fqdn="$1" - domains="$(_get "$AF_URL_DOMAINS" "" 10)" - _info 'Getting domain zone...' + domains="$(_get "$AF_URL_DOMAINS" '' 10)" + _info 'Getting domain zone…' _debug2 'FQDN' "$fqdn" _debug2 'Domains' "$domains" @@ -166,10 +162,26 @@ _get_zone() { return 1 } +# Sets the credentials for accessing ArtFiles's API +# Usage: _set_credentials +_set_credentials() +{ + _info 'Setting credentials…' + AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" + AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" + if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then + _err 'Missing ArtFiles.de username and/or password.' + _err 'Please ensure both are set via export command & try again.' + + return 1 + fi +} + # Adds the HTTP Authorization & Content-Type headers to a follow-up request. # Usage: _set_headers -_set_headers() { - encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" - export _H1="Authorization: Basic $encoded" +_set_headers() +{ + _info 'Setting headers…' + export _H1="$(printf -- 'Authorization: Basic %s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" export _H2='Content-Type: application/json' } From 2961a90e7ffb37ad498a8d841d00dbb2a08d251c Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:14:49 +0200 Subject: [PATCH 165/687] Make ShellCheck & ShellFormat happy --- dnsapi/dns_artfiles.sh | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 6224c416..04cdf026 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -24,8 +24,7 @@ AF_URL_DOMAINS=${AF_URL_DCP}'domain/get_domains.html' # Adds a new TXT record for given ACME challenge value & domain. # Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value" -dns_artfiles_add() -{ +dns_artfiles_add() { domain="$1" txtValue="$2" _info 'Using ArtFiles.de DNS addition API…' @@ -56,8 +55,7 @@ dns_artfiles_add() # Removes the existing TXT record for given ACME challenge value & domain. # Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value" -dns_artfiles_rm() -{ +dns_artfiles_rm() { domain="$1" txtValue="$2" _info 'Using ArtFiles.de DNS removal API…' @@ -91,15 +89,13 @@ dns_artfiles_rm() # Cleans awful TXT records response of ArtFiles's API & pretty prints it. # Usage: _clean_records -_clean_records() -{ +_clean_records() { _info 'Cleaning TXT records…' # Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid # usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\' # from '\"' & turn '\n' into real LF characters. # Yup, awful API to use - but that's all we got to get this working, so… ;) _debug2 'Raw ' "$response" - response="$(printf -- '%s' "$response" | sed 's/^.*TXT":"\([^}]*\).*$/\1/;s/,".*$//;s/.$//;s/\\"/"/g;s/\\n/\n/g')" _debug2 'Clean' "$response" } @@ -107,8 +103,7 @@ _clean_records() # Executes an HTTP GET or POST request for getting or setting DNS records, # containing given payload upon POST. # Usage: _dns [GET | SET] [payload] -_dns() -{ +_dns() { _info 'Executing HTTP request…' action="$1" payload="$(printf -- '%s' "$2" | _url_encode)" @@ -134,8 +129,7 @@ _dns() # Gets the root domain zone for given domain. # Usage: _get_zone _acme-challenge.www.example.com -_get_zone() -{ +_get_zone() { fqdn="$1" domains="$(_get "$AF_URL_DOMAINS" '' 10)" _info 'Getting domain zone…' @@ -164,8 +158,7 @@ _get_zone() # Sets the credentials for accessing ArtFiles's API # Usage: _set_credentials -_set_credentials() -{ +_set_credentials() { _info 'Setting credentials…' AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}" AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}" @@ -179,9 +172,9 @@ _set_credentials() # Adds the HTTP Authorization & Content-Type headers to a follow-up request. # Usage: _set_headers -_set_headers() -{ +_set_headers() { _info 'Setting headers…' - export _H1="$(printf -- 'Authorization: Basic %s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" + encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)" + export _H1="Authorization: Basic $encoded" export _H2='Content-Type: application/json' } From 8b3acb719eb6eee82ef40edff94ed2372ecdc1df Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Wed, 5 Jul 2023 13:04:08 +0200 Subject: [PATCH 166/687] Fix TXT record removal --- dnsapi/dns_artfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index 04cdf026..faf8c2ae 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -76,7 +76,7 @@ dns_artfiles_rm() { fi _clean_records - response="$(printf -- '%s' "$response" | sed '$d')" + response="$(printf -- '%s' "$response" | sed '/_acme-challenge "'"$txtValue"'"/d')" _dns 'SET' "$response" if ! _contains "$response" "$AF_API_SUCCESS"; then _err 'Removing ACME challenge value failed.' From 299a157409c7cd07228cbaf31ccfc0879dba8f44 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 11:17:19 +0800 Subject: [PATCH 167/687] fix https://github.com/acmesh-official/acme.sh/issues/4680 zerossl returns retry-after header within "200 OK" code. so we don't check the "503" code anymore. --- acme.sh | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/acme.sh b/acme.sh index 0cc52131..85082d5c 100755 --- a/acme.sh +++ b/acme.sh @@ -2222,40 +2222,40 @@ _send_signed_request() { _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)" - if ! _startswith "$code" "2"; then - _body="$response" - if [ "$needbase64" ]; then - _body="$(echo "$_body" | _dbase64 multiline)" - _debug3 _body "$_body" - fi - - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') - if [ "$code" = '503' ]; then - _sleep_overload_retry_sec=$_retryafter - if [ -z "$_sleep_overload_retry_sec" ]; then - _sleep_overload_retry_sec=5 - fi - if [ $_sleep_overload_retry_sec -le 600 ]; then - _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." - _sleep $_sleep_overload_retry_sec - continue - else - _info "The retryafter=$_retryafter is too large > 600, not retry anymore." - fi - fi - if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then - _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec - continue + _body="$response" + if [ "$needbase64" ]; then + _body="$(echo "$_body" | _dbase64 multiline)" + _debug3 _body "$_body" + fi + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + + if [ "$code" = '503' ] || [ "$_retryafter" ]; then + _sleep_overload_retry_sec=$_retryafter + if [ -z "$_sleep_overload_retry_sec" ]; then + _sleep_overload_retry_sec=5 fi - if _contains "$_body" "The Replay Nonce is not recognized"; then - _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec + if [ $_sleep_overload_retry_sec -le 600 ]; then + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _sleep $_sleep_overload_retry_sec continue + else + _info "The retryafter=$_retryafter is too large > 600, not retry anymore." + return 1 fi fi + if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then + _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi + if _contains "$_body" "The Replay Nonce is not recognized"; then + _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi + return 0 done _info "Giving up sending to CA server after $MAX_REQUEST_RETRY_TIMES retries." From 09041fb81d3e6f8e931c97a9141f49d5fc3009dc Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 11:19:09 +0800 Subject: [PATCH 168/687] fix format --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 85082d5c..f680e0fb 100755 --- a/acme.sh +++ b/acme.sh @@ -2224,8 +2224,8 @@ _send_signed_request() { _body="$response" if [ "$needbase64" ]; then - _body="$(echo "$_body" | _dbase64 multiline)" - _debug3 _body "$_body" + _body="$(echo "$_body" | _dbase64 multiline)" + _debug3 _body "$_body" fi _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') From 0472f5da6a01229967647cc31f2c113141e49ed3 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 11:43:44 +0800 Subject: [PATCH 169/687] Revert "fix format" This reverts commit 09041fb81d3e6f8e931c97a9141f49d5fc3009dc. Revert "fix https://github.com/acmesh-official/acme.sh/issues/4680" This reverts commit 299a157409c7cd07228cbaf31ccfc0879dba8f44. --- acme.sh | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/acme.sh b/acme.sh index f680e0fb..0cc52131 100755 --- a/acme.sh +++ b/acme.sh @@ -2222,40 +2222,40 @@ _send_signed_request() { _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)" - _body="$response" - if [ "$needbase64" ]; then - _body="$(echo "$_body" | _dbase64 multiline)" - _debug3 _body "$_body" - fi - _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') - - if [ "$code" = '503' ] || [ "$_retryafter" ]; then - _sleep_overload_retry_sec=$_retryafter - if [ -z "$_sleep_overload_retry_sec" ]; then - _sleep_overload_retry_sec=5 + if ! _startswith "$code" "2"; then + _body="$response" + if [ "$needbase64" ]; then + _body="$(echo "$_body" | _dbase64 multiline)" + _debug3 _body "$_body" + fi + + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + if [ "$code" = '503' ]; then + _sleep_overload_retry_sec=$_retryafter + if [ -z "$_sleep_overload_retry_sec" ]; then + _sleep_overload_retry_sec=5 + fi + if [ $_sleep_overload_retry_sec -le 600 ]; then + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _sleep $_sleep_overload_retry_sec + continue + else + _info "The retryafter=$_retryafter is too large > 600, not retry anymore." + fi fi - if [ $_sleep_overload_retry_sec -le 600 ]; then - _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." - _sleep $_sleep_overload_retry_sec + if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then + _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec + continue + fi + if _contains "$_body" "The Replay Nonce is not recognized"; then + _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _CACHED_NONCE="" + _sleep $_sleep_retry_sec continue - else - _info "The retryafter=$_retryafter is too large > 600, not retry anymore." - return 1 fi fi - if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then - _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec - continue - fi - if _contains "$_body" "The Replay Nonce is not recognized"; then - _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." - _CACHED_NONCE="" - _sleep $_sleep_retry_sec - continue - fi - return 0 done _info "Giving up sending to CA server after $MAX_REQUEST_RETRY_TIMES retries." From 3761fb4377f2a50ba9c1a4f863671ba1afa8c5eb Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 12:37:01 +0800 Subject: [PATCH 170/687] fix bug https://github.com/acmesh-official/acme.sh/issues/4442 --- acme.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index 0cc52131..37bef388 100755 --- a/acme.sh +++ b/acme.sh @@ -2116,6 +2116,7 @@ _send_signed_request() { if [ -z "$keyfile" ]; then keyfile="$ACCOUNT_KEY_PATH" fi + _debug "=======Begin Send Signed Request=======" _debug url "$url" _debug payload "$payload" @@ -4602,9 +4603,10 @@ issue() { _d="*.$_d" fi _debug2 _d "$_d" - _authorizations_map="$_d,$response + _authorizations_map="$_d,$response#$_authz_url $_authorizations_map" done + _debug2 _authorizations_map "$_authorizations_map" _index=0 @@ -4656,7 +4658,8 @@ $_authorizations_map" _on_issue_err "$_post_hook" return 1 fi - + _authz_url="$(echo "$_candidates" | sed "s/$_idn_d,//" | _egrep_o "#.*" | sed "s/^#//")" + _debug _authz_url "$_authz_url" if [ -z "$thumbprint" ]; then thumbprint="$(__calc_account_thumbprint)" fi @@ -4708,7 +4711,7 @@ $_authorizations_map" _debug keyauthorization "$keyauthorization" fi - dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot" + dvlist="$d$sep$keyauthorization$sep$uri$sep$vtype$sep$_currentRoot$sep$_authz_url" _debug dvlist "$dvlist" vlist="$vlist$dvlist$dvsep" @@ -4725,6 +4728,7 @@ $_authorizations_map" keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) vtype=$(echo "$ventry" | cut -d "$sep" -f 4) _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) + _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) _debug d "$d" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _debug "$d is already verified, skip $vtype." @@ -4850,7 +4854,7 @@ $_authorizations_map" uri=$(echo "$ventry" | cut -d "$sep" -f 3) vtype=$(echo "$ventry" | cut -d "$sep" -f 4) _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - + _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _info "$d is already verified, skip $vtype." continue @@ -4860,6 +4864,7 @@ $_authorizations_map" _debug "d" "$d" _debug "keyauthorization" "$keyauthorization" _debug "uri" "$uri" + _debug "_authz_url" "$_authz_url" removelevel="" token="$(printf "%s" "$keyauthorization" | cut -d '.' -f 1)" @@ -4967,6 +4972,7 @@ $_authorizations_map" MAX_RETRY_TIMES=30 fi + _debug "Lets check the status of the authz" while true; do waittimes=$(_math "$waittimes" + 1) if [ "$waittimes" -ge "$MAX_RETRY_TIMES" ]; then @@ -5029,7 +5035,7 @@ $_authorizations_map" _sleep 2 _debug "checking" - _send_signed_request "$uri" + _send_signed_request "$_authz_url" if [ "$?" != "0" ]; then _err "$d:Verify error:$response" From 8fd3a64e3581e01909d1e781ab4a4a697b3f0f37 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 12:51:56 +0800 Subject: [PATCH 171/687] fix https://github.com/acmesh-official/acme.sh/issues/4442 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 37bef388..65b0a5b9 100755 --- a/acme.sh +++ b/acme.sh @@ -5020,9 +5020,9 @@ $_authorizations_map" break fi - if [ "$status" = "pending" ]; then + if _contains "$status" "pending"; then _info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" - elif [ "$status" = "processing" ]; then + elif _contains "$status" "processing"; then _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" else _err "$d:Verify error:$response" From a7455d7edd0e81f34b8e9071286e201389728148 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 8 Jul 2023 14:11:51 +0800 Subject: [PATCH 172/687] fix https://github.com/acmesh-official/acme.sh/issues/4562#issuecomment-1598731384 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 65b0a5b9..7a9468fd 100755 --- a/acme.sh +++ b/acme.sh @@ -2278,7 +2278,7 @@ _setopt() { if [ ! -f "$__conf" ]; then touch "$__conf" fi - if [ -n "$(tail -c 1 <"$__conf")" ]; then + if [ -n "$(tail -c1 <"$__conf")" ]; then echo >>"$__conf" fi From ee50f254df99368e0afbefd522806615f0c46a85 Mon Sep 17 00:00:00 2001 From: Arnaud Launay <2205303+alaunay@users.noreply.github.com> Date: Sun, 9 Jul 2023 20:08:10 +0200 Subject: [PATCH 173/687] Add BookMyName API support --- dnsapi/dns_bookmyname.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 7acdea02..62548fd0 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -13,15 +13,15 @@ # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide -# BMN urls: -# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' -# https://BMN_USER:BMN_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' +# BookMyName urls: +# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' +# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' # Output: #good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX #good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX -# Be careful, BookMyName DNS servers can be slow to pick up changes; using dnssleep is thus advised. +# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised. # Usage: # export BOOKMYNAME_USERNAME="ABCDE-FREE" From d86414febbaeeefe1ef563ada1882051ccd6c758 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 11 Jul 2023 23:41:24 +0000 Subject: [PATCH 174/687] Excluded scopes for api key test --- deploy/panos.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 880e4cec..2bb9f08f 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -56,7 +56,9 @@ deployer() { if [ "$type" = 'keytest' ]; then _debug "**** Testing saved API Key ****" _H1="Content-Type: application/x-www-form-urlencoded" - content="type=commit&key=$_panos_key&action=partial&cmd=acmekeytest" + #Exclude all scopes for the empty commit + _exclude_scope="excludeexcludeexclude" + content="type=commit&key=$_panos_key&cmd=$_exclude_scopeacmekeytest" fi # Generate API Key From e69a19db5c555c8a23fb31e1be393d0f220341fa Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 11 Jul 2023 23:56:41 +0000 Subject: [PATCH 175/687] Incorporated partial commit to address issue #4198 --- deploy/panos.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 2bb9f08f..f18482fc 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -36,8 +36,9 @@ parse_response() { message="PAN-OS Key could not be set." fi else - status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g') - message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g') + status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g') + message=$(echo "$1" | tr -d '\n' | sed 's/.*\(\|\|\)\([^<]*\).*/\2/g') + _debug "Firewall message: $message" if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then _debug "**** API Key has EXPIRED or is INVALID ****" unset _panos_key @@ -58,7 +59,7 @@ deployer() { _H1="Content-Type: application/x-www-form-urlencoded" #Exclude all scopes for the empty commit _exclude_scope="excludeexcludeexclude" - content="type=commit&key=$_panos_key&cmd=$_exclude_scopeacmekeytest" + content="type=commit&action=partial&key=$_panos_key&cmd=$_exclude_scopeacmekeytest" fi # Generate API Key @@ -104,20 +105,21 @@ deployer() { if [ "$type" = 'commit' ]; then _debug "**** Committing changes ****" export _H1="Content-Type: application/x-www-form-urlencoded" - #Check for force commit + #Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution! if [ "$FORCE" ]; then - cmd=$(printf "%s" "<$_panos_user>" | _url_encode) + _debug "Force switch detected. Committing ALL changes to the firewall." + cmd=$(printf "%s" "$_panos_user" | _url_encode) else - cmd=$(printf "%s" "<$_panos_user>" | _url_encode) + _exclude_scope="excludeexclude" + cmd=$(printf "%s" "$_exclude_scope$_panos_user" | _url_encode) fi - content="type=commit&key=$_panos_key&cmd=$cmd" + content="type=commit&action=partial&key=$_panos_key&cmd=$cmd" fi response=$(_post "$content" "$panos_url" "" "POST") parse_response "$response" "$type" # Saving response to variables response_status=$status - #DEBUG _debug response_status "$response_status" if [ "$response_status" = "success" ]; then _debug "Successfully deployed $type" From b556908cab48cf71ad577f912693316eea1a7078 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Wed, 12 Jul 2023 00:03:21 +0000 Subject: [PATCH 176/687] Modified ECC file test --- deploy/panos.sh | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index f18482fc..e11a6eed 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -137,15 +137,10 @@ panos_deploy() { _ckey="$2" _cfullchain="$5" - # VALID ECC KEY CHECK - keysuffix=$(printf '%s' "$_ckey" | tail -c 8) - if [ "$keysuffix" = "_ecc.key" ] && [ ! -f "$_ckey" ]; then - _debug "The ECC key $_ckey doesn't exist. Attempting to strip '_ecc' from the key name" - _ckey=$(echo "$_ckey" | sed 's/\(.*\)_ecc.key$/\1.key/g') - if [ ! -f "$_ckey" ]; then - _err "Unable to find a valid key. Try issuing the certificate using RSA (non-ECC) encryption." - return 1 - fi + # VALID FILE CHECK + if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then + _err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying." + return 1 fi # PANOS_HOST From dd958872a87bc4e383ea38aaed03919d0b753783 Mon Sep 17 00:00:00 2001 From: Steven Zhu Date: Fri, 14 Jul 2023 12:47:44 -0400 Subject: [PATCH 177/687] Fix SES region variable The last version do not save the SES region into the config file, breaking the notification hook. --- notify/aws_ses.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 571fd392..30db45ad 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -43,6 +43,7 @@ aws_ses_send() { _err "Please specify your region and try again. see https://docs.aws.amazon.com/general/latest/gr/ses.html" return 1 fi + _saveaccountconf_mutable AWS_SES_REGION "$AWS_SES_REGION" #save for future use, unless using a role which will be fetched as needed if [ -z "$_using_role" ]; then From edd1b60c3d39269dc1c5ff15ea842f1a0d3624f2 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 18 Jul 2023 19:43:47 +0000 Subject: [PATCH 178/687] Removed ability to specify API key to facilitate future multiple host functionality. --- deploy/panos.sh | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index e11a6eed..27919a25 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -8,21 +8,13 @@ # Firewall admin with superuser and IP address is required. # # REQURED: -# export PANOS_HOST="" # required -# export PANOS_USER="" # required -# -# AND one of the two authenticiation methods: -# -# Method 1: Password (RECOMMENDED) +# export PANOS_HOST="" +# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role # export PANOS_PASS="" # -# Method 2: API KEY -# export PANOS_KEY="" -# -# -# The Password method will automatically generate a new API key if +# The script will automatically generate a new API key if # no key is found, or if a saved key has expired or is invalid. -# + # This function is to parse the XML response from the firewall parse_response() { @@ -53,13 +45,15 @@ deployer() { type=$1 # Types are keytest, keygen, cert, key, commit panos_url="https://$_panos_host/api/" - #Test API Key by performing an empty commit. + #Test API Key by performing a lookup if [ "$type" = 'keytest' ]; then _debug "**** Testing saved API Key ****" _H1="Content-Type: application/x-www-form-urlencoded" - #Exclude all scopes for the empty commit - _exclude_scope="excludeexcludeexclude" - content="type=commit&action=partial&key=$_panos_key&cmd=$_exclude_scopeacmekeytest" + # Get Version Info to test key + content="type=version&key=$_panos_key" + ## Exclude all scopes for the empty commit + #_exclude_scope="excludeexcludeexclude" + #content="type=commit&action=partial&key=$_panos_key&cmd=$_exclude_scopeacmekeytest" fi # Generate API Key @@ -170,22 +164,17 @@ panos_deploy() { _getdeployconf PANOS_PASS fi - # PANOS_KEY - if [ "$PANOS_KEY" ]; then - _debug "Detected ENV variable PANOS_KEY. Saving to file." - _savedeployconf PANOS_KEY "$PANOS_KEY" 1 - else - _debug "Attempting to load variable PANOS_KEY from file." - _getdeployconf PANOS_KEY - fi - #Store variables _panos_host=$PANOS_HOST - _panos_key=$PANOS_KEY _panos_user=$PANOS_USER _panos_pass=$PANOS_PASS - #Test API Key if found. If the key is invalid, the variable panos_key will be unset. + #Load saved keys + _getdeployconf PANOS_KEY + _panos_key=$PANOS_KEY + + + #Test API Key if found. If the key is invalid, the variable _panos_key will be unset. if [ "$_panos_host" ] && [ "$_panos_key" ]; then _debug "**** Testing API KEY ****" deployer keytest @@ -198,8 +187,8 @@ panos_deploy() { elif [ -z "$_panos_user" ]; then _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs." return 1 - elif [ -z "$_panos_key" ] && { [ -z "$_panos_user" ] || [ -z "$_panos_pass" ]; }; then - _err "No pass OR valid API key found. If this is your first time deploying please set PANOS_PASS and/or PANOS_KEY in ENV variables. You can delete them after you have succesfully deployed the certs." + elif [ -z "$_panos_pass" ]; then + _err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs." return 1 else # Generate a new API key if no valid API key is found From ae035deb92b1557832fa06e4ebecd0519df6c8b4 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 18 Jul 2023 20:10:31 +0000 Subject: [PATCH 179/687] Fixed shell check errors --- deploy/panos.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 27919a25..efc1a656 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -15,7 +15,6 @@ # The script will automatically generate a new API key if # no key is found, or if a saved key has expired or is invalid. - # This function is to parse the XML response from the firewall parse_response() { type=$2 @@ -130,6 +129,8 @@ panos_deploy() { _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename _ckey="$2" _cfullchain="$5" + _regen_keys=false #Flag to regenerate keys if PANOS_USER or PANOS_PASS changes. + # VALID FILE CHECK if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then @@ -164,15 +165,22 @@ panos_deploy() { _getdeployconf PANOS_PASS fi + # PANOS_KEY + _getdeployconf PANOS_KEY + if [ "$PANOS_KEY" ]; then + _debug "Detected saved key." + _panos_key=$PANOS_KEY + else + _debug "No key detected" + unset _panos_key + fi + + #Store variables _panos_host=$PANOS_HOST _panos_user=$PANOS_USER _panos_pass=$PANOS_PASS - #Load saved keys - _getdeployconf PANOS_KEY - _panos_key=$PANOS_KEY - #Test API Key if found. If the key is invalid, the variable _panos_key will be unset. if [ "$_panos_host" ] && [ "$_panos_key" ]; then From 02de281e40ecebd2e68a12d92066f44303b57348 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 18 Jul 2023 20:15:46 +0000 Subject: [PATCH 180/687] Removed unused variable --- deploy/panos.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index efc1a656..9e48e4b3 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -129,7 +129,6 @@ panos_deploy() { _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename _ckey="$2" _cfullchain="$5" - _regen_keys=false #Flag to regenerate keys if PANOS_USER or PANOS_PASS changes. # VALID FILE CHECK From 1984f44ffe1e192c4d0b66fd026df4aa29801684 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Tue, 18 Jul 2023 20:18:12 +0000 Subject: [PATCH 181/687] Shell formatting --- deploy/panos.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 9e48e4b3..89458e5f 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -130,7 +130,6 @@ panos_deploy() { _ckey="$2" _cfullchain="$5" - # VALID FILE CHECK if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then _err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying." @@ -174,13 +173,11 @@ panos_deploy() { unset _panos_key fi - #Store variables _panos_host=$PANOS_HOST _panos_user=$PANOS_USER _panos_pass=$PANOS_PASS - #Test API Key if found. If the key is invalid, the variable _panos_key will be unset. if [ "$_panos_host" ] && [ "$_panos_key" ]; then _debug "**** Testing API KEY ****" From c7f6f20c9d4ae05a5ce366d8f3f62cd3eb1b1710 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 20 Jul 2023 02:48:29 +0800 Subject: [PATCH 182/687] Add SYNO_USE_TEMP_ADMIN variable & Fix broken logic 1. Fix the broken logic in (Sorry for including fix commit in same PR, I'm feeling quite tired and would like to go to sleep right away...) 2. Provides new method to obtain credential info for authentication, it will create a temp admin user if SYNO_USE_TEMP_ADMIN is set, instead of requiring the user's own credentials which will be saved in disk. I do really don't like to have plaintext credentials be saved in disk, and I noticed that you've spent a lot of time fighting with 2FA related stuffs, so why not just get rid of the whole old way. :) --- deploy/synology_dsm.sh | 89 +++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7398b350..d7dd1890 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -9,8 +9,11 @@ # Issues: https://github.com/acmesh-official/acme.sh/issues/2727 ################################################################################ # Usage: -# 1. export SYNO_Username="adminUser" -# 2. export SYNO_Password="adminPassword" +# - Create temp admin user automatically: +# export SYNO_USE_TEMP_ADMIN=1 +# - Or provide your own admin user credential: +# 1. export SYNO_Username="adminUser" +# 2. export SYNO_Password="adminPassword" # Optional exports (shown values are the defaults): # - export SYNO_Certificate="" to replace a specific certificate via description # - export SYNO_Scheme="http" @@ -22,6 +25,7 @@ ################################################################################ # Dependencies: # - jq & curl +# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set) ################################################################################ # Return value: # 0 means success, otherwise error. @@ -38,6 +42,7 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get username & password, but don't save until we authenticated successfully + _getdeployconf SYNO_USE_TEMP_ADMIN _getdeployconf SYNO_Username _getdeployconf SYNO_Password _getdeployconf SYNO_Create @@ -45,12 +50,25 @@ synology_dsm_deploy() { _getdeployconf SYNO_TOTP_SECRET _getdeployconf SYNO_Device_Name _getdeployconf SYNO_Device_ID - if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then - _err "SYNO_Username & SYNO_Password must be set" - return 1 + + # Prepare temp admin user info if SYNO_USE_TEMP_ADMIN is set + if [ -n "${SYNO_USE_TEMP_ADMIN:-}" ]; then + if ! _exists synouser; then + if ! _exists synogroup; then + _err "Tools are missing for creating temp admin user, please set SYNO_Username & SYNO_Password instead." + return 1 + fi + fi + _debug "Setting temp admin user credential..." + SYNO_Username=sc-acmesh-tmp + SYNO_Password=`openssl rand -base64 16` + # Ignore 2FA-OTP settings which won't be needed. + SYNO_Device_Name= + SYNO_Device_ID= fi - if [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then - _err "SYNO_Device_Name set, but SYNO_Device_ID is empty" + + if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then + _err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password." return 1 fi _debug2 SYNO_Username "$SYNO_Username" @@ -69,6 +87,7 @@ synology_dsm_deploy() { [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Port}" ] || SYNO_Port="5000" + _savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" _savedeployconf SYNO_Scheme "$SYNO_Scheme" _savedeployconf SYNO_Hostname "$SYNO_Hostname" _savedeployconf SYNO_Port "$SYNO_Port" @@ -106,13 +125,11 @@ synology_dsm_deploy() { _info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" _info " See synology_dsm.sh script or ACME.sh Wiki page for details:" _info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide" - DEPRECATED_otp_code="" - if _exists oathtool; then - DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" - else + if ! _exists oathtool; then _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" return 1 fi + DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" if [ -n "$SYNO_DID" ]; then _H1="Cookie: did=$SYNO_DID" @@ -123,21 +140,30 @@ synology_dsm_deploy() { response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") _debug3 response "$response" # END - DEPRECATED, only kept for legacy compatibility reasons + # If SYNO_DeviceDevice_ID & SYNO_Device_Name both empty, just log in normally + elif [ -z "${SYNO_Device_ID:-}" ] && [ -z "${SYNO_Device_Name:-}" ]; then + if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then + _debug "Creating temp admin user in Synology DSM" + synouser --del "$SYNO_Username" >/dev/null 2>/dev/null + synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "" 0 >/dev/null + synogroup --memberadd administrators "$SYNO_Username" >/dev/null + fi + response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") + _debug3 response "$response" # Get device ID if still empty first, otherwise log in right away - elif [ -z "${SYNO_Device_ID:-}" ]; then + elif [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then printf "Enter OTP code for user '%s': " "$SYNO_Username" read -r otp_code - if [ -z "${SYNO_Device_Name:-}" ]; then - printf "Enter device name or leave empty for default (CertRenewal): " - read -r SYNO_Device_Name - [ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal" - fi - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") _debug3 response "$response" SYNO_Device_ID=$(echo "$response" | grep "device_id" | sed -n 's/.*"device_id" *: *"\([^"]*\).*/\1/p') _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" else + if [ -z "${SYNO_Device_Name:-}" ]; then + printf "Enter device name or leave empty for default (CertRenewal): " + read -r SYNO_Device_Name + [ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal" + fi response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") _debug3 response "$response" fi @@ -146,9 +172,12 @@ synology_dsm_deploy() { token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') _debug "Session ID" "$sid" _debug SynoToken "$token" - if [ -z "$SYNO_DID" ] && [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then + if [ -z "$sid" ] || [ -z "$token" ]; then _err "Unable to authenticate to $_base_url - check your username & password." - _err "If two-factor authentication is enabled for the user, set SYNO_Device_ID." + _err "If two-factor authentication is enabled for the user:" + _err "- set SYNO_Device_Name then input *correct* OTP-code manually" + _err "- get & set SYNO_Device_ID via your browser cookies" + _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" return 1 fi @@ -159,8 +188,10 @@ synology_dsm_deploy() { # Now that we know the username & password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" - _savedeployconf SYNO_Device_Name "$SYNO_Device_Name" - _savedeployconf SYNO_Device_ID "$SYNO_Device_ID" + if [ -z "${SYNO_USE_TEMP_ADMIN:-}" ]; then + _savedeployconf SYNO_Device_Name "$SYNO_Device_Name" + _savedeployconf SYNO_Device_ID "$SYNO_Device_ID" + fi _info "Getting certificates in Synology DSM" response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") @@ -172,6 +203,7 @@ synology_dsm_deploy() { if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then _err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set" + _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" return 1 fi @@ -206,10 +238,11 @@ synology_dsm_deploy() { else _info "Restarting HTTP services failed" fi - + _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" _logout return 0 else + _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" _err "Unable to update certificate, error code $response" _logout return 1 @@ -222,3 +255,13 @@ _logout() { response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=logout") _debug3 response "$response" } + +_remove_temp_admin() { + flag=$1 + username=$2 + + if [ -n "${flag}" ]; then + _debug "Removing temp admin user in Synology DSM" + synouser --del "$username" >/dev/null + fi +} From 9e958f4e32794db65fa7fd938df2bcc27f7faaff Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 20 Jul 2023 13:09:21 +0800 Subject: [PATCH 183/687] Fix shellcheck --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d7dd1890..22e485ce 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -61,7 +61,7 @@ synology_dsm_deploy() { fi _debug "Setting temp admin user credential..." SYNO_Username=sc-acmesh-tmp - SYNO_Password=`openssl rand -base64 16` + SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16) # Ignore 2FA-OTP settings which won't be needed. SYNO_Device_Name= SYNO_Device_ID= From cf86d57a9f61e9e2d759c8a44811c3ea6cb612c6 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 20 Jul 2023 13:34:57 +0800 Subject: [PATCH 184/687] Fix for shfmt check --- deploy/synology_dsm.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 22e485ce..b69916c7 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -66,7 +66,7 @@ synology_dsm_deploy() { SYNO_Device_Name= SYNO_Device_ID= fi - + if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then _err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password." return 1 @@ -104,8 +104,7 @@ synology_dsm_deploy() { _err "Do not use a backslash (\) in your certificate description" return 1 fi - - _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" _debug "Getting API version" @@ -259,7 +258,7 @@ _logout() { _remove_temp_admin() { flag=$1 username=$2 - + if [ -n "${flag}" ]; then _debug "Removing temp admin user in Synology DSM" synouser --del "$username" >/dev/null From ba468bb5e4156c6b914b8653abb2af9d4b2006b4 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 20 Jul 2023 13:38:36 +0800 Subject: [PATCH 185/687] Fix for shfmt check --- deploy/synology_dsm.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index b69916c7..8dc99a85 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -104,7 +104,8 @@ synology_dsm_deploy() { _err "Do not use a backslash (\) in your certificate description" return 1 fi - _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" + + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" _debug "Getting API version" From a9f631f404eaaeaa9a39ba14bb8236a4925db9e8 Mon Sep 17 00:00:00 2001 From: sg1888 Date: Fri, 21 Jul 2023 16:49:20 +0000 Subject: [PATCH 186/687] Added help verbiage for --ecc flag --- acme.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 7a9468fd..d356084c 100755 --- a/acme.sh +++ b/acme.sh @@ -1553,7 +1553,7 @@ createDomainKey() { createCSR() { _info "Creating csr" if [ -z "$1" ]; then - _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...]" + _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...] [--ecc]" return fi @@ -6936,7 +6936,8 @@ Parameters: --no-profile Only valid for '--install' command, which means: do not install aliases to user profile. --no-color Do not output color text. --force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails. - --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr' + --ecc Specifies use of the ECC cert. Only valid for '--install-cert', '--renew', '--remove ', '--revoke', + '--deploy', '--to-pkcs8', '--to-pkcs12' and '--create-csr'. --csr Specifies the input csr. --pre-hook Command to be run before obtaining any certificates. --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. From 2014ca9feb3758999338b31827acbe12c3ca2813 Mon Sep 17 00:00:00 2001 From: Malte Rabenseifner Date: Wed, 26 Jul 2023 15:36:11 +0200 Subject: [PATCH 187/687] Fix the API calls that get the list of domains that PLESK can manage --- dnsapi/dns_pleskxml.sh | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 799c374c..9cb0b1be 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -46,6 +46,10 @@ pleskxml_tplt_get_domains="< # Also used to test credentials and URI. # No params. +pleskxml_tplt_get_additional_domains="" +# Get a list of additional domains that PLESK can manage, so we can check root domain + host for acme.sh +# No params. + pleskxml_tplt_get_dns_records="%s" # Get all DNS records for a Plesk domain ID. # PARAM = Plesk domain id to query @@ -375,16 +379,44 @@ _pleskxml_get_root_domain() { return 1 fi - # Generate a crude list of domains known to this Plesk account. + # Generate a crude list of domains known to this Plesk account based on subscriptions. # We convert tags to so it'll flag on a hit with either or fields, # for non-Western character sets. # Output will be one line per known domain, containing 2 tages and a single tag # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + debug_output="$(printf "$output" | sed -n 's:.*\(.*\).*:\1:p')" + + _debug 'Domains managed by Plesk server are:' + _debug "$debug_output" + + _debug "Querying Plesk server for list of additional managed domains..." + + _call_api "$pleskxml_tplt_get_additional_domains" + if [ "$pleskxml_retcode" -ne 0 ]; then + return 1 + fi + + # Generate a crude list of additional domains known to this Plesk account based on sites. + # We convert tags to so it'll flag on a hit with either or fields, + # for non-Western character sets. + # Output will be one line per known domain, containing 2 tages and a single tag + # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. - _debug 'Domains managed by Plesk server are (ignore the hacked output):' - _debug "$output" + output_additional="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" + debug_additional="$(printf "$output_additional" | sed -n 's:.*\(.*\).*:\1:p')" + + _debug 'Additional domains managed by Plesk server are:' + _debug "$debug_additional" + + # Concate the two outputs together. + + output="$(printf "$output $NEWLINE $output_additional")" + debug_output="$(printf "$output" | sed -n 's:.*\(.*\).*:\1:p')" + + _debug 'Domains (including additional) managed by Plesk server are:' + _debug "$debug_output" # loop and test if domain, or any parent domain, is managed by Plesk # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain From 4d4b6edbc2e59c147b487306604de75e25657f1e Mon Sep 17 00:00:00 2001 From: samuel <53528911+samuel-jimenez@users.noreply.github.com> Date: Wed, 26 Jul 2023 10:29:38 -0500 Subject: [PATCH 188/687] Add DNSExit.com API support --- dnsapi/dns_dnsexit.sh | 185 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 dnsapi/dns_dnsexit.sh diff --git a/dnsapi/dns_dnsexit.sh b/dnsapi/dns_dnsexit.sh new file mode 100644 index 00000000..62d7d757 --- /dev/null +++ b/dnsapi/dns_dnsexit.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +#use dns-01 at DNSExit.com + +#Author: Samuel Jimenez +#Report Bugs here: https://github.com/acmesh-official/acme.sh + +#DNSEXIT_API_KEY=ABCDEFGHIJ0123456789abcdefghij +#DNSEXIT_AUTH_USER=login@email.address +#DNSEXIT_AUTH_PASS=aStrongPassword +DNSEXIT_API_URL="https://api.dnsexit.com/dns/" +DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp" + +######## Public functions ##################### +#Usage: dns_dnsexit_add _acme-challenge.*.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_dnsexit_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using DNSExit.com" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug 'Load account auth' + if ! get_account_info; then + return 1 + fi + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"add\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":0,\"overwrite\":false}}"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_dnsexit_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using DNSExit.com" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug 'Load account auth' + if ! get_account_info; then + return 1 + fi + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + _err "$response" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"delete\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\"}}"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + while true; do + _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$_domain" + if [ -z "$_domain" ]; then + return 1 + fi + + _debug login "$DNSEXIT_AUTH_USER" + _debug password "$DNSEXIT_AUTH_PASS" + _debug domain "$_domain" + + _dnsexit_http "login=$DNSEXIT_AUTH_USER&password=$DNSEXIT_AUTH_PASS&domain=$_domain" + + if _contains "$response" "0=$_domain"; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + return 0 + else + _debug "Go to next level of $_domain" + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_dnsexit_rest() { + m=POST + ep="" + data="$1" + _debug _dnsexit_rest "$ep" + _debug data "$data" + + api_key_trimmed=$(echo "$DNSEXIT_API_KEY" | tr -d '"') + + export _H1="apikey: $api_key_trimmed" + export _H2='Content-Type: application/json' + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$DNSEXIT_API_URL/$ep" "" "$m")" + else + response="$(_get "$DNSEXIT_API_URL/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} + +_dnsexit_http() { + m=GET + param="$1" + _debug param "$param" + _debug get "$DNSEXIT_HOSTS_URL?$param" + + response="$(_get "$DNSEXIT_HOSTS_URL?$param")" + + _debug response "$response" + + if [ "$?" != "0" ]; then + _err "Error $param" + return 1 + fi + + _debug2 response "$response" + return 0 +} + +get_account_info() { + + DNSEXIT_API_KEY="${DNSEXIT_API_KEY:-$(_readaccountconf_mutable DNSEXIT_API_KEY)}" + if test -z "$DNSEXIT_API_KEY"; then + DNSEXIT_API_KEY='' + _err 'DNSEXIT_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable DNSEXIT_API_KEY "$DNSEXIT_API_KEY" + + DNSEXIT_AUTH_USER="${DNSEXIT_AUTH_USER:-$(_readaccountconf_mutable DNSEXIT_AUTH_USER)}" + if test -z "$DNSEXIT_AUTH_USER"; then + DNSEXIT_AUTH_USER="" + _err 'DNSEXIT_AUTH_USER was not exported' + return 1 + fi + + _saveaccountconf_mutable DNSEXIT_AUTH_USER "$DNSEXIT_AUTH_USER" + + DNSEXIT_AUTH_PASS="${DNSEXIT_AUTH_PASS:-$(_readaccountconf_mutable DNSEXIT_AUTH_PASS)}" + if test -z "$DNSEXIT_AUTH_PASS"; then + DNSEXIT_AUTH_PASS="" + _err 'DNSEXIT_AUTH_PASS was not exported' + return 1 + fi + + _saveaccountconf_mutable DNSEXIT_AUTH_PASS "$DNSEXIT_AUTH_PASS" + + return 0 +} From c48c8d07de31bbb65a5621d37b9ff6b056e7a8a9 Mon Sep 17 00:00:00 2001 From: Harald Kapper <4014716+hknet@users.noreply.github.com> Date: Thu, 27 Jul 2023 21:49:23 +0200 Subject: [PATCH 189/687] Update dns_kappernet.sh dns update waiting time is reduced now (new backend at kapper.net) --- dnsapi/dns_kappernet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 83a7e5f8..0a8951cb 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -45,8 +45,8 @@ dns_kappernet_add() { if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then if _contains "$response" "{\"OK\":true"; then - _info "Waiting 120 seconds for DNS to spread the new record" - _sleep 120 + _info "Waiting 1 second for DNS to spread the new record" + _sleep 1 return 0 else _err "Error creating a TXT DNS Record: $fullhostname TXT $txtvalue" From a51025fe8f5c0bacfecb943d997806e55477ce3e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Jul 2023 15:32:50 +0800 Subject: [PATCH 190/687] fix https://github.com/acmesh-official/acme.sh/issues/3645 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7a9468fd..03c838ac 100755 --- a/acme.sh +++ b/acme.sh @@ -924,7 +924,9 @@ _sed_i() { } _egrep_o() { - if ! egrep -o "$1" 2>/dev/null; then + if _exists egrep; then + egrep -o "$1" 2>/dev/null; + else sed -n 's/.*\('"$1"'\).*/\1/p' fi } From 80006f47300bd0559729a2800ae014475f7499ce Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Sat, 29 Jul 2023 10:26:59 +0200 Subject: [PATCH 191/687] Added bug report url --- dnsapi/dns_artfiles.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index faf8c2ae..a762837e 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -5,7 +5,7 @@ ################################################################################ # Author: Martin Arndt, https://troublezone.net/ # Released: 2022-02-27 -# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXX +# Issues: https://github.com/acmesh-official/acme.sh/issues/4718 ################################################################################ # Usage: # 1. export AF_API_USERNAME='api12345678' From 7f39cdc85660ad3d1fb6b2f6b70cc094fd093e29 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Jul 2023 16:45:49 +0800 Subject: [PATCH 192/687] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 03c838ac..7605c396 100755 --- a/acme.sh +++ b/acme.sh @@ -925,7 +925,7 @@ _sed_i() { _egrep_o() { if _exists egrep; then - egrep -o "$1" 2>/dev/null; + egrep -o "$1" 2>/dev/null else sed -n 's/.*\('"$1"'\).*/\1/p' fi From 3b7be478aa7f5f257397e9cf8cccea3e1a2aa502 Mon Sep 17 00:00:00 2001 From: Malte Rabenseifner Date: Sat, 29 Jul 2023 11:27:33 +0200 Subject: [PATCH 193/687] Fix stuff from tests ShellCheck tests have brought up a couple of issues, that I was not aware of needed to be taken care. This should fix the tests. --- dnsapi/dns_pleskxml.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 9cb0b1be..81973e07 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -386,13 +386,13 @@ _pleskxml_get_root_domain() { # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" - debug_output="$(printf "$output" | sed -n 's:.*\(.*\).*:\1:p')" - + debug_output="$(printf "%s" "$output" | sed -n 's:.*\(.*\).*:\1:p')" + _debug 'Domains managed by Plesk server are:' - _debug "$debug_output" + _debug "$debug_output" _debug "Querying Plesk server for list of additional managed domains..." - + _call_api "$pleskxml_tplt_get_additional_domains" if [ "$pleskxml_retcode" -ne 0 ]; then return 1 @@ -405,18 +405,18 @@ _pleskxml_get_root_domain() { # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned. output_additional="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')" - debug_additional="$(printf "$output_additional" | sed -n 's:.*\(.*\).*:\1:p')" + debug_additional="$(printf "%s" "$output_additional" | sed -n 's:.*\(.*\).*:\1:p')" _debug 'Additional domains managed by Plesk server are:' _debug "$debug_additional" - + # Concate the two outputs together. - - output="$(printf "$output $NEWLINE $output_additional")" - debug_output="$(printf "$output" | sed -n 's:.*\(.*\).*:\1:p')" - + + output="$(printf "%s" "$output $NEWLINE $output_additional")" + debug_output="$(printf "%s" "$output" | sed -n 's:.*\(.*\).*:\1:p')" + _debug 'Domains (including additional) managed by Plesk server are:' - _debug "$debug_output" + _debug "$debug_output" # loop and test if domain, or any parent domain, is managed by Plesk # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain From a7f3d413ef81782a43cf568ab7a136ffb7e9e5e5 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Jul 2023 22:32:30 +0800 Subject: [PATCH 194/687] fix for solaris --- acme.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 7605c396..c79cadfc 100755 --- a/acme.sh +++ b/acme.sh @@ -2103,9 +2103,20 @@ _head_n() { } _tail_n() { - if ! tail -n "$1" 2>/dev/null; then + if _is_solaris; then #fix for solaris tail -"$1" + else + tail -n "$1" + fi +} + +_tail_c() { + if _is_solaris; then + #fix for solaris + tail -"$1"c + else + tail -c "$1" fi } @@ -2280,7 +2291,7 @@ _setopt() { if [ ! -f "$__conf" ]; then touch "$__conf" fi - if [ -n "$(tail -c1 <"$__conf")" ]; then + if [ -n "$(_tail_c 1 <"$__conf")" ]; then echo >>"$__conf" fi From 6db8ae451ab3263570bdb2eb3b33d10c91f289c5 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Jul 2023 23:17:20 +0800 Subject: [PATCH 195/687] fix for solaris --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index c79cadfc..3c9ba003 100755 --- a/acme.sh +++ b/acme.sh @@ -924,10 +924,10 @@ _sed_i() { } _egrep_o() { - if _exists egrep; then - egrep -o "$1" 2>/dev/null - else + if _is_solaris; then sed -n 's/.*\('"$1"'\).*/\1/p' + else + egrep -o "$1" fi } From 15ee036db17d13a8ec75275e0b7ef729a79dc9f2 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 29 Jul 2023 23:30:44 +0800 Subject: [PATCH 196/687] fix for solaris --- acme.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 3c9ba003..75efde4c 100755 --- a/acme.sh +++ b/acme.sh @@ -923,11 +923,17 @@ _sed_i() { fi } +if [ "$(echo abc | egrep -o b 2>/dev/null)" = "b" ]; then + __USE_EGREP=1 +else + __USE_EGREP="" +fi + _egrep_o() { - if _is_solaris; then - sed -n 's/.*\('"$1"'\).*/\1/p' - else + if [ "$__USE_EGREP" ]; then egrep -o "$1" + else + sed -n 's/.*\('"$1"'\).*/\1/p' fi } From b6f62ac446ab9ff78f4a90c4330dc314678545c9 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 30 Jul 2023 10:58:22 +0800 Subject: [PATCH 197/687] fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation see https://bugs.launchpad.net/ubuntu/+source/curl/+bug/2018342 --- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/OpenBSD.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 6daa9be4..5a0d81ba 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -62,7 +62,7 @@ jobs: nat: | "8080": "80" prepare: | - pkg install -y curl socat + pkg install -y curl socat libnghttp2 usesh: true run: | cd ../acmetest \ diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 7746645a..745a9408 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -66,7 +66,7 @@ jobs: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | "8080": "80" - prepare: pkg_add socat curl wget + prepare: pkg_add socat curl wget libnghttp2 usesh: true copyback: false run: | From d52b38777aaf19bc49ef6edd5d23546ddd3a4f03 Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Wed, 9 Aug 2023 19:52:37 +0200 Subject: [PATCH 198/687] Fix Auth API access for DSM 6 --- deploy/synology_dsm.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7398b350..ba35d784 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -91,8 +91,10 @@ synology_dsm_deploy() { _debug "Getting API version" response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") + api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([0-9]*\)".*/\1/p') api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') _debug3 response "$response" + _debug3 api_path "$api_path" _debug3 api_version "$api_version" # Login, get the session ID & SynoToken from JSON @@ -133,12 +135,12 @@ synology_dsm_deploy() { [ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal" fi - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") _debug3 response "$response" SYNO_Device_ID=$(echo "$response" | grep "device_id" | sed -n 's/.*"device_id" *: *"\([^"]*\).*/\1/p') _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" else - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") _debug3 response "$response" fi From b793dbf977dbf5d6b6829d185e0b2a0fa130941a Mon Sep 17 00:00:00 2001 From: Martin Arndt <5111490+Eagle3386@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:55:45 +0200 Subject: [PATCH 199/687] Fix device ID property name for DSM 6 --- deploy/synology_dsm.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index ba35d784..21c7ac9b 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -136,8 +136,11 @@ synology_dsm_deploy() { fi response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") - _debug3 response "$response" - SYNO_Device_ID=$(echo "$response" | grep "device_id" | sed -n 's/.*"device_id" *: *"\([^"]*\).*/\1/p') + _secure_debug3 response "$response" + + id_property='device_id' + [ "${api_version}" -gt '6' ] || id_property='did' + SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" else response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") From 8d00f489cd6072d562dce05e7a43a5bdb0877113 Mon Sep 17 00:00:00 2001 From: Vito <35035879+vitoyucepi@users.noreply.github.com> Date: Sun, 20 Aug 2023 20:05:45 +0300 Subject: [PATCH 200/687] Remove excessive full stop from help --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 07aef029..70f1daac 100755 --- a/acme.sh +++ b/acme.sh @@ -6925,7 +6925,7 @@ Parameters: These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: - --cert-file Path to copy the cert file to after issue/renew.. + --cert-file Path to copy the cert file to after issue/renew. --key-file Path to copy the key file to after issue/renew. --ca-file Path to copy the intermediate cert file to after issue/renew. --fullchain-file Path to copy the fullchain cert file to after issue/renew. From 13d31ecb7f195f623a9a4deff9c2eb3fc6aecaeb Mon Sep 17 00:00:00 2001 From: Nirjas Jakilim Date: Mon, 21 Aug 2023 12:28:50 +0600 Subject: [PATCH 201/687] fixed regex for nginx conf path Fixed the regex for nginx path configuration to fix grep: unrecognized option error --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 75efde4c..8c662486 100755 --- a/acme.sh +++ b/acme.sh @@ -3130,7 +3130,7 @@ _setNginx() { _err "nginx command is not found." return 1 fi - NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "--conf-path=[^ ]* " | tr -d " ")" + NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "\-\-conf-path=[^ ]* " | tr -d " ")" _debug NGINX_CONF "$NGINX_CONF" NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)" _debug NGINX_CONF "$NGINX_CONF" From 9143cd1485a4a0220897124fec78eb2ec45f81ec Mon Sep 17 00:00:00 2001 From: glocknerc <65351984+glocknerc@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:07:07 +0200 Subject: [PATCH 202/687] Change grep to be case-insensitive when looking for Set-Cookie header since INWX change casing to lowercase --- dnsapi/dns_inwx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index ba789da9..e483c0e8 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -194,7 +194,7 @@ _inwx_login() { response="$(_post "$xml_content" "$INWX_Api" "" "POST")" - INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") _H1=$INWX_Cookie export _H1 export INWX_Cookie From ef20a0128fc5ed0b4c58036f1419cfcc8a98d186 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:22:20 +0200 Subject: [PATCH 203/687] Add support for Lima-City --- dnsapi/dns_limacity.sh | 93 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 dnsapi/dns_limacity.sh diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh new file mode 100644 index 00000000..f6a134eb --- /dev/null +++ b/dnsapi/dns_limacity.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env sh + +# Created by Laraveluser +# +# Pass credentials before "acme.sh --issue --dns dns_limacity ..." +# -- +# export LIMACITY_APIKEY="" +# -- +# +# Pleas note: APIKEY must have following roles: dns.admin, domains.reader + +######## Public functions ##################### + +LIMACITY_APIKEY="${LIMACITY_APIKEY:-$(_readaccountconf_mutable LIMACITY_APIKEY)}" +AUTH=$(printf "%s" "api:$LIMACITY_APIKEY" | _base64 -w 0) +export _H1="Authorization: Basic $AUTH" +export _H2="Content-Type: application/json" +APIBASE=https://www.lima-city.de/usercp + +#Usage: dns_limacity_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_limacity_add() { + _debug LIMACITY_APIKEY "$LIMACITY_APIKEY" + if [ "$LIMACITY_APIKEY" = "" ]; then + _err "No Credentials given" + return 1 + fi + + # save the dns server and key to the account conf file. + _saveaccountconf_mutable LIMACITY_APIKEY "${LIMACITY_APIKEY}" + + fulldomain=$1 + txtvalue=$2 + if ! _lima_get_domain_id "$fulldomain"; then return 1; fi + + msg=$(_post "{\"nameserver_record\":{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\",\"ttl\":60}}" "${APIBASE}/domains/${LIMACITY_DOMAINID}/records.json" "" "POST") + _debug "$msg" + + if [ "$(echo "$msg" | _egrep_o "\"status\":\"ok\"")" = "" ]; then + _err "$msg" + return 1 + fi + + return 0 +} + +#Usage: dns_limacity_rm _acme-challenge.www.domain.com +dns_limacity_rm() { + + fulldomain=$1 + txtvalue=$2 + if ! _lima_get_domain_id "$fulldomain"; then return 1; fi + + for recordId in $(_get "${APIBASE}/domains/${LIMACITY_DOMAINID}/records.json" | _egrep_o "{\"id\":[0-9]*[^}]*,\"name\":\"${fulldomain}\"" | _egrep_o "[0-9]*"); do + _post "" "https://www.lima-city.de/usercp/domains/${LIMACITY_DOMAINID}/records/${recordId}" "" "DELETE" + done + + return 0 +} + +#################### Private functions below ################################## + +_lima_get_root() { + _lima_get_root=$1 + i=1 + while true; do + h=$(printf "%s" "$_lima_get_root" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 0 + fi + + if _contains "$h" "\."; then + domain=$h + fi + + i=$(_math "$i" + 1) + done +} + +_lima_get_domain_id() { + _lima_get_root "$1" + _debug "$domain" + + LIMACITY_DOMAINID=$(_get "${APIBASE}/domains.json" | _egrep_o "{\"id\":[0-9]*[^}]*$domain" | _egrep_o "[0-9]*") + + _debug "$LIMACITY_DOMAINID" + if [ -z "$LIMACITY_DOMAINID" ]; then + return 1 + fi + + return 0 +} From 9b0b5bce9f79672dff5eb80dbb74a0ec4c88986f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 28 Aug 2023 15:30:26 +0200 Subject: [PATCH 204/687] inwx: Be case insensitive while searching for the cookie. At least since 2023-08-25 the cookie is set via `set-cookie' instead the expecting `Set-Cookie' string. A month earlier it was working. Ignore the case while matching the cookie. Fixes: #4763 Signed-off-by: Sebastian Andrzej Siewior --- dnsapi/dns_inwx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index ba789da9..e483c0e8 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -194,7 +194,7 @@ _inwx_login() { response="$(_post "$xml_content" "$INWX_Api" "" "POST")" - INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") _H1=$INWX_Cookie export _H1 export INWX_Cookie From 089d35708b99fe326660c8d95ed30b5040532d40 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 14:31:17 +0800 Subject: [PATCH 205/687] fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation see https://bugs.launchpad.net/ubuntu/+source/curl/+bug/2018342 https://github.com/acmesh-official/acme.sh/commit/b6f62ac446ab9ff78f4a90c4330dc314678545c9 https://github.com/acmesh-official/acme.sh/issues/4775 --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 615e5d8b..a13cb51c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -332,7 +332,7 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | - pkg_add curl socat + pkg_add curl socat libnghttp2 usesh: true copyback: false run: | @@ -384,7 +384,7 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | - pkg install -y curl socat + pkg install -y curl socat libnghttp2 usesh: true copyback: false run: | From 29a2920a2c585488ba1f81f9d459d86aab951f9e Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 14:49:43 +0800 Subject: [PATCH 206/687] Add dns_tencent.sh Adapt to Tencent Cloud (DNSPod) API 3.0 --- dnsapi/dns_tencent.sh | 201 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 dnsapi/dns_tencent.sh diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh new file mode 100644 index 00000000..30e33f03 --- /dev/null +++ b/dnsapi/dns_tencent.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env sh +set -x +Tencent_API="https://dnspod.tencentcloudapi.com" + +#Tencent_SecretId="AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA" +#Tencent_SecretKey="Gu5t9xGARNpq86cd98joQYCN3Cozk1qA" + +#Usage: dns_tencent_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_tencent_add() { + fulldomain=$1 + txtvalue=$2 + + Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" + Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" + if [ -z "$Tencent_SecretId" ] || [ -z "$Tencent_SecretKey" ]; then + Tencent_SecretId="" + Tencent_SecretKey="" + _err "You don't specify tencent api SecretId and SecretKey yet." + return 1 + fi + + #save the api SecretId and SecretKey to the account conf file. + _saveaccountconf_mutable Tencent_SecretId "$Tencent_SecretId" + _saveaccountconf_mutable Tencent_SecretKey "$Tencent_SecretKey" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + + _debug "Add record" + _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "CreateRecord" +} + +dns_tencent_rm() { + fulldomain=$1 + txtvalue=$2 + Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" + Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + + _debug "Get record list" + sleep 30 + _check_exist_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "DescribeRecordFilterList" + + record_id="$(echo "$response" | _egrep_o "\"RecordId\":\s*[0-9]+" | _egrep_o "[0-9]+")" + _debug2 record_id "$record_id" + + if [ -z "$record_id" ]; then + _debug "record not found, skip" + else + _debug "Delete record" + _delete_record_query "$record_id" && _tencent_rest "DeleteRecord" + fi +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _describe_records_query "$h" "@" + if ! _tencent_rest "DescribeRecordList" "ignore"; then + return 1 + fi + + if _contains "$response" "\"TotalCount\":"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _debug _sub_domain "$_sub_domain" + _domain="$h" + _debug _domain "$_domain" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_tencent_rest() { + action=$1 + service="dnspod" + payload="${query}" + timestamp=$(date -u +%s) + + token=$(tencent_signature_v3 $service "$action" "$payload" "$timestamp") + version="2021-03-23" + + if ! response="$(tencent_api_request $service $version "$action" "$payload" "$timestamp")"; then + _err "Error <$1>" + return 1 + fi + + _debug2 response "$response" + if [ -z "$2" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then + _err "$message" + return 1 + fi + fi +} + +_add_record_query() { + query="{\"Domain\":\"$1\",\"SubDomain\":\"$2\",\"RecordType\":\"TXT\",\"RecordLineId\":\"0\",\"RecordLine\":\"0\",\"Value\":\"$3\",\"TTL\":600}" +} + +_describe_records_query() { + query="{\"Domain\":\"$1\",\"Limit\":3000}" +} + +_delete_record_query() { + query="{\"Domain\":\"$_domain\",\"RecordId\":$1}" +} + +_check_exist_query() { + _domain="$1" + _subdomain="$2" + _value="$3" + query="{\"Domain\":\"$_domain\",\"SubDomain\":\"$_subdomain\",\"RecordValue\":\"$_value\"}" +} + +# shell client for tencent cloud api v3 | @author: rehiy + +tencent_sha256() { + printf %b "$@" | openssl dgst -sha256 -hex | sed 's/^.* //' +} + +tencent_hmac_sha256() { + k=$1 + shift + printf %b "$@" | openssl dgst -sha256 -hmac "$k" | sed 's/^.* //' +} + +tencent_hmac_sha256_hexkey() { + k=$1 + shift + printf %b "$@" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$k" | sed 's/^.* //' +} + +tencent_signature_v3() { + service=$1 + action=$(echo "$2" | tr '[:upper:]' '[:lower:]') + payload=${3:-'{}'} + timestamp=${4:-$(date +%s)} + + domain="$service.tencentcloudapi.com" + secretId=${Tencent_SecretId:-'tencent-cloud-secret-id'} + secretKey=${Tencent_SecretKey:-'tencent-cloud-secret-key'} + + algorithm='TC3-HMAC-SHA256' + date=$(date -u -d "@$timestamp" +%Y-%m-%d 2>/dev/null) + [ -z "$date" ] && date=$(date -u -r "$timestamp" +%Y-%m-%d) + + canonicalUri='/' + canonicalQuery='' + canonicalHeaders="content-type:application/json\nhost:$domain\nx-tc-action:$action\n" + + signedHeaders='content-type;host;x-tc-action' + canonicalRequest="POST\n$canonicalUri\n$canonicalQuery\n$canonicalHeaders\n$signedHeaders\n$(tencent_sha256 "$payload")" + + credentialScope="$date/$service/tc3_request" + stringToSign="$algorithm\n$timestamp\n$credentialScope\n$(tencent_sha256 "$canonicalRequest")" + + secretDate=$(tencent_hmac_sha256 "TC3$secretKey" "$date") + secretService=$(tencent_hmac_sha256_hexkey "$secretDate" "$service") + secretSigning=$(tencent_hmac_sha256_hexkey "$secretService" 'tc3_request') + signature=$(tencent_hmac_sha256_hexkey "$secretSigning" "$stringToSign") + + echo "$algorithm Credential=$secretId/$credentialScope, SignedHeaders=$signedHeaders, Signature=$signature" +} + +tencent_api_request() { + service=$1 + version=$2 + action=$3 + payload=${4:-'{}'} + timestamp=${5:-$(date +%s)} + + token=$(tencent_signature_v3 "$service" "$action" "$payload" "$timestamp") + + _H1="Content-Type: application/json" + _H2="Authorization: $token" + _H3="X-TC-Version: $version" + _H4="X-TC-Timestamp: $timestamp" + _H5="X-TC-Action: $action" + + _post "$payload" "$Tencent_API" "" "POST" "application/json" +} From e5b76ed4c4326c6ce039121c1ed78908aa450288 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 15:13:37 +0800 Subject: [PATCH 207/687] Delete dnsapi/dns_tencent.sh --- dnsapi/dns_tencent.sh | 201 ------------------------------------------ 1 file changed, 201 deletions(-) delete mode 100644 dnsapi/dns_tencent.sh diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh deleted file mode 100644 index 30e33f03..00000000 --- a/dnsapi/dns_tencent.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env sh -set -x -Tencent_API="https://dnspod.tencentcloudapi.com" - -#Tencent_SecretId="AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA" -#Tencent_SecretKey="Gu5t9xGARNpq86cd98joQYCN3Cozk1qA" - -#Usage: dns_tencent_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_tencent_add() { - fulldomain=$1 - txtvalue=$2 - - Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" - Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" - if [ -z "$Tencent_SecretId" ] || [ -z "$Tencent_SecretKey" ]; then - Tencent_SecretId="" - Tencent_SecretKey="" - _err "You don't specify tencent api SecretId and SecretKey yet." - return 1 - fi - - #save the api SecretId and SecretKey to the account conf file. - _saveaccountconf_mutable Tencent_SecretId "$Tencent_SecretId" - _saveaccountconf_mutable Tencent_SecretKey "$Tencent_SecretKey" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - return 1 - fi - - _debug "Add record" - _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "CreateRecord" -} - -dns_tencent_rm() { - fulldomain=$1 - txtvalue=$2 - Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" - Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - return 1 - fi - - _debug "Get record list" - sleep 30 - _check_exist_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "DescribeRecordFilterList" - - record_id="$(echo "$response" | _egrep_o "\"RecordId\":\s*[0-9]+" | _egrep_o "[0-9]+")" - _debug2 record_id "$record_id" - - if [ -z "$record_id" ]; then - _debug "record not found, skip" - else - _debug "Delete record" - _delete_record_query "$record_id" && _tencent_rest "DeleteRecord" - fi -} - -#################### Private functions below ################################## - -_get_root() { - domain=$1 - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) - if [ -z "$h" ]; then - #not valid - return 1 - fi - - _describe_records_query "$h" "@" - if ! _tencent_rest "DescribeRecordList" "ignore"; then - return 1 - fi - - if _contains "$response" "\"TotalCount\":"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") - _debug _sub_domain "$_sub_domain" - _domain="$h" - _debug _domain "$_domain" - return 0 - fi - p="$i" - i=$(_math "$i" + 1) - done - return 1 -} - -_tencent_rest() { - action=$1 - service="dnspod" - payload="${query}" - timestamp=$(date -u +%s) - - token=$(tencent_signature_v3 $service "$action" "$payload" "$timestamp") - version="2021-03-23" - - if ! response="$(tencent_api_request $service $version "$action" "$payload" "$timestamp")"; then - _err "Error <$1>" - return 1 - fi - - _debug2 response "$response" - if [ -z "$2" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_add_record_query() { - query="{\"Domain\":\"$1\",\"SubDomain\":\"$2\",\"RecordType\":\"TXT\",\"RecordLineId\":\"0\",\"RecordLine\":\"0\",\"Value\":\"$3\",\"TTL\":600}" -} - -_describe_records_query() { - query="{\"Domain\":\"$1\",\"Limit\":3000}" -} - -_delete_record_query() { - query="{\"Domain\":\"$_domain\",\"RecordId\":$1}" -} - -_check_exist_query() { - _domain="$1" - _subdomain="$2" - _value="$3" - query="{\"Domain\":\"$_domain\",\"SubDomain\":\"$_subdomain\",\"RecordValue\":\"$_value\"}" -} - -# shell client for tencent cloud api v3 | @author: rehiy - -tencent_sha256() { - printf %b "$@" | openssl dgst -sha256 -hex | sed 's/^.* //' -} - -tencent_hmac_sha256() { - k=$1 - shift - printf %b "$@" | openssl dgst -sha256 -hmac "$k" | sed 's/^.* //' -} - -tencent_hmac_sha256_hexkey() { - k=$1 - shift - printf %b "$@" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$k" | sed 's/^.* //' -} - -tencent_signature_v3() { - service=$1 - action=$(echo "$2" | tr '[:upper:]' '[:lower:]') - payload=${3:-'{}'} - timestamp=${4:-$(date +%s)} - - domain="$service.tencentcloudapi.com" - secretId=${Tencent_SecretId:-'tencent-cloud-secret-id'} - secretKey=${Tencent_SecretKey:-'tencent-cloud-secret-key'} - - algorithm='TC3-HMAC-SHA256' - date=$(date -u -d "@$timestamp" +%Y-%m-%d 2>/dev/null) - [ -z "$date" ] && date=$(date -u -r "$timestamp" +%Y-%m-%d) - - canonicalUri='/' - canonicalQuery='' - canonicalHeaders="content-type:application/json\nhost:$domain\nx-tc-action:$action\n" - - signedHeaders='content-type;host;x-tc-action' - canonicalRequest="POST\n$canonicalUri\n$canonicalQuery\n$canonicalHeaders\n$signedHeaders\n$(tencent_sha256 "$payload")" - - credentialScope="$date/$service/tc3_request" - stringToSign="$algorithm\n$timestamp\n$credentialScope\n$(tencent_sha256 "$canonicalRequest")" - - secretDate=$(tencent_hmac_sha256 "TC3$secretKey" "$date") - secretService=$(tencent_hmac_sha256_hexkey "$secretDate" "$service") - secretSigning=$(tencent_hmac_sha256_hexkey "$secretService" 'tc3_request') - signature=$(tencent_hmac_sha256_hexkey "$secretSigning" "$stringToSign") - - echo "$algorithm Credential=$secretId/$credentialScope, SignedHeaders=$signedHeaders, Signature=$signature" -} - -tencent_api_request() { - service=$1 - version=$2 - action=$3 - payload=${4:-'{}'} - timestamp=${5:-$(date +%s)} - - token=$(tencent_signature_v3 "$service" "$action" "$payload" "$timestamp") - - _H1="Content-Type: application/json" - _H2="Authorization: $token" - _H3="X-TC-Version: $version" - _H4="X-TC-Timestamp: $timestamp" - _H5="X-TC-Action: $action" - - _post "$payload" "$Tencent_API" "" "POST" "application/json" -} From b32d22731b00b723600e0de9f6b9fceb60952f37 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Sep 2023 15:32:12 +0800 Subject: [PATCH 208/687] remove --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 73ff3321..717ecf5f 100644 --- a/README.md +++ b/README.md @@ -506,10 +506,6 @@ Support this project with your organization. Your logo will show up here with a -#### Sponsors - -[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation) - # 19. License & Others From 8bdcd224862af85d99e682844e71122772c3eba7 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Sep 2023 15:44:45 +0800 Subject: [PATCH 209/687] fix https://github.com/acmesh-official/acme.sh/issues/4746 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 70f1daac..a8256609 100755 --- a/acme.sh +++ b/acme.sh @@ -931,7 +931,7 @@ fi _egrep_o() { if [ "$__USE_EGREP" ]; then - egrep -o "$1" + egrep -o -- "$1" else sed -n 's/.*\('"$1"'\).*/\1/p' fi From 04946e992eb60a3cc85b4c9b0e0fe9a577ac1e5e Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Sep 2023 17:15:17 +0800 Subject: [PATCH 210/687] change the default debug level to 2. --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 92faeb5e..7b61b109 100755 --- a/acme.sh +++ b/acme.sh @@ -107,7 +107,7 @@ DEFAULT_LOG_LEVEL="$LOG_LEVEL_1" DEBUG_LEVEL_1=1 DEBUG_LEVEL_2=2 DEBUG_LEVEL_3=3 -DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1 +DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_2 DEBUG_LEVEL_NONE=0 DOH_CLOUDFLARE=1 @@ -6899,7 +6899,7 @@ Parameters: -f, --force Force install, force cert renewal or override sudo restrictions. --staging, --test Use staging server, for testing. - --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted. + --debug [0|1|2|3] Output debug info. Defaults to $DEBUG_LEVEL_DEFAULT if argument is omitted. --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security. -w, --webroot Specifies the web root folder for web root mode. From c18364c75549e840a9db0025fc86947f4fdab114 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Sep 2023 17:18:12 +0800 Subject: [PATCH 211/687] change default log level to 2 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 7b61b109..4fab21d2 100755 --- a/acme.sh +++ b/acme.sh @@ -102,7 +102,7 @@ ECC_SUFFIX="${ECC_SEP}ecc" LOG_LEVEL_1=1 LOG_LEVEL_2=2 LOG_LEVEL_3=3 -DEFAULT_LOG_LEVEL="$LOG_LEVEL_1" +DEFAULT_LOG_LEVEL="$LOG_LEVEL_2" DEBUG_LEVEL_1=1 DEBUG_LEVEL_2=2 @@ -6917,7 +6917,7 @@ Parameters: -k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521. -ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096 --log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted. - --log-level <1|2> Specifies the log level, default is 1. + --log-level <1|2> Specifies the log level, default is $DEFAULT_LOG_LEVEL. --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug. --eab-kid Key Identifier for External Account Binding. --eab-hmac-key HMAC key for External Account Binding. From eed8a7f0788190d44e6a603bd49eb96c508fdb3c Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Sep 2023 17:27:21 +0800 Subject: [PATCH 212/687] add more debug code https://github.com/acmesh-official/acme.sh/issues/4768 --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 4fab21d2..54dfa9a5 100755 --- a/acme.sh +++ b/acme.sh @@ -5015,9 +5015,9 @@ $_authorizations_map" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" _debug2 errordetail "$errordetail" if [ "$errordetail" ]; then - _err "$d:Verify error:$errordetail" + _err "Invalid status, $d:Verify error detail:$errordetail" else - _err "$d:Verify error:$error" + _err "Invalid status, $d:Verify error:$error" fi if [ "$DEBUG" ]; then if [ "$vtype" = "$VTYPE_HTTP" ]; then @@ -5044,7 +5044,7 @@ $_authorizations_map" elif _contains "$status" "processing"; then _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" else - _err "$d:Verify error:$response" + _err "Unknown status: $status, $d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5057,7 +5057,7 @@ $_authorizations_map" _send_signed_request "$_authz_url" if [ "$?" != "0" ]; then - _err "$d:Verify error:$response" + _err "Invalid code, $d:Verify error:$response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" From 87dc4fe388244663055cea068b23c97632561544 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:23:14 +0800 Subject: [PATCH 213/687] =?UTF-8?q?fix=20for=20curl=20bugs=20nghttp2=5Fopt?= =?UTF-8?q?ion=5Fset=5Fno=5Frfc9113=5Fleading=5Fand=5Ftrailing=5F=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In #4776, I mistakenly added libnghttp2 to NetBsd, and now it has been corrected and added to OpenBsd --- .github/workflows/DNS.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index a13cb51c..8bae3520 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -280,7 +280,7 @@ jobs: - uses: vmactions/openbsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkg_add socat curl + prepare: pkg_add socat curl libnghttp2 usesh: true copyback: false run: | @@ -332,7 +332,7 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | - pkg_add curl socat libnghttp2 + pkg_add curl socat usesh: true copyback: false run: | From 09b41aa66711777b90c8d6200b825330ffee2e09 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:38:51 +0800 Subject: [PATCH 214/687] fix for nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation In #4776, I mistakenly added libnghttp2 to NetBSD, now for correction. --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 8bae3520..507755c9 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -280,7 +280,7 @@ jobs: - uses: vmactions/openbsd-vm@v0 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkg_add socat curl libnghttp2 + prepare: pkg_add socat curl usesh: true copyback: false run: | From 3abcfd8fa926fb1ee03b45826f8a12644e63ff05 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:47:59 +0800 Subject: [PATCH 215/687] Add dns_tencent.sh Adapt to Tencent Cloud (DNSPod) API 3.0 --- dnsapi/dns_tencent.sh | 210 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 dnsapi/dns_tencent.sh diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh new file mode 100644 index 00000000..b4b4cb24 --- /dev/null +++ b/dnsapi/dns_tencent.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env sh +Tencent_API="https://dnspod.tencentcloudapi.com" + +#Tencent_SecretId="AKIDz81d2cd22cdcdc2dcd1cc1d1A" +#Tencent_SecretKey="Gu5t9abcabcaabcbabcbbbcbcbbccbbcb" + +#Usage: dns_tencent_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_tencent_add() { + fulldomain=$1 + txtvalue=$2 + + Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" + Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" + if [ -z "$Tencent_SecretId" ] || [ -z "$Tencent_SecretKey" ]; then + Tencent_SecretId="" + Tencent_SecretKey="" + _err "You don't specify tencent api SecretId and SecretKey yet." + return 1 + fi + + #save the api SecretId and SecretKey to the account conf file. + _saveaccountconf_mutable Tencent_SecretId "$Tencent_SecretId" + _saveaccountconf_mutable Tencent_SecretKey "$Tencent_SecretKey" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + + _debug "Add record" + _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "CreateRecord" +} + +dns_tencent_rm() { + fulldomain=$1 + txtvalue=$2 + Tencent_SecretId="${Tencent_SecretId:-$(_readaccountconf_mutable Tencent_SecretId)}" + Tencent_SecretKey="${Tencent_SecretKey:-$(_readaccountconf_mutable Tencent_SecretKey)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + + _debug "Get record list" + attempt=1 + max_attempts=5 + while [ -z "$record_id" ] && [ $attempt -le $max_attempts ]; do + _check_exist_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "DescribeRecordFilterList" + record_id="$(echo "$response" | _egrep_o "\"RecordId\":\s*[0-9]+" | _egrep_o "[0-9]+")" + _debug2 record_id "$record_id" + if [ -z "$record_id" ]; then + _debug "Due to TencentCloud API synchronization delay, record not found, waiting 10 seconds and retrying" + sleep 10 + attempt=$((attempt + 1)) + fi + done + + record_id="$(echo "$response" | _egrep_o "\"RecordId\":\s*[0-9]+" | _egrep_o "[0-9]+")" + _debug2 record_id "$record_id" + + if [ -z "$record_id" ]; then + _debug "record not found after $max_attempts attempts, skip" + else + _debug "Delete record" + _delete_record_query "$record_id" && _tencent_rest "DeleteRecord" + fi +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _describe_records_query "$h" "@" + if ! _tencent_rest "DescribeRecordList" "ignore"; then + return 1 + fi + + if _contains "$response" "\"TotalCount\":"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _debug _sub_domain "$_sub_domain" + _domain="$h" + _debug _domain "$_domain" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_tencent_rest() { + action=$1 + service="dnspod" + payload="${query}" + timestamp=$(date -u +%s) + + token=$(tencent_signature_v3 $service "$action" "$payload" "$timestamp") + version="2021-03-23" + + if ! response="$(tencent_api_request $service $version "$action" "$payload" "$timestamp")"; then + _err "Error <$1>" + return 1 + fi + + _debug2 response "$response" + if [ -z "$2" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then + _err "$message" + return 1 + fi + fi +} + +_add_record_query() { + query="{\"Domain\":\"$1\",\"SubDomain\":\"$2\",\"RecordType\":\"TXT\",\"RecordLineId\":\"0\",\"RecordLine\":\"0\",\"Value\":\"$3\",\"TTL\":600}" +} + +_describe_records_query() { + query="{\"Domain\":\"$1\",\"Limit\":3000}" +} + +_delete_record_query() { + query="{\"Domain\":\"$_domain\",\"RecordId\":$1}" +} + +_check_exist_query() { + _domain="$1" + _subdomain="$2" + _value="$3" + query="{\"Domain\":\"$_domain\",\"SubDomain\":\"$_subdomain\",\"RecordValue\":\"$_value\"}" +} + +# shell client for tencent cloud api v3 | @author: rehiy + +tencent_sha256() { + printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hex | sed 's/^.* //' +} + +tencent_hmac_sha256() { + k=$1 + shift + printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac "$k" | sed 's/^.* //' +} + +tencent_hmac_sha256_hexkey() { + k=$1 + shift + printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -mac HMAC -macopt "hexkey:$k" | sed 's/^.* //' +} + +tencent_signature_v3() { + service=$1 + action=$(echo "$2" | tr '[:upper:]' '[:lower:]') + payload=${3:-'{}'} + timestamp=${4:-$(date +%s)} + + domain="$service.tencentcloudapi.com" + secretId=${Tencent_SecretId:-'tencent-cloud-secret-id'} + secretKey=${Tencent_SecretKey:-'tencent-cloud-secret-key'} + + algorithm='TC3-HMAC-SHA256' + date=$(date -u -d "@$timestamp" +%Y-%m-%d 2>/dev/null) + [ -z "$date" ] && date=$(date -u -r "$timestamp" +%Y-%m-%d) + + canonicalUri='/' + canonicalQuery='' + canonicalHeaders="content-type:application/json\nhost:$domain\nx-tc-action:$action\n" + + signedHeaders='content-type;host;x-tc-action' + canonicalRequest="POST\n$canonicalUri\n$canonicalQuery\n$canonicalHeaders\n$signedHeaders\n$(tencent_sha256 "$payload")" + + credentialScope="$date/$service/tc3_request" + stringToSign="$algorithm\n$timestamp\n$credentialScope\n$(tencent_sha256 "$canonicalRequest")" + + secretDate=$(tencent_hmac_sha256 "TC3$secretKey" "$date") + secretService=$(tencent_hmac_sha256_hexkey "$secretDate" "$service") + secretSigning=$(tencent_hmac_sha256_hexkey "$secretService" 'tc3_request') + signature=$(tencent_hmac_sha256_hexkey "$secretSigning" "$stringToSign") + + echo "$algorithm Credential=$secretId/$credentialScope, SignedHeaders=$signedHeaders, Signature=$signature" +} + +tencent_api_request() { + service=$1 + version=$2 + action=$3 + payload=${4:-'{}'} + timestamp=${5:-$(date +%s)} + + token=$(tencent_signature_v3 "$service" "$action" "$payload" "$timestamp") + + _H1="Content-Type: application/json" + _H2="Authorization: $token" + _H3="X-TC-Version: $version" + _H4="X-TC-Timestamp: $timestamp" + _H5="X-TC-Action: $action" + + _post "$payload" "$Tencent_API" "" "POST" "application/json" +} From 27b1dd04c4d240d368d79216e84debbaeed813ae Mon Sep 17 00:00:00 2001 From: LJea Date: Sun, 3 Sep 2023 01:02:16 +0900 Subject: [PATCH 216/687] improve the compatibility Fixed an issue where some embedded devices could not obtain nanoseconds resulting in abnormal parameter coding --- dnsapi/dns_ali.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index c2105672..c69839dc 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -117,7 +117,7 @@ _ali_urlencode() { _ali_nonce() { #_head_n 1 Date: Sun, 3 Sep 2023 01:31:57 +0800 Subject: [PATCH 217/687] Following Neilpang's suggestions and project standards, replace some functions. --- dnsapi/dns_tencent.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index b4b4cb24..746f00f0 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -51,7 +51,7 @@ dns_tencent_rm() { _debug2 record_id "$record_id" if [ -z "$record_id" ]; then _debug "Due to TencentCloud API synchronization delay, record not found, waiting 10 seconds and retrying" - sleep 10 + _sleep 10 attempt=$((attempt + 1)) fi done @@ -71,7 +71,7 @@ dns_tencent_rm() { _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) @@ -144,19 +144,20 @@ _check_exist_query() { # shell client for tencent cloud api v3 | @author: rehiy tencent_sha256() { - printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hex | sed 's/^.* //' + printf %b "$@" | _digest sha256 hex } tencent_hmac_sha256() { k=$1 shift - printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -hmac "$k" | sed 's/^.* //' + hex_key=$(_ascii_hex "$k" | tr -d ' ') + printf %b "$@" | _hmac sha256 "$hex_key" hex } tencent_hmac_sha256_hexkey() { k=$1 shift - printf %b "$@" | ${ACME_OPENSSL_BIN:-openssl} dgst -sha256 -mac HMAC -macopt "hexkey:$k" | sed 's/^.* //' + printf %b "$@" | _hmac sha256 "$k" hex } tencent_signature_v3() { From e3c4c9265dfe2d2816e68dfe310d5f6fcda4f25b Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Sun, 3 Sep 2023 21:21:05 +0800 Subject: [PATCH 218/687] Replace some functions. --- dnsapi/dns_tencent.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index 746f00f0..5cce4aeb 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -45,14 +45,14 @@ dns_tencent_rm() { _debug "Get record list" attempt=1 max_attempts=5 - while [ -z "$record_id" ] && [ $attempt -le $max_attempts ]; do + while [ -z "$record_id" ] && [ "$attempt" -le $max_attempts ]; do _check_exist_query "$_domain" "$_sub_domain" "$txtvalue" && _tencent_rest "DescribeRecordFilterList" record_id="$(echo "$response" | _egrep_o "\"RecordId\":\s*[0-9]+" | _egrep_o "[0-9]+")" _debug2 record_id "$record_id" if [ -z "$record_id" ]; then _debug "Due to TencentCloud API synchronization delay, record not found, waiting 10 seconds and retrying" _sleep 10 - attempt=$((attempt + 1)) + attempt=$(_math "$attempt + 1") fi done @@ -162,7 +162,7 @@ tencent_hmac_sha256_hexkey() { tencent_signature_v3() { service=$1 - action=$(echo "$2" | tr '[:upper:]' '[:lower:]') + action=$(echo "$2" | _lower_case) payload=${3:-'{}'} timestamp=${4:-$(date +%s)} From 772bbdc862777cf06c649271c9319f45b9075313 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Wed, 6 Sep 2023 12:57:19 +0800 Subject: [PATCH 219/687] Replace some functions --- dnsapi/dns_tencent.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index 5cce4aeb..b926225b 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -150,7 +150,7 @@ tencent_sha256() { tencent_hmac_sha256() { k=$1 shift - hex_key=$(_ascii_hex "$k" | tr -d ' ') + hex_key=$(printf %b "$k" | _hex_dump | tr -d ' ') printf %b "$@" | _hmac sha256 "$hex_key" hex } @@ -183,6 +183,7 @@ tencent_signature_v3() { credentialScope="$date/$service/tc3_request" stringToSign="$algorithm\n$timestamp\n$credentialScope\n$(tencent_sha256 "$canonicalRequest")" + _debug "stringToSign: $stringToSign" secretDate=$(tencent_hmac_sha256 "TC3$secretKey" "$date") secretService=$(tencent_hmac_sha256_hexkey "$secretDate" "$service") From af534a73fc75cddf5a60f0ec1b13f79056b51940 Mon Sep 17 00:00:00 2001 From: KincaidYang <91786638+KincaidYang@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:09:52 +0800 Subject: [PATCH 220/687] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=95=8F=E6=84=9Fdebug=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dnsapi/dns_tencent.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index b926225b..2f8d3b67 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -183,7 +183,6 @@ tencent_signature_v3() { credentialScope="$date/$service/tc3_request" stringToSign="$algorithm\n$timestamp\n$credentialScope\n$(tencent_sha256 "$canonicalRequest")" - _debug "stringToSign: $stringToSign" secretDate=$(tencent_hmac_sha256 "TC3$secretKey" "$date") secretService=$(tencent_hmac_sha256_hexkey "$secretDate" "$service") From ae4c186f55b10b26d9bb0528bc90893413bd967e Mon Sep 17 00:00:00 2001 From: Tobias Grave Date: Thu, 7 Sep 2023 08:40:46 +0200 Subject: [PATCH 221/687] Fix Variomedia API --- dnsapi/dns_variomedia.sh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index a35b8f0f..200b3f50 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -69,7 +69,7 @@ dns_variomedia_rm() { return 1 fi - _record_id="$(echo "$response" | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" + _record_id="$(echo "$response" | sed -E 's/,"tags":\[[^]]*\]//g' | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep -- "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')" _debug _record_id "$_record_id" if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." @@ -93,11 +93,11 @@ dns_variomedia_rm() { # _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { - fulldomain=$1 - i=1 + domain=$1 + i=2 + p=1 while true; do - h=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) - _debug h "$h" + h=$(printf "%s" "$domain" | cut -d . -f $i-100) if [ -z "$h" ]; then return 1 fi @@ -106,17 +106,14 @@ _get_root() { return 1 fi - if _startswith "$response" "\{\"data\":"; then - if _contains "$response" "\"id\":\"$h\""; then - _sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")" - _domain=$h - return 0 - fi + if _contains "$response" "\"id\":\"$h\""; then + _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) + _domain="$h" + return 0 fi + p=$i i=$(_math "$i" + 1) done - - _debug "root domain not found" return 1 } From 29b2960805ac850a564e5ec6521720a3511a1771 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 7 Sep 2023 15:01:37 +0800 Subject: [PATCH 222/687] Optimze comment & remove tail space --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 15f961e2..455d9de4 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -19,7 +19,7 @@ # - export SYNO_Scheme="http" # - export SYNO_Hostname="localhost" # - export SYNO_Port="5000" -# - export SYNO_Create=1 to allow creating the certificate if it doesn't exist +# - export SYNO_Create=1 - to allow creating the certificate if it doesn't exist # - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled # - export SYNO_Device_ID="" - required for skipping 2FA-OTP # 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com @@ -191,7 +191,7 @@ synology_dsm_deploy() { _H1="X-SYNO-TOKEN: $token" export _H1 - _debug2 H1 "${_H1}" + _debug2 H1 "${_H1}" # Now that we know the username & password are good, save them _savedeployconf SYNO_Username "$SYNO_Username" From 1a08be0a3fca85413421cedcf598ac4d3f5ded04 Mon Sep 17 00:00:00 2001 From: Julien Furgerot Date: Mon, 11 Sep 2023 15:05:12 +0200 Subject: [PATCH 223/687] dns_gandi: implements personal access token in addition to the (deprecated) API key --- dnsapi/dns_gandi_livedns.sh | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index 931da883..f299779e 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -1,7 +1,8 @@ #!/usr/bin/env sh # Gandi LiveDNS v5 API -# https://doc.livedns.gandi.net/ +# https://api.gandi.net/docs/livedns/ +# https://api.gandi.net/docs/authentication/ for token + apikey (deprecated) authentication # currently under beta # # Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable @@ -19,13 +20,23 @@ dns_gandi_livedns_add() { fulldomain=$1 txtvalue=$2 - if [ -z "$GANDI_LIVEDNS_KEY" ]; then - _err "No API key specified for Gandi LiveDNS." - _err "Create your key and export it as GANDI_LIVEDNS_KEY" + if [ -z "$GANDI_LIVEDNS_KEY" -a -z "$GANDI_LIVEDNS_TOKEN" ]; then + _err "No Token or API key (deprecated) specified for Gandi LiveDNS." + _err "Create your token or key and export it as GANDI_LIVEDNS_KEY or GANDI_LIVEDNS_TOKEN respectively" return 1 fi - _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY" + # Keep only one secret in configuration + if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then + _saveaccountconf GANDI_LIVEDNS_TOKEN "$GANDI_LIVEDNS_TOKEN" + _clearaccountconf GANDI_LIVEDNS_KEY + elif [ -n "$GANDI_LIVEDNS_KEY" ]; then + _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY" + _clearaccountconf GANDI_LIVEDNS_TOKEN + fi + + + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -157,7 +168,12 @@ _gandi_livedns_rest() { _debug "$ep" export _H1="Content-Type: application/json" - export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY" + + if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then + export _H2="Authorization: Bearer $GANDI_LIVEDNS_TOKEN" + else + export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY" + fi if [ "$m" = "GET" ]; then response="$(_get "$GANDI_LIVEDNS_API/$ep")" From 558e706bdeb395ce0164cb9b7a31078269413d33 Mon Sep 17 00:00:00 2001 From: Julien Furgerot Date: Tue, 12 Sep 2023 15:54:44 +0200 Subject: [PATCH 224/687] fix ci errors (shellcheck & shfmt) --- dnsapi/dns_gandi_livedns.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index f299779e..14939d7c 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -20,7 +20,7 @@ dns_gandi_livedns_add() { fulldomain=$1 txtvalue=$2 - if [ -z "$GANDI_LIVEDNS_KEY" -a -z "$GANDI_LIVEDNS_TOKEN" ]; then + if [ -z "$GANDI_LIVEDNS_KEY" ] && [ -z "$GANDI_LIVEDNS_TOKEN" ]; then _err "No Token or API key (deprecated) specified for Gandi LiveDNS." _err "Create your token or key and export it as GANDI_LIVEDNS_KEY or GANDI_LIVEDNS_TOKEN respectively" return 1 @@ -35,9 +35,6 @@ dns_gandi_livedns_add() { _clearaccountconf GANDI_LIVEDNS_TOKEN fi - - - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" From dfd49e46ad268d6f1796cf850b0b353b667cc11d Mon Sep 17 00:00:00 2001 From: Tobias Grave Date: Thu, 14 Sep 2023 09:15:08 +0200 Subject: [PATCH 225/687] Fix root zone determination for Variomedia API --- dnsapi/dns_variomedia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 200b3f50..aa743807 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -94,7 +94,7 @@ dns_variomedia_rm() { # _domain=domain.com _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 59f976dc48873787d089df34c3ebc092a14bc110 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 20 Sep 2023 18:07:16 +0800 Subject: [PATCH 226/687] fix https://github.com/acmesh-official/acme.sh/issues/4798 --- acme.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 067780d7..bce7a41d 100755 --- a/acme.sh +++ b/acme.sh @@ -2118,12 +2118,7 @@ _tail_n() { } _tail_c() { - if _is_solaris; then - #fix for solaris - tail -"$1"c - else - tail -c "$1" - fi + tail -c "$1" 2>/dev/null || tail -"$1"c } # url payload needbase64 keyfile From 87a7bde61813391e6c8379ae93c921bd68889c53 Mon Sep 17 00:00:00 2001 From: Romeo Dumitrescu Date: Mon, 25 Sep 2023 18:43:01 +0300 Subject: [PATCH 227/687] fix: Synology DSM API path regex Fix the regex for looking up the API path value from the Synology API query. --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 21c7ac9b..10da861a 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -91,7 +91,7 @@ synology_dsm_deploy() { _debug "Getting API version" response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") - api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([0-9]*\)".*/\1/p') + api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p') api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') _debug3 response "$response" _debug3 api_path "$api_path" From f2e1b589b5c5ff115fe9e8d87f4a926cd575b5ff Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 6 Oct 2023 20:01:28 +0800 Subject: [PATCH 228/687] start 3.0.8 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index bce7a41d..34291708 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.7 +VER=3.0.8 PROJECT_NAME="acme.sh" From e15513bfdd6fb843f8b57be407bffe28bb12de6b Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 6 Oct 2023 20:05:39 +0800 Subject: [PATCH 229/687] fix format --- notify/mattermost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/mattermost.sh b/notify/mattermost.sh index 9037ae0d..f13f6ebc 100644 --- a/notify/mattermost.sh +++ b/notify/mattermost.sh @@ -38,7 +38,7 @@ mattermost_send() { _data="$_data\"message\": \"$_content\"}" export _H1="Authorization: Bearer $MATTERMOST_BOT_TOKEN" - + response="" if _post "$_data" "$MATTERMOST_API_URL" "" "POST" "application/json; charset=utf-8"; then MATTERMOST_RESULT_OK=$(echo "$response" | _egrep_o 'create_at') if [ "$?" = "0" ] && [ "$MATTERMOST_RESULT_OK" ]; then From ed72b090af3fce68195b7ab3d605d70831fca45d Mon Sep 17 00:00:00 2001 From: Keith Chiem Date: Wed, 18 Oct 2023 20:32:39 -0700 Subject: [PATCH 230/687] deploy hook for Ruckus ZoneDirector / Unleashed --- deploy/ruckus.sh | 110 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100755 deploy/ruckus.sh diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh new file mode 100755 index 00000000..d16f40e4 --- /dev/null +++ b/deploy/ruckus.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +# Here is a script to deploy cert to Ruckus Zone Director/Unleashed. +# +# Adapted from: +# https://ms264556.net/pages/PfSenseLetsEncryptToRuckus +# +# ```sh +# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus +# ``` +# +# Then you need to set the environment variables for the +# deploy script to work. +# +# ```sh +# export RUCKUS_HOST=ruckus.example.com +# export RUCKUS_USER=myruckususername +# export RUCKUS_PASS=myruckuspassword +# +# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus +# ``` +# +# returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +ruckus_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + _err_code=0 + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _getdeployconf RUCKUS_HOST + _getdeployconf RUCKUS_USER + _getdeployconf RUCKUS_PASS + + if [ -z "$RUCKUS_HOST" ]; then + _debug "Using _cdomain as RUCKUS_HOST, please set if not correct." + RUCKUS_HOST="$_cdomain" + fi + + if [ -z "$RUCKUS_USER" ]; then + _err "Need to set the env variable RUCKUS_USER" + return 1 + fi + + if [ -z "$RUCKUS_PASS" ]; then + _err "Need to set the env variable RUCKUS_PASS" + return 1 + fi + + _savedeployconf RUCKUS_HOST "$RUCKUS_HOST" + _savedeployconf RUCKUS_USER "$RUCKUS_USER" + _savedeployconf RUCKUS_PASS "$RUCKUS_PASS" + + _debug RUCKUS_HOST "$RUCKUS_HOST" + _debug RUCKUS_USER "$RUCKUS_USER" + _debug RUCKUS_PASS "$RUCKUS_PASS" + + COOKIE_JAR=$(mktemp) + cleanup() { + rm $COOKIE_JAR + } + trap cleanup EXIT + + LOGIN_URL=$(curl https://$RUCKUS_HOST -ksSLo /dev/null -w '%{url_effective}') + _debug LOGIN_URL "$LOGIN_URL" + + XSS=$(curl -ksSic $COOKIE_JAR $LOGIN_URL -d username=$RUCKUS_USER -d password="$RUCKUS_PASS" -d ok='Log In' | awk '/^HTTP_X_CSRF_TOKEN:/ { print $2 }' | tr -d '\040\011\012\015') + _debug XSS "$XSS" + + if [ -n "$XSS" ]; then + _info "Authentication successful" + else + _err "Authentication failed" + return 1 + fi + + BASE_URL=$(dirname $LOGIN_URL) + CONF_ARGS="-ksSo /dev/null -b $COOKIE_JAR -c $COOKIE_JAR" + UPLOAD="$CONF_ARGS $BASE_URL/_upload.jsp?request_type=xhr" + CMD="$CONF_ARGS $BASE_URL/_cmdstat.jsp" + + REPLACE_CERT_AJAX='' + CERT_REBOOT_AJAX='' + + _info "Uploading certificate" + curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ccert" -F action=uploadcert -F callback=uploader_uploadcert || return 1 + + _info "Uploading private key" + curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ckey" -F action=uploadprivatekey -F callback=uploader_uploadprivatekey || return 1 + + _info "Replacing certificate" + curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$REPLACE_CERT_AJAX" || return 1 + + _info "Rebooting" + curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$CERT_REBOOT_AJAX" || return 1 + + return 0 +} + From fe890c62f4229c8696d85edfd2336130214135db Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 22 Oct 2023 23:07:00 +0800 Subject: [PATCH 231/687] fix https://github.com/acmesh-official/acme.sh/issues/4835 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 34291708..3fdaa804 100755 --- a/acme.sh +++ b/acme.sh @@ -931,7 +931,7 @@ fi _egrep_o() { if [ "$__USE_EGREP" ]; then - egrep -o -- "$1" + egrep -o -- "$1" 2>/dev/null else sed -n 's/.*\('"$1"'\).*/\1/p' fi From 8ca5ca6594227b473edc8882753371c6176e6f0e Mon Sep 17 00:00:00 2001 From: podguzovvasily Date: Tue, 24 Oct 2023 16:58:47 +0300 Subject: [PATCH 232/687] Update haproxy.sh resolved issue with HAProxy https://github.com/acmesh-official/acme.sh/issues/4788 according https://serversforhackers.com/c/letsencrypt-with-haproxy --- deploy/haproxy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index c255059d..d638abb8 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -147,7 +147,7 @@ haproxy_deploy() { # Create a temporary PEM file _temppem="$(_mktemp)" _debug _temppem "${_temppem}" - cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}" + cat "${_ccert}" "${_cca}" "${_ckey}" >"${_temppem}" _ret="$?" # Check that we could create the temporary file From 00dbc3881fa377646115a237bb12193f13504973 Mon Sep 17 00:00:00 2001 From: Adnan RIHAN Date: Wed, 1 Nov 2023 20:02:16 +0100 Subject: [PATCH 233/687] Fixed variables --- deploy/proxmoxve.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/proxmoxve.sh b/deploy/proxmoxve.sh index 216a8fc7..f9de590c 100644 --- a/deploy/proxmoxve.sh +++ b/deploy/proxmoxve.sh @@ -99,11 +99,11 @@ proxmoxve_deploy() { _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" fi - _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key + _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY "$_proxmoxve_api_token_key" # PVE API Token header value. Used in "Authorization: PVEAPIToken". _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" - _debug2 "Auth Header" _proxmoxve_header_api_token + _debug2 "Auth Header" "$_proxmoxve_header_api_token" # Ugly. I hate putting heredocs inside functions because heredocs don't # account for whitespace correctly but it _does_ work and is several times @@ -124,8 +124,8 @@ HEREDOC ) _debug2 Payload "$_json_payload" - # Push certificates to server. - export _HTTPS_INSECURE=1 + _info "Push certificates to server" + export HTTPS_INSECURE=1 export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" _post "$_json_payload" "$_target_url" "" POST "application/json" From 199977be6a6785f7507f8ee21fe7d350979909e6 Mon Sep 17 00:00:00 2001 From: Gavin Leo Date: Mon, 30 Oct 2023 11:16:37 +0800 Subject: [PATCH 234/687] Fix https://github.com/acmesh-official/acme.sh/issues/4460 Update gcore API url. --- dnsapi/dns_gcore.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh index d549a650..5f7f037e 100755 --- a/dnsapi/dns_gcore.sh +++ b/dnsapi/dns_gcore.sh @@ -4,8 +4,8 @@ #GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb' # -GCORE_Api="https://api.gcorelabs.com/dns/v2" -GCORE_Doc="https://apidocs.gcore.com/dns" +GCORE_Api="https://api.gcore.com/dns/v2" +GCORE_Doc="https://api.gcore.com/docs/dns" ######## Public functions ##################### From 8454ffa331905efc0e85f70a12a6c1a9dbf5c128 Mon Sep 17 00:00:00 2001 From: Matthew Robinson Date: Thu, 2 Nov 2023 08:30:44 -0700 Subject: [PATCH 235/687] Fix issue with similar domain names causing an error in selecting the proper root domain to add challenge records in --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 50c93260..bb0682a7 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -157,7 +157,7 @@ _get_root() { # iterate over names (a.b.c.d -> b.c.d -> c.d -> d) while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f $i-100 | sed 's/\./\\./g') _debug "Checking domain: $h" if [ -z "$h" ]; then _error "invalid domain" From 5342c7c82b4ef07e0921070d1b1392b094a3644e Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Fri, 3 Nov 2023 18:14:26 +0800 Subject: [PATCH 236/687] support West.cn Domain Signed-off-by: mrbaiwei --- dnsapi/dns_west.sh | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 dnsapi/dns_west.sh diff --git a/dnsapi/dns_west.sh b/dnsapi/dns_west.sh new file mode 100644 index 00000000..6a9ebe5d --- /dev/null +++ b/dnsapi/dns_west.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env sh + +# West.cn Domain api +# +#WEST_Username="uername" +# +#WEST_Key="sADDsdasdgdsf" + +REST_API="https://api.west.cn/API/v2" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_west_add() { + fulldomain=$1 + txtvalue=$2 + + WEST_Username="${WEST_Username:-$(_readaccountconf_mutable WEST_Username)}" + WEST_Key="${WEST_Key:-$(_readaccountconf_mutable WEST_Key)}" + if [ -z "$WEST_Username" ] || [ -z "$WEST_Key" ]; then + WEST_Username="" + WEST_Key="" + _err "You don't specify dnspod api key and key id yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable WEST_Username "$WEST_Username" + _saveaccountconf_mutable WEST_Key "$WEST_Key" + + add_record "$fulldomain" "$txtvalue" +} + +#Usage: rm _acme-challenge.www.domain.com +dns_west_rm() { + fulldomain=$1 + txtvalue=$2 + + WEST_Username="${WEST_Username:-$(_readaccountconf_mutable WEST_Username)}" + WEST_Key="${WEST_Key:-$(_readaccountconf_mutable WEST_Key)}" + + if ! _rest POST "domain/dns/" "act=dnsrec.list&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT"; then + _err "Record.Lis error." + return 1 + fi + + if _contains "$response" 'no records'; then + _info "Don't need to remove." + return 0 + fi + + record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"record_id"' | cut -d : -f 2 | cut -d ',' -f 1) + _debug record_id "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id." + return 1 + fi + + if ! _rest POST "domain/dns/" "act=dnsrec.remove&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_id=$record_id"; then + _err "Record.Remove error." + return 1 + fi + + _contains "$response" "success" + + +} + +#add the txt record. +#usage: add fulldomain txtvalue +add_record() { + fulldomain=$1 + txtvalue=$2 + + _info "Adding record" + + if ! _rest POST "domain/dns/" "act=dnsrec.add&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT&value=$txtvalue"; then + return 1 + fi + + _contains "$response" "success" +} + +#Usage: method URI data +_rest() { + m="$1" + ep="$2" + data="$3" + _debug "$ep" + url="$REST_API/$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d '\r')" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d '\r')" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 6ea09444ec792f2f4e690cc2fb479e669cae4e7e Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Sat, 4 Nov 2023 00:04:05 +0800 Subject: [PATCH 237/687] Update dns_west.sh Signed-off-by: mrbaiwei --- dnsapi/dns_west.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_west.sh b/dnsapi/dns_west.sh index 6a9ebe5d..1ef302ca 100644 --- a/dnsapi/dns_west.sh +++ b/dnsapi/dns_west.sh @@ -2,8 +2,8 @@ # West.cn Domain api # -#WEST_Username="uername" -# +#WEST_Username="username" +# set key at https://www.west.cn/manager/API/APIconfig.asp #WEST_Key="sADDsdasdgdsf" REST_API="https://api.west.cn/API/v2" @@ -63,8 +63,6 @@ dns_west_rm() { fi _contains "$response" "success" - - } #add the txt record. From feffbba6de593693dff8d5c87a7c021b21eadcf1 Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Sat, 4 Nov 2023 14:16:11 +0800 Subject: [PATCH 238/687] Update dns_west.sh Signed-off-by: mrbaiwei --- dnsapi/dns_west.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_west.sh b/dnsapi/dns_west.sh index 1ef302ca..afb50fad 100644 --- a/dnsapi/dns_west.sh +++ b/dnsapi/dns_west.sh @@ -20,8 +20,8 @@ dns_west_add() { if [ -z "$WEST_Username" ] || [ -z "$WEST_Key" ]; then WEST_Username="" WEST_Key="" - _err "You don't specify dnspod api key and key id yet." - _err "Please create you key and try again." + _err "You don't specify west api key and username yet." + _err "Please set you key and try again." return 1 fi @@ -41,7 +41,7 @@ dns_west_rm() { WEST_Key="${WEST_Key:-$(_readaccountconf_mutable WEST_Key)}" if ! _rest POST "domain/dns/" "act=dnsrec.list&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT"; then - _err "Record.Lis error." + _err "dnsrec.list error." return 1 fi @@ -58,7 +58,7 @@ dns_west_rm() { fi if ! _rest POST "domain/dns/" "act=dnsrec.remove&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_id=$record_id"; then - _err "Record.Remove error." + _err "dnsrec.remove error." return 1 fi From 1cc3a13c497d8981dc7c6b700e0b38f8d0469262 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 4 Nov 2023 10:04:26 +0100 Subject: [PATCH 239/687] fix comments --- .github/workflows/pr_dns.yml | 3 ++- .github/workflows/pr_notify.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 5faa9105..b627d3ab 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -22,9 +22,10 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). + Please make sure you've read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). Then reply on this message, otherwise, your code will not be reviewed or merged. We look forward to reviewing your Pull request shortly ✨ + 注意: 必须通过了 [DNS-API-Test](../wiki/DNS-API-Test) 才会被 review. 无论是修改, 还是新加的 dns api, 都必须确保通过这个测试. ` }) diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml index 4844e297..3b0e3e4b 100644 --- a/.github/workflows/pr_notify.yml +++ b/.github/workflows/pr_notify.yml @@ -22,7 +22,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** - Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify). + Please make sure you've read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify). Then reply on this message, otherwise, your code will not be reviewed or merged. We look forward to reviewing your Pull request shortly ✨ ` From a60d0c41087e3b79e60c0c0587c29a0de25c5dee Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Mon, 6 Nov 2023 11:25:09 +0800 Subject: [PATCH 240/687] Update dns_west_cn.sh Signed-off-by: mrbaiwei --- dnsapi/{dns_west.sh => dns_west_cn.sh} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename dnsapi/{dns_west.sh => dns_west_cn.sh} (96%) diff --git a/dnsapi/dns_west.sh b/dnsapi/dns_west_cn.sh similarity index 96% rename from dnsapi/dns_west.sh rename to dnsapi/dns_west_cn.sh index afb50fad..fa723b64 100644 --- a/dnsapi/dns_west.sh +++ b/dnsapi/dns_west_cn.sh @@ -3,15 +3,15 @@ # West.cn Domain api # #WEST_Username="username" -# set key at https://www.west.cn/manager/API/APIconfig.asp #WEST_Key="sADDsdasdgdsf" +#Set key at https://www.west.cn/manager/API/APIconfig.asp REST_API="https://api.west.cn/API/v2" ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_west_add() { +dns_west_cn_add() { fulldomain=$1 txtvalue=$2 @@ -33,7 +33,7 @@ dns_west_add() { } #Usage: rm _acme-challenge.www.domain.com -dns_west_rm() { +dns_west_cn_rm() { fulldomain=$1 txtvalue=$2 From eb99803b53de63bad45cf144621fe5a59892f2d8 Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Mon, 6 Nov 2023 13:18:36 +0800 Subject: [PATCH 241/687] Update west.cn domain api Signed-off-by: mrbaiwei --- dnsapi/dns_west_cn.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_west_cn.sh b/dnsapi/dns_west_cn.sh index fa723b64..bff4598a 100644 --- a/dnsapi/dns_west_cn.sh +++ b/dnsapi/dns_west_cn.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh # West.cn Domain api -# #WEST_Username="username" #WEST_Key="sADDsdasdgdsf" #Set key at https://www.west.cn/manager/API/APIconfig.asp From bea71f34115428299b8c73fd6cc56dedc39697f7 Mon Sep 17 00:00:00 2001 From: mrbaiwei Date: Tue, 7 Nov 2023 07:20:25 +0800 Subject: [PATCH 242/687] Update dns_west_cn.sh Signed-off-by: mrbaiwei --- dnsapi/dns_west_cn.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_west_cn.sh b/dnsapi/dns_west_cn.sh index bff4598a..d0bb7d49 100644 --- a/dnsapi/dns_west_cn.sh +++ b/dnsapi/dns_west_cn.sh @@ -72,7 +72,7 @@ add_record() { _info "Adding record" - if ! _rest POST "domain/dns/" "act=dnsrec.add&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT&value=$txtvalue"; then + if ! _rest POST "domain/dns/" "act=dnsrec.add&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT&record_value=$txtvalue"; then return 1 fi From 15d10eeebcb03884ceddfe2df84d142f7fe43e8d Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Fri, 10 Nov 2023 08:22:28 +0100 Subject: [PATCH 243/687] dns_1984.hosting.sh: update login and account status URLs --- dnsapi/dns_1984hosting.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index 2c6b2e4f..e4ef2e4b 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -128,7 +128,7 @@ _1984hosting_login() { _debug "Login to 1984Hosting as user $One984HOSTING_Username." username=$(printf '%s' "$One984HOSTING_Username" | _url_encode) password=$(printf '%s' "$One984HOSTING_Password" | _url_encode) - url="https://1984.hosting/accounts/checkuserauth/" + url="https://1984.hosting/api/auth/" _get "https://1984.hosting/accounts/login/" | grep "csrfmiddlewaretoken" csrftoken="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')" @@ -185,7 +185,7 @@ _check_cookies() { return 1 fi - _authget "https://1984.hosting/accounts/loginstatus/" + _authget "https://1984.hosting/api/auth/" if _contains "$_response" '"ok": true'; then _debug "Cached cookies still valid." return 0 From 074cf00a7c0cd154a84522881f1386657aa7cc17 Mon Sep 17 00:00:00 2001 From: Sander Cox Date: Tue, 14 Nov 2023 11:28:24 +0100 Subject: [PATCH 244/687] Update dns_gcloud.sh rm logs record added The logs show record was added twice but the second time was actual the rm command thus the removal of the record! --- dnsapi/dns_gcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 2788ad59..dc82c09d 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -42,7 +42,7 @@ dns_gcloud_rm() { echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? _dns_gcloud_execute_tr || return $? - _info "$fulldomain record added" + _info "$fulldomain record removed" } #################### Private functions below ################################## From f899d0d8ed620271756e590ba8c7b38ac19e6177 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 20 Nov 2023 23:39:25 +0100 Subject: [PATCH 245/687] update --- .github/workflows/FreeBSD.yml | 6 +++--- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/NetBSD.yml | 6 +++--- .github/workflows/OpenBSD.yml | 6 +++--- .github/workflows/PebbleStrict.yml | 4 ++-- .github/workflows/Ubuntu.yml | 2 +- .github/workflows/Windows.yml | 2 +- .github/workflows/dockerhub.yml | 2 +- .github/workflows/shellcheck.yml | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index 0fa55fd4..b90c9ccd 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -41,7 +41,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 + runs-on: ubuntu-latest env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -51,7 +51,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: vmactions/cf-tunnel@v0 id: tunnel with: @@ -61,7 +61,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0 + - uses: vmactions/freebsd-vm@v1 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 156fa5df..33e43483 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -33,7 +33,7 @@ jobs: TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 TEST_ACME_Server: "LetsEncrypt.org_test" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: | cd .. \ diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index c1f29769..c3f046ab 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -44,7 +44,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install tools run: brew install socat - name: Clone acmetest diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 25872c42..e9301860 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -36,7 +36,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 + runs-on: ubuntu-latest env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -45,7 +45,7 @@ jobs: CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: vmactions/cf-tunnel@v0 id: tunnel with: @@ -55,7 +55,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0 + - uses: vmactions/netbsd-vm@v1 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' nat: | diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index 745a9408..e141c47b 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -41,7 +41,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 + runs-on: ubuntu-latest env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -51,7 +51,7 @@ jobs: TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: vmactions/cf-tunnel@v0 id: tunnel with: @@ -61,7 +61,7 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0 + - uses: vmactions/openbsd-vm@v1 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 9f3a98ce..3f8fdb62 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -33,7 +33,7 @@ jobs: TEST_CA: "Pebble Intermediate CA" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble @@ -58,7 +58,7 @@ jobs: TEST_IPCERT: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 4bf2ba29..53cc1060 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -70,7 +70,7 @@ jobs: TestingDomain: ${{ matrix.TestingDomain }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install tools run: sudo apt-get install -y socat wget - name: Start StepCA diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index c02e2f77..61ef5ad8 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -49,7 +49,7 @@ jobs: - name: Set git to use LF run: | git config --global core.autocrlf false - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 48c44429..ea446d84 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -41,7 +41,7 @@ jobs: if: "contains(needs.CheckToken.outputs.hasToken, 'true')" steps: - name: checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index a5a08bbf..746727d4 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -22,7 +22,7 @@ jobs: ShellCheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Shellcheck run: sudo apt-get install -y shellcheck - name: DoShellcheck @@ -31,7 +31,7 @@ jobs: shfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install shfmt run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt - name: shfmt From f364d4fbefa8fca1b8e78745247d916a96241c5e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 21 Nov 2023 08:45:54 +0100 Subject: [PATCH 246/687] fix --- .github/workflows/NetBSD.yml | 142 +++++++++++++++++------------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index e9301860..e5206913 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -1,71 +1,71 @@ -name: NetBSD -on: - push: - branches: - - '*' - paths: - - '*.sh' - - '.github/workflows/NetBSD.yml' - - pull_request: - branches: - - dev - paths: - - '*.sh' - - '.github/workflows/NetBSD.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - - - -jobs: - NetBSD: - strategy: - matrix: - include: - - TEST_ACME_Server: "LetsEncrypt.org_test" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - #- TEST_ACME_Server: "ZeroSSL.com" - # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - # CA: "ZeroSSL RSA Domain Secure Site CA" - # CA_EMAIL: "githubtest@acme.sh" - # TEST_PREFERRED_CHAIN: "" - runs-on: ubuntu-latest - env: - TEST_LOCAL: 1 - TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} - steps: - - uses: actions/checkout@v4 - - uses: vmactions/cf-tunnel@v0 - id: tunnel - with: - protocol: http - port: 8080 - - name: Set envs - run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - - name: Clone acmetest - run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v1 - with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' - nat: | - "8080": "80" - prepare: | - pkg_add curl socat - usesh: true - copyback: false - run: | - cd ../acmetest \ - && ./letest.sh - - +name: NetBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/NetBSD.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/NetBSD.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + + + +jobs: + NetBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" + runs-on: ubuntu-latest + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + steps: + - uses: actions/checkout@v4 + - uses: vmactions/cf-tunnel@v0 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/netbsd-vm@v1 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + nat: | + "8080": "80" + prepare: | + pkg_add curl socat + usesh: true + copyback: false + run: | + cd ../acmetest \ + && ./letest.sh + + From a4bd89c93857eeed29653978aee66da753119f95 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 21 Nov 2023 09:00:22 +0100 Subject: [PATCH 247/687] fix --- .github/workflows/NetBSD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index e5206913..a5565d09 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -61,7 +61,7 @@ jobs: nat: | "8080": "80" prepare: | - pkg_add curl socat + /usr/sbin/pkg_add curl socat usesh: true copyback: false run: | From 7aaf4432d4068ec10dff5447d5843957f729de0a Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 30 Nov 2023 11:49:54 +0100 Subject: [PATCH 248/687] haproxy: sanitize the PEM in the deploy script Sanitize the PEM of the haproxy deploy script by removing the '\n', this way it could be injected directly over the CLI. --- deploy/haproxy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index d638abb8..6c1b4a68 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -147,7 +147,7 @@ haproxy_deploy() { # Create a temporary PEM file _temppem="$(_mktemp)" _debug _temppem "${_temppem}" - cat "${_ccert}" "${_cca}" "${_ckey}" >"${_temppem}" + cat "${_ccert}" "${_cca}" "${_ckey}" | grep . >"${_temppem}" _ret="$?" # Check that we could create the temporary file From 0f7be905004fba8b6d4ec59354dd623ce8aa5c33 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 16 Mar 2023 17:24:24 +0100 Subject: [PATCH 249/687] haproxy: deploy script can update existing certificate over stats socket Since version 2.2, HAProxy is able to update dynamically certificates, without a reload. This patch uses socat to push the certificate into HAProxy in order to achieve hot update. With this method, reloading is not required. This should be used only to update an existing certificate in haproxy. 2 new variables are available: - DEPLOY_HAPROXY_HOT_UPDATE="yes" update over the stats socket instead of reloading - DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" set the path on the stats socket. --- deploy/haproxy.sh | 80 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 6c1b4a68..f6ddd7b9 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -36,6 +36,14 @@ # Note: This functionality requires HAProxy was compiled against # a version of OpenSSL that supports this. # +# export DEPLOY_HAPROXY_HOT_UPDATE="yes" +# export DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" +# +# OPTIONAL: Deploy the certificate over the HAProxy stats socket without +# needing to reload HAProxy. Default is "no". +# +# Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat +# address format. ######## Public functions ##################### @@ -53,6 +61,8 @@ haproxy_deploy() { DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" DEPLOY_HAPROXY_ISSUER_DEFAULT="no" DEPLOY_HAPROXY_RELOAD_DEFAULT="true" + DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT="no" + DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT="UNIX:/run/haproxy/admin.sock" _debug _cdomain "${_cdomain}" _debug _ckey "${_ckey}" @@ -118,6 +128,26 @@ haproxy_deploy() { Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}" fi + # HOT_UPDATE is optional. If not provided then assume "${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_HOT_UPDATE + _debug2 DEPLOY_HAPROXY_HOT_UPDATE "${DEPLOY_HAPROXY_HOT_UPDATE}" + if [ -n "${DEPLOY_HAPROXY_HOT_UPDATE}" ]; then + Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE}" + _savedomainconf Le_Deploy_haproxy_hot_update "${Le_Deploy_haproxy_hot_update}" + elif [ -z "${Le_Deploy_haproxy_hot_update}" ]; then + Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}" + fi + + # STATS_SOCKET is optional. If not provided then assume "${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}" + _getdeployconf DEPLOY_HAPROXY_STATS_SOCKET + _debug2 DEPLOY_HAPROXY_STATS_SOCKET "${DEPLOY_HAPROXY_STATS_SOCKET}" + if [ -n "${DEPLOY_HAPROXY_STATS_SOCKET}" ]; then + Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET}" + _savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}" + elif [ -z "${Le_Deploy_haproxy_stats_socket}" ]; then + Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}" + fi + # Set the suffix depending if we are creating a bundle or not if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then _info "Bundle creation requested" @@ -142,6 +172,7 @@ haproxy_deploy() { _issuer="${_pem}.issuer" _ocsp="${_pem}.ocsp" _reload="${Le_Deploy_haproxy_reload}" + _statssock="${Le_Deploy_haproxy_stats_socket}" _info "Deploying PEM file" # Create a temporary PEM file @@ -265,15 +296,48 @@ haproxy_deploy() { fi fi - # Reload HAProxy - _debug _reload "${_reload}" - eval "${_reload}" - _ret=$? - if [ "${_ret}" != "0" ]; then - _err "Error code ${_ret} during reload" - return ${_ret} + if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then + # Update certificate over HAProxy stats socket. + _info "Update the certificate over HAProxy stats socket." + if _exists socat; then + _socat_cert_cmd="echo 'show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'" + _debug _socat_cert_cmd "${_socat_cert_cmd}" + eval "${_socat_cert_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Couldn't find '${_pem}' in haproxy 'show ssl cert'" + return "${_ret}" + fi + _socat_cert_set_cmd="echo -e 'set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'" + _debug _socat_cert_set_cmd "${_socat_cert_set_cmd}" + eval "${_socat_cert_set_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Can't update '${_pem}' in haproxy" + return "${_ret}" + fi + _socat_cert_commit_cmd="echo 'commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'" + _debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}" + eval "${_socat_cert_commit_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Can't commit '${_pem}' in haproxy" + return ${_ret} + fi + else + _err "'socat' is not available, couldn't update over stats socket" + fi else - _info "Reload successful" + # Reload HAProxy + _debug _reload "${_reload}" + eval "${_reload}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Error code ${_ret} during reload" + return ${_ret} + else + _info "Reload successful" + fi fi return 0 From 98a7a01dbb85ec7e8ca2fa60497b6f7db70add98 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 6 Apr 2023 16:14:44 +0200 Subject: [PATCH 250/687] haproxy: deploy script can add a new certificate over the stats socket DEPLOY_HAPROXY_HOT_UPDATE="yes" now allows to add a new certificate within HAProxy instead of updating an existing one. In order to work, the ${DEPLOY_HAPROXY_PEM_PATH} value must be used as a parameter to the "crt" keyword in the haproxy configuration. The patch uses the following commands over HAProxy stats socket: - show ssl cert - new ssl cert - set ssl cert - commit ssl cert - add ssl crt-list --- deploy/haproxy.sh | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index f6ddd7b9..b4c021d5 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -298,15 +298,35 @@ haproxy_deploy() { if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then # Update certificate over HAProxy stats socket. - _info "Update the certificate over HAProxy stats socket." if _exists socat; then + # look for the certificate on the stats socket, to chose between updating or creating one _socat_cert_cmd="echo 'show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'" _debug _socat_cert_cmd "${_socat_cert_cmd}" eval "${_socat_cert_cmd}" _ret=$? if [ "${_ret}" != "0" ]; then - _err "Couldn't find '${_pem}' in haproxy 'show ssl cert'" - return "${_ret}" + _newcert="1" + _info "Creating new certificate '${_pem}' over HAProxy stats socket." + # certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate. + _socat_crtlist_show_cmd="echo 'show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'" + _debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}" + eval "${_socat_crtlist_show_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Couldn't find '${Le_Deploy_haproxy_pem_path}' in haproxy 'show ssl crt-list'" + return "${_ret}" + fi + # create a new certificate + _socat_new_cmd="echo 'new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'" + _debug _socat_new_cmd "${_socat_new_cmd}" + eval "${_socat_new_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Couldn't create '${_pem}' in haproxy" + return "${_ret}" + fi + else + _info "Update existing certificate '${_pem}' over HAProxy stats socket." fi _socat_cert_set_cmd="echo -e 'set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'" _debug _socat_cert_set_cmd "${_socat_cert_set_cmd}" @@ -324,6 +344,17 @@ haproxy_deploy() { _err "Can't commit '${_pem}' in haproxy" return ${_ret} fi + if [ "${_newcert}" = "1" ]; then + # if this is a new certificate, it needs to be inserted into the crt-list` + _socat_cert_add_cmd="echo 'add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'" + _debug _socat_cert_add_cmd "${_socat_cert_add_cmd}" + eval "${_socat_cert_add_cmd}" + _ret=$? + if [ "${_ret}" != "0" ]; then + _err "Can't update '${_pem}' in haproxy" + return "${_ret}" + fi + fi else _err "'socat' is not available, couldn't update over stats socket" fi From 36fc3210967c839884bea8e2f90a4bdf180c89a2 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 30 Nov 2023 15:22:51 +0100 Subject: [PATCH 251/687] haproxy: use the master CLI for hot update DEPLOY_HAPROXY_MASTER_CLI allows to use the HAProxy master CLI instead of a stats socket for DEPLOY_HAPROXY_HOT_UPDATE="yes" The syntax of the master CLI is slightly different, a prefix with the process number need to be added before any command. This patch uses ${_cmdpfx} in front of every socat commands which is filled when the master CLI is used. --- deploy/haproxy.sh | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index b4c021d5..ef7fe45e 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -44,6 +44,11 @@ # # Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat # address format. +# +# export DEPLOY_HAPROXY_MASTER_CLI="UNIX:/run/haproxy-master.sock" +# +# OPTIONAL: To use the master CLI with DEPLOY_HAPROXY_HOT_UPDATE="yes" instead +# of a stats socket, use this variable. ######## Public functions ##################### @@ -54,6 +59,7 @@ haproxy_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _cmdpfx="" # Some defaults DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy" @@ -148,6 +154,16 @@ haproxy_deploy() { Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}" fi + # MASTER_CLI is optional. No defaults are used. When the master CLI is used, + # all commands are sent with a prefix. + _getdeployconf DEPLOY_HAPROXY_MASTER_CLI + _debug2 DEPLOY_HAPROXY_MASTER_CLI "${DEPLOY_HAPROXY_MASTER_CLI}" + if [ -n "${DEPLOY_HAPROXY_MASTER_CLI}" ]; then + Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_MASTER_CLI}" + _savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}" + _cmdpfx="@1 " # command prefix used for master CLI only. + fi + # Set the suffix depending if we are creating a bundle or not if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then _info "Bundle creation requested" @@ -297,18 +313,25 @@ haproxy_deploy() { fi if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then - # Update certificate over HAProxy stats socket. + # set the socket name for messages + if [ -n "${_cmdpfx}" ]; then + _socketname="master CLI" + else + _socketname="stats socket" + fi + + # Update certificate over HAProxy stats socket or master CLI. if _exists socat; then # look for the certificate on the stats socket, to chose between updating or creating one - _socat_cert_cmd="echo 'show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'" + _socat_cert_cmd="echo '${_cmdpfx}show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'" _debug _socat_cert_cmd "${_socat_cert_cmd}" eval "${_socat_cert_cmd}" _ret=$? if [ "${_ret}" != "0" ]; then _newcert="1" - _info "Creating new certificate '${_pem}' over HAProxy stats socket." + _info "Creating new certificate '${_pem}' over HAProxy ${_socketname}." # certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate. - _socat_crtlist_show_cmd="echo 'show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'" + _socat_crtlist_show_cmd="echo '${_cmdpfx}show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'" _debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}" eval "${_socat_crtlist_show_cmd}" _ret=$? @@ -317,7 +340,7 @@ haproxy_deploy() { return "${_ret}" fi # create a new certificate - _socat_new_cmd="echo 'new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'" + _socat_new_cmd="echo '${_cmdpfx}new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'" _debug _socat_new_cmd "${_socat_new_cmd}" eval "${_socat_new_cmd}" _ret=$? @@ -326,9 +349,9 @@ haproxy_deploy() { return "${_ret}" fi else - _info "Update existing certificate '${_pem}' over HAProxy stats socket." + _info "Update existing certificate '${_pem}' over HAProxy ${_socketname}." fi - _socat_cert_set_cmd="echo -e 'set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'" + _socat_cert_set_cmd="echo -e '${_cmdpfx}set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'" _debug _socat_cert_set_cmd "${_socat_cert_set_cmd}" eval "${_socat_cert_set_cmd}" _ret=$? @@ -336,7 +359,7 @@ haproxy_deploy() { _err "Can't update '${_pem}' in haproxy" return "${_ret}" fi - _socat_cert_commit_cmd="echo 'commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'" + _socat_cert_commit_cmd="echo '${_cmdpfx}commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'" _debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}" eval "${_socat_cert_commit_cmd}" _ret=$? @@ -346,7 +369,7 @@ haproxy_deploy() { fi if [ "${_newcert}" = "1" ]; then # if this is a new certificate, it needs to be inserted into the crt-list` - _socat_cert_add_cmd="echo 'add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'" + _socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'" _debug _socat_cert_add_cmd "${_socat_cert_add_cmd}" eval "${_socat_cert_add_cmd}" _ret=$? @@ -356,7 +379,7 @@ haproxy_deploy() { fi fi else - _err "'socat' is not available, couldn't update over stats socket" + _err "'socat' is not available, couldn't update over ${_socketname}" fi else # Reload HAProxy From e09d45c84475f3d1e223c51787fd35c9fe0bada8 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Fri, 1 Dec 2023 15:29:18 +0100 Subject: [PATCH 252/687] haproxy; don't use '*' in the filename for wildcard domain By default acme.sh uses the '*' character in the filename for wildcard. That can be confusing within HAProxy since the * character in front of a filename in the stat socket is used to specified an uncommitted transaction. This patch replace the '*' by a '_' in the filename. This is only done when using the default filename, the name can still be forced with an asterisk. --- deploy/haproxy.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index ef7fe45e..4b6ca0e1 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -102,6 +102,11 @@ haproxy_deploy() { _savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" + # We better not have '*' as the first character + if [ "${Le_Deploy_haproxy_pem_name%%"${Le_Deploy_haproxy_pem_name#?}"}" = '*' ]; then + # removes the first characters and add a _ instead + Le_Deploy_haproxy_pem_name="_${Le_Deploy_haproxy_pem_name#?}" + fi fi # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" From 3b7bc5a56ad5046b63c747923c510c1e6a51bb95 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 2 Dec 2023 22:50:59 +0100 Subject: [PATCH 253/687] update dragonflybsd-vm@v1 --- .github/workflows/DNS.yml | 32 +++---- .github/workflows/DragonFlyBSD.yml | 142 ++++++++++++++--------------- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 507755c9..6e68df9c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -65,7 +65,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file @@ -113,7 +113,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install tools run: brew install socat - name: Clone acmetest @@ -164,7 +164,7 @@ jobs: - name: Set git to use LF run: | git config --global core.autocrlf false - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install cygwin base packages with chocolatey run: | choco config get cacheLocation @@ -204,7 +204,7 @@ jobs: FreeBSD: - runs-on: macos-12 + runs-on: ubuntu-latest needs: Windows env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -223,10 +223,10 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/freebsd-vm@v0 + - uses: vmactions/freebsd-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg install -y socat curl @@ -255,7 +255,7 @@ jobs: OpenBSD: - runs-on: macos-12 + runs-on: ubuntu-latest needs: FreeBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -274,10 +274,10 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/openbsd-vm@v0 + - uses: vmactions/openbsd-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: pkg_add socat curl @@ -306,7 +306,7 @@ jobs: NetBSD: - runs-on: macos-12 + runs-on: ubuntu-latest needs: OpenBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -325,10 +325,10 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/netbsd-vm@v0 + - uses: vmactions/netbsd-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | @@ -358,7 +358,7 @@ jobs: DragonFlyBSD: - runs-on: macos-12 + runs-on: ubuntu-latest needs: NetBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -377,10 +377,10 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/dragonflybsd-vm@v0 + - uses: vmactions/dragonflybsd-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | @@ -433,7 +433,7 @@ jobs: TokenName4: ${{ secrets.TokenName4}} TokenName5: ${{ secrets.TokenName5}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/solaris-vm@v0 diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 5a0d81ba..3d4f650d 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -1,71 +1,71 @@ -name: DragonFlyBSD -on: - push: - branches: - - '*' - paths: - - '*.sh' - - '.github/workflows/DragonFlyBSD.yml' - - pull_request: - branches: - - dev - paths: - - '*.sh' - - '.github/workflows/DragonFlyBSD.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - - - -jobs: - DragonFlyBSD: - strategy: - matrix: - include: - - TEST_ACME_Server: "LetsEncrypt.org_test" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - #- TEST_ACME_Server: "ZeroSSL.com" - # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - # CA: "ZeroSSL RSA Domain Secure Site CA" - # CA_EMAIL: "githubtest@acme.sh" - # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 - env: - TEST_LOCAL: 1 - TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} - steps: - - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0 - id: tunnel - with: - protocol: http - port: 8080 - - name: Set envs - run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - - name: Clone acmetest - run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/dragonflybsd-vm@v0 - with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' - copyback: "false" - nat: | - "8080": "80" - prepare: | - pkg install -y curl socat libnghttp2 - usesh: true - run: | - cd ../acmetest \ - && ./letest.sh - - +name: DragonFlyBSD +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/DragonFlyBSD.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/DragonFlyBSD.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + + +jobs: + DragonFlyBSD: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" + runs-on: ubuntu-latest + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} + steps: + - uses: actions/checkout@v4 + - uses: vmactions/cf-tunnel@v0 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/dragonflybsd-vm@v1 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + copyback: "false" + nat: | + "8080": "80" + prepare: | + pkg install -y curl socat libnghttp2 + usesh: true + run: | + cd ../acmetest \ + && ./letest.sh + + From a12a3640a7a887bf3695acc08b1e29d4b2342242 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Dec 2023 14:40:32 +0100 Subject: [PATCH 254/687] update --- .github/workflows/DragonFlyBSD.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index 3d4f650d..f360f85c 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -57,13 +57,13 @@ jobs: run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/dragonflybsd-vm@v1 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' - copyback: "false" + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | "8080": "80" prepare: | pkg install -y curl socat libnghttp2 usesh: true + copyback: false run: | cd ../acmetest \ && ./letest.sh From f71d8d7348934e8a4f6835431d74fdd5a1bce0f2 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Dec 2023 14:44:23 +0100 Subject: [PATCH 255/687] minor --- .github/workflows/Solaris.yml | 148 +++++++++++++++++----------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 34d31a59..4ae46d79 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -1,74 +1,74 @@ -name: Solaris -on: - push: - branches: - - '*' - paths: - - '*.sh' - - '.github/workflows/Solaris.yml' - - pull_request: - branches: - - dev - paths: - - '*.sh' - - '.github/workflows/Solaris.yml' - - - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - Solaris: - strategy: - matrix: - include: - - TEST_ACME_Server: "LetsEncrypt.org_test" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - - TEST_ACME_Server: "LetsEncrypt.org_test" - CA_ECDSA: "" - CA: "" - CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 - ACME_USE_WGET: 1 - #- TEST_ACME_Server: "ZeroSSL.com" - # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" - # CA: "ZeroSSL RSA Domain Secure Site CA" - # CA_EMAIL: "githubtest@acme.sh" - # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 - env: - TEST_LOCAL: 1 - TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} - CA_ECDSA: ${{ matrix.CA_ECDSA }} - CA: ${{ matrix.CA }} - CA_EMAIL: ${{ matrix.CA_EMAIL }} - TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} - ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} - steps: - - uses: actions/checkout@v3 - - uses: vmactions/cf-tunnel@v0 - id: tunnel - with: - protocol: http - port: 8080 - - name: Set envs - run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - - name: Clone acmetest - run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0 - with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' - copyback: "false" - nat: | - "8080": "80" - prepare: pkgutil -y -i socat curl wget - run: | - cd ../acmetest \ - && ./letest.sh - +name: Solaris +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/Solaris.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/Solaris.yml' + + + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + Solaris: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" + runs-on: macos-12 + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} + steps: + - uses: actions/checkout@v4 + - uses: vmactions/cf-tunnel@v0 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/solaris-vm@v0 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' + copyback: "false" + nat: | + "8080": "80" + prepare: pkgutil -y -i socat curl wget + run: | + cd ../acmetest \ + && ./letest.sh + From 50f6a459cf66912a01738eaa8db69178f9be03fb Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 4 Dec 2023 09:41:39 +0100 Subject: [PATCH 256/687] update solaris --- .github/workflows/DNS.yml | 4 ++-- .github/workflows/Solaris.yml | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 6e68df9c..95fad2d1 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -413,7 +413,7 @@ jobs: Solaris: - runs-on: macos-12 + runs-on: ubuntu-latest needs: DragonFlyBSD env: TEST_DNS : ${{ secrets.TEST_DNS }} @@ -436,7 +436,7 @@ jobs: - uses: actions/checkout@v4 - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0 + - uses: vmactions/solaris-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' copyback: false diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index 4ae46d79..bdd3f040 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -14,12 +14,12 @@ on: - '*.sh' - '.github/workflows/Solaris.yml' - - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true + + jobs: Solaris: strategy: @@ -41,7 +41,7 @@ jobs: # CA: "ZeroSSL RSA Domain Secure Site CA" # CA_EMAIL: "githubtest@acme.sh" # TEST_PREFERRED_CHAIN: "" - runs-on: macos-12 + runs-on: ubuntu-latest env: TEST_LOCAL: 1 TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} @@ -61,14 +61,15 @@ jobs: run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV - name: Clone acmetest run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - - uses: vmactions/solaris-vm@v0 + - uses: vmactions/solaris-vm@v1 with: envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' - copyback: "false" nat: | "8080": "80" prepare: pkgutil -y -i socat curl wget + copyback: false run: | cd ../acmetest \ && ./letest.sh + From f0ac566c9369cbc64daf72c9c9449d20c181fb04 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 4 Dec 2023 23:51:06 +0100 Subject: [PATCH 257/687] add Omnios --- .github/workflows/DNS.yml | 51 ++++++++++++++++++++++++ .github/workflows/Omnios.yml | 75 ++++++++++++++++++++++++++++++++++++ README.md | 2 +- 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/Omnios.yml diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 95fad2d1..9373fdaf 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -463,3 +463,54 @@ jobs: ./letest.sh + Omnios: + runs-on: ubuntu-latest + needs: DragonFlyBSD + env: + TEST_DNS : ${{ secrets.TEST_DNS }} + TestingDomain: ${{ secrets.TestingDomain }} + TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }} + TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }} + TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }} + CASE: le_test_dnsapi + TEST_LOCAL: 1 + DEBUG: ${{ secrets.DEBUG }} + http_proxy: ${{ secrets.http_proxy }} + https_proxy: ${{ secrets.https_proxy }} + HTTPS_INSECURE: 1 # always set to 1 to ignore https error, since Omnios doesn't accept the expired ISRG X1 root + TokenName1: ${{ secrets.TokenName1}} + TokenName2: ${{ secrets.TokenName2}} + TokenName3: ${{ secrets.TokenName3}} + TokenName4: ${{ secrets.TokenName4}} + TokenName5: ${{ secrets.TokenName5}} + steps: + - uses: actions/checkout@v4 + - name: Clone acmetest + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/omnios-vm@v1 + with: + envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' + copyback: false + prepare: pkgutil -y -i socat + run: | + pkg set-mediator -v -I default@1.1 openssl + export PATH=/usr/gnu/bin:$PATH + if [ "${{ secrets.TokenName1}}" ] ; then + export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" + fi + if [ "${{ secrets.TokenName2}}" ] ; then + export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" + fi + if [ "${{ secrets.TokenName3}}" ] ; then + export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" + fi + if [ "${{ secrets.TokenName4}}" ] ; then + export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" + fi + if [ "${{ secrets.TokenName5}}" ] ; then + export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" + fi + cd ../acmetest + ./letest.sh + + diff --git a/.github/workflows/Omnios.yml b/.github/workflows/Omnios.yml new file mode 100644 index 00000000..e3da0be8 --- /dev/null +++ b/.github/workflows/Omnios.yml @@ -0,0 +1,75 @@ +name: Omnios +on: + push: + branches: + - '*' + paths: + - '*.sh' + - '.github/workflows/Omnios.yml' + + pull_request: + branches: + - dev + paths: + - '*.sh' + - '.github/workflows/Omnios.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + + +jobs: + Omnios: + strategy: + matrix: + include: + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + - TEST_ACME_Server: "LetsEncrypt.org_test" + CA_ECDSA: "" + CA: "" + CA_EMAIL: "" + TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + ACME_USE_WGET: 1 + #- TEST_ACME_Server: "ZeroSSL.com" + # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" + # CA: "ZeroSSL RSA Domain Secure Site CA" + # CA_EMAIL: "githubtest@acme.sh" + # TEST_PREFERRED_CHAIN: "" + runs-on: ubuntu-latest + env: + TEST_LOCAL: 1 + TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} + CA_ECDSA: ${{ matrix.CA_ECDSA }} + CA: ${{ matrix.CA }} + CA_EMAIL: ${{ matrix.CA_EMAIL }} + TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} + steps: + - uses: actions/checkout@v4 + - uses: vmactions/cf-tunnel@v0 + id: tunnel + with: + protocol: http + port: 8080 + - name: Set envs + run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV + - name: Clone acmetest + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + - uses: vmactions/omnios-vm@v1 + with: + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' + nat: | + "8080": "80" + prepare: pkg install socat wget + copyback: false + run: | + cd ../acmetest \ + && ./letest.sh + + diff --git a/README.md b/README.md index 717ecf5f..a64ba4d7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml) [![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml) [![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml) - +[![Omnios](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml) ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) From f4315e2c6f6ba22185fb92102ee592f824ef8a8e Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 5 Dec 2023 19:33:10 +0100 Subject: [PATCH 258/687] fix _date2time --- .github/workflows/DNS.yml | 4 ++-- acme.sh | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 9373fdaf..bf56c1d6 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -465,7 +465,7 @@ jobs: Omnios: runs-on: ubuntu-latest - needs: DragonFlyBSD + needs: Solaris env: TEST_DNS : ${{ secrets.TEST_DNS }} TestingDomain: ${{ secrets.TestingDomain }} @@ -491,7 +491,7 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' copyback: false - prepare: pkgutil -y -i socat + prepare: pkg install socat run: | pkg set-mediator -v -I default@1.1 openssl export PATH=/usr/gnu/bin:$PATH diff --git a/acme.sh b/acme.sh index 3fdaa804..75030acd 100755 --- a/acme.sh +++ b/acme.sh @@ -1795,6 +1795,10 @@ _date2time() { if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then return fi + #Omnios + if da="$(echo "$1" | tr -d "Z" | tr "T" ' ')" perl -MTime::Piece -e 'print Time::Piece->strptime($ENV{da}, "%Y-%m-%d %H:%M:%S")->epoch, "\n";' 2>/dev/null; then + return + fi _err "Can not parse _date2time $1" return 1 } From 8cb1b6b5d548c5561060087cd81cfd9c8f8ab2fa Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 5 Dec 2023 20:19:40 +0100 Subject: [PATCH 259/687] update --- README.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a64ba4d7..9a5c106b 100644 --- a/README.md +++ b/README.md @@ -73,20 +73,21 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) |7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD |8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD |9|[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD -|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian -|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS -|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE -|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) -|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux -|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora -|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux -|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux -|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia -|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux -|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux -|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 -|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) -|23|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) +|10|[![Omnios](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml)|Omnios +|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian +|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS +|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE +|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl) +|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux +|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora +|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux +|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux +|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia +|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux +|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux +|22|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 +|23|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) +|24|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) Check our [testing project](https://github.com/acmesh-official/acmetest): From f59a92589759de16bf7b639de027309c614dd458 Mon Sep 17 00:00:00 2001 From: LordDarkneo <40838306+LordDarkneo@users.noreply.github.com> Date: Fri, 22 Dec 2023 09:09:29 -0500 Subject: [PATCH 260/687] Update synology_dsm.sh Issue for lougout --- deploy/synology_dsm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 10da861a..5ada76de 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -223,7 +223,8 @@ synology_dsm_deploy() { #################### Private functions below ################################## _logout() { - # Logout to not occupy a permanent session, e.g. in DSM's "Connected Users" widget - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=logout") + # Logout to not occupy a permanent session, e.g. in DSM's "Connected Users" widget + #Edit Darkneo - reuse previous variables to logout properly only for CERT user + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid") _debug3 response "$response" } From 05696d443a59a205d5e0b1b2f06beef35c4cd0a3 Mon Sep 17 00:00:00 2001 From: LordDarkneo <40838306+LordDarkneo@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:34:35 -0500 Subject: [PATCH 261/687] Update synology_dsm.sh #2727 issue when logging out on older version - using variables to unlog only for CERT user --- deploy/synology_dsm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 5ada76de..0dd4d49e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -223,8 +223,7 @@ synology_dsm_deploy() { #################### Private functions below ################################## _logout() { - # Logout to not occupy a permanent session, e.g. in DSM's "Connected Users" widget - #Edit Darkneo - reuse previous variables to logout properly only for CERT user + # Logout SERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables) response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid") _debug3 response "$response" } From 6992659ba9063fc3ed8d912ab0cf6d8e8a353d2c Mon Sep 17 00:00:00 2001 From: LordDarkneo <40838306+LordDarkneo@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:36:52 -0500 Subject: [PATCH 262/687] Update synology_dsm.sh --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 0dd4d49e..1d945cad 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -223,7 +223,7 @@ synology_dsm_deploy() { #################### Private functions below ################################## _logout() { - # Logout SERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables) + # Logout CERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables) response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid") _debug3 response "$response" } From 112257c49e50a50adec33399579aeb8ef4bd12c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me?= Date: Tue, 26 Dec 2023 01:36:40 +0100 Subject: [PATCH 263/687] Add notification support for ntfy.sh --- notify/ntfy.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 notify/ntfy.sh diff --git a/notify/ntfy.sh b/notify/ntfy.sh new file mode 100644 index 00000000..5761c755 --- /dev/null +++ b/notify/ntfy.sh @@ -0,0 +1,37 @@ +#!/usr/bin/bash + +# support ntfy + +#NTFY_URL="https://ntfy.sh" +#NTFY_TOPIC="xxxxxxxxxxxxx" + +ntfy_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + NTFY_URL="${NTFY_URL:-$(_readaccountconf_mutable NTFY_URL)}" + if [ "$NTFY_URL" ]; then + _saveaccountconf_mutable NTFY_URL "$NTFY_URL" + fi + + NTFY_TOPIC="${NTFY_TOPIC:-$(_readaccountconf_mutable NTFY_TOPIC)}" + if [ "$NTFY_TOPIC" ]; then + _saveaccountconf_mutable NTFY_TOPIC "$NTFY_TOPIC" + fi + + _data="${_subject}. $_content" + response="$(_post "$_data" "$NTFY_URL/$NTFY_TOPIC" "" "POST" "")" + + if [ "$?" = "0" ] && _contains "$response" "expires"; then + _info "ntfy event fired success." + return 0 + fi + + _err "ntfy event fired error." + _err "$response" + return 1 +} From a3612f53dd8c83aed111c5bfc13b9f08e4b6d908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me?= Date: Tue, 26 Dec 2023 01:52:16 +0100 Subject: [PATCH 264/687] change shebang to sh --- notify/ntfy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/ntfy.sh b/notify/ntfy.sh index 5761c755..650d1c74 100644 --- a/notify/ntfy.sh +++ b/notify/ntfy.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env sh # support ntfy From 3ca97d7258204c200eb1fdef32654aff5a23691a Mon Sep 17 00:00:00 2001 From: Dario Pilori Date: Thu, 4 Jan 2024 18:28:05 +0100 Subject: [PATCH 265/687] Remove whitespace in script name in routeros.sh deploy hook --- deploy/routeros.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index c4c9470d..d1779b8d 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -137,7 +137,7 @@ routeros_deploy() { return $_err_code fi - DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \ + DEPLOY_SCRIPT_CMD="/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \ comment=\"generated by routeros deploy script in acme.sh\" \ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\ @@ -158,11 +158,11 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ return $_err_code fi - if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then + if ! _ssh_remote_cmd "/system script run \"LECertDeploy-$_cdomain\""; then return $_err_code fi - if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then + if ! _ssh_remote_cmd "/system script remove \"LECertDeploy-$_cdomain\""; then return $_err_code fi From 97723fbbc92aada0784ea6e0d4050241e4588b5c Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:45:34 +0100 Subject: [PATCH 266/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index f6a134eb..6719b405 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -82,7 +82,7 @@ _lima_get_domain_id() { _lima_get_root "$1" _debug "$domain" - LIMACITY_DOMAINID=$(_get "${APIBASE}/domains.json" | _egrep_o "{\"id\":[0-9]*[^}]*$domain" | _egrep_o "[0-9]*") + LIMACITY_DOMAINID=$(_get "${APIBASE}/domains.json" | _egrep_o ":[0-9]*[^}]*$domain" | _egrep_o "[0-9]*") _debug "$LIMACITY_DOMAINID" if [ -z "$LIMACITY_DOMAINID" ]; then From ab911f1ce91fe821be2482a32f64fb0690d8ff65 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 17:54:23 +0100 Subject: [PATCH 267/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index 6719b405..d7d5223d 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -63,7 +63,7 @@ _lima_get_root() { _lima_get_root=$1 i=1 while true; do - h=$(printf "%s" "$_lima_get_root" | cut -d . -f $i-100) + h=$(printf "%s" "$_lima_get_root" | cut -d . -f $(_math "$i" -100)) _debug h "$h" if [ -z "$h" ]; then #not valid From 7022d27b8ea4e92a4d9d060b2a90bebfcec62202 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 17:58:54 +0100 Subject: [PATCH 268/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index d7d5223d..7a349e2c 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -63,7 +63,7 @@ _lima_get_root() { _lima_get_root=$1 i=1 while true; do - h=$(printf "%s" "$_lima_get_root" | cut -d . -f $(_math "$i" -100)) + h=$(printf "%s" "$_lima_get_root" | cut -d . -f `_math "$i" -100`) _debug h "$h" if [ -z "$h" ]; then #not valid From 42827be7c3a7084d0edbb5656e82e62725654678 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 18:39:28 +0100 Subject: [PATCH 269/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 57 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index 7a349e2c..bec1d7cc 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -59,35 +59,36 @@ dns_limacity_rm() { #################### Private functions below ################################## -_lima_get_root() { - _lima_get_root=$1 - i=1 - while true; do - h=$(printf "%s" "$_lima_get_root" | cut -d . -f `_math "$i" -100`) - _debug h "$h" - if [ -z "$h" ]; then - #not valid - return 0 - fi - - if _contains "$h" "\."; then - domain=$h - fi - - i=$(_math "$i" + 1) - done -} - _lima_get_domain_id() { - _lima_get_root "$1" + domain="$1" _debug "$domain" - - LIMACITY_DOMAINID=$(_get "${APIBASE}/domains.json" | _egrep_o ":[0-9]*[^}]*$domain" | _egrep_o "[0-9]*") - - _debug "$LIMACITY_DOMAINID" - if [ -z "$LIMACITY_DOMAINID" ]; then - return 1 + i=2 + p=1 + + response=$(_get "${APIBASE}/domains.json") + if "$response"; then + response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" + if [ "$hostedzone" ]; then + LIMACITY_DOMAINID=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$LIMACITY_DOMAINID" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done fi - - return 0 + return 1 } From 7b7c834b087bdfa670c7b78736e33d7b91a48ae4 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 19:48:14 +0100 Subject: [PATCH 270/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index bec1d7cc..d6989d51 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -65,9 +65,9 @@ _lima_get_domain_id() { i=2 p=1 - response=$(_get "${APIBASE}/domains.json") - if "$response"; then - response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" + domains=$(_get "${APIBASE}/domains.json") + if [ "$(echo "$domains" | _egrep_o "^\{\"domains\"")" ] ; then + response="$(echo "$domains" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" @@ -76,7 +76,7 @@ _lima_get_domain_id() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "{.*\"unicode_fqdn\":\s*\"$h\".*}")" if [ "$hostedzone" ]; then LIMACITY_DOMAINID=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$LIMACITY_DOMAINID" ]; then From ad5acb80fe32f388cb202d075e0ffcc41f12a4c1 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:33:01 +0100 Subject: [PATCH 271/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index d6989d51..5fa6853b 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -66,7 +66,7 @@ _lima_get_domain_id() { p=1 domains=$(_get "${APIBASE}/domains.json") - if [ "$(echo "$domains" | _egrep_o "^\{\"domains\"")" ] ; then + if [ "$(echo "$domains" | _egrep_o "^\{\"domains\"")" ]; then response="$(echo "$domains" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From b79c3f5cc4eff383f501ad31d60843b84a6b2b21 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 12 Jan 2024 20:36:49 +0100 Subject: [PATCH 272/687] fix pkg_add --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index bf56c1d6..7fd7c45c 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -332,7 +332,7 @@ jobs: with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' prepare: | - pkg_add curl socat + /usr/sbin/pkg_add curl socat usesh: true copyback: false run: | From 9e073c954d2e2e30f381ae94072d38d4d80196d1 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:39:44 +0100 Subject: [PATCH 273/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index 5fa6853b..f497e396 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -51,7 +51,7 @@ dns_limacity_rm() { if ! _lima_get_domain_id "$fulldomain"; then return 1; fi for recordId in $(_get "${APIBASE}/domains/${LIMACITY_DOMAINID}/records.json" | _egrep_o "{\"id\":[0-9]*[^}]*,\"name\":\"${fulldomain}\"" | _egrep_o "[0-9]*"); do - _post "" "https://www.lima-city.de/usercp/domains/${LIMACITY_DOMAINID}/records/${recordId}" "" "DELETE" + _post "" "${APIBASE}/domains/${LIMACITY_DOMAINID}/records/${recordId}" "" "DELETE" done return 0 @@ -66,7 +66,7 @@ _lima_get_domain_id() { p=1 domains=$(_get "${APIBASE}/domains.json") - if [ "$(echo "$domains" | _egrep_o "^\{\"domains\"")" ]; then + if [ "$(echo "$domains" | _egrep_o "{.*\"domains\"")" ]; then response="$(echo "$domains" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) From 85e3ecfe0b47dd1dd0e2bd0f926d30d3eed230cd Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 13 Jan 2024 20:28:21 +0100 Subject: [PATCH 274/687] fix omnios --- .github/workflows/DNS.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 7fd7c45c..727ba315 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -493,8 +493,6 @@ jobs: copyback: false prepare: pkg install socat run: | - pkg set-mediator -v -I default@1.1 openssl - export PATH=/usr/gnu/bin:$PATH if [ "${{ secrets.TokenName1}}" ] ; then export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" fi From bfb41ce12327ccd49fd7ef0b4d077d2f1a6506e7 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 12 Jan 2024 15:38:52 -0600 Subject: [PATCH 275/687] Fix acmesh-official#4836 (Switch to new Gandi LiveDNS API) 1. Updated LiveDNS API URL for the new API to allow Personal Access Tokens to work 2. Updated authorization header syntax to allow deprecated API Keys to work with the new API 3. Removed white space in JSON response parsing to match responses returned by the server --- dnsapi/dns_gandi_livedns.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index 14939d7c..6092f45c 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -13,7 +13,7 @@ # ######## Public functions ##################### -GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5" +GANDI_LIVEDNS_API="https://api.gandi.net/v5/livedns" #Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_gandi_livedns_add() { @@ -78,7 +78,7 @@ dns_gandi_livedns_rm() { _gandi_livedns_rest PUT \ "domains/$_domain/records/$_sub_domain/TXT" \ "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && - _contains "$response" '{"message": "DNS Record Created"}' && + _contains "$response" '{"message":"DNS Record Created"}' && _info "Removing record $(__green "success")" } @@ -134,7 +134,7 @@ _dns_gandi_append_record() { _debug new_rrset_values "$_rrset_values" _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && - _contains "$response" '{"message": "DNS Record Created"}' && + _contains "$response" '{"message":"DNS Record Created"}' && _info "Adding record $(__green "success")" } @@ -144,11 +144,11 @@ _dns_gandi_existing_rrset_values() { if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then return 1 fi - if ! _contains "$response" '"rrset_type": "TXT"'; then + if ! _contains "$response" '"rrset_type":"TXT"'; then _debug "Does not have a _acme-challenge TXT record yet." return 1 fi - if _contains "$response" '"rrset_values": \[\]'; then + if _contains "$response" '"rrset_values":\[\]'; then _debug "Empty rrset_values for TXT record, no previous TXT record." return 1 fi @@ -169,7 +169,7 @@ _gandi_livedns_rest() { if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then export _H2="Authorization: Bearer $GANDI_LIVEDNS_TOKEN" else - export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY" + export _H2="Authorization: Apikey $GANDI_LIVEDNS_KEY" fi if [ "$m" = "GET" ]; then From 122dfa12acea1e6f378a407c4a61da3ece186023 Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Tue, 30 Jan 2024 15:51:55 -0800 Subject: [PATCH 276/687] add imdsv2 support to dns_aws --- dnsapi/dns_aws.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index bb0682a7..e3b8e28b 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -207,6 +207,65 @@ _use_container_role() { } _use_instance_role() { + # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html + # https://aws.amazon.com/blogs/security/get-the-full-benefits-of-imdsv2-and-disable-imdsv1-across-your-aws-infrastructure/ + _url="http://169.254.169.254/latest/meta-data/" + _response=$(curl --write-out "%{http_code}\n" -s -HEAD $_url) + _debug "_response" "$_response" + if [ "$_response" -eq "401" ]; then + _use_imdsv2_instance_role + else + _use_imdsv1_instance_role + fi +} + +_use_imdsv2_instance_role() { + _request_token_url="http://169.254.169.254/latest/api/token" + _instance_role_url="http://169.254.169.254/latest/meta-data/iam" + _request_token="$(curl -s -X PUT "$_request_token_url" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")" + _debug "_request_token" "$_request_token" + if [ -z "$_request_token" ]; then + _debug "Unable to fetch IMDSv2 token from instance metadata" + return 1 + fi + _instance_role_name="$(curl -s -H "X-aws-ec2-metadata-token: $_request_token" http://169.254.169.254/latest/meta-data/iam/security-credentials/)" + _debug "_instance_role_name" "$_instance_role_name" + if [ -z "$_instance_role_name" ]; then + _debug "Unable to fetch instance role name from instance metadata" + return 1 + fi + _use_metadata_imdsv2 "http://169.254.169.254/latest/meta-data/iam/security-credentials/$_instance_role_name" "$_request_token" +} + +_use_metadata_imdsv2() { + _aws_creds="$( + curl -s -H "X-aws-ec2-metadata-token: $2" "$1" | + _normalizeJson | + tr '{,}' '\n' | + while read -r _line; do + _key="$(echo "${_line%%:*}" | tr -d '"')" + _value="${_line#*:}" + _debug3 "_key" "$_key" + _secure_debug3 "_value" "$_value" + case "$_key" in + AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; + SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; + Token) echo "AWS_SESSION_TOKEN=$_value" ;; + esac + done | + paste -sd' ' - + )" + _secure_debug "_aws_creds" "$_aws_creds" + + if [ -z "$_aws_creds" ]; then + return 1 + fi + + eval "$_aws_creds" + _using_role=true +} + +_use_imdsv1_instance_role() { _url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" _debug "_url" "$_url" if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then @@ -215,10 +274,10 @@ _use_instance_role() { fi _aws_role=$(_get "$_url" "" 1) _debug "_aws_role" "$_aws_role" - _use_metadata "$_url$_aws_role" + _use_metadata_imdsv1 "$_url$_aws_role" } -_use_metadata() { +_use_metadata_imdsv1() { _aws_creds="$( _get "$1" "" 1 | _normalizeJson | From 7da9a45c6151150b16e34d4fabdfc5d8c181d294 Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Wed, 31 Jan 2024 15:39:08 -0800 Subject: [PATCH 277/687] combined functions for cleaner code --- dnsapi/dns_aws.sh | 80 +++++++++++------------------------------------ 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index e3b8e28b..7a5ad4b1 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -209,75 +209,33 @@ _use_container_role() { _use_instance_role() { # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html # https://aws.amazon.com/blogs/security/get-the-full-benefits-of-imdsv2-and-disable-imdsv1-across-your-aws-infrastructure/ - _url="http://169.254.169.254/latest/meta-data/" - _response=$(curl --write-out "%{http_code}\n" -s -HEAD $_url) - _debug "_response" "$_response" - if [ "$_response" -eq "401" ]; then - _use_imdsv2_instance_role - else - _use_imdsv1_instance_role + _instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" + #_response=$(curl --write-out "%{http_code}\n" -s -HEAD $_url) + if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then + _debug "Using IMDSv2" + _token_url="http://169.254.169.254/latest/api/token" + export _H1="X-aws-ec2-metadata-token-ttl-seconds: 21600" + _token="$(_post "" "$_token_url" "" "PUT")" + _debug "_token" "$_token" + if [ -z "$_token" ]; then + _debug "Unable to fetch IMDSv2 token from instance metadata" + return 1 + fi + export _H1="X-aws-ec2-metadata-token: $_token" fi -} -_use_imdsv2_instance_role() { - _request_token_url="http://169.254.169.254/latest/api/token" - _instance_role_url="http://169.254.169.254/latest/meta-data/iam" - _request_token="$(curl -s -X PUT "$_request_token_url" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")" - _debug "_request_token" "$_request_token" - if [ -z "$_request_token" ]; then - _debug "Unable to fetch IMDSv2 token from instance metadata" + if ! _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 200; then + _debug "Unable to fetch IAM role from instance metadata" return 1 fi - _instance_role_name="$(curl -s -H "X-aws-ec2-metadata-token: $_request_token" http://169.254.169.254/latest/meta-data/iam/security-credentials/)" + _instance_role_name=$(_get "$_instance_role_name_url" "" 1) _debug "_instance_role_name" "$_instance_role_name" - if [ -z "$_instance_role_name" ]; then - _debug "Unable to fetch instance role name from instance metadata" - return 1 - fi - _use_metadata_imdsv2 "http://169.254.169.254/latest/meta-data/iam/security-credentials/$_instance_role_name" "$_request_token" -} -_use_metadata_imdsv2() { - _aws_creds="$( - curl -s -H "X-aws-ec2-metadata-token: $2" "$1" | - _normalizeJson | - tr '{,}' '\n' | - while read -r _line; do - _key="$(echo "${_line%%:*}" | tr -d '"')" - _value="${_line#*:}" - _debug3 "_key" "$_key" - _secure_debug3 "_value" "$_value" - case "$_key" in - AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;; - SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;; - Token) echo "AWS_SESSION_TOKEN=$_value" ;; - esac - done | - paste -sd' ' - - )" - _secure_debug "_aws_creds" "$_aws_creds" - - if [ -z "$_aws_creds" ]; then - return 1 - fi - - eval "$_aws_creds" - _using_role=true -} - -_use_imdsv1_instance_role() { - _url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" - _debug "_url" "$_url" - if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then - _debug "Unable to fetch IAM role from instance metadata" - return 1 - fi - _aws_role=$(_get "$_url" "" 1) - _debug "_aws_role" "$_aws_role" - _use_metadata_imdsv1 "$_url$_aws_role" + _use_metadata "$_instance_role_name_url$_instance_role_name" "$_token" } -_use_metadata_imdsv1() { +_use_metadata() { + export _H1="X-aws-ec2-metadata-token: $2" _aws_creds="$( _get "$1" "" 1 | _normalizeJson | From bd247c35f2303a6ff8635dc378be52cdd9a09d04 Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Wed, 31 Jan 2024 15:48:44 -0800 Subject: [PATCH 278/687] remove comments --- dnsapi/dns_aws.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 7a5ad4b1..c87a7012 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -210,7 +210,6 @@ _use_instance_role() { # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html # https://aws.amazon.com/blogs/security/get-the-full-benefits-of-imdsv2-and-disable-imdsv1-across-your-aws-infrastructure/ _instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" - #_response=$(curl --write-out "%{http_code}\n" -s -HEAD $_url) if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then _debug "Using IMDSv2" _token_url="http://169.254.169.254/latest/api/token" From b9157e29cb803e39448cf0ecd68f56e81076be5b Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Wed, 31 Jan 2024 15:52:59 -0800 Subject: [PATCH 279/687] spacing cleanup --- dnsapi/dns_aws.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index c87a7012..855100aa 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -207,15 +207,14 @@ _use_container_role() { } _use_instance_role() { - # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html - # https://aws.amazon.com/blogs/security/get-the-full-benefits-of-imdsv2-and-disable-imdsv1-across-your-aws-infrastructure/ _instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" + if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then _debug "Using IMDSv2" _token_url="http://169.254.169.254/latest/api/token" export _H1="X-aws-ec2-metadata-token-ttl-seconds: 21600" _token="$(_post "" "$_token_url" "" "PUT")" - _debug "_token" "$_token" + _secure_debug3 "_token" "$_token" if [ -z "$_token" ]; then _debug "Unable to fetch IMDSv2 token from instance metadata" return 1 @@ -227,9 +226,9 @@ _use_instance_role() { _debug "Unable to fetch IAM role from instance metadata" return 1 fi + _instance_role_name=$(_get "$_instance_role_name_url" "" 1) _debug "_instance_role_name" "$_instance_role_name" - _use_metadata "$_instance_role_name_url$_instance_role_name" "$_token" } From 22374b81de4ccd73abb89af5ba01a8f8d7bb4a49 Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Wed, 31 Jan 2024 16:02:45 -0800 Subject: [PATCH 280/687] delete a cr to force a workflow run --- dnsapi/dns_aws.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 855100aa..a29cbd1e 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -145,7 +145,6 @@ dns_aws_rm() { fi _sleep 1 return 1 - } #################### Private functions below ################################## From 48e4e41e05353fc470204b86b0135186311ba581 Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Wed, 31 Jan 2024 17:32:56 -0800 Subject: [PATCH 281/687] add cr to force a new gh actions run --- dnsapi/dns_aws.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index a29cbd1e..1df5b21b 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -229,6 +229,7 @@ _use_instance_role() { _instance_role_name=$(_get "$_instance_role_name_url" "" 1) _debug "_instance_role_name" "$_instance_role_name" _use_metadata "$_instance_role_name_url$_instance_role_name" "$_token" + } _use_metadata() { From f8dac5905ce49088995f4c12c36b5bb5842ffb16 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 3 Feb 2024 18:07:50 +0800 Subject: [PATCH 282/687] check the status of Order object and the Authorization object. --- acme.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 75030acd..aa41a1d9 100755 --- a/acme.sh +++ b/acme.sh @@ -4515,7 +4515,7 @@ issue() { vlist="$Le_Vlist" _cleardomainconf "Le_Vlist" - _info "Getting domain auth token for each domain" + _debug "Getting domain auth token for each domain" sep='#' dvsep=',' if [ -z "$vlist" ]; then @@ -4571,12 +4571,22 @@ issue() { if [ "$_notAfter" ]; then _newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\"" fi + _debug "STEP 1, Ordering a Certificate" if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then _err "Create new order error." _clearup _on_issue_err "$_post_hook" return 1 fi + if _contains "$response" "invalid"; then + if echo "$response" | _normalizeJson | grep '"status":"invalid"' >/dev/null 2>&1; then + _err "Create new order with invalid status." + _err "$response" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi + fi Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)" _debug Le_LinkOrder "$Le_LinkOrder" @@ -4601,6 +4611,7 @@ issue() { return 1 fi + _debug "STEP 2, Get the authorizations of each domain" #domain and authz map _authorizations_map="" for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do @@ -4609,6 +4620,7 @@ issue() { _err "get to authz error." _err "_authorizations_seg" "$_authorizations_seg" _err "_authz_url" "$_authz_url" + _err "$response" _clearup _on_issue_err "$_post_hook" return 1 @@ -4616,6 +4628,14 @@ issue() { response="$(echo "$response" | _normalizeJson)" _debug2 response "$response" + if echo "$response" | grep '"status":"invalid"' >/dev/null 2>&1; then + _err "get authz objec with invalid status, please try again later." + _err "_authorizations_seg" "$_authorizations_seg" + _err "$response" + _clearup + _on_issue_err "$_post_hook" + return 1 + fi _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "')" if _contains "$response" "\"wildcard\" *: *true"; then _d="*.$_d" From 3dca67112d4df8d0124617053f1c2bf64e2a9aef Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 3 Feb 2024 18:39:58 +0800 Subject: [PATCH 283/687] fix netbsd --- .github/workflows/NetBSD.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index a5565d09..4574bef5 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -20,7 +20,6 @@ concurrency: - jobs: NetBSD: strategy: @@ -44,6 +43,7 @@ jobs: CA: ${{ matrix.CA }} CA_EMAIL: ${{ matrix.CA_EMAIL }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} + ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} steps: - uses: actions/checkout@v4 - uses: vmactions/cf-tunnel@v0 @@ -57,7 +57,7 @@ jobs: run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - uses: vmactions/netbsd-vm@v1 with: - envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN' + envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' nat: | "8080": "80" prepare: | From 7ec692cdefb3ef3775c3a12e3fe46e147a89c75b Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 3 Feb 2024 23:59:48 +0800 Subject: [PATCH 284/687] fix socat for netbsd: listens to ipv4 by default. --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index aa41a1d9..270a0531 100755 --- a/acme.sh +++ b/acme.sh @@ -2499,10 +2499,10 @@ _startserver() { _debug Le_Listen_V6 "$Le_Listen_V6" _NC="socat" - if [ "$Le_Listen_V4" ]; then - _NC="$_NC -4" - elif [ "$Le_Listen_V6" ]; then + if [ "$Le_Listen_V6" ]; then _NC="$_NC -6" + else + _NC="$_NC -4" fi if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then From 802121d54a28b2a5636878331e494abb76e6ea1a Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 11:42:28 +0800 Subject: [PATCH 285/687] show dns message on any branch --- .github/workflows/pr_dns.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index b627d3ab..645597e8 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -4,8 +4,6 @@ on: pull_request_target: types: - opened - branches: - - 'dev' paths: - 'dnsapi/*.sh' From 99e5c159a7d0fe4cd22ee5fdff2de04f95d67017 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:17:03 +0800 Subject: [PATCH 286/687] check socat "Permission denied" --- acme.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 270a0531..4a3b53a2 100755 --- a/acme.sh +++ b/acme.sh @@ -2519,12 +2519,21 @@ _startserver() { _content_len="$(printf "%s" "$content" | wc -c)" _debug _content_len "$_content_len" _debug "_NC" "$_NC $SOCAT_OPTIONS" + _socaterr="$(_mktemp)" $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \ echo 'HTTP/1.0 200 OK'; \ echo 'Content-Length\: $_content_len'; \ echo ''; \ -printf '%s' '$content';" & +printf '%s' '$content';" 2>"$_socaterr" & serverproc="$!" + if [ -f "$_socaterr" ]; Then + if grep "Permission denied" "$_socaterr" >/dev/null; Then + _err "socat: $(cat $_socaterr)" + _err "Can not listen for user: $(whoami)" + _err "Maybe try with root again?" + return 1 + fi + fi } _stopserver() { From 0084cb7403f6310e005d99ec70443a7190aca8fb Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:18:58 +0800 Subject: [PATCH 287/687] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4a3b53a2..53ff9563 100755 --- a/acme.sh +++ b/acme.sh @@ -2527,7 +2527,7 @@ echo ''; \ printf '%s' '$content';" 2>"$_socaterr" & serverproc="$!" if [ -f "$_socaterr" ]; Then - if grep "Permission denied" "$_socaterr" >/dev/null; Then + if grep "Permission denied" "$_socaterr" >/dev/null; then _err "socat: $(cat $_socaterr)" _err "Can not listen for user: $(whoami)" _err "Maybe try with root again?" From 37e4f35c936621db5cab970ad77b638126458dea Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:21:50 +0800 Subject: [PATCH 288/687] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 53ff9563..36bcbce2 100755 --- a/acme.sh +++ b/acme.sh @@ -2526,7 +2526,7 @@ echo 'Content-Length\: $_content_len'; \ echo ''; \ printf '%s' '$content';" 2>"$_socaterr" & serverproc="$!" - if [ -f "$_socaterr" ]; Then + if [ -f "$_socaterr" ]; then if grep "Permission denied" "$_socaterr" >/dev/null; then _err "socat: $(cat $_socaterr)" _err "Can not listen for user: $(whoami)" From bd6bbba9487d3cf0803e361b2f81307da9c5193a Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:27:06 +0800 Subject: [PATCH 289/687] remove socaterr temp file --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 36bcbce2..320e22af 100755 --- a/acme.sh +++ b/acme.sh @@ -2531,6 +2531,7 @@ printf '%s' '$content';" 2>"$_socaterr" & _err "socat: $(cat $_socaterr)" _err "Can not listen for user: $(whoami)" _err "Maybe try with root again?" + rm -f "$_socaterr" return 1 fi fi From e04093efe2fd9418277260328e211d0cd2df8316 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:31:34 +0800 Subject: [PATCH 290/687] remove socket err temp file --- acme.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 320e22af..38ccaade 100755 --- a/acme.sh +++ b/acme.sh @@ -2519,19 +2519,19 @@ _startserver() { _content_len="$(printf "%s" "$content" | wc -c)" _debug _content_len "$_content_len" _debug "_NC" "$_NC $SOCAT_OPTIONS" - _socaterr="$(_mktemp)" + export _SOCAT_ERR="$(_mktemp)" $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \ echo 'HTTP/1.0 200 OK'; \ echo 'Content-Length\: $_content_len'; \ echo ''; \ -printf '%s' '$content';" 2>"$_socaterr" & +printf '%s' '$content';" 2>"$_SOCAT_ERR" & serverproc="$!" - if [ -f "$_socaterr" ]; then - if grep "Permission denied" "$_socaterr" >/dev/null; then - _err "socat: $(cat $_socaterr)" + if [ -f "$_SOCAT_ERR" ]; then + if grep "Permission denied" "$_SOCAT_ERR" >/dev/null; then + _err "socat: $(cat $_SOCAT_ERR)" _err "Can not listen for user: $(whoami)" _err "Maybe try with root again?" - rm -f "$_socaterr" + rm -f "$_SOCAT_ERR" return 1 fi fi @@ -2541,10 +2541,12 @@ _stopserver() { pid="$1" _debug "pid" "$pid" if [ -z "$pid" ]; then + rm -f "$_SOCAT_ERR" return fi kill $pid + rm -f "$_SOCAT_ERR" } From d76272f0ea102a67563b8728df56b7d8a0d18eb1 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Feb 2024 12:35:07 +0800 Subject: [PATCH 291/687] fix message --- .github/workflows/pr_dns.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml index 645597e8..4d7a325d 100644 --- a/.github/workflows/pr_dns.yml +++ b/.github/workflows/pr_dns.yml @@ -20,6 +20,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: `**Welcome** + First thing: don't send PR to the master branch, please send to the dev branch instead. Please make sure you've read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). Then reply on this message, otherwise, your code will not be reviewed or merged. We look forward to reviewing your Pull request shortly ✨ From 10b4bb598a48613eaadebecd05a9cffc6e1f2e36 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 12 Feb 2024 13:16:08 +0800 Subject: [PATCH 292/687] fix https://github.com/acmesh-official/acme.sh/issues/4995#issuecomment-1937486243 --- acme.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 38ccaade..9c5b1481 100755 --- a/acme.sh +++ b/acme.sh @@ -3195,7 +3195,8 @@ _setNginx() { return 1 fi _info "Check the nginx conf before setting up." - if ! nginx -t >/dev/null; then + if ! nginx -t >/dev/null 2>&1; then + _err "It seems that nginx conf is not correct, cannot continue." return 1 fi @@ -3222,14 +3223,14 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { fi _debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)" _info "nginx conf is done, let's check it again." - if ! nginx -t >/dev/null; then + if ! nginx -t >/dev/null 2>&1; then _err "It seems that nginx conf was broken, let's restore." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi _info "Reload nginx" - if ! nginx -s reload >/dev/null; then + if ! nginx -s reload >/dev/null 2>&1; then _err "It seems that nginx reload error, let's restore." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 From b0ca4435fdbee019ac72f8df0cb304e1de5deffc Mon Sep 17 00:00:00 2001 From: Ciaran Walsh Date: Wed, 21 Feb 2024 00:21:09 +0000 Subject: [PATCH 293/687] Fix for empty error objects in response breaking extraction of domain validation types Fix for empty error objects in the response which mess up the extraction of domain validation types due to the closing brace in the error object prematurely matching the end of the search pattern. This seems to be a recent change with ZeroSSL in particular where "error":{} is being included in responses. There could potentially be a related issue if there is a complex error object ever returned in the validation check response where an embedded sub-object could lead to an incomplete extraction of the error message, roughly around line 5040. Adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 --- acme.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 38ccaade..34ac49e8 100755 --- a/acme.sh +++ b/acme.sh @@ -4722,7 +4722,8 @@ $_authorizations_map" _debug keyauthorization "$keyauthorization" fi - entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + # Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 + entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$keyauthorization" -a -z "$entry" ]; then @@ -6283,7 +6284,8 @@ _deactivate() { fi _debug "Trigger validation." vtype="$(_getIdType "$_d_domain")" - entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + # Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 + entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then _err "Error, can not get domain token $d" From cf3839ececc8d53bb55446958f7345bb1f8f8c4c Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 22 Feb 2024 12:38:51 +0800 Subject: [PATCH 294/687] doc(deploy): update usage doc --- deploy/synology_dsm.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 55898a6f..09d02c2a 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -9,12 +9,13 @@ # Issues: https://github.com/acmesh-official/acme.sh/issues/2727 ################################################################################ # Usage: +# 1. Set required environment variables (two ways): # - Create temp admin user automatically: # export SYNO_USE_TEMP_ADMIN=1 # - Or provide your own admin user credential: # 1. export SYNO_Username="adminUser" # 2. export SYNO_Password="adminPassword" -# Optional exports (shown values are the defaults): +# 2. Set optional environment variables (shown values are the defaults): # - export SYNO_Certificate="" - to replace a specific certificate via description # - export SYNO_Scheme="http" # - export SYNO_Hostname="localhost" @@ -22,7 +23,8 @@ # - export SYNO_Create=1 - to allow creating the certificate if it doesn't exist # - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled # - export SYNO_Device_ID="" - required for skipping 2FA-OTP -# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com +# 3. Run command: +# acme.sh --deploy --deploy-hook synology_dsm -d example.com ################################################################################ # Dependencies: # - jq & curl From f840f7d75b736e9c9cc2166cb194e175ef3e88b0 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Fri, 23 Feb 2024 19:58:24 +0800 Subject: [PATCH 295/687] refactor: unify variable naming convention --- deploy/synology_dsm.sh | 210 ++++++++++++++++++++++------------------- 1 file changed, 115 insertions(+), 95 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 09d02c2a..d39d0c22 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -10,25 +10,26 @@ ################################################################################ # Usage: # 1. Set required environment variables (two ways): -# - Create temp admin user automatically: -# export SYNO_USE_TEMP_ADMIN=1 -# - Or provide your own admin user credential: -# 1. export SYNO_Username="adminUser" -# 2. export SYNO_Password="adminPassword" -# 2. Set optional environment variables (shown values are the defaults): -# - export SYNO_Certificate="" - to replace a specific certificate via description -# - export SYNO_Scheme="http" -# - export SYNO_Hostname="localhost" -# - export SYNO_Port="5000" -# - export SYNO_Create=1 - to allow creating the certificate if it doesn't exist -# - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled -# - export SYNO_Device_ID="" - required for skipping 2FA-OTP +# - Create temp admin user automatically +# `export SYNO_UseTempAdmin=1` +# - Or provide your own admin user credential by: +# 1. `export SYNO_Username="adminUser"` +# 2. `export SYNO_Password="adminPassword"` +# 2. Set optional environment variables (shown values are the defaults) +# - `export SYNO_Scheme="http"` +# - `export SYNO_Hostname="localhost"` +# - `export SYNO_Port="5000"` +# - `export SYNO_Create=1` - to allow creating the cert if it doesn't exist +# - `export SYNO_Certificate=""` - to replace a specific cert by its description +# - `export SYNO_DeviceName=""` - required for 2FA-OTP +# - `export SYNO_DeviceID=""` - required for omitting 2FA-OTP (only pro +# users may set) # 3. Run command: # acme.sh --deploy --deploy-hook synology_dsm -d example.com ################################################################################ # Dependencies: # - jq & curl -# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set) +# - synouser & synogroup (When available and SYNO_UseTempAdmin is set) ################################################################################ # Return value: # 0 means success, otherwise error. @@ -44,53 +45,66 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" - # Get username & password, but don't save until we authenticated successfully - _getdeployconf SYNO_USE_TEMP_ADMIN + # Get username and password, but don't save until we authenticated successfully _getdeployconf SYNO_Username _getdeployconf SYNO_Password + _getdeployconf SYNO_DeviceName + _getdeployconf SYNO_DeviceID _getdeployconf SYNO_Create - _getdeployconf SYNO_DID - _getdeployconf SYNO_TOTP_SECRET - _getdeployconf SYNO_Device_Name + + # ## START ## - DEPRECATED, for backward compatibility _getdeployconf SYNO_Device_ID + _getdeployconf SYNO_Device_Name + [ -n "$SYNO_DeviceID" ] || SYNO_DeviceID="$SYNO_Device_ID" + [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="$SYNO_Device_Name" + # ## END ## - DEPRECATED, for backward compatibility + [ -n "$SYNO_Create" ] || SYNO_Create=1 + + # Prepare to use temp admin if SYNO_UseTempAdmin is set + _getdeployconf SYNO_UseTempAdmin + _debug2 SYNO_UseTempAdmin "$SYNO_UseTempAdmin" - # Prepare temp admin user info if SYNO_USE_TEMP_ADMIN is set - if [ -n "${SYNO_USE_TEMP_ADMIN:-}" ]; then - if ! _exists synouser; then - if ! _exists synogroup; then - _err "Tools are missing for creating temp admin user, please set SYNO_Username & SYNO_Password instead." - return 1 - fi + if [ -n "$SYNO_UseTempAdmin" ]; then + if ! _exists synouser || ! _exists synogroup; then + _err "Tools are missing for creating temp admin user, please set SYNO_Username and SYNO_Password instead." + return 1 fi + # Clean up + [ -n "$SYNO_Username" ] || _savedeployconf SYNO_Username "" + [ -n "$SYNO_Password" ] || _savedeployconf SYNO_Password "" + synouser --del "$SYNO_Username" >/dev/null 2>/dev/null + _debug "Setting temp admin user credential..." SYNO_Username=sc-acmesh-tmp SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16) # Ignore 2FA-OTP settings which won't be needed. - SYNO_Device_Name= - SYNO_Device_ID= + SYNO_DeviceID= + SYNO_DeviceName= + + _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" + else + _debug2 SYNO_Username "$SYNO_Username" + _secure_debug2 SYNO_Password "$SYNO_Password" + _debug2 SYNO_Create "$SYNO_Create" + _debug2 SYNO_DeviceName "$SYNO_DeviceName" + _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" fi - if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then - _err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password." + if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then + _err "You must set either SYNO_UseTempAdmin, or set both SYNO_Username and SYNO_Password." return 1 fi - _debug2 SYNO_Username "$SYNO_Username" - _secure_debug2 SYNO_Password "$SYNO_Password" - _debug2 SYNO_Create "$SYNO_Create" - _debug2 SYNO_Device_Name "$SYNO_Device_Name" - _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" - # Optional scheme, hostname & port for Synology DSM + # Optional scheme, hostname and port for Synology DSM _getdeployconf SYNO_Scheme _getdeployconf SYNO_Hostname _getdeployconf SYNO_Port - # Default values for scheme, hostname & port - # Defaulting to localhost & http, because it's localhost… - [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" - [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" - [ -n "${SYNO_Port}" ] || SYNO_Port="5000" - _savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" + # Default values for scheme, hostname and port + # Defaulting to localhost and http, because it's localhost… + [ -n "$SYNO_Scheme" ] || SYNO_Scheme="http" + [ -n "$SYNO_Hostname" ] || SYNO_Hostname="localhost" + [ -n "$SYNO_Port" ] || SYNO_Port="5000" _savedeployconf SYNO_Scheme "$SYNO_Scheme" _savedeployconf SYNO_Hostname "$SYNO_Hostname" _savedeployconf SYNO_Port "$SYNO_Port" @@ -100,7 +114,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verify it's real _getdeployconf SYNO_Certificate - _debug SYNO_Certificate "${SYNO_Certificate:-}" + _debug SYNO_Certificate "$SYNO_Certificate" # shellcheck disable=SC1003 # We are not trying to escape a single quote if printf "%s" "$SYNO_Certificate" | grep '\\'; then @@ -108,10 +122,16 @@ synology_dsm_deploy() { return 1 fi + if [ -n "$SYNO_UseTempAdmin" ]; then + _debug "Creating temp admin user in Synology DSM..." + synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null + synogroup --memberadd administrators "$SYNO_Username" >/dev/null + fi + _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" - _debug "Getting API version" + _debug "Getting API version..." response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p') api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') @@ -119,13 +139,15 @@ synology_dsm_deploy() { _debug3 api_path "$api_path" _debug3 api_version "$api_version" - # Login, get the session ID & SynoToken from JSON - _info "Logging into $SYNO_Hostname:$SYNO_Port" + # Login, get the session ID and SynoToken from JSON + _info "Logging into $SYNO_Hostname:$SYNO_Port..." encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" otp_code="" - # START - DEPRECATED, only kept for legacy compatibility reasons + # ## START ## - DEPRECATED, for backward compatibility + _getdeployconf SYNO_TOTP_SECRET + if [ -n "$SYNO_TOTP_SECRET" ]; then _info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" _info " See synology_dsm.sh script or ACME.sh Wiki page for details:" @@ -134,47 +156,45 @@ synology_dsm_deploy() { _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" return 1 fi - DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)" + DEPRECATED_otp_code="$(oathtool --base32 --totp "$SYNO_TOTP_SECRET" 2>/dev/null)" - if [ -n "$SYNO_DID" ]; then - _H1="Cookie: did=$SYNO_DID" + if [ -z "$SYNO_DeviceID" ]; then + _getdeployconf SYNO_DID + [ -n "$SYNO_DID" ] || SYNO_DeviceID="$SYNO_DID" + fi + if [ -n "$SYNO_DeviceID" ]; then + _H1="Cookie: did=$SYNO_DeviceID" export _H1 _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DeviceID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") _debug3 response "$response" - # END - DEPRECATED, only kept for legacy compatibility reasons - # If SYNO_DeviceDevice_ID & SYNO_Device_Name both empty, just log in normally - elif [ -z "${SYNO_Device_ID:-}" ] && [ -z "${SYNO_Device_Name:-}" ]; then - if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then - _debug "Creating temp admin user in Synology DSM" - synouser --del "$SYNO_Username" >/dev/null 2>/dev/null - synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "" 0 >/dev/null - synogroup --memberadd administrators "$SYNO_Username" >/dev/null - fi + # ## END ## - DEPRECATED, for backward compatibility + # If SYNO_Device_ID & SYNO_DeviceName both empty, just log in normally + elif [ -z "${SYNO_DeviceID:-}" ] && [ -z "${SYNO_DeviceName:-}" ]; then response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") _debug3 response "$response" # Get device ID if still empty first, otherwise log in right away - # If SYNO_Device_Name is set, we treat that account enabled two-factor authorization, consider SYNO_Device_ID is not set, so it won't be able to login without requiring the OTP code. - elif [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then - printf "Enter OTP code for user '%s': " "$SYNO_Username" - read -r otp_code - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name") - _secure_debug3 response "$response" + # If SYNO_DeviceName is set, we treat that account enabled two-factor authorization, consider SYNO_DeviceID is not set, so it won't be able to login without requiring the OTP code. + elif [ -n "${SYNO_DeviceName:-}" ] && [ -z "${SYNO_DeviceID:-}" ]; then + printf "Enter OTP code for user '%s': " "$SYNO_Username" + read -r otp_code + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DeviceName") + _secure_debug3 response "$response" - id_property='device_id' - [ "${api_version}" -gt '6' ] || id_property='did' - SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') - _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" - # Otherwise, if SYNO_Device_ID is set, we can just use it to login. + id_property='device_id' + [ "${api_version}" -gt '6' ] || id_property='did' + SYNO_DeviceID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') + _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" + # Otherwise, if SYNO_DeviceID is set, we can just use it to login. else - if [ -z "${SYNO_Device_Name:-}" ]; then + if [ -z "${SYNO_DeviceName:-}" ]; then printf "Enter device name or leave empty for default (CertRenewal): " - read -r SYNO_Device_Name - [ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal" + read -r SYNO_DeviceName + [ -n "${SYNO_DeviceName}" ] || SYNO_DeviceName="CertRenewal" fi - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DeviceName&device_id=$SYNO_DeviceID") _secure_debug3 response "$response" fi @@ -185,8 +205,8 @@ synology_dsm_deploy() { if [ -z "$sid" ] || [ -z "$token" ]; then _err "Unable to authenticate to $_base_url - check your username & password." _err "If two-factor authentication is enabled for the user:" - _err "- set SYNO_Device_Name then input *correct* OTP-code manually" - _err "- get & set SYNO_Device_ID via your browser cookies" + _err "- set SYNO_DeviceName then input *correct* OTP-code manually" + _err "- get & set SYNO_DeviceID via your browser cookies" _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" return 1 fi @@ -195,15 +215,15 @@ synology_dsm_deploy() { export _H1 _debug2 H1 "${_H1}" - # Now that we know the username & password are good, save them - _savedeployconf SYNO_Username "$SYNO_Username" - _savedeployconf SYNO_Password "$SYNO_Password" - if [ -z "${SYNO_USE_TEMP_ADMIN:-}" ]; then - _savedeployconf SYNO_Device_Name "$SYNO_Device_Name" - _savedeployconf SYNO_Device_ID "$SYNO_Device_ID" + # Now that we know the username and password are good, save them if not in temp admin mode. + if [ -z "$SYNO_UseTempAdmin" ]; then + _savedeployconf SYNO_Username "$SYNO_Username" + _savedeployconf SYNO_Password "$SYNO_Password" + _savedeployconf SYNO_DeviceID "$SYNO_DeviceID" + _savedeployconf SYNO_DeviceName "$SYNO_DeviceName" fi - _info "Getting certificates in Synology DSM" + _info "Getting certificates in Synology DSM..." response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") _debug3 response "$response" escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')" @@ -211,16 +231,16 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then - _err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set" - _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" + if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then + _err "Unable to find certificate: $SYNO_Certificate and $SYNO_Create is not set." + _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" return 1 fi # We've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64" - _info "Generate form POST request" + _info "Generating form POST request.." nl="\0015\0012" delim="--------------------------$(_utc_date | tr -d -- '-: ')" content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012" @@ -238,22 +258,22 @@ synology_dsm_deploy() { content="$(printf "%b_" "$content")" content="${content%_}" # protect trailing \n - _info "Upload certificate to the Synology DSM" + _info "Upload certificate to the Synology DSM." response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token&_sid=$sid" "" "POST" "multipart/form-data; boundary=${delim}") _debug3 response "$response" if ! echo "$response" | grep '"error":' >/dev/null; then if echo "$response" | grep '"restart_httpd":true' >/dev/null; then - _info "Restarting HTTP services succeeded" + _info "Restarting HTTP services succeeded..." else - _info "Restarting HTTP services failed" + _info "Restarting HTTP services failed." fi - _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" + _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" _logout return 0 else - _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" - _err "Unable to update certificate, error code $response" + _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" + _err "Unable to update certificate, error code $response." _logout return 1 fi @@ -271,7 +291,7 @@ _remove_temp_admin() { username=$2 if [ -n "${flag}" ]; then - _debug "Removing temp admin user in Synology DSM" + _debug "Removing temp admin user in Synology DSM..." synouser --del "$username" >/dev/null fi } From 7248560169b1c76d6821fdb459bd7125f0a850dc Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Fri, 23 Feb 2024 20:00:00 +0800 Subject: [PATCH 296/687] feat: support DSM 6.x --- deploy/synology_dsm.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d39d0c22..cd8ef239 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -122,16 +122,23 @@ synology_dsm_deploy() { return 1 fi + # Create temp admin user if [ -n "$SYNO_UseTempAdmin" ]; then _debug "Creating temp admin user in Synology DSM..." synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null - synogroup --memberadd administrators "$SYNO_Username" >/dev/null + if [ -n "$(synogroup --help | grep '\-\-memberadd')" ]; then + synogroup --memberaddx administrators "$SYNO_Username" >/dev/null + else + # For supporting DSM 6.x which only has `--member` parameter. + cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') + _secure_debug3 admin_users "$cur_admins$SYNO_Username" + synogroup --memberx administrators $cur_admins $SYNO_Username >/dev/null + fi fi + _debug "Getting API version..." _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" - - _debug "Getting API version..." response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p') api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') From dbe0d477d6de710cd390eaa6a13b5be3cdd10f16 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 04:50:30 +0800 Subject: [PATCH 297/687] feat: more user-friendly logic & error messages. --- deploy/synology_dsm.sh | 206 +++++++++++++++++++++++++++-------------- 1 file changed, 136 insertions(+), 70 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index cd8ef239..0a2bdf7a 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -9,26 +9,33 @@ # Issues: https://github.com/acmesh-official/acme.sh/issues/2727 ################################################################################ # Usage: -# 1. Set required environment variables (two ways): -# - Create temp admin user automatically -# `export SYNO_UseTempAdmin=1` -# - Or provide your own admin user credential by: +# 1. Set required environment variables: +# - use automatically created temp admin user to authenticate +# 1. disable "enfore 2FA-OTP for admins" via control panel +# 2. `export SYNO_UseTempAdmin=1` +# - or provide your own admin user credential to authenticate # 1. `export SYNO_Username="adminUser"` # 2. `export SYNO_Password="adminPassword"` # 2. Set optional environment variables (shown values are the defaults) -# - `export SYNO_Scheme="http"` -# - `export SYNO_Hostname="localhost"` -# - `export SYNO_Port="5000"` -# - `export SYNO_Create=1` - to allow creating the cert if it doesn't exist -# - `export SYNO_Certificate=""` - to replace a specific cert by its description -# - `export SYNO_DeviceName=""` - required for 2FA-OTP -# - `export SYNO_DeviceID=""` - required for omitting 2FA-OTP (only pro -# users may set) +# - common optional variables +# - `export SYNO_Scheme="http"` +# - `export SYNO_Hostname="localhost"` +# - `export SYNO_Port="5000"` +# - `export SYNO_Create=1` - to allow creating the cert if it doesn't exist +# - `export SYNO_Certificate=""` - to replace a specific cert by its +# description +# - 2FA-OTP optional variables (with your own admin user) +# - `export SYNO_DeviceName=""` - required for 2FA-OTP, script won't require +# interactive input the device name if set. +# - `export SYNO_OTPCode=""` - required for 2FA-OTP, script won't require +# interactive input the code if set. +# - `export SYNO_DeviceID=""` - required for omitting 2FA-OTP (might be +# deprecated, auth with OTP code instead) # 3. Run command: # acme.sh --deploy --deploy-hook synology_dsm -d example.com ################################################################################ # Dependencies: -# - jq & curl +# - curl # - synouser & synogroup (When available and SYNO_UseTempAdmin is set) ################################################################################ # Return value: @@ -48,44 +55,48 @@ synology_dsm_deploy() { # Get username and password, but don't save until we authenticated successfully _getdeployconf SYNO_Username _getdeployconf SYNO_Password - _getdeployconf SYNO_DeviceName _getdeployconf SYNO_DeviceID - _getdeployconf SYNO_Create + _getdeployconf SYNO_DeviceName # ## START ## - DEPRECATED, for backward compatibility _getdeployconf SYNO_Device_ID _getdeployconf SYNO_Device_Name - [ -n "$SYNO_DeviceID" ] || SYNO_DeviceID="$SYNO_Device_ID" - [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="$SYNO_Device_Name" + [ -n "$SYNO_DeviceID" ] || SYNO_DeviceID="${SYNO_Device_ID:-}" + [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="${SYNO_Device_Name:-}" # ## END ## - DEPRECATED, for backward compatibility - [ -n "$SYNO_Create" ] || SYNO_Create=1 # Prepare to use temp admin if SYNO_UseTempAdmin is set _getdeployconf SYNO_UseTempAdmin _debug2 SYNO_UseTempAdmin "$SYNO_UseTempAdmin" + # Back to use existing admin user if explicitly requested + if [ "$SYNO_UseTempAdmin" -eq 0 ]; then + _debug2 Back to use existing user rather than temp admin user. + SYNO_UseTempAdmin="" + fi + _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" + if [ -n "$SYNO_UseTempAdmin" ]; then if ! _exists synouser || ! _exists synogroup; then _err "Tools are missing for creating temp admin user, please set SYNO_Username and SYNO_Password instead." return 1 fi - # Clean up + [ -n "$SYNO_Username" ] || _savedeployconf SYNO_Username "" [ -n "$SYNO_Password" ] || _savedeployconf SYNO_Password "" - synouser --del "$SYNO_Username" >/dev/null 2>/dev/null _debug "Setting temp admin user credential..." SYNO_Username=sc-acmesh-tmp SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16) - # Ignore 2FA-OTP settings which won't be needed. + # Set 2FA-OTP settings to empty consider they won't be needed. SYNO_DeviceID= SYNO_DeviceName= - - _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" + SYNO_OTPCode= + # Pre-delete temp admin user if already exists. + synouser --del "$SYNO_Username" >/dev/null 2>/dev/null else _debug2 SYNO_Username "$SYNO_Username" _secure_debug2 SYNO_Password "$SYNO_Password" - _debug2 SYNO_Create "$SYNO_Create" _debug2 SYNO_DeviceName "$SYNO_DeviceName" _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" fi @@ -114,7 +125,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verify it's real _getdeployconf SYNO_Certificate - _debug SYNO_Certificate "$SYNO_Certificate" + _debug SYNO_Certificate "${SYNO_Certificate:-}" # shellcheck disable=SC1003 # We are not trying to escape a single quote if printf "%s" "$SYNO_Certificate" | grep '\\'; then @@ -122,20 +133,6 @@ synology_dsm_deploy() { return 1 fi - # Create temp admin user - if [ -n "$SYNO_UseTempAdmin" ]; then - _debug "Creating temp admin user in Synology DSM..." - synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null - if [ -n "$(synogroup --help | grep '\-\-memberadd')" ]; then - synogroup --memberaddx administrators "$SYNO_Username" >/dev/null - else - # For supporting DSM 6.x which only has `--member` parameter. - cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') - _secure_debug3 admin_users "$cur_admins$SYNO_Username" - synogroup --memberx administrators $cur_admins $SYNO_Username >/dev/null - fi - fi - _debug "Getting API version..." _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url" @@ -151,7 +148,6 @@ synology_dsm_deploy() { encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" - otp_code="" # ## START ## - DEPRECATED, for backward compatibility _getdeployconf SYNO_TOTP_SECRET @@ -178,31 +174,85 @@ synology_dsm_deploy() { response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DeviceID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") _debug3 response "$response" # ## END ## - DEPRECATED, for backward compatibility - # If SYNO_Device_ID & SYNO_DeviceName both empty, just log in normally - elif [ -z "${SYNO_DeviceID:-}" ] && [ -z "${SYNO_DeviceName:-}" ]; then - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") - _debug3 response "$response" - # Get device ID if still empty first, otherwise log in right away - # If SYNO_DeviceName is set, we treat that account enabled two-factor authorization, consider SYNO_DeviceID is not set, so it won't be able to login without requiring the OTP code. - elif [ -n "${SYNO_DeviceName:-}" ] && [ -z "${SYNO_DeviceID:-}" ]; then + # If SYNO_DeviceID or SYNO_OTPCode is set, we treat current account enabled 2FA-OTP. + # Notice that if SYNO_UseTempAdmin=1, both variables will be unset + else + if [ -n "$SYNO_UseTempAdmin" ]; then + _debug "Creating temp admin user in Synology DSM..." + synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null + if synogroup --help | grep -q '\-\-memberadd'; then + synogroup --memberadd administrators "$SYNO_Username" >/dev/null + else + # For supporting DSM 6.x which only has `--member` parameter. + cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') + _secure_debug3 admin_users "$cur_admins$SYNO_Username" + # shellcheck disable=SC2086 + synogroup --member administrators $cur_admins $SYNO_Username >/dev/null + fi + fi + if [ -n "$SYNO_DeviceID" ] || [ -n "$SYNO_OTPCode" ]; then + response='{"error":{"code":403}}' + # Assume the current account disabled 2FA-OTP, try to log in right away. + else + response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") + _debug3 response "$response" + fi + fi + + error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + # Account has 2FA-OTP enabled, since error 403 reported. + if [ "${error_code:-0}" -eq 403 ]; then + if [ -z "$SYNO_DeviceName" ]; then + printf "Enter device name or leave empty for default (CertRenewal): " + read -r SYNO_DeviceName + [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="CertRenewal" + fi + + if [ -n "$SYNO_DeviceID" ]; then + # Omit OTP code with SYNO_DeviceID. + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DeviceName&device_id=$SYNO_DeviceID") + _secure_debug3 response "$response" + else + # Require the OTP code if still unset. + if [ -z "$SYNO_OTPCode" ]; then printf "Enter OTP code for user '%s': " "$SYNO_Username" - read -r otp_code - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DeviceName") + read -r SYNO_OTPCode + fi + + if [ -z "$SYNO_OTPCode" ]; then + response='{"error":{"code":404}}' + else + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DeviceName&otp_code=$SYNO_OTPCode") _secure_debug3 response "$response" id_property='device_id' [ "${api_version}" -gt '6' ] || id_property='did' SYNO_DeviceID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" - # Otherwise, if SYNO_DeviceID is set, we can just use it to login. - else - if [ -z "${SYNO_DeviceName:-}" ]; then - printf "Enter device name or leave empty for default (CertRenewal): " - read -r SYNO_DeviceName - [ -n "${SYNO_DeviceName}" ] || SYNO_DeviceName="CertRenewal" + fi fi - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DeviceName&device_id=$SYNO_DeviceID") - _secure_debug3 response "$response" + error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + fi + + if [ -n "$error_code" ]; then + if [ "$error_code" -eq 403 ] && [ -n "$SYNO_DeviceID" ]; then + _savedeployconf SYNO_DeviceID "" + _err "Failed to authenticate with SYNO_DeviceID (may expired or invalid), please try again in a new terminal window." + elif [ "$error_code" -eq 404 ]; then + _err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window." + elif [ "$error_code" -eq 406 ]; then + if [ -n "$SYNO_UseTempAdmin" ]; then + _err "SYNO_UseTempAdmin=1 is not supported if enforce auth with 2FA-OTP is enabled." + else + _err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue." + fi + elif [ "$error_code" -eq 400 ] || [ "$error_code" -eq 401 ] || [ "$error_code" -eq 408 ] || [ "$error_code" -eq 409 ] || [ "$error_code" -eq 410 ]; then + _err "Failed to authenticate with a non-existent or disabled account, or the account password is incorrect or has expired." + else + _err "Failed to authenticate with error: $error_code." + fi + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + return 1 fi sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') @@ -210,11 +260,9 @@ synology_dsm_deploy() { _debug "Session ID" "$sid" _debug SynoToken "$token" if [ -z "$sid" ] || [ -z "$token" ]; then - _err "Unable to authenticate to $_base_url - check your username & password." - _err "If two-factor authentication is enabled for the user:" - _err "- set SYNO_DeviceName then input *correct* OTP-code manually" - _err "- get & set SYNO_DeviceID via your browser cookies" - _remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username" + # Still can't get necessary info even got no errors, may Synology have API updated? + _err "Unable to authenticate to $_base_url, you may report the full log to the community." + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" return 1 fi @@ -223,12 +271,15 @@ synology_dsm_deploy() { _debug2 H1 "${_H1}" # Now that we know the username and password are good, save them if not in temp admin mode. - if [ -z "$SYNO_UseTempAdmin" ]; then + if [ -n "$SYNO_UseTempAdmin" ]; then + _savedeployconf SYNO_Username "" + _savedeployconf SYNO_Password "" + else _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" - _savedeployconf SYNO_DeviceID "$SYNO_DeviceID" - _savedeployconf SYNO_DeviceName "$SYNO_DeviceName" fi + _savedeployconf SYNO_DeviceID "$SYNO_DeviceID" + _savedeployconf SYNO_DeviceName "$SYNO_DeviceName" _info "Getting certificates in Synology DSM..." response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") @@ -238,9 +289,24 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" + error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + if [ -n "$error_code" ]; then + if [ "$error_code" -eq 105 ]; then + _err "Current user is not administrator and does not have sufficient permission for deploying." + else + _err "Failed to fetch certificate info with error: $error_code, contact Synology for more info about it." + fi + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + return 1 + fi + + _getdeployconf SYNO_Create + _debug2 SYNO_Create "$SYNO_Create" + [ -n "$SYNO_Create" ] || SYNO_Create=1 + if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then _err "Unable to find certificate: $SYNO_Certificate and $SYNO_Create is not set." - _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" return 1 fi @@ -275,11 +341,11 @@ synology_dsm_deploy() { else _info "Restarting HTTP services failed." fi - _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" _logout return 0 else - _remove_temp_admin "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" _err "Unable to update certificate, error code $response." _logout return 1 @@ -293,12 +359,12 @@ _logout() { _debug3 response "$response" } -_remove_temp_admin() { +_temp_admin_cleanup() { flag=$1 username=$2 if [ -n "${flag}" ]; then - _debug "Removing temp admin user in Synology DSM..." + _debug "Cleanuping temp admin info..." synouser --del "$username" >/dev/null fi } From 59d1e16f9cb33ebeac1624f131a39c7088514204 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 06:21:03 +0800 Subject: [PATCH 298/687] feat: bypass enforce temp admin 2FA --- deploy/synology_dsm.sh | 66 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 0a2bdf7a..4b12a18e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -11,8 +11,7 @@ # Usage: # 1. Set required environment variables: # - use automatically created temp admin user to authenticate -# 1. disable "enfore 2FA-OTP for admins" via control panel -# 2. `export SYNO_UseTempAdmin=1` +# `export SYNO_UseTempAdmin=1` # - or provide your own admin user credential to authenticate # 1. `export SYNO_Username="adminUser"` # 2. `export SYNO_Password="adminPassword"` @@ -70,8 +69,8 @@ synology_dsm_deploy() { _debug2 SYNO_UseTempAdmin "$SYNO_UseTempAdmin" # Back to use existing admin user if explicitly requested - if [ "$SYNO_UseTempAdmin" -eq 0 ]; then - _debug2 Back to use existing user rather than temp admin user. + if [ "$SYNO_UseTempAdmin" == "0" ]; then + _debug2 "Back to use existing user rather than temp admin user." SYNO_UseTempAdmin="" fi _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" @@ -177,31 +176,46 @@ synology_dsm_deploy() { # If SYNO_DeviceID or SYNO_OTPCode is set, we treat current account enabled 2FA-OTP. # Notice that if SYNO_UseTempAdmin=1, both variables will be unset else - if [ -n "$SYNO_UseTempAdmin" ]; then - _debug "Creating temp admin user in Synology DSM..." - synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null - if synogroup --help | grep -q '\-\-memberadd'; then - synogroup --memberadd administrators "$SYNO_Username" >/dev/null - else - # For supporting DSM 6.x which only has `--member` parameter. - cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') - _secure_debug3 admin_users "$cur_admins$SYNO_Username" - # shellcheck disable=SC2086 - synogroup --member administrators $cur_admins $SYNO_Username >/dev/null - fi - fi if [ -n "$SYNO_DeviceID" ] || [ -n "$SYNO_OTPCode" ]; then response='{"error":{"code":403}}' # Assume the current account disabled 2FA-OTP, try to log in right away. else + if [ -n "$SYNO_UseTempAdmin" ]; then + _debug "Creating temp admin user in Synology DSM..." + synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null + if synogroup --help | grep -q '\-\-memberadd'; then + synogroup --memberadd administrators "$SYNO_Username" >/dev/null + else + # For supporting DSM 6.x which only has `--member` parameter. + cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') + _secure_debug3 admin_users "$cur_admins$SYNO_Username" + # shellcheck disable=SC2086 + synogroup --member administrators $cur_admins $SYNO_Username >/dev/null + fi + # havig a workaround to temporary disable enforce 2FA-OTP + otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) + if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then + synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none + _info "Temporary disabled enforce 2FA-OTP to complete authentication." + _info "previous_otp_enforce_option" "$otp_enforce_option" + + else + otp_enforce_option="" + fi + fi response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") + if [ -n "$SYNO_UseTempAdmin" ] && [ -n "$otp_enforce_option" ]; then + synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option" + _info "Restored previous enforce 2FA-OTP option." + fi _debug3 response "$response" fi fi error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') # Account has 2FA-OTP enabled, since error 403 reported. - if [ "${error_code:-0}" -eq 403 ]; then + # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf + if [ "$error_code" == "403" ]; then if [ -z "$SYNO_DeviceName" ]; then printf "Enter device name or leave empty for default (CertRenewal): " read -r SYNO_DeviceName @@ -235,18 +249,18 @@ synology_dsm_deploy() { fi if [ -n "$error_code" ]; then - if [ "$error_code" -eq 403 ] && [ -n "$SYNO_DeviceID" ]; then + if [ "$error_code" == "403" ] && [ -n "$SYNO_DeviceID" ]; then _savedeployconf SYNO_DeviceID "" _err "Failed to authenticate with SYNO_DeviceID (may expired or invalid), please try again in a new terminal window." - elif [ "$error_code" -eq 404 ]; then + elif [ "$error_code" == "404" ]; then _err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window." - elif [ "$error_code" -eq 406 ]; then + elif [ "$error_code" == "406" ]; then if [ -n "$SYNO_UseTempAdmin" ]; then _err "SYNO_UseTempAdmin=1 is not supported if enforce auth with 2FA-OTP is enabled." else _err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue." fi - elif [ "$error_code" -eq 400 ] || [ "$error_code" -eq 401 ] || [ "$error_code" -eq 408 ] || [ "$error_code" -eq 409 ] || [ "$error_code" -eq 410 ]; then + elif [ "$error_code" == "400" ] || [ "$error_code" == "401" ] || [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then _err "Failed to authenticate with a non-existent or disabled account, or the account password is incorrect or has expired." else _err "Failed to authenticate with error: $error_code." @@ -313,7 +327,7 @@ synology_dsm_deploy() { # We've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64" - _info "Generating form POST request.." + _info "Generating form POST request..." nl="\0015\0012" delim="--------------------------$(_utc_date | tr -d -- '-: ')" content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012" @@ -337,16 +351,16 @@ synology_dsm_deploy() { if ! echo "$response" | grep '"error":' >/dev/null; then if echo "$response" | grep '"restart_httpd":true' >/dev/null; then - _info "Restarting HTTP services succeeded..." + _info "Restart HTTP services succeeded." else - _info "Restarting HTTP services failed." + _info "Restart HTTP services failed." fi _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" _logout return 0 else _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" - _err "Unable to update certificate, error code $response." + _err "Unable to update certificate, got error response: $response." _logout return 1 fi From afed62f6de12384acbcd269672e711bed0ffa863 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 07:05:00 +0800 Subject: [PATCH 299/687] fix: should save `SYNO_UseTempAdmin` only after login success. --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 4b12a18e..65340211 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -31,7 +31,7 @@ # - `export SYNO_DeviceID=""` - required for omitting 2FA-OTP (might be # deprecated, auth with OTP code instead) # 3. Run command: -# acme.sh --deploy --deploy-hook synology_dsm -d example.com +# `acme.sh --deploy --deploy-hook synology_dsm -d example.com`` ################################################################################ # Dependencies: # - curl @@ -73,7 +73,6 @@ synology_dsm_deploy() { _debug2 "Back to use existing user rather than temp admin user." SYNO_UseTempAdmin="" fi - _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" if [ -n "$SYNO_UseTempAdmin" ]; then if ! _exists synouser || ! _exists synogroup; then @@ -288,6 +287,7 @@ synology_dsm_deploy() { if [ -n "$SYNO_UseTempAdmin" ]; then _savedeployconf SYNO_Username "" _savedeployconf SYNO_Password "" + _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" else _savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Password "$SYNO_Password" From 5b449999a5fc2da598dd11accce58b5a34c4a2cc Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 20:55:49 +0800 Subject: [PATCH 300/687] refactor: unify variable naming convention again (revert some changes) --- deploy/synology_dsm.sh | 269 ++++++++++++++++++++++------------------- 1 file changed, 145 insertions(+), 124 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 65340211..0157b469 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -11,31 +11,31 @@ # Usage: # 1. Set required environment variables: # - use automatically created temp admin user to authenticate -# `export SYNO_UseTempAdmin=1` +# `export SYNO_USE_TEMP_ADMIN=1` # - or provide your own admin user credential to authenticate -# 1. `export SYNO_Username="adminUser"` -# 2. `export SYNO_Password="adminPassword"` +# 1. `export SYNO_USERNAME="adminUser"` +# 2. `export SYNO_PASSWORD="adminPassword"` # 2. Set optional environment variables (shown values are the defaults) # - common optional variables -# - `export SYNO_Scheme="http"` -# - `export SYNO_Hostname="localhost"` -# - `export SYNO_Port="5000"` -# - `export SYNO_Create=1` - to allow creating the cert if it doesn't exist -# - `export SYNO_Certificate=""` - to replace a specific cert by its +# - `export SYNO_SCHEME="http"` +# - `export SYNO_HOSTNAME="localhost"` +# - `export SYNO_PORT="5000"` +# - `export SYNO_CREATE=""` - to allow creating the cert if it doesn't exist +# - `export SYNO_CERTIFICATE=""` - to replace a specific cert by its # description # - 2FA-OTP optional variables (with your own admin user) -# - `export SYNO_DeviceName=""` - required for 2FA-OTP, script won't require -# interactive input the device name if set. -# - `export SYNO_OTPCode=""` - required for 2FA-OTP, script won't require +# - `export SYNO_OTP_CODE=""` - required for 2FA-OTP, script won't require # interactive input the code if set. -# - `export SYNO_DeviceID=""` - required for omitting 2FA-OTP (might be +# - `export SYNO_DEVICE_NAME=""` - required for 2FA-OTP, script won't require +# interactive input the device name if set. +# - `export SYNO_DEVICE_ID=""` - required for omitting 2FA-OTP (might be # deprecated, auth with OTP code instead) # 3. Run command: # `acme.sh --deploy --deploy-hook synology_dsm -d example.com`` ################################################################################ # Dependencies: # - curl -# - synouser & synogroup (When available and SYNO_UseTempAdmin is set) +# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set) ################################################################################ # Return value: # 0 means success, otherwise error. @@ -52,87 +52,85 @@ synology_dsm_deploy() { _debug _cdomain "$_cdomain" # Get username and password, but don't save until we authenticated successfully - _getdeployconf SYNO_Username - _getdeployconf SYNO_Password - _getdeployconf SYNO_DeviceID - _getdeployconf SYNO_DeviceName - - # ## START ## - DEPRECATED, for backward compatibility - _getdeployconf SYNO_Device_ID - _getdeployconf SYNO_Device_Name - [ -n "$SYNO_DeviceID" ] || SYNO_DeviceID="${SYNO_Device_ID:-}" - [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="${SYNO_Device_Name:-}" - # ## END ## - DEPRECATED, for backward compatibility - - # Prepare to use temp admin if SYNO_UseTempAdmin is set - _getdeployconf SYNO_UseTempAdmin - _debug2 SYNO_UseTempAdmin "$SYNO_UseTempAdmin" - - # Back to use existing admin user if explicitly requested - if [ "$SYNO_UseTempAdmin" == "0" ]; then - _debug2 "Back to use existing user rather than temp admin user." - SYNO_UseTempAdmin="" - fi - - if [ -n "$SYNO_UseTempAdmin" ]; then + _migratedeployconf SYNO_Username SYNO_USERNAME + _migratedeployconf SYNO_Password SYNO_PASSWORD + _migratedeployconf SYNO_Device_ID SYNO_DEVICE_ID + _migratedeployconf SYNO_Device_Name SYNO_DEVICE_NAME + _getdeployconf SYNO_USERNAME + _getdeployconf SYNO_PASSWORD + _getdeployconf SYNO_DEVICE_ID + _getdeployconf SYNO_DEVICE_NAME + + # Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set + _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" + _getdeployconf SYNO_USE_TEMP_ADMIN + __check2cleardeployconfexp SYNO_USE_TEMP_ADMIN + _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" + + if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then if ! _exists synouser || ! _exists synogroup; then - _err "Tools are missing for creating temp admin user, please set SYNO_Username and SYNO_Password instead." + _err "Tools are missing for creating temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." return 1 fi - [ -n "$SYNO_Username" ] || _savedeployconf SYNO_Username "" - [ -n "$SYNO_Password" ] || _savedeployconf SYNO_Password "" + [ -n "$SYNO_USERNAME" ] || _savedeployconf SYNO_USERNAME "" + [ -n "$SYNO_PASSWORD" ] || _savedeployconf SYNO_PASSWORD "" _debug "Setting temp admin user credential..." - SYNO_Username=sc-acmesh-tmp - SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16) + SYNO_USERNAME=sc-acmesh-tmp + SYNO_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16) # Set 2FA-OTP settings to empty consider they won't be needed. - SYNO_DeviceID= - SYNO_DeviceName= - SYNO_OTPCode= + SYNO_DEVICE_ID= + SYNO_DEVICE_NAME= + SYNO_OTP_CODE= # Pre-delete temp admin user if already exists. - synouser --del "$SYNO_Username" >/dev/null 2>/dev/null + synouser --del "$SYNO_USERNAME" >/dev/null 2>/dev/null else - _debug2 SYNO_Username "$SYNO_Username" - _secure_debug2 SYNO_Password "$SYNO_Password" - _debug2 SYNO_DeviceName "$SYNO_DeviceName" - _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" + _debug2 SYNO_USERNAME "$SYNO_USERNAME" + _secure_debug2 SYNO_PASSWORD "$SYNO_PASSWORD" + _debug2 SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME" + _secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID" fi - if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then - _err "You must set either SYNO_UseTempAdmin, or set both SYNO_Username and SYNO_Password." + if [ -z "$SYNO_USERNAME" ] || [ -z "$SYNO_PASSWORD" ]; then + _err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_USERNAME and SYNO_PASSWORD." return 1 fi # Optional scheme, hostname and port for Synology DSM - _getdeployconf SYNO_Scheme - _getdeployconf SYNO_Hostname - _getdeployconf SYNO_Port + _migratedeployconf SYNO_Scheme SYNO_SCHEME + _migratedeployconf SYNO_Hostname SYNO_HOSTNAME + _migratedeployconf SYNO_Port SYNO_PORT + _getdeployconf SYNO_SCHEME + _getdeployconf SYNO_HOSTNAME + _getdeployconf SYNO_PORT # Default values for scheme, hostname and port # Defaulting to localhost and http, because it's localhost… - [ -n "$SYNO_Scheme" ] || SYNO_Scheme="http" - [ -n "$SYNO_Hostname" ] || SYNO_Hostname="localhost" - [ -n "$SYNO_Port" ] || SYNO_Port="5000" - _savedeployconf SYNO_Scheme "$SYNO_Scheme" - _savedeployconf SYNO_Hostname "$SYNO_Hostname" - _savedeployconf SYNO_Port "$SYNO_Port" - _debug2 SYNO_Scheme "$SYNO_Scheme" - _debug2 SYNO_Hostname "$SYNO_Hostname" - _debug2 SYNO_Port "$SYNO_Port" + [ -n "$SYNO_SCHEME" ] || SYNO_SCHEME="http" + [ -n "$SYNO_HOSTNAME" ] || SYNO_HOSTNAME="localhost" + [ -n "$SYNO_PORT" ] || SYNO_PORT="5000" + _savedeployconf SYNO_SCHEME "$SYNO_SCHEME" + _savedeployconf SYNO_HOSTNAME "$SYNO_HOSTNAME" + _savedeployconf SYNO_PORT "$SYNO_PORT" + _debug2 SYNO_SCHEME "$SYNO_SCHEME" + _debug2 SYNO_HOSTNAME "$SYNO_HOSTNAME" + _debug2 SYNO_PORT "$SYNO_PORT" # Get the certificate description, but don't save it until we verify it's real - _getdeployconf SYNO_Certificate - _debug SYNO_Certificate "${SYNO_Certificate:-}" + _migratedeployconf SYNO_Certificate SYNO_CERTIFICATE "base64" + _getdeployconf SYNO_CERTIFICATE + __check2cleardeployconfexp SYNO_CERTIFICATE + _debug SYNO_CERTIFICATE "${SYNO_CERTIFICATE:-}" # shellcheck disable=SC1003 # We are not trying to escape a single quote - if printf "%s" "$SYNO_Certificate" | grep '\\'; then + if printf "%s" "$SYNO_CERTIFICATE" | grep '\\'; then _err "Do not use a backslash (\) in your certificate description" return 1 fi _debug "Getting API version..." - _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" + _base_url="$SYNO_SCHEME://$SYNO_HOSTNAME:$SYNO_PORT" _debug _base_url "$_base_url" response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p') @@ -142,9 +140,9 @@ synology_dsm_deploy() { _debug3 api_version "$api_version" # Login, get the session ID and SynoToken from JSON - _info "Logging into $SYNO_Hostname:$SYNO_Port..." - encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)" - encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)" + _info "Logging into $SYNO_HOSTNAME:$SYNO_PORT..." + encoded_username="$(printf "%s" "$SYNO_USERNAME" | _url_encode)" + encoded_password="$(printf "%s" "$SYNO_PASSWORD" | _url_encode)" # ## START ## - DEPRECATED, for backward compatibility _getdeployconf SYNO_TOTP_SECRET @@ -159,37 +157,37 @@ synology_dsm_deploy() { fi DEPRECATED_otp_code="$(oathtool --base32 --totp "$SYNO_TOTP_SECRET" 2>/dev/null)" - if [ -z "$SYNO_DeviceID" ]; then + if [ -z "$SYNO_DEVICE_ID" ]; then _getdeployconf SYNO_DID - [ -n "$SYNO_DID" ] || SYNO_DeviceID="$SYNO_DID" + [ -n "$SYNO_DID" ] || SYNO_DEVICE_ID="$SYNO_DID" fi - if [ -n "$SYNO_DeviceID" ]; then - _H1="Cookie: did=$SYNO_DeviceID" + if [ -n "$SYNO_DEVICE_ID" ]; then + _H1="Cookie: did=$SYNO_DEVICE_ID" export _H1 _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DeviceID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") _debug3 response "$response" # ## END ## - DEPRECATED, for backward compatibility - # If SYNO_DeviceID or SYNO_OTPCode is set, we treat current account enabled 2FA-OTP. - # Notice that if SYNO_UseTempAdmin=1, both variables will be unset + # If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP. + # Notice that if SYNO_USE_TEMP_ADMIN=1, both variables will be unset else - if [ -n "$SYNO_DeviceID" ] || [ -n "$SYNO_OTPCode" ]; then + if [ -n "$SYNO_DEVICE_ID" ] || [ -n "$SYNO_OTP_CODE" ]; then response='{"error":{"code":403}}' # Assume the current account disabled 2FA-OTP, try to log in right away. else - if [ -n "$SYNO_UseTempAdmin" ]; then + if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then _debug "Creating temp admin user in Synology DSM..." - synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "scruelt@hotmail.com" 0 >/dev/null + synouser --add "$SYNO_USERNAME" "$SYNO_PASSWORD" "" 0 "scruelt@hotmail.com" 0 >/dev/null if synogroup --help | grep -q '\-\-memberadd'; then - synogroup --memberadd administrators "$SYNO_Username" >/dev/null + synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null else # For supporting DSM 6.x which only has `--member` parameter. cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') - _secure_debug3 admin_users "$cur_admins$SYNO_Username" + _secure_debug3 admin_users "$cur_admins$SYNO_USERNAME" # shellcheck disable=SC2086 - synogroup --member administrators $cur_admins $SYNO_Username >/dev/null + synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null fi # havig a workaround to temporary disable enforce 2FA-OTP otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) @@ -203,7 +201,7 @@ synology_dsm_deploy() { fi fi response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") - if [ -n "$SYNO_UseTempAdmin" ] && [ -n "$otp_enforce_option" ]; then + if [ -n "$SYNO_USE_TEMP_ADMIN" ] && [ -n "$otp_enforce_option" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option" _info "Restored previous enforce 2FA-OTP option." fi @@ -215,47 +213,47 @@ synology_dsm_deploy() { # Account has 2FA-OTP enabled, since error 403 reported. # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf if [ "$error_code" == "403" ]; then - if [ -z "$SYNO_DeviceName" ]; then + if [ -z "$SYNO_DEVICE_NAME" ]; then printf "Enter device name or leave empty for default (CertRenewal): " - read -r SYNO_DeviceName - [ -n "$SYNO_DeviceName" ] || SYNO_DeviceName="CertRenewal" + read -r SYNO_DEVICE_NAME + [ -n "$SYNO_DEVICE_NAME" ] || SYNO_DEVICE_NAME="CertRenewal" fi - if [ -n "$SYNO_DeviceID" ]; then - # Omit OTP code with SYNO_DeviceID. - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DeviceName&device_id=$SYNO_DeviceID") + if [ -n "$SYNO_DEVICE_ID" ]; then + # Omit OTP code with SYNO_DEVICE_ID. + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DEVICE_NAME&device_id=$SYNO_DEVICE_ID") _secure_debug3 response "$response" else # Require the OTP code if still unset. - if [ -z "$SYNO_OTPCode" ]; then - printf "Enter OTP code for user '%s': " "$SYNO_Username" - read -r SYNO_OTPCode + if [ -z "$SYNO_OTP_CODE" ]; then + printf "Enter OTP code for user '%s': " "$SYNO_USERNAME" + read -r SYNO_OTP_CODE fi - if [ -z "$SYNO_OTPCode" ]; then + if [ -z "$SYNO_OTP_CODE" ]; then response='{"error":{"code":404}}' else - response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DeviceName&otp_code=$SYNO_OTPCode") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DEVICE_NAME&otp_code=$SYNO_OTP_CODE") _secure_debug3 response "$response" id_property='device_id' [ "${api_version}" -gt '6' ] || id_property='did' - SYNO_DeviceID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') - _secure_debug2 SYNO_DeviceID "$SYNO_DeviceID" + SYNO_DEVICE_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') + _secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID" fi fi error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') fi if [ -n "$error_code" ]; then - if [ "$error_code" == "403" ] && [ -n "$SYNO_DeviceID" ]; then - _savedeployconf SYNO_DeviceID "" - _err "Failed to authenticate with SYNO_DeviceID (may expired or invalid), please try again in a new terminal window." + if [ "$error_code" == "403" ] && [ -n "$SYNO_DEVICE_ID" ]; then + _cleardeployconf SYNO_DEVICE_ID + _err "Failed to authenticate with SYNO_DEVICE_ID (may expired or invalid), please try again in a new terminal window." elif [ "$error_code" == "404" ]; then _err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window." elif [ "$error_code" == "406" ]; then - if [ -n "$SYNO_UseTempAdmin" ]; then - _err "SYNO_UseTempAdmin=1 is not supported if enforce auth with 2FA-OTP is enabled." + if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then + _err "SYNO_USE_TEMP_ADMIN=1 is not supported if enforce auth with 2FA-OTP is enabled." else _err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue." fi @@ -264,7 +262,7 @@ synology_dsm_deploy() { else _err "Failed to authenticate with error: $error_code." fi - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi @@ -275,7 +273,7 @@ synology_dsm_deploy() { if [ -z "$sid" ] || [ -z "$token" ]; then # Still can't get necessary info even got no errors, may Synology have API updated? _err "Unable to authenticate to $_base_url, you may report the full log to the community." - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi @@ -284,21 +282,23 @@ synology_dsm_deploy() { _debug2 H1 "${_H1}" # Now that we know the username and password are good, save them if not in temp admin mode. - if [ -n "$SYNO_UseTempAdmin" ]; then - _savedeployconf SYNO_Username "" - _savedeployconf SYNO_Password "" - _savedeployconf SYNO_UseTempAdmin "$SYNO_UseTempAdmin" + if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then + _cleardeployconf SYNO_USERNAME + _cleardeployconf SYNO_PASSWORD + _cleardeployconf SYNO_DEVICE_ID + _cleardeployconf SYNO_DEVICE_NAME + _savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" else - _savedeployconf SYNO_Username "$SYNO_Username" - _savedeployconf SYNO_Password "$SYNO_Password" + _savedeployconf SYNO_USERNAME "$SYNO_USERNAME" + _savedeployconf SYNO_PASSWORD "$SYNO_PASSWORD" + _savedeployconf SYNO_DEVICE_ID "$SYNO_DEVICE_ID" + _savedeployconf SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME" fi - _savedeployconf SYNO_DeviceID "$SYNO_DeviceID" - _savedeployconf SYNO_DeviceName "$SYNO_DeviceName" _info "Getting certificates in Synology DSM..." response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") _debug3 response "$response" - escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')" + escaped_certificate="$(printf "%s" "$SYNO_CERTIFICATE" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')" _debug escaped_certificate "$escaped_certificate" id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" @@ -310,22 +310,22 @@ synology_dsm_deploy() { else _err "Failed to fetch certificate info with error: $error_code, contact Synology for more info about it." fi - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi - _getdeployconf SYNO_Create - _debug2 SYNO_Create "$SYNO_Create" - [ -n "$SYNO_Create" ] || SYNO_Create=1 + _migratedeployconf SYNO_Create SYNO_CREATE + _getdeployconf SYNO_CREATE + _debug2 SYNO_CREATE "$SYNO_CREATE" - if [ -z "$id" ] && [ -z "$SYNO_Create" ]; then - _err "Unable to find certificate: $SYNO_Certificate and $SYNO_Create is not set." - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + if [ -z "$id" ] && [ -z "$SYNO_CREATE" ]; then + _err "Unable to find certificate: $SYNO_CERTIFICATE and $SYNO_CREATE is not set." + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi # We've verified this certificate description is a thing, so save it - _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64" + _savedeployconf SYNO_CERTIFICATE "$SYNO_CERTIFICATE" "base64" _info "Generating form POST request..." nl="\0015\0012" @@ -334,7 +334,7 @@ synology_dsm_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_CERTIFICATE}" if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then _debug2 default "This is the default certificate" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true" @@ -355,11 +355,11 @@ synology_dsm_deploy() { else _info "Restart HTTP services failed." fi - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" _logout return 0 else - _temp_admin_cleanup "$SYNO_UseTempAdmin" "$SYNO_Username" + _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" _err "Unable to update certificate, got error response: $response." _logout return 1 @@ -382,3 +382,24 @@ _temp_admin_cleanup() { synouser --del "$username" >/dev/null fi } + +#_cleardeployconf key +_cleardeployconf() { + _cleardomainconf "SAVED_$1" +} + +# key +__check2cleardeployconfexp() { + # Warning: + _key="$1" + _clear_key="CLEAR_$_key" + # Clear saved settings if explicitly requested + if [ -n "$(eval echo \$$_clear_key)" ]; then + _debug2 "$_key: value cleared from config, exported value will be ignored." + _cleardeployconf "$_key" + eval $_key= + export $_key= + eval SAVED_$_key= + export SAVED_$_key= + fi +} From 192ec598a34397c33c4dd9bf5318053c4dfff5ed Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 19:52:06 +0800 Subject: [PATCH 301/687] feat: add `SYNO_LOCAL_HOSTNAME` to prevent remote deploy via temp admin method --- deploy/synology_dsm.sh | 53 ++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 0157b469..f1ff27a9 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -8,30 +8,34 @@ # Updated: 2023-07-03 # Issues: https://github.com/acmesh-official/acme.sh/issues/2727 ################################################################################ -# Usage: +# Usage (shown values are the examples): # 1. Set required environment variables: # - use automatically created temp admin user to authenticate -# `export SYNO_USE_TEMP_ADMIN=1` +# export SYNO_USE_TEMP_ADMIN=1 # - or provide your own admin user credential to authenticate -# 1. `export SYNO_USERNAME="adminUser"` -# 2. `export SYNO_PASSWORD="adminPassword"` -# 2. Set optional environment variables (shown values are the defaults) +# 1. export SYNO_USERNAME="adminUser" +# 2. export SYNO_PASSWORD="adminPassword" +# 2. Set optional environment variables # - common optional variables -# - `export SYNO_SCHEME="http"` -# - `export SYNO_HOSTNAME="localhost"` -# - `export SYNO_PORT="5000"` -# - `export SYNO_CREATE=""` - to allow creating the cert if it doesn't exist -# - `export SYNO_CERTIFICATE=""` - to replace a specific cert by its +# - export SYNO_SCHEME="http" - defaults to "http" +# - export SYNO_HOSTNAME="localhost" - defaults to "localhost" +# - export SYNO_PORT="5000" - defaults to "5000" +# - export SYNO_CREATE=1 - to allow creating the cert if it doesn't exist +# - export SYNO_CERTIFICATE="" - to replace a specific cert by its # description # - 2FA-OTP optional variables (with your own admin user) -# - `export SYNO_OTP_CODE=""` - required for 2FA-OTP, script won't require -# interactive input the code if set. -# - `export SYNO_DEVICE_NAME=""` - required for 2FA-OTP, script won't require -# interactive input the device name if set. -# - `export SYNO_DEVICE_ID=""` - required for omitting 2FA-OTP (might be -# deprecated, auth with OTP code instead) +# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to +# interactive input the OTP code +# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to +# interactive input the device name +# - export SYNO_DEVICE_ID="" - (deprecated) required for omitting 2FA-OTP +# (please auth with OTP code instead) +# - temp admin optional variables +# - export SYNO_LOCAL_HOSTNAME=1 - if set to 1, force to treat hostname is +# targeting current local machine (since +# this method only locally supported) # 3. Run command: -# `acme.sh --deploy --deploy-hook synology_dsm -d example.com`` +# acme.sh --deploy --deploy-hook synology_dsm -d example.com ################################################################################ # Dependencies: # - curl @@ -83,8 +87,6 @@ synology_dsm_deploy() { SYNO_DEVICE_ID= SYNO_DEVICE_NAME= SYNO_OTP_CODE= - # Pre-delete temp admin user if already exists. - synouser --del "$SYNO_USERNAME" >/dev/null 2>/dev/null else _debug2 SYNO_USERNAME "$SYNO_USERNAME" _secure_debug2 SYNO_PASSWORD "$SYNO_PASSWORD" @@ -178,7 +180,16 @@ synology_dsm_deploy() { # Assume the current account disabled 2FA-OTP, try to log in right away. else if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then + _getdeployconf SYNO_LOCAL_HOSTNAME + _debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}" + if [ "$SYNO_LOCAL_HOSTNAME" != "1" ] && [ "$SYNO_LOCAL_HOSTNAME" == "$SYNO_HOSTNAME" ]; then + if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then + _err "SYNO_USE_TEMP_ADMIN=1 Only support locally deployment, if you are sure that hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." + return 1 + fi + fi _debug "Creating temp admin user in Synology DSM..." + synouser --del "$SYNO_USERNAME" >/dev/null 2>/dev/null synouser --add "$SYNO_USERNAME" "$SYNO_PASSWORD" "" 0 "scruelt@hotmail.com" 0 >/dev/null if synogroup --help | grep -q '\-\-memberadd'; then synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null @@ -229,6 +240,7 @@ synology_dsm_deploy() { printf "Enter OTP code for user '%s': " "$SYNO_USERNAME" read -r SYNO_OTP_CODE fi + _secure_debug SYNO_OTP_CODE "${SYNO_OTP_CODE:-}" if [ -z "$SYNO_OTP_CODE" ]; then response='{"error":{"code":404}}' @@ -288,6 +300,7 @@ synology_dsm_deploy() { _cleardeployconf SYNO_DEVICE_ID _cleardeployconf SYNO_DEVICE_NAME _savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" + _savedeployconf SYNO_LOCAL_HOSTNAME "$SYNO_HOSTNAME" else _savedeployconf SYNO_USERNAME "$SYNO_USERNAME" _savedeployconf SYNO_PASSWORD "$SYNO_PASSWORD" @@ -308,7 +321,7 @@ synology_dsm_deploy() { if [ "$error_code" -eq 105 ]; then _err "Current user is not administrator and does not have sufficient permission for deploying." else - _err "Failed to fetch certificate info with error: $error_code, contact Synology for more info about it." + _err "Failed to fetch certificate info with error: $error_code, please try again or contact Synology to learn more." fi _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 From 50eda6b6786dae308b0959ec6b464c7bfca7408b Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 21:07:15 +0800 Subject: [PATCH 302/687] fix: lint --- deploy/synology_dsm.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index f1ff27a9..24a6f024 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -206,7 +206,6 @@ synology_dsm_deploy() { synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none _info "Temporary disabled enforce 2FA-OTP to complete authentication." _info "previous_otp_enforce_option" "$otp_enforce_option" - else otp_enforce_option="" fi @@ -403,16 +402,15 @@ _cleardeployconf() { # key __check2cleardeployconfexp() { - # Warning: _key="$1" _clear_key="CLEAR_$_key" # Clear saved settings if explicitly requested - if [ -n "$(eval echo \$$_clear_key)" ]; then + if [ -n "$(eval echo \$"$_clear_key")" ]; then _debug2 "$_key: value cleared from config, exported value will be ignored." _cleardeployconf "$_key" - eval $_key= - export $_key= - eval SAVED_$_key= - export SAVED_$_key= + eval "$_key"= + export "$_key"= + eval SAVED_"$_key"= + export SAVED_"$_key"= fi } From 68e3a12a918e349da1f0bd97aa7ce0906dd97484 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 23:38:44 +0800 Subject: [PATCH 303/687] feat: improve robustness of the usage of DSM tool `synogroup` --- deploy/synology_dsm.sh | 43 ++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 24a6f024..1e4be8e9 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -68,7 +68,7 @@ synology_dsm_deploy() { # Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" _getdeployconf SYNO_USE_TEMP_ADMIN - __check2cleardeployconfexp SYNO_USE_TEMP_ADMIN + _check2cleardeployconfexp SYNO_USE_TEMP_ADMIN _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then @@ -122,7 +122,7 @@ synology_dsm_deploy() { # Get the certificate description, but don't save it until we verify it's real _migratedeployconf SYNO_Certificate SYNO_CERTIFICATE "base64" _getdeployconf SYNO_CERTIFICATE - __check2cleardeployconfexp SYNO_CERTIFICATE + _check2cleardeployconfexp SYNO_CERTIFICATE _debug SYNO_CERTIFICATE "${SYNO_CERTIFICATE:-}" # shellcheck disable=SC1003 # We are not trying to escape a single quote @@ -189,16 +189,24 @@ synology_dsm_deploy() { fi fi _debug "Creating temp admin user in Synology DSM..." - synouser --del "$SYNO_USERNAME" >/dev/null 2>/dev/null - synouser --add "$SYNO_USERNAME" "$SYNO_PASSWORD" "" 0 "scruelt@hotmail.com" 0 >/dev/null - if synogroup --help | grep -q '\-\-memberadd'; then + if synogroup --help | grep -q '\-\-memberadd '; then + _temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null - else + elif synogroup --help | grep -q '\-\-member '; then # For supporting DSM 6.x which only has `--member` parameter. cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') - _secure_debug3 admin_users "$cur_admins$SYNO_USERNAME" - # shellcheck disable=SC2086 - synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null + if [ -n "$cur_admins" ]; then + _temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD + _secure_debug3 admin_users "$cur_admins$SYNO_USERNAME" + # shellcheck disable=SC2086 + synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null + else + _err "Tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead." + return 1 + fi + else + _err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead." + return 1 fi # havig a workaround to temporary disable enforce 2FA-OTP otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) @@ -385,13 +393,20 @@ _logout() { _debug3 response "$response" } +_temp_admin_create() { + _username="$1" + _password="$2" + synouser --del "$_username" >/dev/null 2>/dev/null + synouser --add "$_username" "$_password" "" 0 "scruelt@hotmail.com" 0 >/dev/null +} + _temp_admin_cleanup() { - flag=$1 - username=$2 + _flag=$1 + _username=$2 - if [ -n "${flag}" ]; then + if [ -n "${_flag}" ]; then _debug "Cleanuping temp admin info..." - synouser --del "$username" >/dev/null + synouser --del "$_username" >/dev/null fi } @@ -401,7 +416,7 @@ _cleardeployconf() { } # key -__check2cleardeployconfexp() { +_check2cleardeployconfexp() { _key="$1" _clear_key="CLEAR_$_key" # Clear saved settings if explicitly requested From ff090d2f74f994da4bca89b942b08bb714b25a46 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Mon, 26 Feb 2024 23:45:19 +0800 Subject: [PATCH 304/687] fix lint --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 1e4be8e9..7eca0f9c 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -190,13 +190,13 @@ synology_dsm_deploy() { fi _debug "Creating temp admin user in Synology DSM..." if synogroup --help | grep -q '\-\-memberadd '; then - _temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD + _temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD" synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null elif synogroup --help | grep -q '\-\-member '; then # For supporting DSM 6.x which only has `--member` parameter. cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}') if [ -n "$cur_admins" ]; then - _temp_admin_create $SYNO_USERNAME $SYNO_PASSWORD + _temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD" _secure_debug3 admin_users "$cur_admins$SYNO_USERNAME" # shellcheck disable=SC2086 synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null From bd3a2b1bb5765fb3bc7da130264883637a486511 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Tue, 27 Feb 2024 12:40:52 +0800 Subject: [PATCH 305/687] Prevent leaving blank lines in config file after cleared keys. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 9c5b1481..999c4f8d 100755 --- a/acme.sh +++ b/acme.sh @@ -2351,7 +2351,7 @@ _clear_conf() { _sdkey="$2" if [ "$_c_c_f" ]; then _conf_data="$(cat "$_c_c_f")" - echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" >"$_c_c_f" + echo "$_conf_data" | sed "/^$_sdkey *=.*$/d" >"$_c_c_f" else _err "config file is empty, can not clear" fi From 6af52933155c913d236f5be7bc1c5d4eccf05887 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 28 Feb 2024 02:00:07 +0800 Subject: [PATCH 306/687] doc: adjust --- deploy/synology_dsm.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 7eca0f9c..b3bd6197 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -23,17 +23,17 @@ # - export SYNO_CREATE=1 - to allow creating the cert if it doesn't exist # - export SYNO_CERTIFICATE="" - to replace a specific cert by its # description -# - 2FA-OTP optional variables (with your own admin user) -# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to -# interactive input the OTP code -# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to -# interactive input the device name -# - export SYNO_DEVICE_ID="" - (deprecated) required for omitting 2FA-OTP -# (please auth with OTP code instead) # - temp admin optional variables # - export SYNO_LOCAL_HOSTNAME=1 - if set to 1, force to treat hostname is # targeting current local machine (since # this method only locally supported) +# - exsiting admin 2FA-OTP optional variables +# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to +# interactive input the OTP code +# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to +# interactive input the device name +# - export SYNO_DEVICE_ID="" - (deprecated, auth with OTP code instead) +# required for omitting 2FA-OTP # 3. Run command: # acme.sh --deploy --deploy-hook synology_dsm -d example.com ################################################################################ From 2cbdf274b151178e89943706581512d3d5faa7ca Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 28 Feb 2024 18:30:06 +0800 Subject: [PATCH 307/687] feat(config_migrate): always remove domain old key & replace old value by new value --- acme.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/acme.sh b/acme.sh index 9c5b1481..80a94530 100755 --- a/acme.sh +++ b/acme.sh @@ -2393,16 +2393,21 @@ _readdomainconf() { #_migratedomainconf oldkey newkey base64encode _migratedomainconf() { - _old_key="$1" - _new_key="$2" - _b64encode="$3" - _value=$(_readdomainconf "$_old_key") - if [ -z "$_value" ]; then - return 1 # oldkey is not found - fi - _savedomainconf "$_new_key" "$_value" "$_b64encode" - _cleardomainconf "$_old_key" - _debug "Domain config $_old_key has been migrated to $_new_key" +  _old_key="$1" +  _new_key="$2" +  _b64encode="$3" +  _old_value=$(_readdomainconf "$_old_key") +  _cleardomainconf "$_old_key" +  if [ -z "$_old_value" ]; then +    return 1 # migrated failed: old value is empty +  fi +  _new_value=$(_readdomainconf "$_new_key") +  if [ -n "$_new_value" ]; then +    _debug "Domain config new key exists, old key $_old_key='$_old_value' has been removed." +    return 1 # migrated failed: old value replaced by new value +  fi +  _savedomainconf "$_new_key" "$_old_value" "$_b64encode" +  _debug "Domain config $_old_key has been migrated to $_new_key." } #_migratedeployconf oldkey newkey base64encode From 79640f6b7d3f58e52a9c7a6c22244c8648e15a80 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 28 Feb 2024 20:02:24 +0800 Subject: [PATCH 308/687] replace wired space symbol --- acme.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/acme.sh b/acme.sh index 80a94530..1b6b299d 100755 --- a/acme.sh +++ b/acme.sh @@ -2393,21 +2393,21 @@ _readdomainconf() { #_migratedomainconf oldkey newkey base64encode _migratedomainconf() { -  _old_key="$1" -  _new_key="$2" -  _b64encode="$3" -  _old_value=$(_readdomainconf "$_old_key") -  _cleardomainconf "$_old_key" -  if [ -z "$_old_value" ]; then -    return 1 # migrated failed: old value is empty -  fi -  _new_value=$(_readdomainconf "$_new_key") -  if [ -n "$_new_value" ]; then -    _debug "Domain config new key exists, old key $_old_key='$_old_value' has been removed." -    return 1 # migrated failed: old value replaced by new value -  fi -  _savedomainconf "$_new_key" "$_old_value" "$_b64encode" -  _debug "Domain config $_old_key has been migrated to $_new_key." + _old_key="$1" + _new_key="$2" + _b64encode="$3" + _old_value=$(_readdomainconf "$_old_key") + _cleardomainconf "$_old_key" + if [ -z "$_old_value" ]; then + return 1 # migrated failed: old value is empty + fi + _new_value=$(_readdomainconf "$_new_key") + if [ -n "$_new_value" ]; then + _debug "Domain config new key exists, old key $_old_key='$_old_value' has been removed." + return 1 # migrated failed: old value replaced by new value + fi + _savedomainconf "$_new_key" "$_old_value" "$_b64encode" + _debug "Domain config $_old_key has been migrated to $_new_key." } #_migratedeployconf oldkey newkey base64encode From d3b022fe17d1f7920e3896b8045a426b43229053 Mon Sep 17 00:00:00 2001 From: laraveluser <44818308+laraveluser@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:32:21 +0100 Subject: [PATCH 309/687] Update dns_limacity.sh --- dnsapi/dns_limacity.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index f497e396..649550ae 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -66,7 +66,7 @@ _lima_get_domain_id() { p=1 domains=$(_get "${APIBASE}/domains.json") - if [ "$(echo "$domains" | _egrep_o "{.*\"domains\"")" ]; then + if [ "$(echo "$domains" | _egrep_o "\{.*""domains""")" ]; then response="$(echo "$domains" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) @@ -76,7 +76,7 @@ _lima_get_domain_id() { return 1 fi - hostedzone="$(echo "$response" | _egrep_o "{.*\"unicode_fqdn\":\s*\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "\{.*""unicode_fqdn""[^,]+""$h"".*\}")" if [ "$hostedzone" ]; then LIMACITY_DOMAINID=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$LIMACITY_DOMAINID" ]; then From 92d37f6eaf4f28788e4ccf7201a75a75ee7c3a5c Mon Sep 17 00:00:00 2001 From: Jesse Miller Date: Wed, 6 Mar 2024 15:56:42 -0700 Subject: [PATCH 310/687] Quote echo $data in _porkbun_rest Quote echo $data in _porkbun_rest to avoid brace expansion under ksh (OpenBSD). --- dnsapi/dns_porkbun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index ad4455b6..83553e16 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -134,7 +134,7 @@ _porkbun_rest() { api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') - test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," + test -z "$data" && data="{" || data="$(echo "$data" | cut -d'}' -f1)," data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" export _H1="Content-Type: application/json" From 0bf87bf4afedbdc25bbd836f3b6f3d5bde40b042 Mon Sep 17 00:00:00 2001 From: Harald Kapper <4014716+hknet@users.noreply.github.com> Date: Mon, 11 Mar 2024 00:44:53 +0100 Subject: [PATCH 311/687] dns-record TTL set to 300 reduce TTL for the TXT record from 3600 to 300 to have an easier way to replicate changes for the dns-verification in case multiple submissions for a specific record/domain are done within an hour. --- dnsapi/dns_kappernet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 0a8951cb..e9ea0a4d 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -41,7 +41,7 @@ dns_kappernet_add() { _debug _domain "DOMAIN: $_domain" _info "Trying to add TXT DNS Record" - data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then if _contains "$response" "{\"OK\":true"; then @@ -81,7 +81,7 @@ dns_kappernet_rm() { _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname containing $txtvalue" - data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 From 39fa40ab12cd1a2d3edd8f9c1f1245086f414aaf Mon Sep 17 00:00:00 2001 From: Harald Kapper <4014716+hknet@users.noreply.github.com> Date: Mon, 11 Mar 2024 03:27:17 +0100 Subject: [PATCH 312/687] fixed secret+key storage-usage fixed the key and secret handling via acme account.conf --- dnsapi/dns_kappernet.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 0a8951cb..914671d6 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -6,8 +6,7 @@ #KAPPERNETDNS_Key="yourKAPPERNETapikey" #KAPPERNETDNS_Secret="yourKAPPERNETapisecret" - -KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" +#KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" ############################################################################### # called with @@ -19,10 +18,9 @@ dns_kappernet_add() { KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then - KAPPERNETDNS_Key="" - KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" _err "support@kapper.net to get your key and secret." @@ -41,7 +39,7 @@ dns_kappernet_add() { _debug _domain "DOMAIN: $_domain" _info "Trying to add TXT DNS Record" - data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then if _contains "$response" "{\"OK\":true"; then @@ -66,10 +64,9 @@ dns_kappernet_rm() { KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then - KAPPERNETDNS_Key="" - KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" _err "support@kapper.net to get your key and secret." @@ -81,7 +78,7 @@ dns_kappernet_rm() { _saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret" _info "Trying to remove the TXT Record: $fullhostname containing $txtvalue" - data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D" + data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D" if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then if _contains "$response" "{\"OK\":true"; then return 0 @@ -141,7 +138,7 @@ _kappernet_api() { if [ "$method" = "GET" ]; then response="$(_get "$url")" else - _err "Unsupported method" + _err "Unsupported method or missing Secret/Key" return 1 fi From b2c6b9a320a1c729bc35091a43ee5414f822da5a Mon Sep 17 00:00:00 2001 From: Tim Dery Date: Mon, 11 Mar 2024 10:33:14 -0700 Subject: [PATCH 313/687] attempt _use_metadata fix from j-c-m --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 1df5b21b..27923b64 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -239,7 +239,7 @@ _use_metadata() { _normalizeJson | tr '{,}' '\n' | while read -r _line; do - _key="$(echo "${_line%%:*}" | tr -d '"')" + _key="$(echo "${_line%%:*}" | tr -d '\"')" _value="${_line#*:}" _debug3 "_key" "$_key" _secure_debug3 "_value" "$_value" From 2728d2aa6eec98338affaa92adf93bc692bd3fcf Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 18 Mar 2024 21:09:49 +0100 Subject: [PATCH 314/687] fix format --- deploy/haproxy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/haproxy.sh b/deploy/haproxy.sh index 4b6ca0e1..c8491d92 100644 --- a/deploy/haproxy.sh +++ b/deploy/haproxy.sh @@ -373,7 +373,7 @@ haproxy_deploy() { return ${_ret} fi if [ "${_newcert}" = "1" ]; then - # if this is a new certificate, it needs to be inserted into the crt-list` + # if this is a new certificate, it needs to be inserted into the crt-list` _socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'" _debug _socat_cert_add_cmd "${_socat_cert_add_cmd}" eval "${_socat_cert_add_cmd}" From 5e64781d65a8ca28e132c09a21f66c5da2613b90 Mon Sep 17 00:00:00 2001 From: Adrian Fedoreanu Date: Tue, 19 Mar 2024 19:41:33 +0100 Subject: [PATCH 315/687] update _get_root check --- dnsapi/dns_1984hosting.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index e4ef2e4b..a6def06b 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -215,8 +215,8 @@ _get_root() { return 1 fi - _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." - if _contains "$_response" "serial" && ! _contains "$_response" "null"; then + _authget "https://1984.hosting/domains/zonestatus/$h/?cached=no" + if _contains "$_response" '"ok": true'; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 @@ -250,7 +250,6 @@ _authget() { } # Truncate huge HTML response -# Echo: Argument list too long _htmlget() { export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2") From 492826a7f2d2279e7c01ef23215b49ac51c49908 Mon Sep 17 00:00:00 2001 From: annieoxi Date: Tue, 26 Mar 2024 12:35:54 +0100 Subject: [PATCH 316/687] Fix: Decode eab_hmac_key as single-line This commit resolves the issue #5068. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 1b6b299d..1fa47989 100755 --- a/acme.sh +++ b/acme.sh @@ -3773,7 +3773,7 @@ _regAccount() { eab_sign_t="$eab_protected64.$eab_payload64" _debug3 eab_sign_t "$eab_sign_t" - key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 multi | _hex_dump | tr -d ' ')" + key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" _debug3 key_hex "$key_hex" eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) From 4fcddd18935af75b8f337bf2b4f51317ecee6458 Mon Sep 17 00:00:00 2001 From: asauerwein Date: Sun, 31 Mar 2024 09:16:21 +0200 Subject: [PATCH 317/687] add template option --- deploy/panos.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 89458e5f..61e40678 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -12,6 +12,9 @@ # export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role # export PANOS_PASS="" # +# OPTIONAL +# export PANOS_TEMPLATE="" #Template Name of panorama managed devices +# # The script will automatically generate a new API key if # no key is found, or if a saved key has expired or is invalid. @@ -77,7 +80,10 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + if [ "$_panos_template" ]; then + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template" + fi fi if [ "$type" = 'key' ]; then panos_url="${panos_url}?type=import" @@ -87,6 +93,9 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + if [ "$_panos_template" ]; then + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template" + fi fi #Close multipart content="$content${nl}--$delim--${nl}${nl}" @@ -173,10 +182,20 @@ panos_deploy() { unset _panos_key fi + # PANOS_TEMPLATE + if [ "$PANOS_TEMPLATE" ]; then + _debug "Detected ENV variable PANOS_TEMPLATE. Saving to file." + _savedeployconf PANOS_TEMPLATE "$PANOS_TEMPLATE" 1 + else + _debug "Attempting to load variable PANOS_TEMPLATE from file." + _getdeployconf PANOS_TEMPLATE + fi + #Store variables _panos_host=$PANOS_HOST _panos_user=$PANOS_USER _panos_pass=$PANOS_PASS + _panos_template=$PANOS_TEMPLATE #Test API Key if found. If the key is invalid, the variable _panos_key will be unset. if [ "$_panos_host" ] && [ "$_panos_key" ]; then From c51104f956dcb283b12080afb22267a5fe7d32e0 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 31 Mar 2024 20:33:57 +0200 Subject: [PATCH 318/687] fix format --- deploy/panos.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/panos.sh b/deploy/panos.sh index 61e40678..0dc1b2f0 100644 --- a/deploy/panos.sh +++ b/deploy/panos.sh @@ -14,7 +14,7 @@ # # OPTIONAL # export PANOS_TEMPLATE="" #Template Name of panorama managed devices -# +# # The script will automatically generate a new API key if # no key is found, or if a saved key has expired or is invalid. @@ -80,7 +80,7 @@ deployer() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" - content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" if [ "$_panos_template" ]; then content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template" fi From 43b5ea801f4baa162f921769317a6a8ad85576a0 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 21 Apr 2024 11:21:45 +0200 Subject: [PATCH 319/687] convert to pkcs12 when renewal fix https://github.com/acmesh-official/acme.sh/issues/3474#issuecomment-2058126129 --- acme.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/acme.sh b/acme.sh index 1fa47989..d154cf77 100755 --- a/acme.sh +++ b/acme.sh @@ -1430,6 +1430,9 @@ _toPkcs() { else ${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca" fi + if [ "$?" == "0" ]; then + _savedomainconf "Le_PFXPassword" "$pfxPassword" + fi } @@ -5338,6 +5341,12 @@ $_authorizations_map" _savedomainconf "Le_NextRenewTimeStr" "$Le_NextRenewTimeStr" _savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime" + #convert to pkcs12 + if [ "$Le_PFXPassword" ]; then + _toPkcs "$CERT_PFX_PATH" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$Le_PFXPassword" + fi + export CERT_PFX_PATH + if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then _savedomainconf "Le_RealCertPath" "$_real_cert" _savedomainconf "Le_RealCACertPath" "$_real_ca" From 9ff89b570faccafe1388df4217bfa09db210c43e Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 25 Apr 2024 04:02:49 +0800 Subject: [PATCH 320/687] fix(deploy_dsm): missing gerp -P option on busybox Fixes: #5105 --- deploy/synology_dsm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index b3bd6197..d6930a28 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -227,7 +227,8 @@ synology_dsm_deploy() { fi fi - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" # Account has 2FA-OTP enabled, since error 403 reported. # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf if [ "$error_code" == "403" ]; then @@ -261,7 +262,8 @@ synology_dsm_deploy() { _secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID" fi fi - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" fi if [ -n "$error_code" ]; then @@ -323,7 +325,8 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" if [ -n "$error_code" ]; then if [ "$error_code" -eq 105 ]; then _err "Current user is not administrator and does not have sufficient permission for deploying." From cd01104de9dace481baf4c48bcca010ee074d1bb Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Thu, 25 Apr 2024 13:39:05 +0800 Subject: [PATCH 321/687] fix(deploy_dsm): ensure grep get the error code Added grep -o option to ensure the script won't get other digits as the error code result --- deploy/synology_dsm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index d6930a28..342fb32e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -227,7 +227,7 @@ synology_dsm_deploy() { fi fi - error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') _debug2 error_code "$error_code" # Account has 2FA-OTP enabled, since error 403 reported. # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf @@ -262,7 +262,7 @@ synology_dsm_deploy() { _secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID" fi fi - error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') _debug2 error_code "$error_code" fi @@ -325,7 +325,7 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - error_code=$(echo "$response" | grep '"error":' | grep '"code":[0-9]*' | grep -o '[0-9]*') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') _debug2 error_code "$error_code" if [ -n "$error_code" ]; then if [ "$error_code" -eq 105 ]; then From f44dec2c8df66323733baad579970190fc7a25fa Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 18:43:35 +0300 Subject: [PATCH 322/687] add new provider - Alviy.com --- dnsapi/dns_alviy.sh | 182 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 dnsapi/dns_alviy.sh diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh new file mode 100644 index 00000000..4f736a94 --- /dev/null +++ b/dnsapi/dns_alviy.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env sh + +# Alviy domain api +# Get API key and secret from https://cloud.alviy.com/token +# +# Alviy_token="some-secret-key" +# +# Ex.: acme.sh --issue --staging --dns dns_alviy -d "*.s.example.com" -d "s.example.com" + +Alviy_Api="https://cloud.alviy.com/api/v1" + +######## Public functions ##################### + +#Usage: dns_alviy_add _acme-challenge.www.domain.com "content" +dns_alviy_add() { + fulldomain=$1 + txtvalue=$2 + + Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}" + if [ -z "$Alviy_token" ]; then + Alviy_token="" + _err "Please specify Alviy token." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable Alviy_token "$Alviy_token" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting existing records" + if _alviy_txt_exists $_domain $fulldomain $txtvalue; then + _info "This record already exists, skipping" + return 0 + fi + + _add_data="{\"content\":\"$txtvalue\",\"type\":\"TXT\"}" + _debug2 _add_data "$_add_data" + _info "Adding record" + if _alviy_rest POST "zone/$_domain/domain/$fulldomain/" "$_add_data"; then + _debug "Checking updated records of '${fulldomain}'" + + if ! _alviy_txt_exists $_domain $fulldomain $txtvalue; then + _err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!" + return 1 + fi + + else + _err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set." + return 1 + fi + + _sleep 10 + _info "Added TXT record '${txtvalue}' for '${fulldomain}'." + return 0 +} + +#fulldomain +dns_alviy_rm() { + fulldomain=$1 + txtvalue=$2 + + Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if ! _alviy_txt_exists $_domain $fulldomain $txtvalue; then + _info "The record does not exist, skip" + return 0 + fi + + _add_data="" + uuid=$(echo $response |tr "{" "\n"|grep $txtvalue|tr "," "\n"|grep uuid|cut -d \" -f4) + # delete record + _debug "Delete TXT record for '${fulldomain}'" + if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then + _err "Cannot delete empty TXT record for '$fulldomain'" + return 1 + fi + _info "The record '$fulldomain'='$txtvalue' deleted" +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _alviy_rest GET "zone/$h"; then + return 1 + fi + + if _contains "$response" '"code":"NOT_FOUND"'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_alviy_txt_exists() { + zone=$1 + domain=$2 + content_data=$3 + _debug "Getting existing records" + + if ! _alviy_rest GET "zone/$zone/domain/$domain/TXT/"; then + _info "The record does not exist" + return 1 + fi + + if ! _contains "$response" "$3"; then + _info "The record has other value" + return 1 + fi + # GOOD code return - TRUE function + return 0 +} + +_alviy_rest() { + method=$1 + path="$2" + content_data="$3" + _debug "$path" + + export _H1="Authorization: Bearer $Alviy_token" + export _H2="Content-Type: application/json" + + if [ "$content_data" ] || [ "$method" = "DELETE" ]; then + _debug "data ($method): " "$content_data" + response="$(_post "$content_data" "$Alviy_Api/$path" "" "$method")" + else + response="$(_get "$Alviy_Api/$path")" + fi + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" == "401" ]; then + _err "It seems that your api key or secret is not correct." + return 1 + fi + + + if [ "$_code" != "200" ]; then + _err "API call error ($method): $path Response code $_code" + fi + if [ "$?" != "0" ]; then + _err "error on rest call ($method): $path. Response:" + _err "$response" + return 1 + fi + _debug2 response "$response" + return 0 +} + From 78ba205f4d1da2ccda76482c4fb615333e7a91dd Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:37:49 +0300 Subject: [PATCH 323/687] DNS test init --- dnsapi/dns_alviy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 4f736a94..31d6a9c9 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,6 +1,7 @@ #!/usr/bin/env sh # Alviy domain api +# # Get API key and secret from https://cloud.alviy.com/token # # Alviy_token="some-secret-key" From 2fcda9a73ae2f4a6d8dc30e12c61d14cfc8bc7ee Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:07:29 +0300 Subject: [PATCH 324/687] Quotes recomendations --- dnsapi/dns_alviy.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 31d6a9c9..1077ec06 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -37,7 +37,7 @@ dns_alviy_add() { _debug _domain "$_domain" _debug "Getting existing records" - if _alviy_txt_exists $_domain $fulldomain $txtvalue; then + if _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then _info "This record already exists, skipping" return 0 fi @@ -48,7 +48,7 @@ dns_alviy_add() { if _alviy_rest POST "zone/$_domain/domain/$fulldomain/" "$_add_data"; then _debug "Checking updated records of '${fulldomain}'" - if ! _alviy_txt_exists $_domain $fulldomain $txtvalue; then + if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then _err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!" return 1 fi @@ -79,13 +79,13 @@ dns_alviy_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - if ! _alviy_txt_exists $_domain $fulldomain $txtvalue; then + if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then _info "The record does not exist, skip" return 0 fi _add_data="" - uuid=$(echo $response |tr "{" "\n"|grep $txtvalue|tr "," "\n"|grep uuid|cut -d \" -f4) + uuid=$(echo "$response" |tr "{" "\n"|grep "$txtvalue"|tr "," "\n"|grep uuid|cut -d \" -f4) # delete record _debug "Delete TXT record for '${fulldomain}'" if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then @@ -163,7 +163,7 @@ _alviy_rest() { response="$(_get "$Alviy_Api/$path")" fi _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" - if [ "$_code" == "401" ]; then + if [ "$_code" = "401" ]; then _err "It seems that your api key or secret is not correct." return 1 fi From 2e9f1592252d7d7866de846449b89e1e1ed6da79 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:15:16 +0300 Subject: [PATCH 325/687] shfmt --- dnsapi/dns_alviy.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 1077ec06..975f20d4 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -85,7 +85,7 @@ dns_alviy_rm() { fi _add_data="" - uuid=$(echo "$response" |tr "{" "\n"|grep "$txtvalue"|tr "," "\n"|grep uuid|cut -d \" -f4) + uuid=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | tr "," "\n" | grep uuid | cut -d \" -f4) # delete record _debug "Delete TXT record for '${fulldomain}'" if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then @@ -168,7 +168,6 @@ _alviy_rest() { return 1 fi - if [ "$_code" != "200" ]; then _err "API call error ($method): $path Response code $_code" fi @@ -180,4 +179,3 @@ _alviy_rest() { _debug2 response "$response" return 0 } - From e1acea52f8de193e68d0b377c8b87cc8ddc03932 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:27:04 +0300 Subject: [PATCH 326/687] run DNS test --- dnsapi/dns_alviy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 975f20d4..eab133cb 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,7 +1,6 @@ #!/usr/bin/env sh # Alviy domain api -# # Get API key and secret from https://cloud.alviy.com/token # # Alviy_token="some-secret-key" From d1df5f3021d00418c2884895f5697b181b3d82cb Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:36:11 +0300 Subject: [PATCH 327/687] test DNS --- dnsapi/dns_alviy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index eab133cb..3ea9ebd3 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,5 +1,5 @@ #!/usr/bin/env sh - +# # Alviy domain api # Get API key and secret from https://cloud.alviy.com/token # From 4a8c2251e0ba445a4cb68858132eece7d801ee54 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:47:53 +0300 Subject: [PATCH 328/687] 4th+ level domain --- dnsapi/dns_alviy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 3ea9ebd3..fe1048fe 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -104,7 +104,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev ) if [ -z "$h" ]; then #not valid return 1 From c0b87adee55076b4ef23b496e4ee9cc50c40b7ec Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:51:32 +0300 Subject: [PATCH 329/687] shfmt --- dnsapi/dns_alviy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index fe1048fe..8ff2684e 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -104,7 +104,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev ) + h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) if [ -z "$h" ]; then #not valid return 1 From 7ef1340e2add05a48189312f1a7f507224087fc7 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:16:11 +0300 Subject: [PATCH 330/687] Update dns_alviy.sh --- dnsapi/dns_alviy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 8ff2684e..d90513e8 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -110,7 +110,7 @@ _get_root() { return 1 fi - if ! _alviy_rest GET "zone/$h"; then + if ! _alviy_rest GET "zone/$h/"; then return 1 fi From 03b53cbb60c9131d872637016f759b7bb57cfbe2 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Fri, 26 Apr 2024 20:38:01 +0300 Subject: [PATCH 331/687] run DNS test --- dnsapi/dns_alviy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index d90513e8..6e75c9ab 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,6 +1,7 @@ #!/usr/bin/env sh # # Alviy domain api +# # Get API key and secret from https://cloud.alviy.com/token # # Alviy_token="some-secret-key" From 4bf4259dda037e6c2c117e8e7e7d9618cd36dfb3 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Fri, 26 Apr 2024 23:05:42 +0300 Subject: [PATCH 332/687] Update _get_root logic --- dnsapi/dns_alviy.sh | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 6e75c9ab..6a99c6da 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -103,28 +103,24 @@ dns_alviy_rm() { _get_root() { domain=$1 i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) - if [ -z "$h" ]; then - #not valid - return 1 - fi + h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) + if [ -z "$h" ]; then + #not valid + _debug "can't get host from $domain" + return 1 + fi - if ! _alviy_rest GET "zone/$h/"; then - return 1 - fi + if ! _alviy_rest GET "zone/$h/"; then + return 1 + fi - if _contains "$response" '"code":"NOT_FOUND"'; then - _debug "$h not found" - else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain="$h" - return 0 - fi - p="$i" - i=$(_math "$i" + 1) - done + if _contains "$response" '"code":"NOT_FOUND"'; then + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | rev | cut -d . -f 3- | rev) + _domain="$h" + return 0 + fi return 1 } From 1078fdc157072d88d7658ef92f4ed4b359f904e3 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Fri, 26 Apr 2024 23:25:38 +0300 Subject: [PATCH 333/687] fix Shellcheck --- dnsapi/dns_alviy.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 6a99c6da..2f8b7994 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -102,16 +102,16 @@ dns_alviy_rm() { # _domain=domain.com _get_root() { domain=$1 - i=2 h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) if [ -z "$h" ]; then #not valid - _debug "can't get host from $domain" + hd=$(printf "%s" "$domain" | rev) + _debug "can't get host from $domain $hd" return 1 fi if ! _alviy_rest GET "zone/$h/"; then - return 1 + return 1 fi if _contains "$response" '"code":"NOT_FOUND"'; then From e814cccc4490d1b8c2552258e260e8537e57cbec Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 00:06:22 +0300 Subject: [PATCH 334/687] Update dns_alviy.sh --- dnsapi/dns_alviy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 2f8b7994..93b5750f 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -105,8 +105,8 @@ _get_root() { h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) if [ -z "$h" ]; then #not valid - hd=$(printf "%s" "$domain" | rev) - _debug "can't get host from $domain $hd" + _alviy_rest GET "zone/$domain/" + _debug "can't get host from $domain" return 1 fi From dbe7cb8dbb5650169f8d21f2efce6a06bd9175c6 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 09:55:38 +0300 Subject: [PATCH 335/687] remove rev command --- dnsapi/dns_alviy.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 93b5750f..9501bff1 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -102,7 +102,15 @@ dns_alviy_rm() { # _domain=domain.com _get_root() { domain=$1 - h=$(printf "%s" "$domain" | rev | cut -d . -f 1-2 | rev) + i=3 + a="init" + while [ ! -z $a ] + do + a=$(printf "%s" "$domain" | cut -d . -f $i-) + i=`expr $i + 1` + done + num=`expr $i - 3` + h=$(printf "%s" "$domain" | cut -d . -f $num-) if [ -z "$h" ]; then #not valid _alviy_rest GET "zone/$domain/" @@ -117,7 +125,8 @@ _get_root() { if _contains "$response" '"code":"NOT_FOUND"'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | rev | cut -d . -f 3- | rev) + s_n=`expr $num - 1` + _sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s_n) _domain="$h" return 0 fi From dab244ad2536f43727065700de807d65d4ebaeef Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 11:29:30 +0300 Subject: [PATCH 336/687] shfmt --- dnsapi/dns_alviy.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 9501bff1..d87d1c6e 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -104,13 +104,12 @@ _get_root() { domain=$1 i=3 a="init" - while [ ! -z $a ] - do + while [ ! -z $a ]; do a=$(printf "%s" "$domain" | cut -d . -f $i-) - i=`expr $i + 1` + i=$(($i + 1)) done - num=`expr $i - 3` - h=$(printf "%s" "$domain" | cut -d . -f $num-) + n=$(($i - 3)) + h=$(printf "%s" "$domain" | cut -d . -f $n-) if [ -z "$h" ]; then #not valid _alviy_rest GET "zone/$domain/" @@ -125,8 +124,8 @@ _get_root() { if _contains "$response" '"code":"NOT_FOUND"'; then _debug "$h not found" else - s_n=`expr $num - 1` - _sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s_n) + s=$(($n - 1)) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s) _domain="$h" return 0 fi From 54eec82311c90cca2ce99ff97e5c8132679e1e50 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 11:45:14 +0300 Subject: [PATCH 337/687] spellcheck --- dnsapi/dns_alviy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index d87d1c6e..77c16405 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -104,11 +104,11 @@ _get_root() { domain=$1 i=3 a="init" - while [ ! -z $a ]; do + while [ -n $a ]; do a=$(printf "%s" "$domain" | cut -d . -f $i-) - i=$(($i + 1)) + i=$((i + 1)) done - n=$(($i - 3)) + n=$((i - 3)) h=$(printf "%s" "$domain" | cut -d . -f $n-) if [ -z "$h" ]; then #not valid @@ -124,7 +124,7 @@ _get_root() { if _contains "$response" '"code":"NOT_FOUND"'; then _debug "$h not found" else - s=$(($n - 1)) + s=$((n - 1)) _sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s) _domain="$h" return 0 From d73953af3d5442179874d03f67c460e9cf043280 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:28:06 +0300 Subject: [PATCH 338/687] spellcheck --- dnsapi/dns_alviy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 77c16405..94832e16 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -104,7 +104,7 @@ _get_root() { domain=$1 i=3 a="init" - while [ -n $a ]; do + while [ -n "$a" ]; do a=$(printf "%s" "$domain" | cut -d . -f $i-) i=$((i + 1)) done From aa41df4e7db492f1243e4828203ceaed67d7da96 Mon Sep 17 00:00:00 2001 From: alviy <96288197+alviy@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:49:37 +0300 Subject: [PATCH 339/687] run test --- dnsapi/dns_alviy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 94832e16..2217b0df 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,5 +1,4 @@ #!/usr/bin/env sh -# # Alviy domain api # # Get API key and secret from https://cloud.alviy.com/token From 517baa3235cb5f94ffa866884cd65fa1147c3d10 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Mon, 29 Apr 2024 22:54:31 +1000 Subject: [PATCH 340/687] test DNS for v2 (actual) --- dnsapi/dns_selectel.sh | 479 +++++++++++++++++++++++++++++++++++------ 1 file changed, 418 insertions(+), 61 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1b09882d..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,10 +1,29 @@ #!/usr/bin/env sh +# переменные, которые должны быть определены перед запуском +# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). +# По-умолчанию: v2 +# Если SL_Ver="v1" +# export SL_Key="API_KEY" - Токен Selectel (API key) +# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# https://my.selectel.ru/profile/apikeys +# Если SL_Ver="v2" +# export SL_Expire=60 - время жизни token в минутах (0-1440). +# По-умолчанию: 1400 минут +# export SL_Login_ID= - номер аккаунта в панели управления; +# export SL_Project_Name= - имя проекта. +# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: +# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи +# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. +# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. # -#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# Авторизация описана в: +# https://developers.selectel.ru/docs/control-panel/authorization/ +# https://developers.selectel.com/docs/control-panel/authorization/ -SL_Api="https://api.selectel.ru/domains/v1" +SL_Api="https://api.selectel.ru/domains" +auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens" +_sl_sep='#' ######## Public functions ##################### @@ -13,17 +32,16 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify selectel.ru api key yet." - _err "Please create you key and try again." + #if ! _sl_init_vars; then + if ! _sl_init_vars; then return 1 fi - - #save the api key to the account conf file. - _saveaccountconf_mutable SL_Key "$SL_Key" + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -35,11 +53,68 @@ dns_selectel_add() { _debug _domain "$_domain" _info "Adding record" - if _sl_rest POST "/$_domain_id/records/" "{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"$fulldomain\", \"content\": \"$txtvalue\"}"; then - if _contains "$response" "$txtvalue" || _contains "$response" "record_already_exists"; then + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") + _debug txtvalue "$txtvalue" + _text_tmp='\"'$_text_tmp'\"' + _debug _text_tmp "$_text_tmp" + _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _debug3 _data "$_data" + + if _sl_rest POST "$_ext_uri" "$_data"; then + if _contains "$response" "$txtvalue"; then _info "Added, OK" return 0 fi + if _contains "$response" "already_exists"; then + # запись TXT с $fulldomain уже существует + if [ "$SL_Ver" = "v2" ]; then + # надо добавить к существующей записи еще один content + # + # считать записи rrset + _debug "Getting txt records" + _sl_rest GET "${_ext_uri}" + # Если в данной записи, есть текстовое значение $txtvalue, + # то все хорошо, добавлять ничего не надо и результат успешный + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + return 0 + fi + # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" + _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" + _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" + _debug3 _record_seg "$_record_seg" + _debug3 _record_array "$_record_array" + _debug3 _record_array "$_record_id" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then + _info "Added, OK" + return 0 + fi + elif [ "$SL_Ver" = "v1" ]; then + _info "Added, OK" + return 0 + fi + fi fi _err "Add txt record error." return 1 @@ -49,16 +124,17 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify slectel api key yet." - _err "Please create you key and try again." + #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi - + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" + # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -67,32 +143,90 @@ dns_selectel_rm() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - + # + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + # _debug "Getting txt records" - _sl_rest GET "/${_domain_id}/records/" - + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _sl_rest GET "${_ext_uri}" + # if ! _contains "$response" "$txtvalue"; then _err "Txt record not found" return 1 fi - - _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - _debug2 "_record_seg" "$_record_seg" + # + if [ "$SL_Ver" = "v2" ]; then + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" + _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + elif [ "$SL_Ver" = "v1" ]; then + _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" + # record id + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _debug3 "_record_seg" "$_record_seg" if [ -z "$_record_seg" ]; then _err "can not find _record_seg" return 1 fi - - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" - _debug2 "_record_id" "$_record_id" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 fi - - if ! _sl_rest DELETE "/$_domain_id/records/$_record_id"; then - _err "Delete record error." - return 1 + _debug3 "_record_id" "$_record_id" + # delete all record type TXT with text $txtvalue + if [ "$SL_Ver" = "v2" ]; then + # actual + #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; + _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" + # uri record for DEL or PATCH + _del_uri="${_ext_uri}${_record_id}" + if [ -z "$_new_arr" ]; then + # удалить запись + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + else + # обновить запись, удалив content + _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_del_uri}" "$_data"; then + _info "Patched, OK: ${_del_uri}" + else + _err "Patched record error: ${_del_uri}." + fi + fi + else + # legacy + for _one_id in $_record_id; do + _del_uri="${_ext_uri}${_one_id}" + _debug2 _ext_uri "$_del_uri" + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + done fi return 0 } @@ -105,51 +239,114 @@ dns_selectel_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 + # + if [ "$SL_Ver" = 'v1' ]; then + # version API 1 + if ! _sl_rest GET "/"; then + return 1 + fi + i=2 + p=1 + while true; do + #h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi - if ! _sl_rest GET "/"; then + if _contains "$response" "\"name\" *: *\"$h\","; then + #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + if ! _sl_rest GET "/$h"; then + _err "Error read records of all domains $SL_Ver" + return 1 + fi + _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + _err "Error read records of all domains $SL_Ver" return 1 - fi - - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then + elif [ "$SL_Ver" = "v2" ]; then + # version API 2 + _ext_uri='/zones/' + domain="${domain}." + _debug "domain:: " "$domain" + # read records of all domains + if ! _sl_rest GET "$_ext_uri"; then #not valid + _err "Error read records of all domains $SL_Ver" return 1 fi - - if _contains "$response" "\"name\" *: *\"$h\","; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - _debug "Getting domain id for $h" - if ! _sl_rest GET "/$h"; then + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + _err "The domain was not found among the registered ones" return 1 fi - _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" - return 0 - fi - p=$i - i=$(_math "$i" + 1) - done - return 1 + + _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") + _debug "_domain_record:: " "$_domain_record" + if [ -n "$_domain_record" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" + _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + #not valid + _err "Error read records of all domains $SL_Ver" + return 1 + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi } +################################################################# +# use: method add_url body _sl_rest() { m=$1 ep="$2" data="$3" - _debug "$ep" - export _H1="X-Token: $SL_Key" + _token=$(_get_auth_token) + #_debug "$_token" + if [ -z "$_token" ]; then + _err "BAD key or token $ep" + return 1 + fi + if [ "$SL_Ver" = v2 ]; then + _h1_name="X-Auth-Token" + else + _h1_name='X-Token' + fi + export _H1="${_h1_name}: ${_token}" export _H2="Content-Type: application/json" + _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" + _debug3 "_H1:" "$_H1" + _debug3 "_H2:" "$_H2" if [ "$m" != "GET" ]; then _debug data "$data" - response="$(_post "$data" "$SL_Api/$ep" "" "$m")" + response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else - response="$(_get "$SL_Api/$ep")" + response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi if [ "$?" != "0" ]; then @@ -159,3 +356,163 @@ _sl_rest() { _debug2 response "$response" return 0 } + +#################################################################3 +# use: +_get_auth_token() { + if [ "$SL_Ver" = 'v1' ]; then + # token for v1 + _debug "Token v1" + _token_keystone=$SL_Key + elif [ "$SL_Ver" = 'v2' ]; then + # token for v2. Get a token for calling the API + _debug "Keystone Token v2" + token_v2=$(_readaccountconf_mutable SL_Token_V2) + if [ -n "$token_v2" ]; then + # The structure with the token was considered. Let's check its validity + # field 1 - SL_Login_Name + # field 2 - token keystone + # field 3 - SL_Login_ID + # field 4 - SL_Project_Name + # field 5 - Receipt time + # separator - ';' + _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") + _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") + _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") + _receipt_time=$(_getfield "$token_v2" 5 "$_sl_sep") + _login_id=$(_getfield "$token_v2" 3 "$_sl_sep") + _debug3 _login_name "$_login_name" + _debug3 _login_id "$_login_id" + _debug3 _project_name "$_project_name" + _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # check the validity of the token for the user and the project and its lifetime + #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) + _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) + _debug3 _dt_diff_minute "$_dt_diff_minute" + [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone + if [ "$_project_name" != "$SL_Project_Name" ] || [ "$_login_name" != "$SL_Login_Name" ] || [ "$_login_id" != "$SL_Login_ID" ]; then + unset _token_keystone + fi + _debug "Get exists token" + fi + if [ -z "$_token_keystone" ]; then + # the previous token is incorrect or was not received, get a new one + _debug "Update (get new) token" + _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" + #_secure_debug2 "_data_auth" "$_data_auth" + export _H1="Content-Type: application/json" + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + _result=$(_post "$_data_auth" "$auth_uri") + _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") + #echo $_token_keystone > /root/123456.qwe + #_dt_curr=$EPOCHSECONDS + _dt_curr=$(date +%s) + SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" + _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" + fi + else + # token set empty for unsupported version API + _token_keystone="" + fi + printf -- "%s" "$_token_keystone" +} + +################################################################# +# use: [non_save] +_sl_init_vars() { + _non_save="${1}" + _debug2 _non_save "$_non_save" + + _debug "First init variables" + # version API + SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" + if [ -z "$SL_Ver" ]; then + SL_Ver="v2" + fi + if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then + _err "You don't specify selectel.ru API version." + _err "Please define specify API version." + fi + _debug2 SL_Ver "$SL_Ver" + + if [ "$SL_Ver" = "v1" ]; then + # token + SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + + if [ -z "$SL_Key" ]; then + SL_Key="" + _err "You don't specify selectel.ru api key yet." + _err "Please create you key and try again." + return 1 + fi + #save the api key to the account conf file. + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Key "$SL_Key" + fi + elif [ "$SL_Ver" = "v2" ]; then + # time expire token + SL_Expire="${SL_Expire:-$(_readaccountconf_mutable SL_Expire)}" + if [ -z "$SL_Expire" ]; then + SL_Expire=1400 # 23h 20 min + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Expire "$SL_Expire" + fi + # login service user + SL_Login_Name="${SL_Login_Name:-$(_readaccountconf_mutable SL_Login_Name)}" + if [ -z "$SL_Login_Name" ]; then + SL_Login_Name='' + _err "You did not specify the selectel.ru API service user name." + _err "Please provide a service user name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_Name "$SL_Login_Name" + fi + # user ID + SL_Login_ID="${SL_Login_ID:-$(_readaccountconf_mutable SL_Login_ID)}" + if [ -z "$SL_Login_ID" ]; then + SL_Login_ID='' + _err "You did not specify the selectel.ru API user ID." + _err "Please provide a user ID and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_ID "$SL_Login_ID" + fi + # project name + SL_Project_Name="${SL_Project_Name:-$(_readaccountconf_mutable SL_Project_Name)}" + if [ -z "$SL_Project_Name" ]; then + SL_Project_Name='' + _err "You did not specify the project name." + _err "Please provide a project name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Project_Name "$SL_Project_Name" + fi + # service user password + SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" + #_secure_debug3 SL_Pswd "$SL_Pswd" + if [ -z "$SL_Pswd" ]; then + SL_Pswd='' + _err "You did not specify the service user password." + _err "Please provide a service user password and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Pswd "$SL_Pswd" "12345678" + fi + else + SL_Ver="" + _err "You also specified the wrong version of the selectel.ru API." + _err "Please provide the correct API version and try again." + return 1 + fi + + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Ver "$SL_Ver" + fi + + return 0 +} From 577920de863d7ee142cc86f925eca1d1526bf441 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 08:36:36 +1000 Subject: [PATCH 341/687] test DNS for v2 (actual) 001 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 73fe47ba798d269f3082aa4ec5ca06c1f4f6fb1f Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 09:57:49 +1000 Subject: [PATCH 342/687] test DNS for v1 (legacy) 001 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From b8949ba3dd82f1846eef195e75700c148a91f214 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 10:01:50 +1000 Subject: [PATCH 343/687] test DNS for v1 (legacy) 002 --- dnsapi/dns_selectel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..04c9a388 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,5 +513,6 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From ada7e12b5a85297c42f6169e65612ac0cd2eb709 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 11:03:53 +1000 Subject: [PATCH 344/687] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 04c9a388..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 2e3c1ef4ac7f0d971f2afe4e18a9b07c5e0427ca Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 13:49:53 +1000 Subject: [PATCH 345/687] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 8bb29f53d131f4761752a979d03270d650a260f1 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 16:15:45 +1000 Subject: [PATCH 346/687] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 3ae4ba330035d30deac9bc3b0fb205a9d99047e5 Mon Sep 17 00:00:00 2001 From: zak905 Date: Thu, 18 Apr 2024 12:39:35 +0200 Subject: [PATCH 347/687] dns_ionos.sh: implement dns_ionos_add for ionos cloud --- dnsapi/dns_ionos.sh | 115 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e4ad3318..407bfbd8 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -1,17 +1,24 @@ #!/usr/bin/env sh -# Supports IONOS DNS API v1.0.1 +# Supports IONOS DNS API v1.0.1 and IONOS Cloud DNS API v1.15.4 # # Usage: -# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: +# Export IONOS_PREFIX and IONOS_SECRET or IONOS_TOKEN before calling acme.sh: # # $ export IONOS_PREFIX="..." # $ export IONOS_SECRET="..." +# or +# $ export IONOS_TOKEN="..." # # $ acme.sh --issue --dns dns_ionos ... +# +# if IONOS_PREFIX and IONOS_SECRET are set, the script will use IONOS DNS API +# if IONOS_TOKEN is set, the script will use the IONOS Cloud DNS API IONOS_API="https://api.hosting.ionos.com/dns" +IONOS_CLOUD_API="https://dns.de-fra.ionos.com" IONOS_ROUTE_ZONES="/v1/zones" +IONOS_CLOUD_ROUTE_ZONES="/zones" IONOS_TXT_TTL=60 # minimum accepted by API IONOS_TXT_PRIO=10 @@ -24,11 +31,20 @@ dns_ionos_add() { return 1 fi - _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" + if [ $_context == "core" ];then + _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then - _info "TXT record has been created successfully." - return 0 + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then + _info "TXT record has been created successfully." + return 0 + fi + else + _body="{\"properties\":{\"name\":\"$fulldomain\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" + + if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then + _info "TXT record has been created successfully." + return 0 + fi fi return 1 @@ -58,25 +74,67 @@ dns_ionos_rm() { _ionos_init() { IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}" IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" + IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}" + + if [ -n "$IONOS_PREFIX" ] || [ -n "$IONOS_SECRET" ]; then + _info "You have specified an IONOS api prefix and secret." + _info "The script will use the IONOS DNS API: $IONOS_API" + + _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" + _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" + + if ! _get_root "$fulldomain"; then + _err "Cannot find this domain in your IONOS account." + return 1 + fi + $_context="core" + else if [ -n "$IONOS_TOKEN" ]; then + _info "You have specified an IONOS token." + _info "The script will use the IONOS Cloud DNS API: $IONOS_CLOUD_API" + + _saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN" - if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then - _err "You didn't specify an IONOS api prefix and secret yet." - _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." + if ! _get_cloud_zone "$fulldomain"; then + _err "Cannot find this zone in your IONOS account." + return 1 + fi + $_context="cloud" + else + _err "You didn't specify an IONOS credentials yet." + _err "If you are using the IONOS DNS API, Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." + _err "If you are using the IONOS Cloud DNS API, Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." _err "" _err "Then set them before calling acme.sh:" _err "\$ export IONOS_PREFIX=\"...\"" _err "\$ export IONOS_SECRET=\"...\"" + _err "#or" + _err "\$ export IONOS_TOKEN=\"...\"" _err "\$ acme.sh --issue -d ... --dns dns_ionos" return 1 fi - _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" - _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" + return 0 +} - if ! _get_root "$fulldomain"; then - _err "Cannot find this domain in your IONOS account." - return 1 +_get_cloud_zone() { + zone=$1 + i=1 + p=1 + + if _ionos_cloud_rest GET "$IONOS_ROUTE_ZONES?filter.zoneName=$zone"; then + _response="$(echo "$_response" | tr -d "\n")" + + _zone="$(echo "$_response" | _egrep_o "\"name\":\"$zone\".*\}")" + if [ "$_zone" ]; then + _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + if [ "$_zone_id" ]; then + return 0 + fi + return 1 + fi fi + + return 1 } _get_root() { @@ -169,3 +227,32 @@ _ionos_rest() { return 0 } + +_ionos_cloud_rest() { + method="$1" + route="$2" + data="$3" + + export _H1="Authorization: Bearer $IONOS_TOKEN" + + # clear headers + : >"$HTTP_HEADER" + + if [ "$method" != "GET" ]; then + _response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")" + else + _response="$(_get "$IONOS_CLOUD_API$route")" + fi + + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + + if [ "$?" != "0" ]; then + _err "Error $route: $_response" + return 1 + fi + + _debug2 "_response" "$_response" + _debug2 "_code" "$_code" + + return 0 +} From f35e15204d0f2e592ad5112c5c1416cbb33eb215 Mon Sep 17 00:00:00 2001 From: zak905 Date: Mon, 22 Apr 2024 15:48:01 +0200 Subject: [PATCH 348/687] implement dns_ionos_rm function --- dnsapi/dns_ionos.sh | 92 ++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 407bfbd8..e8e3a37a 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -58,14 +58,27 @@ dns_ionos_rm() { return 1 fi - if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then - _err "Could not find _acme-challenge TXT record." - return 1 - fi + if [ $_context == "core" ];then + if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + + if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then + _info "TXT record has been deleted successfully." + return 0 + fi + else + if ! _ionos_cloud_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + + if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then + _info "TXT record has been deleted successfully." + return 0 + fi - if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then - _info "TXT record has been deleted successfully." - return 0 fi return 1 @@ -76,7 +89,7 @@ _ionos_init() { IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}" - if [ -n "$IONOS_PREFIX" ] || [ -n "$IONOS_SECRET" ]; then + if [ -n "$IONOS_PREFIX" ] && [ -n "$IONOS_SECRET" ]; then _info "You have specified an IONOS api prefix and secret." _info "The script will use the IONOS DNS API: $IONOS_API" @@ -100,7 +113,7 @@ _ionos_init() { fi $_context="cloud" else - _err "You didn't specify an IONOS credentials yet." + _err "You didn't specify any IONOS credentials yet." _err "If you are using the IONOS DNS API, Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." _err "If you are using the IONOS Cloud DNS API, Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." _err "" @@ -116,27 +129,6 @@ _ionos_init() { return 0 } -_get_cloud_zone() { - zone=$1 - i=1 - p=1 - - if _ionos_cloud_rest GET "$IONOS_ROUTE_ZONES?filter.zoneName=$zone"; then - _response="$(echo "$_response" | tr -d "\n")" - - _zone="$(echo "$_response" | _egrep_o "\"name\":\"$zone\".*\}")" - if [ "$_zone" ]; then - _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - if [ "$_zone_id" ]; then - return 0 - fi - return 1 - fi - fi - - return 1 -} - _get_root() { domain=$1 i=1 @@ -172,6 +164,27 @@ _get_root() { return 1 } +_get_cloud_zone() { + zone=$1 + i=1 + p=1 + + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then + _response="$(echo "$_response" | tr -d "\n")" + + _zone="$(echo "$_response" | _egrep_o "\"name\":\"$zone\".*\}")" + if [ "$_zone" ]; then + _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + if [ "$_zone_id" ]; then + return 0 + fi + return 1 + fi + fi + + return 1 +} + _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -191,6 +204,25 @@ _ionos_get_record() { return 1 } +_ionos_cloud_get_record() { + fulldomain=$1 + zone_id=$2 + txtrecord=$3 + + if _ionos_cloud_rest GET "$IONOS_ROUTE_ZONES/$zone_id/records"; then + _response="$(echo "$_response" | tr -d "\n")" + + _record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" + if [ "$_record" ]; then + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + + return 0 + fi + fi + + return 1 +} + _ionos_rest() { method="$1" route="$2" From ff357dd3fb4bfeb6b086e22c3c89b2458019d816 Mon Sep 17 00:00:00 2001 From: zak905 Date: Mon, 22 Apr 2024 16:16:03 +0200 Subject: [PATCH 349/687] fix syntax error --- dnsapi/dns_ionos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e8e3a37a..53813f62 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -101,7 +101,7 @@ _ionos_init() { return 1 fi $_context="core" - else if [ -n "$IONOS_TOKEN" ]; then + elif [ -n "$IONOS_TOKEN" ]; then _info "You have specified an IONOS token." _info "The script will use the IONOS Cloud DNS API: $IONOS_CLOUD_API" From dc2979926f6da8822dade0e4024d145f2e459d4c Mon Sep 17 00:00:00 2001 From: zak905 Date: Wed, 24 Apr 2024 11:58:38 +0200 Subject: [PATCH 350/687] fix zone search --- dnsapi/dns_ionos.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 53813f62..a06cd8c3 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -108,7 +108,7 @@ _ionos_init() { _saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN" if ! _get_cloud_zone "$fulldomain"; then - _err "Cannot find this zone in your IONOS account." + _err "Cannot find zone $zone in your IONOS account." return 1 fi $_context="cloud" @@ -165,20 +165,17 @@ _get_root() { } _get_cloud_zone() { - zone=$1 - i=1 - p=1 + domain=$1 + zone=$(printf "%s" "$domain" | cut -d . -f 2-) if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then _response="$(echo "$_response" | tr -d "\n")" - _zone="$(echo "$_response" | _egrep_o "\"name\":\"$zone\".*\}")" - if [ "$_zone" ]; then - _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - if [ "$_zone_id" ]; then - return 0 - fi - return 1 + _zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*") + + _zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + if [ "$_zone_id" ]; then + return 0 fi fi From 96c35b41eda6df682d07aea81185f143b062d1ea Mon Sep 17 00:00:00 2001 From: zak905 Date: Wed, 24 Apr 2024 12:11:48 +0200 Subject: [PATCH 351/687] fix TXT record lookup and removal --- dnsapi/dns_ionos.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index a06cd8c3..5b8bba3f 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -39,7 +39,8 @@ dns_ionos_add() { return 0 fi else - _body="{\"properties\":{\"name\":\"$fulldomain\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + _body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then _info "TXT record has been created successfully." @@ -69,7 +70,8 @@ dns_ionos_rm() { return 0 fi else - if ! _ionos_cloud_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + if ! _ionos_cloud_get_record "$_record_name" "$_zone_id" "$txtvalue"; then _err "Could not find _acme-challenge TXT record." return 1 fi @@ -202,14 +204,14 @@ _ionos_get_record() { } _ionos_cloud_get_record() { - fulldomain=$1 + _record_name=$1 zone_id=$2 txtrecord=$3 if _ionos_cloud_rest GET "$IONOS_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" - _record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" + _record="$(echo "$_response" | _egrep_o "\"name\":\"$_record_name\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') From ffde1f8343aefc9be7a0efa1ed07821c07a60a5a Mon Sep 17 00:00:00 2001 From: zak905 Date: Thu, 25 Apr 2024 17:38:13 +0200 Subject: [PATCH 352/687] linting based on ShellCheck results --- dnsapi/dns_ionos.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 5b8bba3f..d1430a45 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -31,7 +31,7 @@ dns_ionos_add() { return 1 fi - if [ $_context == "core" ];then + if [ "$_context" == "core" ];then _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then @@ -59,7 +59,7 @@ dns_ionos_rm() { return 1 fi - if [ $_context == "core" ];then + if [ "$_context" == "core" ];then if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then _err "Could not find _acme-challenge TXT record." return 1 @@ -102,7 +102,7 @@ _ionos_init() { _err "Cannot find this domain in your IONOS account." return 1 fi - $_context="core" + _context="core" elif [ -n "$IONOS_TOKEN" ]; then _info "You have specified an IONOS token." _info "The script will use the IONOS Cloud DNS API: $IONOS_CLOUD_API" @@ -113,7 +113,7 @@ _ionos_init() { _err "Cannot find zone $zone in your IONOS account." return 1 fi - $_context="cloud" + _context="cloud" else _err "You didn't specify any IONOS credentials yet." _err "If you are using the IONOS DNS API, Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." From 30d0945855d5121a00a42059a5ae81c3e733bf04 Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 12:38:02 +0200 Subject: [PATCH 353/687] fix regexp for findind acme challenge record from API response --- dnsapi/dns_ionos.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index d1430a45..706c678c 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -70,13 +70,12 @@ dns_ionos_rm() { return 0 fi else - _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) - if ! _ionos_cloud_get_record "$_record_name" "$_zone_id" "$txtvalue"; then + if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then _err "Could not find _acme-challenge TXT record." return 1 fi - if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then + if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then _info "TXT record has been deleted successfully." return 0 fi @@ -204,14 +203,17 @@ _ionos_get_record() { } _ionos_cloud_get_record() { - _record_name=$1 - zone_id=$2 - txtrecord=$3 + zone_id=$1 + txtrecord=$2 + fulldomain=$3 + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) - if _ionos_cloud_rest GET "$IONOS_ROUTE_ZONES/$zone_id/records"; then + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" - _record="$(echo "$_response" | _egrep_o "\"name\":\"$_record_name\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" + pattern="{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"},\"properties\":{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"}}" + + _record="$(echo "$_response" | _egrep_o $pattern)" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') From d8525493a1d21fec4ad0372f8ba5db7bcff664bf Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 15:11:07 +0200 Subject: [PATCH 354/687] attempt to use custom fork of acmetest --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 727ba315..05d845b3 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -67,7 +67,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Clone acmetest - run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ + run: cd .. && git clone --depth=1 -b randomize_record_content_letest https://github.com/zak905/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file run: | cd ../acmetest From b7b1714637eb34559308fbda846209c963025e17 Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 15:34:49 +0200 Subject: [PATCH 355/687] add some debug statements --- dnsapi/dns_ionos.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 706c678c..8d7599cf 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -214,9 +214,10 @@ _ionos_cloud_get_record() { pattern="{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"},\"properties\":{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"}}" _record="$(echo "$_response" | _egrep_o $pattern)" + _info "the found record after grep: $_record" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - + _info "the record id after the search is: $_record_id" return 0 fi fi From c64aae6f390a12dfefa6f42c8438d3399e1f5cd1 Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 15:44:39 +0200 Subject: [PATCH 356/687] more debugging - add function argument printing --- dnsapi/dns_ionos.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 8d7599cf..a105a983 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -208,6 +208,8 @@ _ionos_cloud_get_record() { fulldomain=$3 _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" From 0974c74a8966bcdebced5bf3449415b7d9126a9d Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 16:20:07 +0200 Subject: [PATCH 357/687] transform record name to lower case when searching for TXT record --- dnsapi/dns_ionos.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index a105a983..40dd51d0 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -207,6 +207,9 @@ _ionos_cloud_get_record() { txtrecord=$2 fulldomain=$3 _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + # this is to transform record name to lower case + # IONOS Cloud API transforms all record names to lower case + _record_name=${_record_name@L} _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" From adc8031e34b667a4150f4230d00129812eb16660 Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 30 Apr 2024 17:04:24 +0200 Subject: [PATCH 358/687] fix shell linter and formating --- dnsapi/dns_ionos.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 40dd51d0..874b3721 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -31,7 +31,7 @@ dns_ionos_add() { return 1 fi - if [ "$_context" == "core" ];then + if [ "$_context" = "core" ];then _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then @@ -59,7 +59,7 @@ dns_ionos_rm() { return 1 fi - if [ "$_context" == "core" ];then + if [ "$_context" = "core" ];then if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then _err "Could not find _acme-challenge TXT record." return 1 @@ -218,7 +218,7 @@ _ionos_cloud_get_record() { pattern="{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"},\"properties\":{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"}}" - _record="$(echo "$_response" | _egrep_o $pattern)" + _record="$(echo "$_response" | _egrep_o "$pattern")" _info "the found record after grep: $_record" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') From c3cc13595d8ad3777e0b84cd3a6c456f17152a5f Mon Sep 17 00:00:00 2001 From: zak905 Date: Thu, 2 May 2024 18:48:39 +0200 Subject: [PATCH 359/687] use posix compliant lower case shell command --- dnsapi/dns_ionos.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 874b3721..607f3669 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -205,11 +205,11 @@ _ionos_get_record() { _ionos_cloud_get_record() { zone_id=$1 txtrecord=$2 - fulldomain=$3 - _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) - # this is to transform record name to lower case + # this is to transform the domain to lower case + fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") + # this is to transform record name to lower case # IONOS Cloud API transforms all record names to lower case - _record_name=${_record_name@L} + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" From 52d1d421a3cb393d0cdc4f7e6dbdc2cbb3994513 Mon Sep 17 00:00:00 2001 From: zak905 Date: Fri, 3 May 2024 17:04:49 +0200 Subject: [PATCH 360/687] escape brackets in regexp and format using shfmt --- dnsapi/dns_ionos.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 607f3669..fa01ac43 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -7,7 +7,7 @@ # # $ export IONOS_PREFIX="..." # $ export IONOS_SECRET="..." -# or +# or # $ export IONOS_TOKEN="..." # # $ acme.sh --issue --dns dns_ionos ... @@ -31,7 +31,7 @@ dns_ionos_add() { return 1 fi - if [ "$_context" = "core" ];then + if [ "$_context" = "core" ]; then _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then @@ -59,7 +59,7 @@ dns_ionos_rm() { return 1 fi - if [ "$_context" = "core" ];then + if [ "$_context" = "core" ]; then if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then _err "Could not find _acme-challenge TXT record." return 1 @@ -68,7 +68,7 @@ dns_ionos_rm() { if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then _info "TXT record has been deleted successfully." return 0 - fi + fi else if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then _err "Could not find _acme-challenge TXT record." @@ -78,7 +78,7 @@ dns_ionos_rm() { if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then _info "TXT record has been deleted successfully." return 0 - fi + fi fi @@ -101,7 +101,7 @@ _ionos_init() { _err "Cannot find this domain in your IONOS account." return 1 fi - _context="core" + _context="core" elif [ -n "$IONOS_TOKEN" ]; then _info "You have specified an IONOS token." _info "The script will use the IONOS Cloud DNS API: $IONOS_CLOUD_API" @@ -205,21 +205,21 @@ _ionos_get_record() { _ionos_cloud_get_record() { zone_id=$1 txtrecord=$2 - # this is to transform the domain to lower case - fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") - # this is to transform record name to lower case + # this is to transform the domain to lower case + fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") + # this is to transform record name to lower case # IONOS Cloud API transforms all record names to lower case _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") - _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" + _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" - pattern="{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"},\"properties\":{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"}}" + pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}" _record="$(echo "$_response" | _egrep_o "$pattern")" - _info "the found record after grep: $_record" + _info "the found record after grep: $_record" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') _info "the record id after the search is: $_record_id" From 7a1305c1bb3448ba6573101a0cd9854455b2084d Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 19:12:42 +1000 Subject: [PATCH 361/687] fix del record for v1, delete one entry at a time --- dnsapi/dns_selectel.sh | 58 +++++++++--------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..4806773d 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -2,7 +2,7 @@ # переменные, которые должны быть определены перед запуском # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v2 +# По-умолчанию: v1 # Если SL_Ver="v1" # export SL_Key="API_KEY" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. @@ -32,7 +32,6 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - #if ! _sl_init_vars; then if ! _sl_init_vars; then return 1 fi @@ -66,7 +65,6 @@ dns_selectel_add() { _ext_srv2="/records/" _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -83,29 +81,27 @@ dns_selectel_add() { # запись TXT с $fulldomain уже существует if [ "$SL_Ver" = "v2" ]; then # надо добавить к существующей записи еще один content - # # считать записи rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Если в данной записи, есть текстовое значение $txtvalue, - # то все хорошо, добавлять ничего не надо и результат успешный + # Уже есть значение $txtvalue, добавлять не надо if _contains "$response" "$txtvalue"; then _info "Added, OK" _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + # готовим _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug3 _data "$_data" - # вызов REST API PATCH + _debug2 "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,7 +120,7 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi @@ -151,7 +147,6 @@ dns_selectel_rm() { _ext_srv1="/" _ext_srv2="/records/" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -169,13 +164,9 @@ dns_selectel_rm() { if [ "$SL_Ver" = "v2" ]; then _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" elif [ "$SL_Ver" = "v1" ]; then _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - # record id - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -185,7 +176,7 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -194,7 +185,6 @@ dns_selectel_rm() { # delete all record type TXT with text $txtvalue if [ "$SL_Ver" = "v2" ]; then # actual - #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" @@ -232,14 +222,10 @@ dns_selectel_rm() { } #################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com -# _domain_id=sdjkglgdfewsdfg + _get_root() { domain=$1 - # + if [ "$SL_Ver" = 'v1' ]; then # version API 1 if ! _sl_rest GET "/"; then @@ -248,16 +234,12 @@ _get_root() { i=2 p=1 while true; do - #h=$(printf "%s" "$domain" | cut -d . -f $i-100) h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then - #not valid return 1 fi - if _contains "$response" "\"name\" *: *\"$h\","; then - #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" @@ -280,7 +262,6 @@ _get_root() { _debug "domain:: " "$domain" # read records of all domains if ! _sl_rest GET "$_ext_uri"; then - #not valid _err "Error read records of all domains $SL_Ver" return 1 fi @@ -290,29 +271,24 @@ _get_root() { h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then - #not valid _err "The domain was not found among the registered ones" return 1 fi - _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") _debug "_domain_record:: " "$_domain_record" if [ -n "$_domain_record" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" - #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") return 0 fi p=$i i=$(_math "$i" + 1) done - #not valid _err "Error read records of all domains $SL_Ver" return 1 else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -341,14 +317,12 @@ _sl_rest() { _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" _debug3 "_H1:" "$_H1" _debug3 "_H2:" "$_H2" - if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi - if [ "$?" != "0" ]; then _err "error $ep" return 1 @@ -357,8 +331,6 @@ _sl_rest() { return 0 } -#################################################################3 -# use: _get_auth_token() { if [ "$SL_Ver" = 'v1' ]; then # token for v1 @@ -375,7 +347,7 @@ _get_auth_token() { # field 3 - SL_Login_ID # field 4 - SL_Project_Name # field 5 - Receipt time - # separator - ';' + # separator - '$_sl_sep' _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") @@ -386,7 +358,6 @@ _get_auth_token() { _debug3 _project_name "$_project_name" _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime - #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone @@ -399,13 +370,9 @@ _get_auth_token() { # the previous token is incorrect or was not received, get a new one _debug "Update (get new) token" _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" - #_secure_debug2 "_data_auth" "$_data_auth" export _H1="Content-Type: application/json" - # body url [needbase64] [POST|PUT|DELETE] [ContentType] _result=$(_post "$_data_auth" "$auth_uri") _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") - #echo $_token_keystone > /root/123456.qwe - #_dt_curr=$EPOCHSECONDS _dt_curr=$(date +%s) SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" @@ -427,14 +394,13 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." _err "Please define specify API version." fi _debug2 SL_Ver "$SL_Ver" - if [ "$SL_Ver" = "v1" ]; then # token SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" @@ -509,9 +475,9 @@ _sl_init_vars() { _err "Please provide the correct API version and try again." return 1 fi - if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From 177d9b7cb0fce9baabbc5fa90aa86f8765e33c3b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:38:42 +1000 Subject: [PATCH 362/687] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 4806773d..65729804 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -4,7 +4,7 @@ # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). # По-умолчанию: v1 # Если SL_Ver="v1" -# export SL_Key="API_KEY" - Токен Selectel (API key) +# export SL_Key="API_Key" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. # https://my.selectel.ru/profile/apikeys # Если SL_Ver="v2" @@ -35,12 +35,11 @@ dns_selectel_add() { if ! _sl_init_vars; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -56,9 +55,7 @@ dns_selectel_add() { _ext_srv1="/zones/" _ext_srv2="/rrset/" _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") - _debug txtvalue "$txtvalue" _text_tmp='\"'$_text_tmp'\"' - _debug _text_tmp "$_text_tmp" _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" elif [ "$SL_Ver" = "v1" ]; then _ext_srv1="/" @@ -69,8 +66,8 @@ dns_selectel_add() { return 1 fi _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" - _debug3 _data "$_data" + _debug _ext_uri "$_ext_uri" + _debug _data "$_data" if _sl_rest POST "$_ext_uri" "$_data"; then if _contains "$response" "$txtvalue"; then @@ -101,7 +98,7 @@ dns_selectel_add() { _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug2 "New data for record" "$_data" + _debug "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,12 +121,11 @@ dns_selectel_rm() { if ! _sl_init_vars "nosave"; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -153,7 +149,7 @@ dns_selectel_rm() { # _debug "Getting txt records" _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" + _debug _ext_uri "$_ext_uri" _sl_rest GET "${_ext_uri}" # if ! _contains "$response" "$txtvalue"; then @@ -176,7 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" + # следующие строки меняют алгоритм удаления записей со значением $txtvalue + # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 2-ю строку, то удаляется только первая запись из них + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -188,6 +188,7 @@ dns_selectel_rm() { _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" + _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then # удалить запись if ! _sl_rest DELETE "${_del_uri}"; then @@ -210,7 +211,7 @@ dns_selectel_rm() { # legacy for _one_id in $_record_id; do _del_uri="${_ext_uri}${_one_id}" - _debug2 _ext_uri "$_del_uri" + _debug _del_uri "$_del_uri" if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else @@ -302,7 +303,6 @@ _sl_rest() { data="$3" _token=$(_get_auth_token) - #_debug "$_token" if [ -z "$_token" ]; then _err "BAD key or token $ep" return 1 @@ -394,7 +394,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." @@ -459,7 +459,6 @@ _sl_init_vars() { fi # service user password SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" - #_secure_debug3 SL_Pswd "$SL_Pswd" if [ -z "$SL_Pswd" ]; then SL_Pswd='' _err "You did not specify the service user password." From d989617825ccc0b9a60b4f9f657148243d14b15b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:42:38 +1000 Subject: [PATCH 363/687] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 65729804..9868cb12 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -173,7 +173,7 @@ dns_selectel_rm() { fi # record id # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 1-ю строку, то за раз удаляются все такие записи # если использовать 2-ю строку, то удаляется только первая запись из них #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue From bd48c9938354530480f9bed266558e8a2ff14cff Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 4 May 2024 16:27:31 +0200 Subject: [PATCH 364/687] fix ca names --- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 4 ++-- .github/workflows/Linux.yml | 2 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/Omnios.yml | 4 ++-- .github/workflows/OpenBSD.yml | 4 ++-- .github/workflows/Solaris.yml | 4 ++-- .github/workflows/Ubuntu.yml | 4 ++-- .github/workflows/Windows.yml | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index f360f85c..5c56168f 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index b90c9ccd..961907e8 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 33e43483..4afebaf0 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest env: TEST_LOCAL: 1 - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) TEST_ACME_Server: "LetsEncrypt.org_test" steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index c3f046ab..f5d73ec9 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 4574bef5..a4f90f68 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/Omnios.yml b/.github/workflows/Omnios.yml index e3da0be8..882cedf6 100644 --- a/.github/workflows/Omnios.yml +++ b/.github/workflows/Omnios.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index e141c47b..d5697c10 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index bdd3f040..95bcd8d1 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 53cc1060..e580828f 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 - TEST_ACME_Server: "ZeroSSL.com" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 61ef5ad8..c1fd1085 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" From 957bbab440614725019369ae31c5b01aa261b761 Mon Sep 17 00:00:00 2001 From: Matt Mower Date: Sat, 4 May 2024 11:43:01 -0700 Subject: [PATCH 365/687] feat: Support manually defining extended key usage in CSR - New CLI param: --extended-key-usage - When --extended-key-usage is defined: 1. Set [v3_req]extendedKeyUsage to the provided value. 2. Store the value in domain conf Le_ExtKeyUse for reuse. --- acme.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d154cf77..0d882ba6 100755 --- a/acme.sh +++ b/acme.sh @@ -1243,7 +1243,14 @@ _createcsr() { _debug2 csr "$csr" _debug2 csrconf "$csrconf" - printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\nextendedKeyUsage=serverAuth,clientAuth\n" >"$csrconf" + printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]" >"$csrconf" + + if [ "$Le_ExtKeyUse" ]; then + _savedomainconf Le_ExtKeyUse "$Le_ExtKeyUse" + printf "\nextendedKeyUsage=$Le_ExtKeyUse\n" >>"$csrconf" + else + printf "\nextendedKeyUsage=serverAuth,clientAuth\n" >>"$csrconf" + fi if [ "$acmeValidationv1" ]; then domainlist="$(_idn "$domainlist")" @@ -7007,6 +7014,7 @@ Parameters: --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. --renew-hook Command to be run after each successfully renewed certificate. --deploy-hook The hook file to deploy cert + --extended-key-usage Manually define the CSR extended key usage value. The default is serverAuth,clientAuth. --ocsp, --ocsp-must-staple Generate OCSP-Must-Staple extension. --always-force-new-domain-key Generate new domain key on renewal. Otherwise, the domain key is not changed by default. --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted. @@ -7698,6 +7706,10 @@ _process() { _deploy_hook="$_deploy_hook$2," shift ;; + --extended-key-usage) + Le_ExtKeyUse="$2" + shift + ;; --ocsp-must-staple | --ocsp) Le_OCSP_Staple="1" ;; From a375e924b491e8245ee763305f59627eac996f80 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sun, 5 May 2024 07:42:22 +1000 Subject: [PATCH 366/687] translation of comments into English --- dnsapi/dns_selectel.sh | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 9868cb12..d4ca13b2 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,23 +1,23 @@ #!/usr/bin/env sh -# переменные, которые должны быть определены перед запуском -# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v1 -# Если SL_Ver="v1" -# export SL_Key="API_Key" - Токен Selectel (API key) -# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# Variables that must be defined before running +# export SL_Ver="v1" - version API: 'v2' (actual) or 'v1' (legacy). +# Default: v1 +# If SL_Ver="v1" +# export SL_Key="API_Key" - Token Selectel (API key) +# You can view or create in the control panel in the upper right corner, open the menu: "Profile and setting -> Keys API". # https://my.selectel.ru/profile/apikeys -# Если SL_Ver="v2" -# export SL_Expire=60 - время жизни token в минутах (0-1440). -# По-умолчанию: 1400 минут -# export SL_Login_ID= - номер аккаунта в панели управления; -# export SL_Project_Name= - имя проекта. -# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: -# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи -# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. -# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. +# If SL_Ver="v2" +# export SL_Expire=60 - token lifetime in minutes (0-1440). +# Default: 1400 minutes +# export SL_Login_ID= - account number in the control panel; +# export SL_Project_Name= - name project. +# export SL_Login_name= - service user name. You can view the name in the control panel: +# in the upper right corner open menu: "Profile and setting → User management → Service users +# export SL_Pswd='pswd' - service user password, can be viewed when creating a user or changed to a new one. +# All these variables will be saved in ~/.acme.sh/account.conf and will be reused as needed. # -# Авторизация описана в: +# Authorization is described in: # https://developers.selectel.ru/docs/control-panel/authorization/ # https://developers.selectel.com/docs/control-panel/authorization/ @@ -75,24 +75,24 @@ dns_selectel_add() { return 0 fi if _contains "$response" "already_exists"; then - # запись TXT с $fulldomain уже существует + # record TXT with $fulldomain already exists if [ "$SL_Ver" = "v2" ]; then - # надо добавить к существующей записи еще один content - # считать записи rrset + # It is necessary to add one more content to the comments + # read all records rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Уже есть значение $txtvalue, добавлять не надо + # There is already a $txtvalue value, no need to add it if _contains "$response" "$txtvalue"; then _info "Added, OK" - _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + _info "Txt record ${fulldomain} with value ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... + # group \1 - full record rrset; group \2 - records attribute value, exactly {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" - # готовим _data + # preparing _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" @@ -172,11 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи - # если использовать 2-ю строку, то удаляется только первая запись из них - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue + # the following lines change the algorithm for deleting records with the value $txtvalue + # if you use the 1st line, then all such records are deleted at once + # if you use the 2nd line, then only the first entry from them is deleted + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -190,17 +190,17 @@ dns_selectel_rm() { _del_uri="${_ext_uri}${_record_id}" _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then - # удалить запись + # remove record if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else info "Delete record success: ${_del_uri}." fi else - # обновить запись, удалив content + # update a record by removing one element in content _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" _debug3 _data "$_data" - # вызов REST API PATCH + # REST API PATCH call if _sl_rest PATCH "${_del_uri}" "$_data"; then _info "Patched, OK: ${_del_uri}" else From 373c2b379cf6de315e66263522da9d490fe7af2a Mon Sep 17 00:00:00 2001 From: zak905 Date: Mon, 6 May 2024 14:53:51 +0200 Subject: [PATCH 367/687] remove debug print statements and usage of custom fork of acmetest --- .github/workflows/DNS.yml | 2 +- dnsapi/dns_ionos.sh | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 05d845b3..727ba315 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -67,7 +67,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Clone acmetest - run: cd .. && git clone --depth=1 -b randomize_record_content_letest https://github.com/zak905/acmetest.git && cp -r acme.sh acmetest/ + run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ - name: Set env file run: | cd ../acmetest diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index fa01ac43..70cc858a 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -211,18 +211,14 @@ _ionos_cloud_get_record() { # IONOS Cloud API transforms all record names to lower case _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") - _info "grepping with the following args: zone_id=$zone_id txtrecord=$txtrecord fulldomain=$fulldomain _record_name=$_record_name" - if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}" _record="$(echo "$_response" | _egrep_o "$pattern")" - _info "the found record after grep: $_record" if [ "$_record" ]; then _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - _info "the record id after the search is: $_record_id" return 0 fi fi From 744dea00ca15ee4a42d58848d658d50a4538e312 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 8 May 2024 02:56:21 +0800 Subject: [PATCH 368/687] feat: guide user to run script as root to create temp admin user Message text and comment optimized --- deploy/synology_dsm.sh | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 342fb32e..e6f44e8d 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -39,7 +39,7 @@ ################################################################################ # Dependencies: # - curl -# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set) +# - synouser & synogroup & synosetkeyvalue (Required for SYNO_USE_TEMP_ADMIN=1) ################################################################################ # Return value: # 0 means success, otherwise error. @@ -66,14 +66,17 @@ synology_dsm_deploy() { _getdeployconf SYNO_DEVICE_NAME # Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set - _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" _getdeployconf SYNO_USE_TEMP_ADMIN _check2cleardeployconfexp SYNO_USE_TEMP_ADMIN _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then - if ! _exists synouser || ! _exists synogroup; then - _err "Tools are missing for creating temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." + if ! _exists synouser || ! _exists synogroup || ! _exists synosetkeyvalue; then + _err "Missing required tools to creat temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." + return 1 + fi + if synouser --help 2>&1 | grep -q 'Permission denied'; then + _err "For creating temp admin user, the deploy script must be run as root." return 1 fi @@ -184,7 +187,7 @@ synology_dsm_deploy() { _debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}" if [ "$SYNO_LOCAL_HOSTNAME" != "1" ] && [ "$SYNO_LOCAL_HOSTNAME" == "$SYNO_HOSTNAME" ]; then if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then - _err "SYNO_USE_TEMP_ADMIN=1 Only support locally deployment, if you are sure that hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." + _err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, then execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." return 1 fi fi @@ -201,7 +204,7 @@ synology_dsm_deploy() { # shellcheck disable=SC2086 synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null else - _err "Tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead." + _err "The tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead." return 1 fi else @@ -212,7 +215,7 @@ synology_dsm_deploy() { otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none - _info "Temporary disabled enforce 2FA-OTP to complete authentication." + _info "Temporary disabled enforce 2FA-OTP to complete temp admin authentication." _info "previous_otp_enforce_option" "$otp_enforce_option" else otp_enforce_option="" @@ -230,7 +233,7 @@ synology_dsm_deploy() { error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') _debug2 error_code "$error_code" # Account has 2FA-OTP enabled, since error 403 reported. - # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf + # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf if [ "$error_code" == "403" ]; then if [ -z "$SYNO_DEVICE_NAME" ]; then printf "Enter device name or leave empty for default (CertRenewal): " @@ -274,12 +277,16 @@ synology_dsm_deploy() { _err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window." elif [ "$error_code" == "406" ]; then if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then - _err "SYNO_USE_TEMP_ADMIN=1 is not supported if enforce auth with 2FA-OTP is enabled." + _err "Failed with unexcepted error, please report this by providing full log with '--debug 3'." else _err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue." fi - elif [ "$error_code" == "400" ] || [ "$error_code" == "401" ] || [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then - _err "Failed to authenticate with a non-existent or disabled account, or the account password is incorrect or has expired." + elif [ "$error_code" == "400" ]; then + _err "Failed to authenticate, no such account or incorrect password." + elif [ "$error_code" == "401" ]; then + _err "Failed to authenticate with a non-existent account." + elif [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then + _err "Failed to authenticate, the account password has expired or must be changed." else _err "Failed to authenticate with error: $error_code." fi @@ -293,7 +300,7 @@ synology_dsm_deploy() { _debug SynoToken "$token" if [ -z "$sid" ] || [ -z "$token" ]; then # Still can't get necessary info even got no errors, may Synology have API updated? - _err "Unable to authenticate to $_base_url, you may report the full log to the community." + _err "Unable to authenticate to $_base_url, you may report this by providing full log with '--debug 3'." _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi @@ -331,7 +338,7 @@ synology_dsm_deploy() { if [ "$error_code" -eq 105 ]; then _err "Current user is not administrator and does not have sufficient permission for deploying." else - _err "Failed to fetch certificate info with error: $error_code, please try again or contact Synology to learn more." + _err "Failed to fetch certificate info: $error_code, please try again or contact Synology to learn more." fi _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 From 47ccb2848215a7733ff5cfc5d8e967722e35d5cc Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 8 May 2024 04:46:51 +0800 Subject: [PATCH 369/687] chore: typo --- deploy/synology_dsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index e6f44e8d..a9057a57 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -187,7 +187,7 @@ synology_dsm_deploy() { _debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}" if [ "$SYNO_LOCAL_HOSTNAME" != "1" ] && [ "$SYNO_LOCAL_HOSTNAME" == "$SYNO_HOSTNAME" ]; then if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then - _err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, then execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." + _err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." return 1 fi fi From 1dbc58d4e0de6a0c1fd8fd02937b5a7313db95c4 Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Wed, 8 May 2024 14:01:43 +0800 Subject: [PATCH 370/687] chore: optimize more msgs --- deploy/synology_dsm.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index a9057a57..acac9d1e 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -73,6 +73,7 @@ synology_dsm_deploy() { if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then if ! _exists synouser || ! _exists synogroup || ! _exists synosetkeyvalue; then _err "Missing required tools to creat temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." + _err "Notice: temp admin user authorization method only supports local deployment on DSM." return 1 fi if synouser --help 2>&1 | grep -q 'Permission denied'; then @@ -211,11 +212,14 @@ synology_dsm_deploy() { _err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead." return 1 fi - # havig a workaround to temporary disable enforce 2FA-OTP + # havig a workaround to temporary disable enforce 2FA-OTP, will restore + # it soon (after a single request), though if any accident occurs like + # unexpected interruption, this setting can be easily reverted manually. otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none - _info "Temporary disabled enforce 2FA-OTP to complete temp admin authentication." + _info "Enforcing 2FA-OTP has been disabled to complete temp admin authentication." + _info "Notice: it will be restored soon, if not, you can restore it manually via Control Panel." _info "previous_otp_enforce_option" "$otp_enforce_option" else otp_enforce_option="" From b1d019146ac8173cfd9e0ec86149d027beefb26f Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Mon, 13 May 2024 07:50:46 -0400 Subject: [PATCH 371/687] UBNT removed keytool from UnifiOS, modify to use openssl PKCS12. Also backup certificates before overwrite, and force unifi to start with unifi-core if both are installed. --- deploy/unifi.sh | 84 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index a864135e..0a574e0d 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -5,6 +5,16 @@ # - self-hosted Unifi Controller # - Unifi Cloud Key (Gen1/2/2+) # - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# See below regarding keytool. Not tested. +# - Unifi Dream Machine +# This has not been tested on other "all-in-one" devices such as +# UDM Pro or Unifi Express. +# +# OS Version v2.0.0+ +# Network Application version 7.0.0+ +# OS version ~3.1 removed java and keytool from the UnifiOS. +# Using PKCS12 format keystore appears to work fine. +# # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. @@ -74,14 +84,16 @@ unifi_deploy() { _reload_cmd="" # Unifi Controller environment (self hosted or any Cloud Key) -- - # auto-detect by file /usr/lib/unifi/data/keystore: + # auto-detect by file /usr/lib/unifi/data/keystore _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" if [ -f "$_unifi_keystore" ]; then - _info "Installing certificate for Unifi Controller (Java keystore)" _debug _unifi_keystore "$_unifi_keystore" if ! _exists keytool; then - _err "keytool not found" - return 1 + _do_keytool=0 + _info "Installing certificate for Unifi Controller (PKCS12 keystore)." + else + _do_keytool=1 + _info "Installing certificate for Unifi Controller (Java keystore)" fi if [ ! -w "$_unifi_keystore" ]; then _err "The file $_unifi_keystore is not writable, please change the permission." @@ -99,22 +111,57 @@ unifi_deploy() { return 1 fi - _debug "Import into keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _debug "Import keystore success!" - rm "$_import_pkcs12" + # Save the existing keystore in case something goes wrong. + mv -f "${_unifi_keystore}" "${_unifi_keystore}"_original + _info "Previous keystore saved to ${_unifi_keystore}_original." + + if [ "$_do_keytool" -eq 1 ]; then + _debug "Import into keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _debug "Import keystore success!" + else + _err "Error importing into Unifi Java keystore." + _err "Please re-run with --debug and report a bug." + _info "Restoring original keystore." + mv -f "${_unifi_keystore}"_original "${_unifi_keystore}" + rm "$_import_pkcs12" + return 1 + fi else - _err "Error importing into Unifi Java keystore." - _err "Please re-run with --debug and report a bug." - rm "$_import_pkcs12" - return 1 + _debug "Copying new keystore to $_unifi_keystore" + cp -f "$_import_pkcs12" "$_unifi_keystore" + fi + + # Update unifi service for certificate cipher compatibility + if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \ + -in "$_import_pkcs12" \ + -password pass:aircontrolenterprise \ + -nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \ + -noout | grep -i "signature" | grep -iq ecdsa >/dev/null 2>&1; then + cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original + _info "Updating system configuration for cipher compatibility." + _info "Saved original system config to /usr/lib/unifi/data/system.properties_original" + sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>/usr/lib/unifi/data/system.properties + sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>/usr/lib/unifi/data/system.properties + _info "System configuration updated." fi + rm "$_import_pkcs12" + + # Restarting unifi-core will bring up unifi, doing it out of order results in + # a certificate error, and may break wifiman. (unconfirmed) + # Restart if we aren't doing unifi-core, otherwise stop and let unifi-core restart it. if systemctl -q is-active unifi; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" + else + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" + fi fi _services_updated="${_services_updated} unifi" _info "Install Unifi Controller certificate success!" @@ -165,6 +212,11 @@ unifi_deploy() { return 1 fi + # Save the existing certs in case something goes wrong. + cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt + cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key + _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" From f4406565728901aba9d5219403c7cc94622fa096 Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 14 May 2024 18:35:25 +0200 Subject: [PATCH 372/687] create new script for ionos cloud and rollback changes to dns_ionos.sh --- dnsapi/dns_ionos.sh | 168 ++++++-------------------------------- dnsapi/dns_ionos_cloud.sh | 145 ++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 145 deletions(-) create mode 100644 dnsapi/dns_ionos_cloud.sh diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index 70cc858a..e4ad3318 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -1,24 +1,17 @@ #!/usr/bin/env sh -# Supports IONOS DNS API v1.0.1 and IONOS Cloud DNS API v1.15.4 +# Supports IONOS DNS API v1.0.1 # # Usage: -# Export IONOS_PREFIX and IONOS_SECRET or IONOS_TOKEN before calling acme.sh: +# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: # # $ export IONOS_PREFIX="..." # $ export IONOS_SECRET="..." -# or -# $ export IONOS_TOKEN="..." # # $ acme.sh --issue --dns dns_ionos ... -# -# if IONOS_PREFIX and IONOS_SECRET are set, the script will use IONOS DNS API -# if IONOS_TOKEN is set, the script will use the IONOS Cloud DNS API IONOS_API="https://api.hosting.ionos.com/dns" -IONOS_CLOUD_API="https://dns.de-fra.ionos.com" IONOS_ROUTE_ZONES="/v1/zones" -IONOS_CLOUD_ROUTE_ZONES="/zones" IONOS_TXT_TTL=60 # minimum accepted by API IONOS_TXT_PRIO=10 @@ -31,21 +24,11 @@ dns_ionos_add() { return 1 fi - if [ "$_context" = "core" ]; then - _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - - if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then - _info "TXT record has been created successfully." - return 0 - fi - else - _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) - _body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" + _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" - if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then - _info "TXT record has been created successfully." - return 0 - fi + if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then + _info "TXT record has been created successfully." + return 0 fi return 1 @@ -59,27 +42,14 @@ dns_ionos_rm() { return 1 fi - if [ "$_context" = "core" ]; then - if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then - _err "Could not find _acme-challenge TXT record." - return 1 - fi - - if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then - _info "TXT record has been deleted successfully." - return 0 - fi - else - if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then - _err "Could not find _acme-challenge TXT record." - return 1 - fi - - if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then - _info "TXT record has been deleted successfully." - return 0 - fi + if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then + _info "TXT record has been deleted successfully." + return 0 fi return 1 @@ -88,46 +58,25 @@ dns_ionos_rm() { _ionos_init() { IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}" IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" - IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}" - - if [ -n "$IONOS_PREFIX" ] && [ -n "$IONOS_SECRET" ]; then - _info "You have specified an IONOS api prefix and secret." - _info "The script will use the IONOS DNS API: $IONOS_API" - - _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" - _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" - if ! _get_root "$fulldomain"; then - _err "Cannot find this domain in your IONOS account." - return 1 - fi - _context="core" - elif [ -n "$IONOS_TOKEN" ]; then - _info "You have specified an IONOS token." - _info "The script will use the IONOS Cloud DNS API: $IONOS_CLOUD_API" - - _saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN" - - if ! _get_cloud_zone "$fulldomain"; then - _err "Cannot find zone $zone in your IONOS account." - return 1 - fi - _context="cloud" - else - _err "You didn't specify any IONOS credentials yet." - _err "If you are using the IONOS DNS API, Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." - _err "If you are using the IONOS Cloud DNS API, Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." + if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then + _err "You didn't specify an IONOS api prefix and secret yet." + _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." _err "" _err "Then set them before calling acme.sh:" _err "\$ export IONOS_PREFIX=\"...\"" _err "\$ export IONOS_SECRET=\"...\"" - _err "#or" - _err "\$ export IONOS_TOKEN=\"...\"" _err "\$ acme.sh --issue -d ... --dns dns_ionos" return 1 fi - return 0 + _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" + _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" + + if ! _get_root "$fulldomain"; then + _err "Cannot find this domain in your IONOS account." + return 1 + fi } _get_root() { @@ -165,24 +114,6 @@ _get_root() { return 1 } -_get_cloud_zone() { - domain=$1 - zone=$(printf "%s" "$domain" | cut -d . -f 2-) - - if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then - _response="$(echo "$_response" | tr -d "\n")" - - _zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*") - - _zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - if [ "$_zone_id" ]; then - return 0 - fi - fi - - return 1 -} - _ionos_get_record() { fulldomain=$1 zone_id=$2 @@ -202,30 +133,6 @@ _ionos_get_record() { return 1 } -_ionos_cloud_get_record() { - zone_id=$1 - txtrecord=$2 - # this is to transform the domain to lower case - fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") - # this is to transform record name to lower case - # IONOS Cloud API transforms all record names to lower case - _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") - - if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then - _response="$(echo "$_response" | tr -d "\n")" - - pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}" - - _record="$(echo "$_response" | _egrep_o "$pattern")" - if [ "$_record" ]; then - _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') - return 0 - fi - fi - - return 1 -} - _ionos_rest() { method="$1" route="$2" @@ -262,32 +169,3 @@ _ionos_rest() { return 0 } - -_ionos_cloud_rest() { - method="$1" - route="$2" - data="$3" - - export _H1="Authorization: Bearer $IONOS_TOKEN" - - # clear headers - : >"$HTTP_HEADER" - - if [ "$method" != "GET" ]; then - _response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")" - else - _response="$(_get "$IONOS_CLOUD_API$route")" - fi - - _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" - - if [ "$?" != "0" ]; then - _err "Error $route: $_response" - return 1 - fi - - _debug2 "_response" "$_response" - _debug2 "_code" "$_code" - - return 0 -} diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh new file mode 100644 index 00000000..6204fda0 --- /dev/null +++ b/dnsapi/dns_ionos_cloud.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh + +# Supports IONOS Cloud DNS API v1.15.4 +# +# Usage: +# Export IONOS_TOKEN before calling acme.sh: +# $ export IONOS_TOKEN="..." +# +# $ acme.sh --issue --dns dns_ionos_cloud ... + +IONOS_CLOUD_API="https://dns.de-fra.ionos.com" +IONOS_CLOUD_ROUTE_ZONES="/zones" + +dns_ionos_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _ionos_init; then + return 1 + fi + + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + _body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" + + if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then + _info "TXT record has been created successfully." + return 0 + fi + + return 1 +} + +dns_ionos_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _ionos_init; then + return 1 + fi + + if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + + if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then + _info "TXT record has been deleted successfully." + return 0 + fi + + return 1 +} + +_ionos_init() { + IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}" + + if [ -z "$IONOS_TOKEN" ]; then + _err "You didn't specify an IONOS token yet." + _err "Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." + _err "" + _err "\$ export IONOS_TOKEN=\"...\"" + _err "\$ acme.sh --issue -d ... --dns dns_ionos_cloud" + return 1 + fi + + _saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN" + + if ! _get_cloud_zone "$fulldomain"; then + _err "Cannot find zone $zone in your IONOS account." + return 1 + fi + + return 0 +} + +_get_cloud_zone() { + domain=$1 + zone=$(printf "%s" "$domain" | cut -d . -f 2-) + + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then + _response="$(echo "$_response" | tr -d "\n")" + + _zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*") + + _zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + if [ "$_zone_id" ]; then + return 0 + fi + fi + + return 1 +} + +_ionos_cloud_get_record() { + zone_id=$1 + txtrecord=$2 + # this is to transform the domain to lower case + fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") + # this is to transform record name to lower case + # IONOS Cloud API transforms all record names to lower case + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") + + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then + _response="$(echo "$_response" | tr -d "\n")" + + pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}" + + _record="$(echo "$_response" | _egrep_o "$pattern")" + if [ "$_record" ]; then + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + return 0 + fi + fi + + return 1 +} + +_ionos_cloud_rest() { + method="$1" + route="$2" + data="$3" + + export _H1="Authorization: Bearer $IONOS_TOKEN" + + # clear headers + : >"$HTTP_HEADER" + + if [ "$method" != "GET" ]; then + _response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")" + else + _response="$(_get "$IONOS_CLOUD_API$route")" + fi + + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + + if [ "$?" != "0" ]; then + _err "Error $route: $_response" + return 1 + fi + + _debug2 "_response" "$_response" + _debug2 "_code" "$_code" + + return 0 +} From 2797d2c5359184160fb423ad24b68cc89e2725ca Mon Sep 17 00:00:00 2001 From: zak905 Date: Tue, 14 May 2024 19:50:44 +0200 Subject: [PATCH 373/687] fix add and rm method names --- dnsapi/dns_ionos_cloud.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh index 6204fda0..18a60d18 100644 --- a/dnsapi/dns_ionos_cloud.sh +++ b/dnsapi/dns_ionos_cloud.sh @@ -11,7 +11,7 @@ IONOS_CLOUD_API="https://dns.de-fra.ionos.com" IONOS_CLOUD_ROUTE_ZONES="/zones" -dns_ionos_add() { +dns_ionos_cloud_add() { fulldomain=$1 txtvalue=$2 @@ -30,7 +30,7 @@ dns_ionos_add() { return 1 } -dns_ionos_rm() { +dns_ionos_cloud_rm() { fulldomain=$1 txtvalue=$2 @@ -57,7 +57,7 @@ _ionos_init() { if [ -z "$IONOS_TOKEN" ]; then _err "You didn't specify an IONOS token yet." _err "Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." - _err "" + _err "You need to set it before calling acme.sh:" _err "\$ export IONOS_TOKEN=\"...\"" _err "\$ acme.sh --issue -d ... --dns dns_ionos_cloud" return 1 From fd461fe015608ddf00710bb05ef2aaa3799fa3c7 Mon Sep 17 00:00:00 2001 From: Marvin Dickhaus <2642714+Weishaupt@users.noreply.github.com> Date: Thu, 16 May 2024 22:44:47 +0200 Subject: [PATCH 374/687] Fix missing XML Escaping in Password String Fixes #5060 --- dnsapi/dns_inwx.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index e483c0e8..2f2082d6 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -160,6 +160,15 @@ _inwx_check_cookie() { return 1 } +_htmlEscape() { + local s + s=${1//&/&} + s=${s///>} + s=${s//'"'/"} + printf -- %s "$s" +} + _inwx_login() { if _inwx_check_cookie; then @@ -167,6 +176,8 @@ _inwx_login() { return 0 fi + XML_PASS=$(_htmlEscape "$INWX_Password") + xml_content=$(printf ' account.login @@ -190,7 +201,7 @@ _inwx_login() { - ' "$INWX_User" "$INWX_Password") + ' "$INWX_User" "$XML_PASS") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" From 6b7b5caf54ea0b45508e158db3748d00f48672f2 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sat, 18 Nov 2023 18:57:12 +0200 Subject: [PATCH 375/687] DNS provider API: structured description Instead of using comments declare info in a special variable. Then the variable can be used to print the DNS API provider usage. The usage can be parsed on UI and show all needed inputs for options. The info is stored in plain string that it's both human-readable and easy to parse: dns_example_info='API name An extended description. Multiline. Domains: list of alternative domains to find Site: the dns provider website e.g. example.com Docs: Link to ACME.sh wiki for the provider Options: VARIABLE1 Title for the option1. VARIABLE2 Title for the option2. Default "default value". VARIABLE3 Title for the option3. Description to show on UI. Optional. Issues: Link to a support ticket on https://github.com/acmesh-official/acme.sh Author: First Lastname , Another Author ; ' Here: VARIABLE1 will be required. VARIABLE2 will be required too but will be populated with a "default value". VARIABLE3 is optional and can be empty. A DNS provider may have alternative options like CloudFlare may use API KEY or API Token. You can use a second section OptionsAlt: section. Some providers may have alternative names or domains e.g. Aliyun and AlibabaCloud. Add them to Domains: section. Signed-off-by: Sergey Ponomarev --- dnsapi/dns_1984hosting.sh | 26 +++++++++++--------------- dnsapi/dns_acmedns.sh | 28 ++++++++++++++-------------- dnsapi/dns_acmeproxy.sh | 18 +++++++++++++----- dnsapi/dns_active24.sh | 11 +++++++++-- dnsapi/dns_ad.sh | 17 +++++++++-------- dnsapi/dns_ali.sh | 12 +++++++++--- dnsapi/dns_anx.sh | 13 ++++++++----- dnsapi/dns_artfiles.sh | 23 ++++++++++------------- dnsapi/dns_arvan.sh | 15 ++++++++++----- dnsapi/dns_aurora.sh | 16 +++++++++++----- dnsapi/dns_autodns.sh | 23 +++++++++++------------ dnsapi/dns_aws.sh | 20 +++++++++++--------- dnsapi/dns_azion.sh | 14 +++++++++----- dnsapi/dns_azure.sh | 13 +++++++++++-- dnsapi/dns_bookmyname.sh | 21 ++++++++++----------- dnsapi/dns_bunny.sh | 21 +++++++++------------ dnsapi/dns_cf.sh | 21 ++++++++++++--------- dnsapi/dns_clouddns.sh | 17 +++++++++++------ dnsapi/dns_cloudns.sh | 17 ++++++++++------- dnsapi/dns_cn.sh | 13 ++++++++++--- dnsapi/dns_conoha.sh | 11 +++++++++++ dnsapi/dns_constellix.sh | 14 ++++++++++---- dnsapi/dns_cpanel.sh | 26 +++++++++++++------------- dnsapi/dns_curanet.sh | 16 +++++++++++----- dnsapi/dns_cyon.sh | 28 +++++++++++----------------- dnsapi/dns_da.sh | 37 ++++++++++--------------------------- dnsapi/dns_ddnss.sh | 21 +++++++++------------ dnsapi/dns_desec.sh | 16 +++++++++------- dnsapi/dns_df.sh | 25 +++++++++++-------------- dnsapi/dns_dgon.sh | 20 ++++++++------------ dnsapi/dns_dnsexit.sh | 19 +++++++++++-------- dnsapi/dns_dnshome.sh | 21 ++++++++++----------- dnsapi/dns_dnsimple.sh | 16 ++++++++-------- dnsapi/dns_dnsservices.sh | 17 ++++++++++------- dnsapi/dns_doapi.sh | 19 +++++++++++-------- dnsapi/dns_domeneshop.sh | 9 +++++++++ dnsapi/dns_dp.sh | 14 ++++++++------ dnsapi/dns_dpi.sh | 14 ++++++++------ dnsapi/dns_dreamhost.sh | 14 +++++++++----- dnsapi/dns_duckdns.sh | 18 ++++++++---------- dnsapi/dns_durabledns.sh | 12 +++++++++--- dnsapi/dns_dyn.sh | 25 ++++++++++++------------- dnsapi/dns_dynu.sh | 21 +++++++++++---------- dnsapi/dns_dynv6.sh | 15 +++++++++++---- dnsapi/dns_easydns.sh | 19 +++++++++++-------- dnsapi/dns_edgedns.sh | 25 ++++++++++++++----------- dnsapi/dns_euserv.sh | 24 ++++++++++-------------- dnsapi/dns_exoscale.sh | 8 ++++++++ dnsapi/dns_fornex.sh | 11 +++++++++-- dnsapi/dns_freedns.sh | 19 ++++++++++--------- dnsapi/dns_gandi_livedns.sh | 17 ++++++++++------- dnsapi/dns_gcloud.sh | 10 ++++++++-- dnsapi/dns_gcore.sh | 12 ++++++++---- dnsapi/dns_gd.sh | 16 ++++++++-------- dnsapi/dns_geoscaling.sh | 16 ++++++++-------- dnsapi/dns_googledomains.sh | 15 ++++++++++----- dnsapi/dns_he.sh | 21 ++++++++++----------- dnsapi/dns_hetzner.sh | 12 ++++++++---- dnsapi/dns_hexonet.sh | 14 +++++++++----- dnsapi/dns_hostingde.sh | 15 +++++++++------ dnsapi/dns_huaweicloud.sh | 14 ++++++++++---- dnsapi/dns_infoblox.sh | 14 ++++++++++---- dnsapi/dns_infomaniak.sh | 15 ++++++++------- dnsapi/dns_internetbs.sh | 18 ++++++++++-------- dnsapi/dns_inwx.sh | 13 ++++++++----- dnsapi/dns_ionos.sh | 19 +++++++++---------- dnsapi/dns_ipv64.sh | 18 +++++++++--------- dnsapi/dns_ispconfig.sh | 21 ++++++++++++--------- dnsapi/dns_jd.sh | 15 ++++++++++----- dnsapi/dns_joker.sh | 33 ++++++++++----------------------- dnsapi/dns_kappernet.sh | 17 +++++++++-------- dnsapi/dns_kas.sh | 27 ++++++++++++--------------- dnsapi/dns_kinghost.sh | 19 ++++++++++--------- dnsapi/dns_knot.sh | 10 ++++++++++ dnsapi/dns_la.sh | 12 +++++++++--- dnsapi/dns_leaseweb.sh | 12 +++++++++--- dnsapi/dns_lexicon.sh | 10 +++++++--- dnsapi/dns_linode.sh | 10 ++++++++-- dnsapi/dns_linode_v4.sh | 11 ++++++++--- dnsapi/dns_loopia.sh | 16 +++++++++------- dnsapi/dns_lua.sh | 17 ++++++++++------- dnsapi/dns_maradns.sh | 9 +++++++++ dnsapi/dns_me.sh | 14 +++++++++----- dnsapi/dns_miab.sh | 23 +++++++++++------------ dnsapi/dns_misaka.sh | 15 ++++++++------- dnsapi/dns_myapi.sh | 17 ++++++++++++----- dnsapi/dns_mydevil.sh | 21 +++++++++++---------- dnsapi/dns_mydnsjp.sh | 18 +++++++++--------- dnsapi/dns_mythic_beasts.sh | 9 +++++++++ dnsapi/dns_namecheap.sh | 15 ++++++++++----- dnsapi/dns_namecom.sh | 13 +++++++++---- dnsapi/dns_namesilo.sh | 14 ++++++++++---- dnsapi/dns_nanelo.sh | 13 ++++++++----- dnsapi/dns_nederhost.sh | 10 ++++++++-- dnsapi/dns_neodigit.sh | 16 ++++++++-------- dnsapi/dns_netcup.sh | 12 +++++++++++- dnsapi/dns_netlify.sh | 10 ++++++++-- dnsapi/dns_nic.sh | 17 +++++++++++------ dnsapi/dns_njalla.sh | 11 ++++++++--- dnsapi/dns_nm.sh | 20 +++++++++----------- dnsapi/dns_nsd.sh | 12 +++++++++--- dnsapi/dns_nsone.sh | 15 +++++++++------ dnsapi/dns_nsupdate.sh | 10 ++++++++++ dnsapi/dns_nw.sh | 27 ++++++++++++--------------- dnsapi/dns_oci.sh | 17 +++++++++++++++-- dnsapi/dns_one.sh | 14 +++++++++----- dnsapi/dns_online.sh | 11 +++++++++-- dnsapi/dns_openprovider.sh | 21 ++++++++++----------- dnsapi/dns_openstack.sh | 27 +++++++++++++++++---------- dnsapi/dns_opnsense.sh | 24 ++++++++++++------------ dnsapi/dns_ovh.sh | 20 +++++++++++--------- dnsapi/dns_pdns.sh | 18 ++++++++++-------- dnsapi/dns_pleskxml.sh | 32 ++++++++++++-------------------- dnsapi/dns_pointhq.sh | 14 +++++++++----- dnsapi/dns_porkbun.sh | 13 +++++++++---- dnsapi/dns_rackcorp.sh | 22 ++++++++++------------ dnsapi/dns_rackspace.sh | 14 +++++++++----- dnsapi/dns_rage4.sh | 14 +++++++++----- dnsapi/dns_rcode0.sh | 14 ++++++++++---- dnsapi/dns_regru.sh | 15 +++++++++------ dnsapi/dns_scaleway.sh | 10 ++++++++-- dnsapi/dns_schlundtech.sh | 22 ++++++++++------------ dnsapi/dns_selectel.sh | 12 ++++++++---- dnsapi/dns_selfhost.sh | 15 +++++++++++---- dnsapi/dns_servercow.sh | 25 ++++++++++--------------- dnsapi/dns_simply.sh | 13 ++++++++----- dnsapi/dns_tele3.sh | 19 +++++++++---------- dnsapi/dns_tencent.sh | 12 +++++++++--- dnsapi/dns_transip.sh | 10 ++++++++++ dnsapi/dns_udr.sh | 20 ++++++++++---------- dnsapi/dns_ultra.sh | 14 +++++++++----- dnsapi/dns_unoeuro.sh | 14 +++++++++----- dnsapi/dns_variomedia.sh | 11 ++++++++--- dnsapi/dns_veesp.sh | 16 ++++++++++------ dnsapi/dns_vercel.sh | 11 +++++++---- dnsapi/dns_vscale.sh | 14 ++++++++------ dnsapi/dns_vultr.sh | 12 +++++++++--- dnsapi/dns_websupport.sh | 22 ++++++++++------------ dnsapi/dns_world4you.sh | 13 ++++++++++--- dnsapi/dns_yandex.sh | 18 +++++++++--------- dnsapi/dns_yc.sh | 19 +++++++++++++------ dnsapi/dns_zilore.sh | 8 +++++++- dnsapi/dns_zone.sh | 10 +++++++++- dnsapi/dns_zonomi.sh | 12 +++++++----- 144 files changed, 1399 insertions(+), 986 deletions(-) mode change 100644 => 100755 dnsapi/dns_acmeproxy.sh diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index e4ef2e4b..3f54a714 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -1,22 +1,18 @@ #!/usr/bin/env sh -# This file name is "dns_1984hosting.sh" -# So, here must be a method dns_1984hosting_add() -# Which will be called by acme.sh to add the txt record to your api system. -# returns 0 means success, otherwise error. - -# Author: Adrian Fedoreanu -# Report Bugs here: https://github.com/acmesh-official/acme.sh -# or here... https://github.com/acmesh-official/acme.sh/issues/2851 +# shellcheck disable=SC2034 +dns_1984hosting_info='1984.hosting +Domains: 1984.is +Site: 1984.hosting +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_1984hosting +Options: + One984HOSTING_Username Username + One984HOSTING_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2851 +Author: Adrian Fedoreanu +' ######## Public functions ##################### -# Export 1984HOSTING username and password in following variables -# -# One984HOSTING_Username=username -# One984HOSTING_Password=password -# -# username/password and csrftoken/sessionid cookies are saved in ~/.acme.sh/account.conf - # Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Add a text record. dns_1984hosting_add() { diff --git a/dnsapi/dns_acmedns.sh b/dnsapi/dns_acmedns.sh index 057f9742..f3f50233 100755 --- a/dnsapi/dns_acmedns.sh +++ b/dnsapi/dns_acmedns.sh @@ -1,18 +1,18 @@ #!/usr/bin/env sh -# -#Author: Wolfgang Ebner -#Author: Sven Neubuaer -#Report Bugs here: https://github.com/dampfklon/acme.sh -# -# Usage: -# export ACMEDNS_BASE_URL="https://auth.acme-dns.io" -# -# You can optionally define an already existing account: -# -# export ACMEDNS_USERNAME="" -# export ACMEDNS_PASSWORD="" -# export ACMEDNS_SUBDOMAIN="" -# +# shellcheck disable=SC2034 +dns_acmedns_info='acme-dns Server API + The acme-dns is a limited DNS server with RESTful API to handle ACME DNS challenges. +Site: github.com/joohoi/acme-dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_acmedns +Options: + ACMEDNS_USERNAME Username. Optional. + ACMEDNS_PASSWORD Password. Optional. + ACMEDNS_SUBDOMAIN Subdomain. Optional. + ACMEDNS_BASE_URL API endpoint. Default: "https://auth.acme-dns.io". +Issues: github.com/dampfklon/acme.sh +Author: Wolfgang Ebner, Sven Neubuaer +' + ######## Public functions ##################### #Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh old mode 100644 new mode 100755 index 9d5533f9..a699f645 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -1,9 +1,17 @@ #!/usr/bin/env sh - -## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy) -## API integration by Maarten den Braber -## -## Report any bugs via https://github.com/mdbraber/acme.sh +# shellcheck disable=SC2034 +dns_acmeproxy_info='AcmeProxy Server API + AcmeProxy can be used to as a single host in your network to request certificates through a DNS API. + Clients can connect with the one AcmeProxy host so you do not need to store DNS API credentials on every single host. +Site: github.com/mdbraber/acmeproxy +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_acmeproxy +Options: + ACMEPROXY_ENDPOINT API Endpoint + ACMEPROXY_USERNAME Username + ACMEPROXY_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2251 +Author: Maarten den Braber +' dns_acmeproxy_add() { fulldomain="${1}" diff --git a/dnsapi/dns_active24.sh b/dnsapi/dns_active24.sh index 862f734f..1a6f97f0 100755 --- a/dnsapi/dns_active24.sh +++ b/dnsapi/dns_active24.sh @@ -1,6 +1,13 @@ #!/usr/bin/env sh - -#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_active24_info='Active24.com +Site: Active24.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_active24 +Options: + ACTIVE24_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2059 +Author: Milan Pála +' ACTIVE24_Api="https://api.active24.com" diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index fc4a664b..ccd8226f 100755 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -1,12 +1,13 @@ #!/usr/bin/env sh - -# -#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" - -#This is the Alwaysdata api wrapper for acme.sh -# -#Author: Paul Koppen -#Report Bugs here: https://github.com/wpk-/acme.sh +# shellcheck disable=SC2034 +dns_ad_info='AlwaysData.com +Site: AlwaysData.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ad +Options: + AD_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/pull/503 +Author: Paul Koppen +' AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index c69839dc..9bdfc20b 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_ali_info='AlibabaCloud.com +Domains: Aliyun.com +Site: AlibabaCloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ali +Options: + Ali_Key API Key + Ali_Secret API Secret +' Ali_API="https://alidns.aliyuncs.com/" -#Ali_Key="LTqIA87hOKdjevsf5" -#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2" - #Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_ali_add() { fulldomain=$1 diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index c1a1130a..9e5737c9 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,9 +1,12 @@ #!/usr/bin/env sh - -# Anexia CloudDNS acme.sh hook -# Author: MA - -#ANX_Token="xxxx" +# shellcheck disable=SC2034 +dns_anx_info='Anexia.com CloudDNS +Site: Anexia.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_anx +Options: + ANX_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/3238 +' ANX_API='https://engine.anexia-it.com/api/clouddns/v1' diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index a762837e..abd088f6 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -1,17 +1,14 @@ #!/usr/bin/env sh - -################################################################################ -# ACME.sh 3rd party DNS API plugin for ArtFiles.de -################################################################################ -# Author: Martin Arndt, https://troublezone.net/ -# Released: 2022-02-27 -# Issues: https://github.com/acmesh-official/acme.sh/issues/4718 -################################################################################ -# Usage: -# 1. export AF_API_USERNAME='api12345678' -# 2. export AF_API_PASSWORD='apiPassword' -# 3. acme.sh --issue -d example.com --dns dns_artfiles -################################################################################ +# shellcheck disable=SC2034 +dns_artfiles_info='ArtFiles.de +Site: ArtFiles.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_artfiles +Options: + AF_API_USERNAME API Username + AF_API_PASSWORD API Password +Issues: github.com/acmesh-official/acme.sh/issues/4718 +Author: Martin Arndt +' ########## API configuration ################################################### diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 4ca5b685..ed3b1314 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,11 +1,16 @@ #!/usr/bin/env sh - -# Arvan_Token="Apikey xxxx" +# shellcheck disable=SC2034 +dns_arvan_info='ArvanCloud.ir +Site: ArvanCloud.ir +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_arvan +Options: + Arvan_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2796 +Author: Vahid Fardi +' ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains" -# Author: Vahid Fardi -# Report Bugs here: https://github.com/Neilpang/acme.sh -# + ######## Public functions ##################### #Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_aurora.sh b/dnsapi/dns_aurora.sh index 00f44739..746fce54 100644 --- a/dnsapi/dns_aurora.sh +++ b/dnsapi/dns_aurora.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh - -# -#AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_aurora_info='versio.nl AuroraDNS +Domains: pcextreme.nl +Site: versio.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_aurora +Options: + AURORA_Key API Key + AURORA_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3459 +Author: Jasper Zonneveld +' AURORA_Api="https://api.auroradns.eu" diff --git a/dnsapi/dns_autodns.sh b/dnsapi/dns_autodns.sh index 92534489..309e5f27 100644 --- a/dnsapi/dns_autodns.sh +++ b/dnsapi/dns_autodns.sh @@ -1,16 +1,15 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - -# This is the InternetX autoDNS xml api wrapper for acme.sh -# Author: auerswald@gmail.com -# Created: 2018-01-14 -# -# export AUTODNS_USER="username" -# export AUTODNS_PASSWORD="password" -# export AUTODNS_CONTEXT="context" -# -# Usage: -# acme.sh --issue --dns dns_autodns -d example.com +# shellcheck disable=SC2034 +dns_autodns_info='InternetX autoDNS + InternetX autoDNS XML API +Site: InternetX.com/autodns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_autodns +Options: + AUTODNS_USER Username + AUTODNS_PASSWORD Password + AUTODNS_CONTEXT Context +Author: +' AUTODNS_API="https://gateway.autodns.com" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 27923b64..c599b4e0 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -1,13 +1,15 @@ #!/usr/bin/env sh - -# -#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#AWS_SECRET_ACCESS_KEY="xxxxxxx" - -#This is the Amazon Route53 api wrapper for acme.sh -#All `_sleep` commands are included to avoid Route53 throttling, see -#https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests +# shellcheck disable=SC2034 +dns_aws_info='Amazon AWS Route53 domain API +Site: docs.aws.amazon.com/route53/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws +Options: + AWS_ACCESS_KEY_ID API Key ID + AWS_SECRET_ACCESS_KEY API Secret +' + +# All `_sleep` commands are included to avoid Route53 throttling, see +# https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests AWS_HOST="route53.amazonaws.com" AWS_URL="https://$AWS_HOST" diff --git a/dnsapi/dns_azion.sh b/dnsapi/dns_azion.sh index f215686d..2371833e 100644 --- a/dnsapi/dns_azion.sh +++ b/dnsapi/dns_azion.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#AZION_Email="" -#AZION_Password="" -# +# shellcheck disable=SC2034 +dns_azion_info='Azion.om +Site: Azion.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_azion +Options: + AZION_Email Email + AZION_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/3555 +' AZION_Api="https://api.azionapi.net" diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 1c33c13a..00ccd798 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -1,6 +1,15 @@ #!/usr/bin/env sh - -WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS" +# shellcheck disable=SC2034 +dns_azure_info='Azure +Site: Azure.microsoft.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_azure +Options: + AZUREDNS_SUBSCRIPTIONID Subscription ID + AZUREDNS_TENANTID Tenant ID + AZUREDNS_APPID App ID. App ID of the service principal + AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal + AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false" +' ######## Public functions ##################### diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 62548fd0..668cf074 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -1,18 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_bookmyname_info='BookMyName.com +Site: BookMyName.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bookmyname +Options: + BOOKMYNAME_USERNAME Username + BOOKMYNAME_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/3209 +Author: Neilpang +' -#Here is a sample custom api script. -#This file name is "dns_bookmyname.sh" -#So, here must be a method dns_bookmyname_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: Neilpang -#Report Bugs here: https://github.com/acmesh-official/acme.sh -# ######## Public functions ##################### -# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - # BookMyName urls: # https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' # https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' diff --git a/dnsapi/dns_bunny.sh b/dnsapi/dns_bunny.sh index a9b1ea5a..681f748a 100644 --- a/dnsapi/dns_bunny.sh +++ b/dnsapi/dns_bunny.sh @@ -1,16 +1,13 @@ #!/usr/bin/env sh - -## Will be called by acme.sh to add the TXT record via the Bunny DNS API. -## returns 0 means success, otherwise error. - -## Author: nosilver4u -## GitHub: https://github.com/nosilver4u/acme.sh - -## -## Environment Variables Required: -## -## BUNNY_API_KEY="75310dc4-ca77-9ac3-9a19-f6355db573b49ce92ae1-2655-3ebd-61ac-3a3ae34834cc" -## +# shellcheck disable=SC2034 +dns_bunny_info='Bunny.net +Site: Bunny.net/dns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bunny +Options: + BUNNY_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/4296 +Author: +' ##################### Public functions ##################### diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cd8d9a8d..da63e771 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -1,13 +1,16 @@ #!/usr/bin/env sh - -# -#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#CF_Email="xxxx@sss.com" - -#CF_Token="xxxx" -#CF_Account_ID="xxxx" -#CF_Zone_ID="xxxx" +# shellcheck disable=SC2034 +dns_cf_info='CloudFlare +Site: CloudFlare.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf +Options: + CF_Key API Key + CF_Email Your account email +OptionsAlt: + CF_Token API Token + CF_Account_ID Account ID + CF_Zone_ID Zone ID. Optional. +' CF_Api="https://api.cloudflare.com/client/v4" diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 31ae4ee9..b78d70a4 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh - -# Author: Radek Sprta - -#CLOUDDNS_EMAIL=XXXXX -#CLOUDDNS_PASSWORD="YYYYYYYYY" -#CLOUDDNS_CLIENT_ID=XXXXX +# shellcheck disable=SC2034 +dns_clouddns_info='vshosting.cz CloudDNS +Site: github.com/vshosting/clouddns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_clouddns +Options: + CLOUDDNS_EMAIL Email + CLOUDDNS_PASSWORD Password + CLOUDDNS_CLIENT_ID Client ID +Issues: github.com/acmesh-official/acme.sh/issues/2699 +Author: Radek Sprta +' CLOUDDNS_API='https://admin.vshosting.cloud/clouddns' CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login' diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index 8d7fd437..145a85be 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_cloudns_info='ClouDNS.net +Site: ClouDNS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cloudns +Options: + CLOUDNS_AUTH_ID Regular auth ID + CLOUDNS_SUB_AUTH_ID Sub auth ID + CLOUDNS_AUTH_PASSWORD Auth Password +Author: Boyan Peychev +' -# Author: Boyan Peychev -# Repository: https://github.com/ClouDNS/acme.sh/ -# Editor: I Komang Suryadana - -#CLOUDNS_AUTH_ID=XXXXX -#CLOUDNS_SUB_AUTH_ID=XXXXX -#CLOUDNS_AUTH_PASSWORD="YYYYYYYYY" CLOUDNS_API="https://api.cloudns.net" DOMAIN_TYPE= DOMAIN_MASTER= diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh index 38d1f4aa..797f788e 100644 --- a/dnsapi/dns_cn.sh +++ b/dnsapi/dns_cn.sh @@ -1,7 +1,14 @@ #!/usr/bin/env sh - -# DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/). -# created by 5ll and francis +# shellcheck disable=SC2034 +dns_cn_info='Core-Networks.de +Site: beta.api.Core-Networks.de/doc/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cn +Options: + CN_User User + CN_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2142 +Author: 5ll, francis +' CN_API="https://beta.api.core-networks.de" diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index ddc32074..6ceca829 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -1,4 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_conoha_info='ConoHa.jp +Domains: ConoHa.io +Site: ConoHa.jp +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_conoha +Options: + CONOHA_Username Username + CONOHA_Password Password + CONOHA_TenantId TenantId + CONOHA_IdentityServiceApi Identity Service API. E.g. "https://identity.xxxx.conoha.io/v2.0" +' CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\." diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 69d216f0..0376dda1 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh - -# Author: Wout Decre +# shellcheck disable=SC2034 +dns_constellix_info='Constellix.com +Site: Constellix.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix +Options: + CONSTELLIX_Key API Key + CONSTELLIX_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/2724 +Author: Wout Decre +' CONSTELLIX_Api="https://api.dns.constellix.com/v1" -#CONSTELLIX_Key="XXX" -#CONSTELLIX_Secret="XXX" ######## Public functions ##################### diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index f6126bcb..a6991403 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -1,18 +1,18 @@ #!/usr/bin/env sh -# -#Author: Bjarne Saltbaek -#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 -# -# +# shellcheck disable=SC2034 +dns_cpanel_info='cPanel Server API + Manage DNS via cPanel Dashboard. +Site: cPanel.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_cpanel +Options: + cPanel_Username Username + cPanel_Apitoken API Token + cPanel_Hostname Server URL. E.g. "https://hostname:port" +Issues: github.com/acmesh-official/acme.sh/issues/3732 +Author: Bjarne Saltbaek +' + ######## Public functions ##################### -# -# Export CPANEL username,api token and hostname in the following variables -# -# cPanel_Username=username -# cPanel_Apitoken=apitoken -# cPanel_Hostname=hostname -# -# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record dns_cpanel_add() { diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 4b39f365..a530d304 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh - -#Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. -#Requires api credentials with scope: dns -#Author: Peter L. Hansen -#Version 1.0 +# shellcheck disable=SC2034 +dns_curanet_info='Curanet.dk +Domains: scannet.dk wannafind.dk dandomain.dk +Site: Curanet.dk +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_curanet +Options: + CURANET_AUTHCLIENTID Auth ClientID. Requires scope dns + CURANET_AUTHSECRET Auth Secret +Issues: github.com/acmesh-official/acme.sh/issues/3933 +Author: Peter L. Hansen +' CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token" diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 830e8831..04a515aa 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -1,21 +1,15 @@ #!/usr/bin/env sh - -######## -# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/acmesh-official/acme.sh) -# -# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com -# -# Dependencies: -# ------------- -# - oathtool (When using 2 Factor Authentication) -# -# Issues: -# ------- -# Any issues / questions / suggestions can be posted here: -# https://github.com/noplanman/cyon-api/issues -# -# Author: Armando Lüscher -######## +# shellcheck disable=SC2034 +dns_cyon_info='cyon.ch +Site: cyon.ch +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cyon +Options: + CY_Username Username + CY_Password API Token + CY_OTP_Secret OTP token. Only required if using 2FA +Issues: github.com/noplanman/cyon-api/issues +Author: Armando Lüscher +' dns_cyon_add() { _cyon_load_credentials && diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index 4d3e09b1..b2789a6f 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -1,31 +1,14 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- -# vim: et ts=2 sw=2 -# -# DirectAdmin 1.41.0 API -# The DirectAdmin interface has it's own Let's encrypt functionality, but this -# script can be used to generate certificates for names which are not hosted on -# DirectAdmin -# -# User must provide login data and URL to DirectAdmin incl. port. -# You can create login key, by using the Login Keys function -# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to -# - CMD_API_DNS_CONTROL -# - CMD_API_SHOW_DOMAINS -# -# See also https://www.directadmin.com/api.php and -# https://www.directadmin.com/features.php?id=1298 -# -# Report bugs to https://github.com/TigerP/acme.sh/issues -# -# Values to export: -# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443" -# export DA_Api_Insecure=1 -# -# Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is -# whether ssl cert is checked for validity (0) or whether it is just accepted -# (1) -# +# shellcheck disable=SC2034 +dns_da_info='DirectAdmin Server API +Site: DirectAdmin.com/api.php +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_da +Options: + DA_Api API Server URL. E.g. "https://remoteUser:remotePassword@da.domain.tld:8443" + DA_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +Issues: github.com/TigerP/acme.sh/issues +' + ######## Public functions ##################### # Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index b9da33ff..118b148b 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -1,16 +1,13 @@ #!/usr/bin/env sh - -#Created by RaidenII, to use DuckDNS's API to add/remove text records -#modified by helbgd @ 03/13/2018 to support ddnss.de -#modified by mod242 @ 04/24/2018 to support different ddnss domains -#Please note: the Wildcard Feature must be turned on for the Host record -#and the checkbox for TXT needs to be enabled - -# Pass credentials before "acme.sh --issue --dns dns_ddnss ..." -# -- -# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" -# -- -# +# shellcheck disable=SC2034 +dns_ddnss_info='DDNSS.de +Site: DDNSS.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ddnss +Options: + DDNSS_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2230 +Author: RaidenII, helbgd, mod242 +' DDNSS_DNS_API="https://ddnss.de/upd.php" diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 495a6780..0d6a6c2f 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh -# -# deSEC.io Domain API -# -# Author: Zheng Qian -# -# deSEC API doc -# https://desec.readthedocs.io/en/latest/ +# shellcheck disable=SC2034 +dns_desec_info='deSEC.io +Site: desec.readthedocs.io/en/latest/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_desec +Options: + DDNSS_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2180 +Author: Zheng Qian +' REST_API="https://desec.io/api/v1/domains" diff --git a/dnsapi/dns_df.sh b/dnsapi/dns_df.sh index c0499ddf..513e350c 100644 --- a/dnsapi/dns_df.sh +++ b/dnsapi/dns_df.sh @@ -1,18 +1,15 @@ #!/usr/bin/env sh - -######################################################################## -# https://dyndnsfree.de hook script for acme.sh -# -# Environment variables: -# -# - $DF_user (your dyndnsfree.de username) -# - $DF_password (your dyndnsfree.de password) -# -# Author: Thilo Gass -# Git repo: https://github.com/ThiloGa/acme.sh - -#-- dns_df_add() - Add TXT record -------------------------------------- -# Usage: dns_df_add _acme-challenge.subdomain.domain.com "XyZ123..." +# shellcheck disable=SC2034 +dns_df_info='DynDnsFree.de +Domains: dynup.de +Site: DynDnsFree.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_df +Options: + DF_user Username + DF_password Password +Issues: github.com/acmesh-official/acme.sh/issues/2897 +Author: Thilo Gass +' dyndnsfree_api="https://dynup.de/acme.php" diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index afe1b32e..9aaa9606 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -1,16 +1,12 @@ #!/usr/bin/env sh - -## Will be called by acme.sh to add the txt record to your api system. -## returns 0 means success, otherwise error. - -## Author: thewer -## GitHub: https://github.com/gitwer/acme.sh - -## -## Environment Variables Required: -## -## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc" -## +# shellcheck disable=SC2034 +dns_dgon_info='DigitalOcean.com +Site: DigitalOcean.com/help/api/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dgon +Options: + DO_API_KEY API Key +Author: +' ##################### Public functions ##################### diff --git a/dnsapi/dns_dnsexit.sh b/dnsapi/dns_dnsexit.sh index 62d7d757..9f2871b4 100644 --- a/dnsapi/dns_dnsexit.sh +++ b/dnsapi/dns_dnsexit.sh @@ -1,13 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dnsexit_info='DNSExit.com +Site: DNSExit.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsexit +Options: + DNSEXIT_API_KEY API Key + DNSEXIT_AUTH_USER Username + DNSEXIT_AUTH_PASS Password +Issues: github.com/acmesh-official/acme.sh/issues/4719 +Author: Samuel Jimenez +' -#use dns-01 at DNSExit.com - -#Author: Samuel Jimenez -#Report Bugs here: https://github.com/acmesh-official/acme.sh - -#DNSEXIT_API_KEY=ABCDEFGHIJ0123456789abcdefghij -#DNSEXIT_AUTH_USER=login@email.address -#DNSEXIT_AUTH_PASS=aStrongPassword DNSEXIT_API_URL="https://api.dnsexit.com/dns/" DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp" diff --git a/dnsapi/dns_dnshome.sh b/dnsapi/dns_dnshome.sh index 99608769..59828796 100755 --- a/dnsapi/dns_dnshome.sh +++ b/dnsapi/dns_dnshome.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -# dnsHome.de API for acme.sh -# -# This Script adds the necessary TXT record to a Subdomain -# -# Author dnsHome.de (https://github.com/dnsHome-de) -# -# Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819 -# -# export DNSHOME_Subdomain="" -# export DNSHOME_SubdomainPassword="" +# shellcheck disable=SC2034 +dns_dnshome_info='dnsHome.de +Site: dnsHome.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnshome +Options: + DNSHOME_Subdomain Subdomain + DNSHOME_SubdomainPassword Subdomain Password +Issues: github.com/acmesh-official/acme.sh/issues/3819 +Author: dnsHome.de https://github.com/dnsHome-de +' # Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index d831eb2b..e080ecf0 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -# DNSimple domain api -# https://github.com/pho3nixf1re/acme.sh/issues -# -# This is your oauth token which can be acquired on the account page. Please -# note that this must be an _account_ token and not a _user_ token. -# https://dnsimple.com/a//account/access_tokens -# DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_dnsimple_info='DNSimple.com +Site: DNSimple.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dnsimple +Options: + DNSimple_OAUTH_TOKEN OAuth Token +Issues: github.com/pho3nixf1re/acme.sh/issues +' DNSimple_API="https://api.dnsimple.com/v2" diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 008153a4..44cc6f45 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dnsservices_info='DNS.Services +Site: DNS.Services +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsservices +Options: + DnsServices_Username Username + DnsServices_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/4152 +Author: Bjarke Bruun +' -#This file name is "dns_dnsservices.sh" -#Script for Danish DNS registra and DNS hosting provider https://dns.services - -#Author: Bjarke Bruun -#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 - -# Global variable to connect to the DNS.Services API DNSServices_API=https://dns.services/api ######## Public functions ##################### diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index a001d52c..9bc6a4a4 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh - -# Official Let's Encrypt API for do.de / Domain-Offensive -# -# This is different from the dns_do adapter, because dns_do is only usable for enterprise customers -# This API is also available to private customers/individuals -# -# Provide the required LetsEncrypt token like this: -# DO_LETOKEN="FmD408PdqT1E269gUK57" +# shellcheck disable=SC2034 +dns_doapi_info='Domain-Offensive do.de + Official LetsEncrypt API for do.de / Domain-Offensive. + This is different from the dns_do adapter, because dns_do is only usable for enterprise customers. + This API is also available to private customers/individuals. +Site: do.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_doapi +Options: + DO_LETOKEN LetsEncrypt Token +Issues: github.com/acmesh-official/acme.sh/issues/2057 +' DO_API="https://www.do.de/api/letsencrypt" diff --git a/dnsapi/dns_domeneshop.sh b/dnsapi/dns_domeneshop.sh index 9a3791f4..16d3dbe5 100644 --- a/dnsapi/dns_domeneshop.sh +++ b/dnsapi/dns_domeneshop.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_domeneshop_info='DomeneShop.no +Site: DomeneShop.no +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_domeneshop +Options: + DOMENESHOP_Token Token + DOMENESHOP_Secret Secret +Issues: github.com/acmesh-official/acme.sh/issues/2457 +' DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0" diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 9b8b7a8b..29d32c27 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -1,10 +1,12 @@ #!/usr/bin/env sh - -# Dnspod.cn Domain api -# -#DP_Id="1234" -# -#DP_Key="sADDsdasdgdsf" +# shellcheck disable=SC2034 +dns_dp_info='DNSPod.cn +Site: DNSPod.cn +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dp +Options: + DP_Id Id + DP_Key Key +' REST_API="https://dnsapi.cn" diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh index 2955effd..521f2d69 100755 --- a/dnsapi/dns_dpi.sh +++ b/dnsapi/dns_dpi.sh @@ -1,10 +1,12 @@ #!/usr/bin/env sh - -# Dnspod.com Domain api -# -#DPI_Id="1234" -# -#DPI_Key="sADDsdasdgdsf" +# shellcheck disable=SC2034 +dns_dpi_info='DNSPod.com +Site: DNSPod.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dpi +Options: + DPI_Id Id + DPI_Key Key +' REST_API="https://api.dnspod.com" diff --git a/dnsapi/dns_dreamhost.sh b/dnsapi/dns_dreamhost.sh index a4017938..ce4fff87 100644 --- a/dnsapi/dns_dreamhost.sh +++ b/dnsapi/dns_dreamhost.sh @@ -1,10 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dreamhost_info='DreamHost.com +Site: DreamHost.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dreamhost +Options: + DH_API_KEY API Key +Issues: github.com/RhinoLance/acme.sh +Author: RhinoLance +' -#Author: RhinoLance -#Report Bugs here: https://github.com/RhinoLance/acme.sh -# - -#define the api endpoint DH_API_ENDPOINT="https://api.dreamhost.com/" querystring="" diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index d6e1dbdc..71594873 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -1,14 +1,12 @@ #!/usr/bin/env sh - -#Created by RaidenII, to use DuckDNS's API to add/remove text records -#06/27/2017 - -# Pass credentials before "acme.sh --issue --dns dns_duckdns ..." -# -- -# export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" -# -- -# -# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure may need to be used with acme.sh +# shellcheck disable=SC2034 +dns_duckdns_info='DuckDNS.org +Site: www.DuckDNS.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + DuckDNS_Token API Token +Author: RaidenII +' DuckDNS_API="https://www.duckdns.org/update" diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh index 677ae24d..cd4bd2eb 100644 --- a/dnsapi/dns_durabledns.sh +++ b/dnsapi/dns_durabledns.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#DD_API_User="xxxxx" -#DD_API_Key="xxxxxx" +# shellcheck disable=SC2034 +dns_durabledns_info='DurableDNS.com +Site: DurableDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_durabledns +Options: + DD_API_User API User + DD_API_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2281 +' _DD_BASE="https://durabledns.com/services/dns" diff --git a/dnsapi/dns_dyn.sh b/dnsapi/dns_dyn.sh index 024e0a38..94201923 100644 --- a/dnsapi/dns_dyn.sh +++ b/dnsapi/dns_dyn.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh -# -# Dyn.com Domain API -# -# Author: Gerd Naschenweng -# https://github.com/magicdude4eva -# +# shellcheck disable=SC2034 +dns_dyn_info='Dyn.com +Domains: dynect.net +Site: Dyn.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dyn +Options: + DYN_Customer Customer + DYN_Username API Username + DYN_Password Secret +Author: Gerd Naschenweng +' + # Dyn Managed DNS API # https://help.dyn.com/dns-api-knowledge-base/ # @@ -20,13 +26,6 @@ # ZoneRemoveNode # ZonePublish # -- -# -# Pass credentials before "acme.sh --issue --dns dns_dyn ..." -# -- -# export DYN_Customer="customer" -# export DYN_Username="apiuser" -# export DYN_Password="secret" -# -- DYN_API="https://api.dynect.net/REST" diff --git a/dnsapi/dns_dynu.sh b/dnsapi/dns_dynu.sh index 406ef17d..0dbeda24 100644 --- a/dnsapi/dns_dynu.sh +++ b/dnsapi/dns_dynu.sh @@ -1,20 +1,21 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dynu_info='Dynu.com +Site: Dynu.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dynu +Options: + Dynu_ClientId Client ID + Dynu_Secret Secret +Issues: github.com/shar0119/acme.sh +Author: Dynu Systems Inc +' -#Client ID -#Dynu_ClientId="0b71cae7-a099-4f6b-8ddf-94571cdb760d" -# -#Secret -#Dynu_Secret="aCUEY4BDCV45KI8CSIC3sp2LKQ9" -# #Token Dynu_Token="" # #Endpoint Dynu_EndPoint="https://api.dynu.com/v2" -# -#Author: Dynu Systems, Inc. -#Report Bugs here: https://github.com/shar0119/acme.sh -# + ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 90814b1b..8b94dae7 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,8 +1,15 @@ #!/usr/bin/env sh -#Author StefanAbl -#Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' -#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" -#if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub +# shellcheck disable=SC2034 +dns_dynv6_info='DynV6.com +Site: DynV6.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dynv6 +Options: + DYNV6_TOKEN REST API token. Get from https://DynV6.com/keys +OptionsAlt: + KEY Path to SSH private key file. E.g. "/root/.ssh/dynv6" +Issues: github.com/acmesh-official/acme.sh/issues/2702 +Author: StefanAbl +' dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index ab47a0bc..d168054a 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -1,14 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_easydns_info='easyDNS.net +Site: easyDNS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_easydns +Options: + EASYDNS_Token API Token + EASYDNS_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2647 +Author: Neilpang, wurzelpanzer +' -####################################################### -# -# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh -# # API Documentation: https://sandbox.rest.easydns.net:3001/ -# -# Author: wurzelpanzer [wurzelpanzer@maximolider.net] -# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647 -# + #################### Public functions ################# #EASYDNS_Key="xxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 27650eb1..e88a1483 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -1,4 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_edgedns_info='Akamai.com Edge DNS +Site: techdocs.Akamai.com/edge-dns/reference/edge-dns-api +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_edgedns +Options: Specify individual credentials + AKAMAI_HOST Host + AKAMAI_ACCESS_TOKEN Access token + AKAMAI_CLIENT_TOKEN Client token + AKAMAI_CLIENT_SECRET Client secret +Issues: github.com/acmesh-official/acme.sh/issues/3157 +' # Akamai Edge DNS v2 API # User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to @@ -6,18 +17,10 @@ # Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support -# Values to export: -# --EITHER-- # *** TBD. NOT IMPLEMENTED YET *** -# specify Edgegrid credentials file and section -# AKAMAI_EDGERC= -# AKAMAI_EDGERC_SECTION="default" -## --OR-- -# specify indiviual credentials -# export AKAMAI_HOST = -# export AKAMAI_ACCESS_TOKEN = -# export AKAMAI_CLIENT_TOKEN = -# export AKAMAI_CLIENT_SECRET = +# Specify Edgegrid credentials file and section. +# AKAMAI_EDGERC Edge RC. Full file path +# AKAMAI_EDGERC_SECTION Edge RC Section. E.g. "default" ACME_EDGEDNS_VERSION="0.1.0" diff --git a/dnsapi/dns_euserv.sh b/dnsapi/dns_euserv.sh index cfb4b814..2da00c3d 100644 --- a/dnsapi/dns_euserv.sh +++ b/dnsapi/dns_euserv.sh @@ -1,18 +1,14 @@ #!/usr/bin/env sh - -#This is the euserv.eu api wrapper for acme.sh -# -#Author: Michael Brueckner -#Report Bugs: https://www.github.com/initit/acme.sh or mbr@initit.de - -# -#EUSERV_Username="username" -# -#EUSERV_Password="password" -# -# Dependencies: -# ------------- -# - none - +# shellcheck disable=SC2034 +dns_euserv_info='EUserv.com +Domains: EUserv.eu +Site: EUserv.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_euserv +Options: + EUSERV_Username Username + EUSERV_Password Password +Author: Michael Brueckner +' EUSERV_Api="https://api.euserv.net" diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index ccf05fc5..4cc5a513 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -1,4 +1,12 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_exoscale_info='Exoscale.com +Site: Exoscale.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_exoscale +Options: + EXOSCALE_API_KEY API Key + EXOSCALE_SECRET_KEY API Secret key +' EXOSCALE_API=https://api.exoscale.com/dns/v1 diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index 53be307a..38cdf5e6 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -1,6 +1,13 @@ #!/usr/bin/env sh - -#Author: Timur Umarov +# shellcheck disable=SC2034 +dns_fornex_info='Fornex.com +Site: Fornex.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_fornex +Options: + FORNEX_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/3998 +Author: Timur Umarov +' FORNEX_API_URL="https://fornex.com/api/dns/v0.1" diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 29cee430..114f30e0 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -1,14 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_freedns_info='FreeDNS +Site: FreeDNS.afraid.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_freedns +Options: + FREEDNS_User Username + FREEDNS_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2305 +Author: David Kerr +' -#This file name is "dns_freedns.sh" -#So, here must be a method dns_freedns_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: David Kerr -#Report Bugs here: https://github.com/dkerr64/acme.sh -#or here... https://github.com/acmesh-official/acme.sh/issues/2305 -# ######## Public functions ##################### # Export FreeDNS userid and password in following variables... diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index 6092f45c..141ddccf 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -1,16 +1,19 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_gandi_livedns_info='Gandi.net LiveDNS +Site: Gandi.net/domain/dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gandi_livedns +Options: + GANDI_LIVEDNS_KEY API Key +Issues: github.com/fcrozat/acme.sh +Author: Frédéric Crozat , Dominik Röttsches +' # Gandi LiveDNS v5 API # https://api.gandi.net/docs/livedns/ # https://api.gandi.net/docs/authentication/ for token + apikey (deprecated) authentication # currently under beta -# -# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable -# -#Author: Frédéric Crozat -# Dominik Röttsches -#Report Bugs here: https://github.com/fcrozat/acme.sh -# + ######## Public functions ##################### GANDI_LIVEDNS_API="https://api.gandi.net/v5/livedns" diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index dc82c09d..a6016abc 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -# Author: Janos Lenart +# shellcheck disable=SC2034 +dns_gcloud_info='Google Cloud DNS +Site: Cloud.Google.com/dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcloud +Options: + CLOUDSDK_ACTIVE_CONFIG_NAME Active config name. E.g. "default" +Author: Janos Lenart +' ######## Public functions ##################### diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh index 5f7f037e..ac2e614c 100755 --- a/dnsapi/dns_gcore.sh +++ b/dnsapi/dns_gcore.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb' -# +# shellcheck disable=SC2034 +dns_gcore_info='Gcore.com +Site: Gcore.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcore +Options: + GCORE_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/4460 +' GCORE_Api="https://api.gcore.com/dns/v2" GCORE_Doc="https://api.gcore.com/docs/dns" diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 1729115e..08afa8f5 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -#Godaddy domain api -# Get API key and secret from https://developer.godaddy.com/ -# -# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# GD_Secret="asdfsdfsfsdfsdfdfsdf" -# -# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com" +# shellcheck disable=SC2034 +dns_gd_info='GoDaddy.com +Site: GoDaddy.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gd +Options: + GD_Key API Key + GD_Secret API Secret +' GD_Api="https://api.godaddy.com/v1" diff --git a/dnsapi/dns_geoscaling.sh b/dnsapi/dns_geoscaling.sh index 6ccf4daf..96b3e218 100755 --- a/dnsapi/dns_geoscaling.sh +++ b/dnsapi/dns_geoscaling.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -######################################################################## -# Geoscaling hook script for acme.sh -# -# Environment variables: -# -# - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address) -# - $GEOSCALING_Password (your Geoscaling password) +# shellcheck disable=SC2034 +dns_geoscaling_info='GeoScaling.com +Site: GeoScaling.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_geoscaling +Options: + GEOSCALING_Username Username. This is usually NOT an email address + GEOSCALING_Password Password +' #-- dns_geoscaling_add() - Add TXT record -------------------------------------- # Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_googledomains.sh b/dnsapi/dns_googledomains.sh index 63e3073b..7d241ab6 100755 --- a/dnsapi/dns_googledomains.sh +++ b/dnsapi/dns_googledomains.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_googledomains_info='Google Domains +Site: Domains.Google.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_googledomains +Options: + GOOGLEDOMAINS_ACCESS_TOKEN API Access Token + GOOGLEDOMAINS_ZONE Zone +Issues: github.com/acmesh-official/acme.sh/issues/4545 +Author: Alex Leigh +' -# Author: Alex Leigh -# Created: 2023-03-02 - -#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx" -#GOOGLEDOMAINS_ZONE="xxxx" GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets" ######## Public functions ######## diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index bf4a5030..cfb6efb8 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -######################################################################## -# Hurricane Electric hook script for acme.sh -# -# Environment variables: -# -# - $HE_Username (your dns.he.net username) -# - $HE_Password (your dns.he.net password) -# -# Author: Ondrej Simek -# Git repo: https://github.com/angel333/acme.sh +# shellcheck disable=SC2034 +dns_he_info='Hurricane Electric HE.net +Site: dns.he.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he +Options: + HE_Username Username + HE_Password Password +Issues: github.com/angel333/acme.sh/issues/ +Author: Ondrej Simek +' #-- dns_he_add() - Add TXT record -------------------------------------- # Usage: dns_he_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index 911d4a35..a60bd55d 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#HETZNER_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_hetzner_info='Hetzner.com +Site: Hetzner.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hetzner +Options: + HETZNER_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2943 +' HETZNER_Api="https://dns.hetzner.com/api/v1" diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index 525efe73..6c86e6a4 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -# Hexonet_Login="username!roleId" -# -# Hexonet_Password="rolePassword" +# shellcheck disable=SC2034 +dns_hexonet_info='Hexonet.com +Site: Hexonet.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_hexonet +Options: + Hexonet_Login Login. E.g. "username!roleId" + Hexonet_Password Role Password +Issues: github.com/acmesh-official/acme.sh/issues/2389 +' Hexonet_Api="https://coreapi.1api.net/api/call.cgi" diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 9e3e5664..41ccab2b 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# hosting.de API - -# Values to export: -# export HOSTINGDE_ENDPOINT='https://secure.hosting.de' -# export HOSTINGDE_APIKEY='xxxxx' +# shellcheck disable=SC2034 +dns_hostingde_info='Hosting.de +Site: Hosting.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hostingde +Options: + HOSTINGDE_ENDPOINT Endpoint. E.g. "https://secure.hosting.de" + HOSTINGDE_APIKEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2058 +' ######## Public functions ##################### diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index b61c1d43..f3df41f4 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -# HUAWEICLOUD_Username -# HUAWEICLOUD_Password -# HUAWEICLOUD_DomainName +# shellcheck disable=SC2034 +dns_huaweicloud_info='HuaweiCloud.com +Site: HuaweiCloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_huaweicloud +Options: + HUAWEICLOUD_Username Username + HUAWEICLOUD_Password Password + HUAWEICLOUD_DomainName DomainName +Issues: github.com/acmesh-official/acme.sh/issues/3265 +' iam_api="https://iam.myhuaweicloud.com" dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work diff --git a/dnsapi/dns_infoblox.sh b/dnsapi/dns_infoblox.sh index 6bfd36ee..27f1e61e 100644 --- a/dnsapi/dns_infoblox.sh +++ b/dnsapi/dns_infoblox.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -## Infoblox API integration by Jason Keller and Elijah Tenai -## -## Report any bugs via https://github.com/jasonkeller/acme.sh +# shellcheck disable=SC2034 +dns_infoblox_info='Infoblox.com +Site: Infoblox.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_infoblox +Options: + Infoblox_Creds Credentials. E.g. "username:password" + Infoblox_Server Server hostname. IP or FQDN of infoblox appliance +Issues: github.com/jasonkeller/acme.sh +Author: Jason Keller, Elijah Tenai +' dns_infoblox_add() { diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index a005132c..ea5ef461 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -1,19 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_infomaniak_info='Infomaniak.com +Site: Infomaniak.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_infomaniak +Options: + INFOMANIAK_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3188 +' -############################################################################### -# Infomaniak API integration -# # To use this API you need visit the API dashboard of your account # once logged into https://manager.infomaniak.com add /api/dashboard to the URL # -# Please report bugs to -# https://github.com/acmesh-official/acme.sh/issues/3188 -# # Note: the URL looks like this: # https://manager.infomaniak.com/v3//api/dashboard # Then generate a token with the scope Domain # this is given as an environment variable INFOMANIAK_API_TOKEN -############################################################################### # base variables diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index ae6b9e1e..84dfd70f 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -1,12 +1,14 @@ #!/usr/bin/env sh - -#This is the Internet.BS api wrapper for acme.sh -# -#Author: Ne-Lexa -#Report Bugs here: https://github.com/Ne-Lexa/acme.sh - -#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" -#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_internetbs_info='InternetBS.net +Site: InternetBS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_internetbs +Options: + INTERNETBS_API_KEY API Key + INTERNETBS_API_PASSWORD API Password +Issues: github.com/acmesh-official/acme.sh/issues/2261 +Author: Ne-Lexa +' INTERNETBS_API_URL="https://api.internet.bs" diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index e483c0e8..8c89a697 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_inwx_info='INWX.de +Site: INWX.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_inwx +Options: + INWX_User Username + INWX_Password Password +' -# -#INWX_User="username" -# -#INWX_Password="password" -# # Dependencies: # ------------- # - oathtool (When using 2 Factor Authentication) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e4ad3318..e4d28e11 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -1,14 +1,13 @@ #!/usr/bin/env sh - -# Supports IONOS DNS API v1.0.1 -# -# Usage: -# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: -# -# $ export IONOS_PREFIX="..." -# $ export IONOS_SECRET="..." -# -# $ acme.sh --issue --dns dns_ionos ... +# shellcheck disable=SC2034 +dns_ionos_info='IONOS.de +Site: IONOS.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ionos +Options: + IONOS_PREFIX Prefix + IONOS_SECRET Secret +Issues: github.com/acmesh-official/acme.sh/issues/3379 +' IONOS_API="https://api.hosting.ionos.com/dns" IONOS_ROUTE_ZONES="/v1/zones" diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index 54470119..51025d1e 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh - -#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records -#2022/11/29 - -# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..." -# -- -# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa" -# -- -# +# shellcheck disable=SC2034 +dns_ipv64_info='IPv64.net +Site: IPv64.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ipv64 +Options: + IPv64_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/4419 +Author: Roman Lumetsberger +' IPv64_API="https://ipv64.net/api" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 560f073e..7fd0d99c 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -1,17 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_ispconfig_info='ISPConfig Server API +Site: ISPConfig.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ispconfig +Options: + ISPC_User Remote User + ISPC_Password Remote Password + ISPC_Api API URL. E.g. "https://ispc.domain.tld:8080/remote/json.php" + ISPC_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +' # ISPConfig 3.1 API -# User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: +# User must provide login data and URL to the ISPConfig installation incl. port. +# The remote user in ISPConfig must have access to: # - DNS txt Functions -# Report bugs to https://github.com/sjau/acme.sh - -# Values to export: -# export ISPC_User="remoteUser" -# export ISPC_Password="remotePassword" -# export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" -# export ISPC_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index d0f2a501..a45aa2ca 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -1,9 +1,14 @@ #!/usr/bin/env sh - -# -#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" -#JD_ACCESS_KEY_SECRET="xxxxxxx" -#JD_REGION="cn-north-1" +# shellcheck disable=SC2034 +dns_jd_info='jdcloud.com +Site: jdcloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_jd +Options: + JD_ACCESS_KEY_ID Access key ID + JD_ACCESS_KEY_SECRET Access key secret + JD_REGION Region. E.g. "cn-north-1" +Issues: github.com/acmesh-official/acme.sh/issues/2388 +' _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 78399a1d..49c544b9 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -1,27 +1,14 @@ #!/usr/bin/env sh - -# Joker.com API for acme.sh -# -# This script adds the necessary TXT record to a domain in Joker.com. -# -# You must activate Dynamic DNS in Joker.com DNS configuration first. -# Username and password below refer to Dynamic DNS authentication, -# not your Joker.com login credentials. -# See: https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html -# -# NOTE: This script does not support wildcard certificates, because -# Joker.com API does not support adding two TXT records with the same -# subdomain. Adding the second record will overwrite the first one. -# See: https://joker.com/faq/content/6/496/en/let_s-encrypt-support.html -# "... this request will replace all TXT records for the specified -# label by the provided content" -# -# Author: aattww (https://github.com/aattww/) -# -# Report bugs to https://github.com/acmesh-official/acme.sh/issues/2840 -# -# JOKER_USERNAME="xxxx" -# JOKER_PASSWORD="xxxx" +# shellcheck disable=SC2034 +dns_joker_info='Joker.com +Site: Joker.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_joker +Options: + JOKER_USERNAME Username + JOKER_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2840 +Author: +' JOKER_API="https://svc.joker.com/nic/replace" diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 914671d6..7b6fb8a6 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -1,12 +1,13 @@ #!/usr/bin/env sh - -# kapper.net domain api -# for further questions please contact: support@kapper.net -# please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 - -#KAPPERNETDNS_Key="yourKAPPERNETapikey" -#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" -#KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" +# shellcheck disable=SC2034 +dns_kappernet_info='kapper.net +Site: kapper.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_kappernet +Options: + KAPPERNETDNS_Key API Key + KAPPERNETDNS_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/2977 +' ############################################################################### # called with diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 1253cf27..2164a8e8 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -1,19 +1,16 @@ #!/usr/bin/env sh -######################################################################## -# All-inkl Kasserver hook script for acme.sh -# -# Environment variables: -# -# - $KAS_Login (Kasserver API login name) -# - $KAS_Authtype (Kasserver API auth type. Default: plain) -# - $KAS_Authdata (Kasserver API auth data.) -# -# Last update: squared GmbH -# Credits: -# - dns_he.sh. Thanks a lot man! -# - Martin Kammerlander, Phlegx Systems OG -# - Marc-Oliver Lange -# - https://github.com/o1oo11oo/kasapi.sh +# shellcheck disable=SC2034 +dns_kas_info='All-inkl Kas Server +Site: kas.all-inkl.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_kas +Options: + KAS_Login API login name + KAS_Authtype API auth type. Default: "plain" + KAS_Authdata API auth data +Issues: github.com/acmesh-official/acme.sh/issues/2715 +Author: squared GmbH , Martin Kammerlander , Marc-Oliver Lange +' + ######################################################################## KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")" KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "//g")" diff --git a/dnsapi/dns_kinghost.sh b/dnsapi/dns_kinghost.sh index f640242f..0496008e 100644 --- a/dnsapi/dns_kinghost.sh +++ b/dnsapi/dns_kinghost.sh @@ -1,16 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_kinghost_info='King.host +Domains: KingHost.net KingHost.com.br +Site: King.host +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_kinghost +Options: + KINGHOST_Username Username + KINGHOST_Password Password +Author: Felipe Keller Braz +' -############################################################ # KingHost API support # # https://api.kinghost.net/doc/ # -# # -# Author: Felipe Keller Braz # -# Report Bugs here: https://github.com/kinghost/acme.sh # -# # -# Values to export: # -# export KINGHOST_Username="email@provider.com" # -# export KINGHOST_Password="xxxxxxxxxx" # -############################################################ KING_Api="https://api.kinghost.net/acme" diff --git a/dnsapi/dns_knot.sh b/dnsapi/dns_knot.sh index 729a89cb..5636804a 100644 --- a/dnsapi/dns_knot.sh +++ b/dnsapi/dns_knot.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_knot_info='Knot Server knsupdate +Site: www.knot-dns.cz/docs/2.5/html/man_knsupdate.html +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_knot +Options: + KNOT_SERVER Server hostname. Default: "localhost". + KNOT_KEY File path to TSIG key +' + +# See also dns_nsupdate.sh ######## Public functions ##################### diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 674df410..7a1c0a1c 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#LA_Id="test123" -#LA_Key="d1j2fdo4dee3948" +# shellcheck disable=SC2034 +dns_la_info='dns.la +Site: dns.la +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_la +Options: + LA_Id API ID + LA_Key API key +Issues: github.com/acmesh-official/acme.sh/issues/4257 +' LA_Api="https://api.dns.la/api" diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 4cd3a8f8..66b1f61f 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_leaseweb_info='Leaseweb.com +Site: Leaseweb.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_leaseweb +Options: + LSW_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2558 +Author: Rolph Haspers +' -#Author: Rolph Haspers -#Utilize leaseweb.com API to finish dns-01 verifications. -#Requires a Leaseweb API Key (export LSW_Key="Your Key") #See https://developer.leaseweb.com for more information. ######## Public functions ##################### diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 19702343..a4b2a801 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_lexicon_info='Lexicon DNS client +Site: github.com/AnalogJ/lexicon +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-lexicon-DNS-API +Options: + PROVIDER Provider +' -# dns api wrapper of lexicon for acme.sh - -# https://github.com/AnalogJ/lexicon lexicon_cmd="lexicon" wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-lexicon-dns-api" diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index ead5b164..5e4c694b 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#Author: Philipp Grosswiler +# shellcheck disable=SC2034 +dns_linode_info='Linode.com (Old) + Deprecated. Use dns_linode_v4 +Site: Linode.com +Options: + LINODE_API_KEY API Key +Author: Philipp Grosswiler +' LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 9504afbf..e562f80f 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -#Original Author: Philipp Grosswiler -#v4 Update Author: Aaron W. Swenson +# shellcheck disable=SC2034 +dns_linode_v4_info='Linode.com +Site: Linode.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 +Options: + LINODE_V4_API_KEY API Key +Author: Philipp Grosswiler , Aaron W. Swenson +' LINODE_V4_API_URL="https://api.linode.com/v4/domains" diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 60d072e0..1f943e51 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh - -# -#LOOPIA_User="username" -# -#LOOPIA_Password="password" -# -#LOOPIA_Api="https://api.loopia./RPCSERV" +# shellcheck disable=SC2034 +dns_loopia_info='Loopia.se +Site: Loopia.se +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_loopia +Options: + LOOPIA_Api API URL. E.g. "https://api.loopia./RPCSERV" where the is one of: com, no, rs, se. Default: "se". + LOOPIA_User Username + LOOPIA_Password Password +' LOOPIA_Api_Default="https://api.loopia.se/RPCSERV" diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 30c15579..b037e90f 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -1,11 +1,14 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# -#LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#LUA_Email="user@luadns.net" +# shellcheck disable=SC2034 +dns_lua_info='LuaDNS.com +Domains: LuaDNS.net +Site: LuaDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_lua +Options: + LUA_Key API key + LUA_Email Email +Author: +' LUA_Api="https://api.luadns.com/v1" diff --git a/dnsapi/dns_maradns.sh b/dnsapi/dns_maradns.sh index 4ff6ca2d..09d7248e 100755 --- a/dnsapi/dns_maradns.sh +++ b/dnsapi/dns_maradns.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_maradns_info='MaraDNS Server +Site: MaraDNS.samiam.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_maradns +Options: + MARA_ZONE_FILE Zone file path. E.g. "/etc/maradns/db.domain.com" + MARA_DUENDE_PID_PATH Duende PID Path. E.g. "/run/maradns/etc_maradns_mararc.pid" +Issues: github.com/acmesh-official/acme.sh/issues/2072 +' #Usage: dns_maradns_add _acme-challenge.www.domain.com "token" dns_maradns_add() { diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 49007402..66545c46 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# ME_Key=qmlkdjflmkqdjf -# ME_Secret=qmsdlkqmlksdvnnpae +# shellcheck disable=SC2034 +dns_me_info='DnsMadeEasy.com +Site: DnsMadeEasy.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_me +Options: + ME_Key API Key + ME_Secret API Secret +Author: +' ME_Api=https://api.dnsmadeeasy.com/V2.0/dns/managed diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index dad69bde..ec9867db 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -1,17 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_miab_info='Mail-in-a-Box +Site: MailInaBox.email +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_miab +Options: + MIAB_Username Admin username + MIAB_Password Admin password + MIAB_Server Server hostname. FQDN of your_MIAB Server +Issues: github.com/acmesh-official/acme.sh/issues/2550 +Author: Darven Dissek, William Gertz +' -# Name: dns_miab.sh -# -# Authors: -# Darven Dissek 2018 -# William Gertz 2019 -# -# Thanks to Neil Pang and other developers here for code reused from acme.sh from DNS-01 -# used to communicate with the MailinaBox Custom DNS API -# Report Bugs here: -# https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) -# https://github.com/acmesh-official/acme.sh (for acme.sh) -# ######## Public functions ##################### #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index 36ba5cfd..c6c0f5f3 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -1,11 +1,12 @@ #!/usr/bin/env sh - -# bug reports to support+acmesh@misaka.io -# based on dns_nsone.sh by dev@1e.ca - -# -#Misaka_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_misaka_info='Misaka.io +Site: Misaka.io +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_misaka +Options: + Misaka_Key API Key +Author: +' Misaka_Api="https://dnsapi.misaka.io/dns" diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index 7f3c5a86..c9f5eb9f 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -1,14 +1,21 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_myapi_info='Custom API Example + A sample custom DNS API script. +Domains: example.com +Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + MYAPI_Token API Token. Get API Token from https://example.com/api/. Optional. +Issues: github.com/acmesh-official/acme.sh +Author: Neil Pang +' -#Here is a sample custom api script. #This file name is "dns_myapi.sh" #So, here must be a method dns_myapi_add() #Which will be called by acme.sh to add the txt record to your api system. #returns 0 means success, otherwise error. -# -#Author: Neilpang -#Report Bugs here: https://github.com/acmesh-official/acme.sh -# + ######## Public functions ##################### # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh index 953290af..e9b3d3c8 100755 --- a/dnsapi/dns_mydevil.sh +++ b/dnsapi/dns_mydevil.sh @@ -1,15 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mydevil_info='MyDevil.net + MyDevil.net already supports automatic Lets Encrypt certificates, + except for wildcard domains. + This script depends on devil command that MyDevil.net provides, + which means that it works only on server side. +Site: MyDevil.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_mydevil +Issues: github.com/acmesh-official/acme.sh/issues/2079 +Author: Marcin Konicki +' -# MyDevil.net API (2019-02-03) -# -# MyDevil.net already supports automatic Let's Encrypt certificates, -# except for wildcard domains. -# -# This script depends on `devil` command that MyDevil.net provides, -# which means that it works only on server side. -# -# Author: Marcin Konicki -# ######## Public functions ##################### #Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh index 13866f70..4fa646e8 100755 --- a/dnsapi/dns_mydnsjp.sh +++ b/dnsapi/dns_mydnsjp.sh @@ -1,14 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mydnsjp_info='MyDNS.JP +Site: MyDNS.JP +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_mydnsjp +Options: + MYDNSJP_MasterID Master ID + MYDNSJP_Password Password +Author: epgdatacapbon +' -#Here is a api script for MyDNS.JP. -#This file name is "dns_mydnsjp.sh" -#So, here must be a method dns_mydnsjp_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: epgdatacapbon -#Report Bugs here: https://github.com/epgdatacapbon/acme.sh -# ######## Public functions ##################### # Export MyDNS.JP MasterID and Password in following variables... diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 294ae84c..b85401f4 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mythic_beasts_info='Mythic-Beasts.com +Site: Mythic-Beasts.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_mythic_beasts +Options: + MB_AK API Key + MB_AS API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3848 +' # Mythic Beasts is a long-standing UK service provider using standards-based OAuth2 authentication # To test: ./acme.sh --dns dns_mythic_beasts --test --debug 1 --output-insecure --issue --domain domain.com # Cannot retest once cert is issued diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index a5f667a9..abe64d09 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -1,12 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_namecheap_info='NameCheap.com +Site: NameCheap.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namecheap +Options: + NAMECHEAP_API_KEY API Key + NAMECHEAP_USERNAME Username + NAMECHEAP_SOURCEIP Source IP +Issues: github.com/acmesh-official/acme.sh/issues/2107 +' # Namecheap API # https://www.namecheap.com/support/api/intro.aspx -# -# Requires Namecheap API key set in -#NAMECHEAP_API_KEY, -#NAMECHEAP_USERNAME, -#NAMECHEAP_SOURCEIP # Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. ######## Public functions ##################### diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index 0d5dd2c4..2d146974 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -1,9 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_namecom_info='Name.com +Site: Name.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namecom +Options: + Namecom_Username Username + Namecom_Token API Token +Author: RaidenII +' -#Author: RaidenII -#Created 06/28/2017 -#Updated 03/01/2018, rewrote to support name.com API v4 -#Utilize name.com API to finish dns-01 verifications. ######## Public functions ##################### Namecom_API="https://api.name.com/v4" diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index f961d0bd..2995e7dc 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -#Author: meowthink -#Created 01/14/2017 -#Utilize namesilo.com API to finish dns-01 verifications. +# shellcheck disable=SC2034 +dns_namesilo_info='NameSilo.com +Site: NameSilo.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namesilo +Options: + Namesilo_Key API Key +Author: meowthink +' + +#Utilize API to finish dns-01 verifications. Namesilo_API="https://www.namesilo.com/api" diff --git a/dnsapi/dns_nanelo.sh b/dnsapi/dns_nanelo.sh index 8ccc8c29..1ab47a89 100644 --- a/dnsapi/dns_nanelo.sh +++ b/dnsapi/dns_nanelo.sh @@ -1,9 +1,12 @@ #!/usr/bin/env sh - -# Official DNS API for Nanelo.com - -# Provide the required API Key like this: -# NANELO_TOKEN="FmD408PdqT1E269gUK57" +# shellcheck disable=SC2034 +dns_nanelo_info='Nanelo.com +Site: Nanelo.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nanelo +Options: + NANELO_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/4519 +' NANELO_API="https://api.nanelo.com/v1/" diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index abaae42b..d0b97d3c 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghj" +# shellcheck disable=SC2034 +dns_nederhost_info='NederHost.nl +Site: NederHost.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nederhost +Options: + NederHost_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2089 +' NederHost_Api="https://api.nederhost.nl/dns/v1" diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh index 64ea8786..1119f916 100644 --- a/dnsapi/dns_neodigit.sh +++ b/dnsapi/dns_neodigit.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_neodigit_info='Neodigit.net +Site: Neodigit.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_neodigit +Options: + NEODIGIT_API_TOKEN API Token +Author: Adrian Almenar +' -# -# NEODIGIT_API_TOKEN="jasdfhklsjadhflnhsausdfas" - -# This is Neodigit.net api wrapper for acme.sh -# -# Author: Adrian Almenar -# Report Bugs here: https://github.com/tecnocratica/acme.sh -# NEODIGIT_API_URL="https://api.neodigit.net/v1" # ######## Public functions ##################### diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 776fa02d..687b99bc 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -1,5 +1,15 @@ #!/usr/bin/env sh -#developed by linux-insideDE +# shellcheck disable=SC2034 +dns_netcup_info='netcup.eu +Domains: netcup.de netcup.net +Site: netcup.eu/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_netcup +Options: + NC_Apikey API Key + NC_Apipw API Password + NC_CID Customer Number +Author: linux-insideDE +' NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}" NC_Apipw="${NC_Apipw:-$(_readaccountconf_mutable NC_Apipw)}" diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 0e5dc327..bb5f5809 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#NETLIFY_ACCESS_TOKEN="xxxx" +# shellcheck disable=SC2034 +dns_netlify_info='Netlify.com +Site: Netlify.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_netlify +Options: + NETLIFY_ACCESS_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3088 +' NETLIFY_HOST="api.netlify.com/api/v1/" NETLIFY_URL="https://$NETLIFY_HOST" diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 56170f87..42f35cb0 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh - -# -#NIC_ClientID='0dc0xxxxxxxxxxxxxxxxxxxxxxxxce88' -#NIC_ClientSecret='3LTtxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnuW8' -#NIC_Username="000000/NIC-D" -#NIC_Password="xxxxxxx" +# shellcheck disable=SC2034 +dns_nic_info='nic.ru +Site: nic.ru +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nic +Options: + NIC_ClientID Client ID + NIC_ClientSecret Client Secret + NIC_Username Username + NIC_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2547 +' NIC_Api="https://api.nic.ru" diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index e9243288..5d241ebf 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -# -#NJALLA_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_njalla_info='Njalla +Site: Njal.la +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_njalla +Options: + NJALLA_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2913 +' NJALLA_Api="https://njal.la/api/1/" diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 4dfcc777..1f818a29 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -1,15 +1,13 @@ #!/usr/bin/env sh - -######################################################################## -# https://namemaster.de hook script for acme.sh -# -# Environment variables: -# -# - $NM_user (your namemaster.de API username) -# - $NM_sha256 (your namemaster.de API password_as_sha256hash) -# -# Author: Thilo Gass -# Git repo: https://github.com/ThiloGa/acme.sh +# shellcheck disable=SC2034 +dns_nm_info='NameMaster.de +Site: NameMaster.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nm +Options: + NM_user API Username + NM_sha256 API Password as SHA256 hash +Author: Thilo Gass +' #-- dns_nm_add() - Add TXT record -------------------------------------- # Usage: dns_nm_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh index 0d29a485..3ddaa98c 100644 --- a/dnsapi/dns_nsd.sh +++ b/dnsapi/dns_nsd.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#Nsd_ZoneFile="/etc/nsd/zones/example.com.zone" -#Nsd_Command="sudo nsd-control reload" +# shellcheck disable=SC2034 +dns_nsd_info='NLnetLabs NSD Server +Site: github.com/NLnetLabs/nsd +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#nsd +Options: + Nsd_ZoneFile Zone File path. E.g. "/etc/nsd/zones/example.com.zone" + Nsd_Command Command. E.g. "sudo nsd-control reload" +Issues: github.com/acmesh-official/acme.sh/issues/2245 +' # args: fulldomain txtvalue dns_nsd_add() { diff --git a/dnsapi/dns_nsone.sh b/dnsapi/dns_nsone.sh index 9a998341..2a073950 100644 --- a/dnsapi/dns_nsone.sh +++ b/dnsapi/dns_nsone.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# -#NS1_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_nsone_info='ns1.com +Domains: ns1.net +Site: ns1.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nsone +Options: + NS1_Key API Key +Author: +' NS1_Api="https://api.nsone.net/v1" diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index cd4b7140..9df6262e 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_nsupdate_info='nsupdate RFC 2136 DynDNS client +Site: bind9.readthedocs.io/en/v9.18.19/manpages.html#nsupdate-dynamic-dns-update-utility +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nsupdate +Options: + NSUPDATE_SERVER Server hostname. Default: "localhost". + NSUPDATE_SERVER_PORT Server port. Default: "53". + NSUPDATE_KEY File path to TSIG key. + NSUPDATE_ZONE Domain zone to update. Optional. +' ######## Public functions ##################### diff --git a/dnsapi/dns_nw.sh b/dnsapi/dns_nw.sh index c57d27c2..8c68ead8 100644 --- a/dnsapi/dns_nw.sh +++ b/dnsapi/dns_nw.sh @@ -1,17 +1,16 @@ #!/usr/bin/env sh -######################################################################## -# NocWorx script for acme.sh -# -# Handles DNS Updates for the Following vendors: -# - Nexcess.net -# - Thermo.io -# - Futurehosting.com -# -# Environment variables: -# -# - NW_API_TOKEN (Your API Token) -# - NW_API_ENDPOINT (One of the following listed below) -# +# shellcheck disable=SC2034 +dns_nw_info='Nexcess.net (NocWorx) +Domains: Thermo.io Futurehosting.com +Site: Nexcess.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nw +Options: + NW_API_TOKEN API Token + NW_API_ENDPOINT API Endpoint. Default: "https://portal.nexcess.net". +Issues: github.com/acmesh-official/acme.sh/issues/2088 +Author: Frank Laszlo +' + # Endpoints: # - https://portal.nexcess.net (default) # - https://core.thermo.io @@ -22,8 +21,6 @@ # - https://portal.nexcess.net/api-token # - https://core.thermo.io/api-token # - https://my.futurehosting.com/api-token -# -# Author: Frank Laszlo NW_API_VERSION="0" diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 3b81143f..f1138efa 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -1,6 +1,19 @@ #!/usr/bin/env sh -# -# Acme.sh DNS API plugin for Oracle Cloud Infrastructure +# shellcheck disable=SC2034 +dns_oci_info='Oracle Cloud Infrastructure (OCI) + If OCI CLI configuration file ~/.oci/config has a DEFAULT profile then it will be used. +Site: Cloud.Oracle.com +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-Oracle-Cloud-Infrastructure-DNS +Options: + OCI_CLI_TENANCY OCID of tenancy that contains the target DNS zone. Optional. + OCI_CLI_USER OCID of user with permission to add/remove records from zones. Optional. + OCI_CLI_REGION Should point to the tenancy home region. Optional. + OCI_CLI_KEY_FILE Path to private API signing key file in PEM format. Optional. + OCI_CLI_KEY The private API signing key in PEM format. Optional. +Issues: github.com/acmesh-official/acme.sh/issues/3540 +Author: Avi Miller +' + # Copyright (c) 2021, Oracle and/or its affiliates # # The plugin will automatically use the default profile from an OCI SDK and CLI diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 1565b767..b2adf253 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh -# one.com ui wrapper for acme.sh - -# -# export ONECOM_User="username" -# export ONECOM_Password="password" +# shellcheck disable=SC2034 +dns_one_info='one.com +Site: one.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_one +Options: + ONECOM_User Username + ONECOM_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2103 +' dns_one_add() { fulldomain=$1 diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 9158c268..c83cd458 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -1,9 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_online_info='online.net +Domains: scaleway.com +Site: online.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_online +Options: + ONLINE_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2093 +' # Online API # https://console.online.net/en/api/ -# -# Requires Online API key set in ONLINE_API_KEY ######## Public functions ##################### diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 0a9e5ade..0e93ecf8 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -# This is the OpenProvider API wrapper for acme.sh -# -# Author: Sylvia van Os -# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2104 -# -# export OPENPROVIDER_USER="username" -# export OPENPROVIDER_PASSWORDHASH="hashed_password" -# -# Usage: -# acme.sh --issue --dns dns_openprovider -d example.com +# shellcheck disable=SC2034 +dns_openprovider_info='OpenProvider.eu +Site: OpenProvider.eu +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_openprovider +Options: + OPENPROVIDER_USER Username + OPENPROVIDER_PASSWORDHASH Password hash +Issues: github.com/acmesh-official/acme.sh/issues/2104 +Author: Sylvia van Os +' OPENPROVIDER_API="https://api.openprovider.eu/" #OPENPROVIDER_API="https://api.cte.openprovider.eu/" # Test API diff --git a/dnsapi/dns_openstack.sh b/dnsapi/dns_openstack.sh index fcc1dc2e..fa38bc0b 100755 --- a/dnsapi/dns_openstack.sh +++ b/dnsapi/dns_openstack.sh @@ -1,14 +1,21 @@ #!/usr/bin/env sh - -# OpenStack Designate API plugin -# -# This requires you to have OpenStackClient and python-desginateclient -# installed. -# -# You will require Keystone V3 credentials loaded into your environment, which -# could be either password or v3applicationcredential type. -# -# Author: Andy Botting +# shellcheck disable=SC2034 +dns_openstack_info='OpenStack Designate API + Depends on OpenStackClient and python-desginateclient. + You will require Keystone V3 credentials loaded into your environment, + which could be either password or v3 application credential type. +Site: docs.openstack.org/api-ref/dns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_openstack +Options: + OS_AUTH_URL Auth URL. E.g. "https://keystone.example.com:5000/" + OS_USERNAME Username + OS_PASSWORD Password + OS_PROJECT_NAME Project name + OS_PROJECT_DOMAIN_NAME Project domain name. E.g. "Default" + OS_USER_DOMAIN_NAME User domain name. E.g. "Default" +Issues: github.com/acmesh-official/acme.sh/issues/3054 +Author: Andy Botting +' ######## Public functions ##################### diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index d40cbe28..6d3d3eec 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -1,16 +1,16 @@ #!/usr/bin/env sh - -#OPNsense Bind API -#https://docs.opnsense.org/development/api.html -# -#OPNs_Host="opnsense.example.com" -#OPNs_Port="443" -# optional, defaults to 443 if unset -#OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" -#OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" -#OPNs_Api_Insecure=0 -# optional, defaults to 0 if unset -# Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) +# shellcheck disable=SC2034 +dns_opnsense_info='OPNsense Server +Site: docs.opnsense.org/development/api.html +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_opnsense +Options: + OPNs_Host Server Hostname. E.g. "opnsense.example.com" + OPNs_Port Port. Default: "443". + OPNs_Key API Key + OPNs_Token API Token + OPNs_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +Issues: github.com/acmesh-official/acme.sh/issues/2480 +' ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index e1a958f6..7f62c05e 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -1,13 +1,15 @@ #!/usr/bin/env sh - -#Application Key -#OVH_AK="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#Application Secret -#OVH_AS="sdfsafsdfsdfdsfsdfsa" -# -#Consumer Key -#OVH_CK="sdfsdfsdfsdfsdfdsf" +# shellcheck disable=SC2034 +dns_ovh_info='OVH.com +Domains: kimsufi.com soyoustart.com +Site: OVH.com +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-OVH-domain-api +Options: + OVH_END_POINT Endpoint. "ovh-eu", "ovh-us", "ovh-ca", "kimsufi-eu", "kimsufi-ca", "soyoustart-eu", "soyoustart-ca" or raw URL. Default: "ovh-eu". + OVH_AK Application Key + OVH_AS Application Secret + OVH_CK Consumer Key +' #OVH_END_POINT=ovh-eu diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 6aa2e953..cde3b1a6 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -1,12 +1,14 @@ #!/usr/bin/env sh - -#PowerDNS Embedded API -#https://doc.powerdns.com/md/httpapi/api_spec/ -# -#PDNS_Url="http://ns.example.com:8081" -#PDNS_ServerId="localhost" -#PDNS_Token="0123456789ABCDEF" -#PDNS_Ttl=60 +# shellcheck disable=SC2034 +dns_pdns_info='PowerDNS Server API +Site: PowerDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_pdns +Options: + PDNS_Url API URL. E.g. "http://ns.example.com:8081" + PDNS_ServerId Server ID. E.g. "localhost" + PDNS_Token API Token + PDNS_Ttl=60 Domain TTL. Default: "60". +' DEFAULT_PDNS_TTL=60 diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 81973e07..6b38abcb 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -1,10 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_pleskxml_info='Plesk Server API +Site: Plesk.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_pleskxml +Options: + pleskxml_uri Plesk server API URL. E.g. "https://your-plesk-server.net:8443/enterprise/control/agent.php" + pleskxml_user Username + pleskxml_pass Password +Issues: github.com/acmesh-official/acme.sh/issues/2577 +Author: Stilez, +' -## Name: dns_pleskxml.sh -## Created by Stilez. -## Also uses some code from PR#1832 by @romanlum (https://github.com/acmesh-official/acme.sh/pull/1832/files) - -## This DNS-01 method uses the Plesk XML API described at: +## Plesk XML API described at: ## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 ## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 @@ -16,21 +23,6 @@ ## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. ## The user credentials (username+password) and URL/URI for the Plesk XML API must be set by the user -## before this module is called (case sensitive): -## -## ``` -## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" -## (or probably something similar) -## export pleskxml_user="my plesk username" -## export pleskxml_pass="my plesk password" -## ``` - -## Ok, let's issue a cert now: -## ``` -## acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com -## ``` -## -## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. #################### INTERNAL VARIABLES + NEWLINE + API TEMPLATES ################################## diff --git a/dnsapi/dns_pointhq.sh b/dnsapi/dns_pointhq.sh index 62313109..fe95cd52 100644 --- a/dnsapi/dns_pointhq.sh +++ b/dnsapi/dns_pointhq.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#PointHQ_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#PointHQ_Email="xxxx@sss.com" +# shellcheck disable=SC2034 +dns_pointhq_info='pointhq.com PointDNS +Site: pointhq.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_pointhq +Options: + PointHQ_Key API Key + PointHQ_Email Email +Issues: github.com/acmesh-official/acme.sh/issues/2060 +' PointHQ_Api="https://api.pointhq.com" diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index ad4455b6..bbc7a027 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -1,8 +1,13 @@ #!/usr/bin/env sh - -# -#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" -#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" +# shellcheck disable=SC2034 +dns_porkbun_info='Porkbun.com +Site: Porkbun.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_porkbun +Options: + PORKBUN_API_KEY API Key + PORKBUN_SECRET_API_KEY API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3450 +' PORKBUN_Api="https://porkbun.com/api/json/v3" diff --git a/dnsapi/dns_rackcorp.sh b/dnsapi/dns_rackcorp.sh index 6aabfddc..e1e4f27d 100644 --- a/dnsapi/dns_rackcorp.sh +++ b/dnsapi/dns_rackcorp.sh @@ -1,16 +1,14 @@ #!/usr/bin/env sh - -# Provider: RackCorp (www.rackcorp.com) -# Author: Stephen Dendtler (sdendtler@rackcorp.com) -# Report Bugs here: https://github.com/senjoo/acme.sh -# Alternate email contact: support@rackcorp.com -# -# You'll need an API key (Portal: ADMINISTRATION -> API) -# Set the environment variables as below: -# -# export RACKCORP_APIUUID="UUIDHERE" -# export RACKCORP_APISECRET="SECRETHERE" -# +# shellcheck disable=SC2034 +dns_rackcorp_info='RackCorp.com +Site: RackCorp.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_rackcorp +Options: + RACKCORP_APIUUID API UUID. See Portal: ADMINISTRATION -> API + RACKCORP_APISECRET API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3351 +Author: Stephen Dendtler +' RACKCORP_API_ENDPOINT="https://api.rackcorp.net/api/rest/v2.4/json.php" diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index b50d9168..03edce0d 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh -# -# -#RACKSPACE_Username="" -# -#RACKSPACE_Apikey="" +# shellcheck disable=SC2034 +dns_rackspace_info='RackSpace.com +Site: RackSpace.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_rackspace +Options: + RACKSPACE_Apikey API Key + RACKSPACE_Username Username +Issues: github.com/acmesh-official/acme.sh/issues/2091 +' RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" diff --git a/dnsapi/dns_rage4.sh b/dnsapi/dns_rage4.sh index 4af4541d..ad312759 100755 --- a/dnsapi/dns_rage4.sh +++ b/dnsapi/dns_rage4.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#RAGE4_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#RAGE4_USERNAME="xxxx@sss.com" +# shellcheck disable=SC2034 +dns_rage4_info='rage4.com +Site: rage4.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_rage4 +Options: + RAGE4_TOKEN API Key + RAGE4_USERNAME Username +Issues: github.com/acmesh-official/acme.sh/issues/4306 +' RAGE4_Api="https://rage4.com/rapi/" diff --git a/dnsapi/dns_rcode0.sh b/dnsapi/dns_rcode0.sh index d3f7f219..131a22b1 100755 --- a/dnsapi/dns_rcode0.sh +++ b/dnsapi/dns_rcode0.sh @@ -1,14 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_rcode0_info='Rcode0 rcodezero.at +Site: rcodezero.at +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_rcode0 +Options: + RCODE0_URL API URL. E.g. "https://my.rcodezero.at" + RCODE0_API_TOKEN API Token + RCODE0_TTL TTL. Default: "60". +Issues: github.com/acmesh-official/acme.sh/issues/2490 +' #Rcode0 API Integration #https://my.rcodezero.at/api-doc # # log into https://my.rcodezero.at/enableapi and get your ACME API Token (the ACME API token has limited # access to the REST calls needed for acme.sh only) -# -#RCODE0_URL="https://my.rcodezero.at" -#RCODE0_API_TOKEN="0123456789ABCDEF" -#RCODE0_TTL=60 DEFAULT_RCODE0_URL="https://my.rcodezero.at" DEFAULT_RCODE0_TTL=60 diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 8ff380f0..be5ae117 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# -# REGRU_API_Username="test" -# -# REGRU_API_Password="test" -# +# shellcheck disable=SC2034 +dns_regru_info='reg.ru +Site: reg.ru +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_regru +Options: + REGRU_API_Username Username + REGRU_API_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2336 +' REGRU_API_URL="https://api.reg.ru/api/regru2" diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index a0a0f318..64bfcc38 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_scaleway_info='ScaleWay.com +Site: ScaleWay.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_scaleway +Options: + SCALEWAY_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3295 +' # Scaleway API # https://developers.scaleway.com/en/products/domain/dns/api/ -# -# Requires Scaleway API token set in SCALEWAY_API_TOKEN ######## Public functions ##################### diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index 399c50e0..02146494 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -1,16 +1,14 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - -# Schlundtech DNS API -# Author: mod242 -# Created: 2019-40-29 -# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com -# -# export SCHLUNDTECH_USER="username" -# export SCHLUNDTECH_PASSWORD="password" -# -# Usage: -# acme.sh --issue --dns dns_schlundtech -d example.com +# shellcheck disable=SC2034 +dns_schlundtech_info='SchlundTech.de +Site: SchlundTech.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_schlundtech +Options: + SCHLUNDTECH_USER Username + SCHLUNDTECH_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2246 +Author: +' SCHLUNDTECH_API="https://gateway.schlundtech.de" diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1b09882d..32b0737f 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_selectel_info='Selectel.com +Domains: Selectel.ru +Site: Selectel.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel +Options: + SL_Key API Key +' SL_Api="https://api.selectel.ru/domains/v1" diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index a6ef1f94..4912dfdf 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -1,8 +1,15 @@ #!/usr/bin/env sh -# -# Author: Marvin Edeler -# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 -# Last Edit: 17.02.2022 +# shellcheck disable=SC2034 +dns_selfhost_info='SelfHost.de +Site: SelfHost.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_selfhost +Options: + SELFHOSTDNS_USERNAME Username + SELFHOSTDNS_PASSWORD Password + SELFHOSTDNS_MAP Subdomain name +Issues: github.com/acmesh-official/acme.sh/issues/4291 +Author: Marvin Edeler +' dns_selfhost_add() { fulldomain=$1 diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 52137905..37c2a97b 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -1,19 +1,14 @@ #!/usr/bin/env sh - -########## -# Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/acmesh-official/acme.sh) -# -# Usage: -# export SERVERCOW_API_Username=username -# export SERVERCOW_API_Password=password -# acme.sh --issue -d example.com --dns dns_servercow -# -# Issues: -# Any issues / questions / suggestions can be posted here: -# https://github.com/jhartlep/servercow-dns-api/issues -# -# Author: Jens Hartlep -########## +# shellcheck disable=SC2034 +dns_servercow_info='ServerCow.de +Site: ServerCow.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_servercow +Options: + SERVERCOW_API_Username Username + SERVERCOW_API_Password Password +Issues: github.com/jhartlep/servercow-dns-api/issues +Author: Jens Hartlep +' SERVERCOW_API="https://api.servercow.de/dns/v1/domains" diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 6a8d0e18..9fac3ef7 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_simply_info='Simply.com +Site: Simply.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_simply +Options: + SIMPLY_AccountName Account name + SIMPLY_ApiKey API Key +' -# API-integration for Simply.com (https://www.simply.com) - -#SIMPLY_AccountName="accountname" -#SIMPLY_ApiKey="apikey" -# #SIMPLY_Api="https://api.simply.com/2/" SIMPLY_Api_Default="https://api.simply.com/2" diff --git a/dnsapi/dns_tele3.sh b/dnsapi/dns_tele3.sh index 76c90913..e5974951 100644 --- a/dnsapi/dns_tele3.sh +++ b/dnsapi/dns_tele3.sh @@ -1,14 +1,13 @@ #!/usr/bin/env sh -# -# tele3.cz DNS API -# -# Author: Roman Blizik -# Report Bugs here: https://github.com/par-pa/acme.sh -# -# -- -# export TELE3_Key="MS2I4uPPaI..." -# export TELE3_Secret="kjhOIHGJKHg" -# -- +# shellcheck disable=SC2034 +dns_tele3_info='tele3.cz +Site: tele3.cz +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#tele3 +Options: + TELE3_Key API Key + TELE3_Secret API Secret +Author: Roman Blizik +' TELE3_API="https://www.tele3.cz/acme/" diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index 2f8d3b67..d82768b9 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_tencent_info='Tencent.com +Site: cloud.Tencent.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_tencent +Options: + Tencent_SecretId Secret ID + Tencent_SecretKey Secret Key +Issues: github.com/acmesh-official/acme.sh/issues/4781 +' Tencent_API="https://dnspod.tencentcloudapi.com" -#Tencent_SecretId="AKIDz81d2cd22cdcdc2dcd1cc1d1A" -#Tencent_SecretKey="Gu5t9abcabcaabcbabcbbbcbcbbccbbcb" - #Usage: dns_tencent_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_tencent_add() { fulldomain=$1 diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 64a256ec..6171678e 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_transip_info='TransIP.nl +Site: TransIP.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_transip +Options: + TRANSIP_Username Username + TRANSIP_Key_File Private key file path +Issues: github.com/acmesh-official/acme.sh/issues/2949 +' + TRANSIP_Api_Url="https://api.transip.nl/v6" TRANSIP_Token_Read_Only="false" TRANSIP_Token_Expiration="30 minutes" diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh index caada826..24a843b9 100644 --- a/dnsapi/dns_udr.sh +++ b/dnsapi/dns_udr.sh @@ -1,14 +1,14 @@ #!/usr/bin/env sh - -# united-domains Reselling (https://www.ud-reselling.com/) DNS API -# Author: Andreas Scherer (https://github.com/andischerer) -# Created: 2021-02-01 -# -# Set the environment variables as below: -# -# export UDR_USER="your_username_goes_here" -# export UDR_PASS="some_password_goes_here" -# +# shellcheck disable=SC2034 +dns_udr_info='united-domains Reselling +Site: ud-reselling.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_udr +Options: + UDR_USER Username + UDR_PASS Password +Issues: github.com/acmesh-official/acme.sh/issues/3923 +Author: Andreas Scherer +' UDR_API="https://api.domainreselling.de/api/call.cgi" UDR_TTL="30" diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh index 0f26bd97..8b8c9122 100644 --- a/dnsapi/dns_ultra.sh +++ b/dnsapi/dns_ultra.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -# ULTRA_USR="your_user_goes_here" -# -# ULTRA_PWD="some_password_goes_here" +# shellcheck disable=SC2034 +dns_ultra_info='UltraDNS.com +Site: UltraDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ultra +Options: + ULTRA_USR Username + ULTRA_PWD Password +Issues: github.com/acmesh-official/acme.sh/issues/2118 +' ULTRA_API="https://api.ultradns.com/v3/" ULTRA_AUTH_API="https://api.ultradns.com/v2/" diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index 13ba8a00..a1263abe 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#UNO_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#UNO_User="UExxxxxx" +# shellcheck disable=SC2034 +dns_unoeuro_info='unoeuro.com + Deprecated. The unoeuro.com is now simply.com +Site: unoeuro.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_unoeuro +Options: + UNO_Key API Key + UNO_User Username +' Uno_Api="https://api.simply.com/1" diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index aa743807..23ec29bf 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -# -#VARIOMEDIA_API_TOKEN=000011112222333344445555666677778888 +# shellcheck disable=SC2034 +dns_variomedia_info='variomedia.de +Site: variomedia.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_variomedia +Options: + VARIOMEDIA_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/2564 +' VARIOMEDIA_API="https://api.variomedia.de" diff --git a/dnsapi/dns_veesp.sh b/dnsapi/dns_veesp.sh index b8a41d00..5ea6e718 100644 --- a/dnsapi/dns_veesp.sh +++ b/dnsapi/dns_veesp.sh @@ -1,10 +1,14 @@ #!/usr/bin/env sh - -# bug reports to stepan@plyask.in - -# -# export VEESP_User="username" -# export VEESP_Password="password" +# shellcheck disable=SC2034 +dns_veesp_info='veesp.com +Site: veesp.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_veesp +Options: + VEESP_User Username + VEESP_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/3712 +Author: +' VEESP_Api="https://secure.veesp.com/api" diff --git a/dnsapi/dns_vercel.sh b/dnsapi/dns_vercel.sh index 7bf6b0e5..46a4cb7e 100644 --- a/dnsapi/dns_vercel.sh +++ b/dnsapi/dns_vercel.sh @@ -1,11 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_vercel_info='Vercel.com +Site: Vercel.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_vercel +Options: + VERCEL_TOKEN API Token +' -# Vercel DNS API -# # This is your API token which can be acquired on the account page. # https://vercel.com/account/tokens -# -# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" VERCEL_API="https://api.vercel.com" diff --git a/dnsapi/dns_vscale.sh b/dnsapi/dns_vscale.sh index d717d6e2..54abb439 100755 --- a/dnsapi/dns_vscale.sh +++ b/dnsapi/dns_vscale.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_vscale_info='vscale.io +Site: vscale.io +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_vscale +Options: + VSCALE_API_KEY API Key +Author: Alex Loban +' -#This is the vscale.io api wrapper for acme.sh -# -#Author: Alex Loban -#Report Bugs here: https://github.com/LAV45/acme.sh - -#VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" VSCALE_API_URL="https://api.vscale.io/v1" ######## Public functions ##################### diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 54e5b6ce..94d14f02 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -# -#VULTR_API_KEY=000011112222333344445555666677778888 +# shellcheck disable=SC2034 +dns_vultr_info='vultr.com +Site: vultr.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_vultr +Options: + VULTR_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2374 +Author: +' VULTR_Api="https://api.vultr.com/v2" diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index e824c9c0..3df8d81c 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,18 +1,16 @@ #!/usr/bin/env sh - -# Acme.sh DNS API wrapper for websupport.sk -# -# Original author: trgo.sk (https://github.com/trgosk) -# Tweaks by: akulumbeg (https://github.com/akulumbeg) -# Report Bugs here: https://github.com/akulumbeg/acme.sh +# shellcheck disable=SC2034 +dns_websupport_info='Websupport.sk +Site: Websupport.sk +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_websupport +Options: + WS_ApiKey API Key. Called "Identifier" in the WS Admin + WS_ApiSecret API Secret. Called "Secret key" in the WS Admin +Issues: github.com/acmesh-official/acme.sh/issues/3486 +Author: trgo.sk , akulumbeg +' # Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey -# -# WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -# (called "Identifier" in the WS Admin) -# -# WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -# (called "Secret key" in the WS Admin) WS_Api="https://rest.websupport.sk" diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index dfda4efd..be6ef5c8 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -1,7 +1,14 @@ #!/usr/bin/env sh - -# World4You - www.world4you.com -# Lorenz Stechauner, 2020 - https://www.github.com/NerLOR +# shellcheck disable=SC2034 +dns_world4you_info='World4You.com +Site: World4You.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_world4you +Options: + WORLD4YOU_USERNAME Username + WORLD4YOU_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/3269 +Author: Lorenz Stechauner +' WORLD4YOU_API="https://my.world4you.com/en" PAKETNR='' diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 0a2c3330..d780459f 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh -# Author: non7top@gmail.com -# 07 Jul 2017 -# report bugs at https://github.com/non7top/acme.sh - -# Values to export: -# export PDD_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Sometimes cloudflare / google doesn't pick new dns records fast enough. -# You can add --dnssleep XX to params as workaround. +# shellcheck disable=SC2034 +dns_yandex_info='Yandex Domains +Site: tech.Yandex.com/domain/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_yandex +Options: + PDD_Token API Token +Issues: github.com/non7top/acme.sh/issues +Author: +' ######## Public functions ##################### diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index ec3bbc87..e81b6fd2 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -1,11 +1,18 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_yc_info='Yandex Cloud DNS +Site: Cloud.Yandex.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yc +Options: + YC_Zone_ID DNS Zone ID + YC_Folder_ID YC Folder ID + YC_SA_ID Service Account ID + YC_SA_Key_ID Service Account IAM Key ID + YC_SA_Key_File_Path Private key file path. Optional. + YC_SA_Key_File_PEM_b64 Base64 content of private key file. Use instead of Path to private key file. Optional. +Issues: github.com/acmesh-official/acme.sh/issues/4210 +' -#YC_Zone_ID="" # DNS Zone ID -#YC_Folder_ID="" # YC Folder ID -#YC_SA_ID="" # Service Account ID -#YC_SA_Key_ID="" # Service Account IAM Key ID -#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of YC_SA_Key_File_PEM_b64 -#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of YC_SA_Key_File_Path YC_Api="https://dns.api.cloud.yandex.net/dns/v1" ######## Public functions ##################### diff --git a/dnsapi/dns_zilore.sh b/dnsapi/dns_zilore.sh index 42111025..369ce152 100644 --- a/dnsapi/dns_zilore.sh +++ b/dnsapi/dns_zilore.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_zilore_info='Zilore.com +Site: Zilore.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zilore +Options: + Zilore_Key API Key +' Zilore_API="https://api.zilore.com/dns/v1" -# Zilore_Key="YOUR-ZILORE-API-KEY" ######## Public functions ##################### diff --git a/dnsapi/dns_zone.sh b/dnsapi/dns_zone.sh index 176fc494..e4685707 100755 --- a/dnsapi/dns_zone.sh +++ b/dnsapi/dns_zone.sh @@ -1,8 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_zone_info='Zone.eu +Site: Zone.eu +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zone +Options: + ZONE_Username Username + ZONE_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2146 +' # Zone.ee dns API # https://help.zone.eu/kb/zoneid-api-v2/ -# required ZONE_Username and ZONE_Key ZONE_Api="https://api.zone.eu/v2" ######## Public functions ##################### diff --git a/dnsapi/dns_zonomi.sh b/dnsapi/dns_zonomi.sh index 52a889ea..ee817381 100644 --- a/dnsapi/dns_zonomi.sh +++ b/dnsapi/dns_zonomi.sh @@ -1,9 +1,11 @@ #!/usr/bin/env sh - -# -#ZM_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#https://zonomi.com dns api +# shellcheck disable=SC2034 +dns_zonomi_info='zonomi.com +Site: zonomi.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zonomi +Options: + ZM_Key API Key +' ZM_Api="https://zonomi.com/app/dns/dyndns.jsp" From b821836dc4f00e870784be50104f296c90b435c3 Mon Sep 17 00:00:00 2001 From: Henrik Alves <89079890+henrikalves@users.noreply.github.com> Date: Mon, 27 May 2024 12:45:01 +0200 Subject: [PATCH 376/687] update dns_doapi --- dnsapi/dns_doapi.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index 9bc6a4a4..0804f2e6 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -2,7 +2,6 @@ # shellcheck disable=SC2034 dns_doapi_info='Domain-Offensive do.de Official LetsEncrypt API for do.de / Domain-Offensive. - This is different from the dns_do adapter, because dns_do is only usable for enterprise customers. This API is also available to private customers/individuals. Site: do.de Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_doapi @@ -11,7 +10,7 @@ Options: Issues: github.com/acmesh-official/acme.sh/issues/2057 ' -DO_API="https://www.do.de/api/letsencrypt" +DO_API="https://my.do.de/api/letsencrypt" ######## Public functions ##################### From cc9c85cc1aab1f4aa5a06b6b1e44f5d1ecee4a3c Mon Sep 17 00:00:00 2001 From: zak905 Date: Sun, 9 Jun 2024 21:02:54 +0200 Subject: [PATCH 377/687] use lower_case util function instead of raw bash command --- dnsapi/dns_ionos_cloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh index 18a60d18..d7d72f8e 100644 --- a/dnsapi/dns_ionos_cloud.sh +++ b/dnsapi/dns_ionos_cloud.sh @@ -95,10 +95,10 @@ _ionos_cloud_get_record() { zone_id=$1 txtrecord=$2 # this is to transform the domain to lower case - fulldomain=$(printf "%s" "$3" | tr "[:upper:]" "[:lower:]") + fulldomain=$(printf "%s" "$3" | _lower_case # this is to transform record name to lower case # IONOS Cloud API transforms all record names to lower case - _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | tr "[:upper:]" "[:lower:]") + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | _lower_case) if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then _response="$(echo "$_response" | tr -d "\n")" From 74ffbb2172a782a96c378ec364d6f17110d64047 Mon Sep 17 00:00:00 2001 From: zak905 Date: Mon, 10 Jun 2024 19:53:05 +0200 Subject: [PATCH 378/687] fix forgotten parenthensis --- dnsapi/dns_ionos_cloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh index d7d72f8e..fa229e03 100644 --- a/dnsapi/dns_ionos_cloud.sh +++ b/dnsapi/dns_ionos_cloud.sh @@ -95,7 +95,7 @@ _ionos_cloud_get_record() { zone_id=$1 txtrecord=$2 # this is to transform the domain to lower case - fulldomain=$(printf "%s" "$3" | _lower_case + fulldomain=$(printf "%s" "$3" | _lower_case) # this is to transform record name to lower case # IONOS Cloud API transforms all record names to lower case _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | _lower_case) From 1c9423ef31cc80fee79e25b823b2c12047f01083 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Tue, 11 Jun 2024 12:50:45 -0300 Subject: [PATCH 379/687] fix pagination bug querying Linode API v4 fixes issue #4956 previous code only worked for the first 10 domains on the account (as Linode API returned a paginated response, with only 10 records). This change makes an exact search query for each subdomain, completely removing any need for walking through paginated responses. What makes it work for large accounts with any number of domains. --- dnsapi/dns_linode_v4.sh | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 9504afbf..d0545938 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -126,34 +126,41 @@ _Linode_API() { # _domain=domain.com # _domain_id=12345 _get_root() { - domain=$1 + local full_host_str="$1" + i=2 p=1 + while true; do + # loop through the received string (e.g. _acme-challenge.sub3.sub2.sub1.domain.tld), + # starting from the lowest subdomain, and check if it's a hosted domain + h=$(printf "%s" "$full_host_str" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi - if _rest GET; then - response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then - #not valid - return 1 - fi - + _debug "Querying Linode APIv4 for subdomain: $h" + if _H4="X-Filter: {\"domain\":\"$h\"}" _rest GET; then + _debug "Got response from API: $response" + response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" hostedzone="$(echo "$response" | _egrep_o "\{.*\"domain\": *\"$h\".*}")" if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + _debug "Found domain hosted on Linode DNS. Zone: $h, id: $_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$full_host_str" | cut -d . -f 1-$p) _domain=$h return 0 fi return 1 fi + p=$i i=$(_math "$i" + 1) - done - fi + fi + done + return 1 } @@ -169,6 +176,7 @@ _rest() { export _H1="Accept: application/json" export _H2="Content-Type: application/json" export _H3="Authorization: Bearer $LINODE_V4_API_KEY" + export _H4 # used to query for the root domain on _get_root() if [ "$mtd" != "GET" ]; then # both POST and DELETE. From 05ec3922f1d9b72ca6d65709f21fca2b6d1ded84 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Tue, 11 Jun 2024 17:17:37 -0300 Subject: [PATCH 380/687] minor wording fix minor fix for text coherence --- dnsapi/dns_linode_v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index d0545938..390ec0d8 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -140,7 +140,7 @@ _get_root() { return 1 fi - _debug "Querying Linode APIv4 for subdomain: $h" + _debug "Querying Linode APIv4 for hosted zone: $h" if _H4="X-Filter: {\"domain\":\"$h\"}" _rest GET; then _debug "Got response from API: $response" response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" From 2f8fb360aa789b4198aba092ac61d0fcbb4e5df0 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Wed, 12 Jun 2024 15:03:02 -0300 Subject: [PATCH 381/687] fix CI reported problems for shellcheck and shfmt fix minor problems reported by shellcheck and shfmt --- dnsapi/dns_linode_v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 390ec0d8..12682dbf 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -126,7 +126,7 @@ _Linode_API() { # _domain=domain.com # _domain_id=12345 _get_root() { - local full_host_str="$1" + full_host_str="$1" i=2 p=1 @@ -140,7 +140,7 @@ _get_root() { return 1 fi - _debug "Querying Linode APIv4 for hosted zone: $h" + _debug "Querying Linode APIv4 for hosted zone: $h" if _H4="X-Filter: {\"domain\":\"$h\"}" _rest GET; then _debug "Got response from API: $response" response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" From e0c63d58b2e969aa11058b88835597b124e9b3d8 Mon Sep 17 00:00:00 2001 From: Marek Wester Date: Tue, 28 May 2024 22:46:27 +0200 Subject: [PATCH 382/687] improve compatibility with FreeBSD it is related to this bug report: opnsense/plugins#3525 FreeBSD's sed doesn't have the -z option, so empty certificates are delivered to vault when running the script on FreeBSD. --- deploy/vault.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/vault.sh b/deploy/vault.sh index 569faba2..03a0de83 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -70,10 +70,10 @@ vault_deploy() { # JSON does not allow multiline strings. # So replacing new-lines with "\n" here - _ckey=$(sed -z 's/\n/\\n/g' <"$2") - _ccert=$(sed -z 's/\n/\\n/g' <"$3") - _cca=$(sed -z 's/\n/\\n/g' <"$4") - _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") + _ckey=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$2") + _ccert=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$3") + _cca=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$4") + _cfullchain=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$5") export _H1="X-Vault-Token: $VAULT_TOKEN" From fe4113d6234d5b224f4ad32f290506ef3db0215c Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 17 Jun 2024 15:30:00 +0200 Subject: [PATCH 383/687] add PROJECT_API for https://github.com/acmesh-official/acme.sh/issues/5170 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d154cf77..5f09e29d 100755 --- a/acme.sh +++ b/acme.sh @@ -7075,7 +7075,7 @@ installOnline() { _getRepoHash() { _hash_path=$1 shift - _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" + _hash_url="${PROJECT_API:-https://api.github.com/repos/acmesh-official}/$PROJECT_NAME/git/refs/$_hash_path" _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 } From 617f4acfd6dbd5a21100a552fb4f45583c99d6e0 Mon Sep 17 00:00:00 2001 From: WinSCaP Date: Sat, 22 Jun 2024 11:37:10 +0200 Subject: [PATCH 384/687] Update dns_openprovider.sh for OpenProvider Removed the NS type, as settings nameservers via API is no longer supported. The API implementation is not changed to the new REST API. --- dnsapi/dns_openprovider.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 0e93ecf8..4d115dcf 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -68,7 +68,7 @@ dns_openprovider_add() { new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi @@ -152,7 +152,7 @@ dns_openprovider_rm() { new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi From 89586530a5211a3c8f804c94d45ffefcd0a458b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Weselowski?= Date: Wed, 26 Jun 2024 14:09:44 +0200 Subject: [PATCH 385/687] improve performance and memory usage for dns_anx when fetching all zones the memory usage can exceede limits and also cause timeouts. with this change the zone will be searched via the longest to shortest match using the get endpoint. --- dnsapi/dns_anx.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index c1a1130a..05ac1874 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -127,8 +127,6 @@ _get_root() { i=1 p=1 - _anx_rest GET "zone.json" - while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" @@ -137,6 +135,7 @@ _get_root() { return 1 fi + _anx_rest GET "zone.json/${h}" if _contains "$response" "\"name\":\"$h\""; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 65868ab8a76869ebb6edbd1372fc22ee52a4344c Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 3 Jul 2024 18:27:47 +0800 Subject: [PATCH 386/687] remove centos --- .github/workflows/Linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 4afebaf0..c74e9d3e 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -26,7 +26,7 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:7", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 From 5789e80d741462f36fc2b1949a965550c051444d Mon Sep 17 00:00:00 2001 From: IIIPr0t0typ3III Date: Fri, 5 Jul 2024 18:43:11 +0200 Subject: [PATCH 387/687] Fixed a bug where the zone_id was corrupted for domains containing the string 'id' dns_dynv6.sh This will now search for `"id:"` instead of `id` and therefore will only find the id field and not any other field containing the sub-string 'id' --- dnsapi/dns_dynv6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 8b94dae7..7ef66bf3 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -206,7 +206,7 @@ _get_zone_id() { return 1 fi - zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')" + zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep '"id":' | tr -d '"')" _zone_id="${zone_id#id:}" _debug "zone id: $_zone_id" } From 51151293d7556dde713c197d0fdc83b97cbbe642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B5=D0=B2?= <73811032+vlad-kms@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:01:25 +1000 Subject: [PATCH 388/687] Remove `date -d` on macOS --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index c8aa2db7..511ab7f5 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -356,7 +356,7 @@ _get_auth_token() { _debug3 _login_name "$_login_name" _debug3 _login_id "$_login_id" _debug3 _project_name "$_project_name" - _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" From a2bc79ddd51c6ecdd831a105530ad5e8618ff346 Mon Sep 17 00:00:00 2001 From: Felix Schmidt Date: Sun, 7 Jul 2024 12:30:15 +0200 Subject: [PATCH 389/687] Fixed a bug where trying to add entries where the fulldomain contains upper case characters would not be accepted (dynv6 API rejects those). Now the fulldomain will be cast to lowercase first which should not make any difference since DNS is case insensitive. --- dnsapi/dns_dynv6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 7ef66bf3..a8bb2adf 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -16,8 +16,8 @@ dynv6_api="https://dynv6.com/api/v2" # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$(echo "$1" | tr 'A-Z' 'a-z') + txtvalue="$2" _info "Using dynv6 api" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" @@ -50,8 +50,8 @@ dns_dynv6_add() { #Usage: fulldomain txtvalue #Remove the txt record after validation. dns_dynv6_rm() { - fulldomain=$1 - txtvalue=$2 + fulldomain=$(echo "$1" | tr 'A-Z' 'a-z') + txtvalue="$2" _info "Using dynv6 API" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" From ab86e056a26112ca5ef145c60cc28afbd0ca2baa Mon Sep 17 00:00:00 2001 From: Felix Schmidt Date: Sun, 7 Jul 2024 13:02:47 +0200 Subject: [PATCH 390/687] Changed A-Z and a-z to [:upper:] and [:lower:] from last commit to comply with requested standards. This does not change any functionality in this special case but the request for [:upper:] and [:lower:] makes a lot of sense in general. --- dnsapi/dns_dynv6.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index a8bb2adf..b15fe36f 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -16,7 +16,7 @@ dynv6_api="https://dynv6.com/api/v2" # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { - fulldomain=$(echo "$1" | tr 'A-Z' 'a-z') + fulldomain=$(echo "$1" | tr '[:upper:]' '[:lower:]') txtvalue="$2" _info "Using dynv6 api" _debug fulldomain "$fulldomain" @@ -50,7 +50,7 @@ dns_dynv6_add() { #Usage: fulldomain txtvalue #Remove the txt record after validation. dns_dynv6_rm() { - fulldomain=$(echo "$1" | tr 'A-Z' 'a-z') + fulldomain=$(echo "$1" | tr '[:upper:]' '[:lower:]') txtvalue="$2" _info "Using dynv6 API" _debug fulldomain "$fulldomain" From 3c35eadbc40618278166efaae62a9d6527d14f3b Mon Sep 17 00:00:00 2001 From: PMExtra Date: Thu, 11 Jul 2024 18:29:20 +0800 Subject: [PATCH 391/687] feat(deploy_ali_cdn): support Alibaba Cloud CDN deployment --- deploy/ali_cdn.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 deploy/ali_cdn.sh diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh new file mode 100644 index 00000000..0f33ab46 --- /dev/null +++ b/deploy/ali_cdn.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh + +# Script to create certificate to Alibaba Cloud CDN +# +# This deployment required following variables +# export Ali_Key="ALIACCESSKEY" +# export Ali_Secret="ALISECRETKEY" +# export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com" +# If you have more than one domain, just +# export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com" +# +# The credentials are shared with all domains, also shared with dns_ali api + +Ali_API="https://cdn.aliyuncs.com/" + +ali_cdn_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" + Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" + if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then + Ali_Key="" + Ali_Secret="" + _err "You don't specify aliyun api key and secret yet." + return 1 + fi + + #save the api key and secret to the account conf file. + _saveaccountconf_mutable Ali_Key "$Ali_Key" + _saveaccountconf_mutable Ali_Secret "$Ali_Secret" + + _getdeployconf DEPLOY_ALI_CDN_DOMAIN + if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then + _savedeployconf DEPLOY_ALI_CDN_DOMAIN "$DEPLOY_ALI_CDN_DOMAIN" + else + DEPLOY_ALI_CDN_DOMAIN="$_cdomain" + fi + + # read cert and key files and urlencode both + _cert=$(_url_encode_upper <"$_cfullchain") + _key=$(_url_encode_upper <"$_ckey") + + _debug2 _cert "$_cert" + _debug2 _key "$_key" + + ## update domain ssl config + for domain in $DEPLOY_ALI_CDN_DOMAIN; do + _set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key" + if _ali_rest "Set CDN domain SSL certificate for $domain" "" POST; then + _info "Domain $domain certificate has been deployed successfully" + fi + done + + return 0 +} + +#################### Private functions below ################################## + +# act ign mtd +_ali_rest() { + act="$1" + ign="$2" + mtd="$3" + + signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) + signature=$(_ali_urlencode "$signature") + url="$Ali_API?$query&Signature=$signature" + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + # post payload is not supported yet because of signature + response="$(_post "" "$url")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" != "0" ]; then + _err "Error <$act>" + return 1 + fi + + if [ -z "$ign" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then + _err "$message" + return 1 + fi + fi +} + +_ali_urlencode() { + _str="$1" + _str_len=${#_str} + _u_i=1 + while [ "$_u_i" -le "$_str_len" ]; do + _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" + case $_str_c in [a-zA-Z0-9.~_-]) + printf "%s" "$_str_c" + ;; + *) + printf "%%%02X" "'$_str_c" + ;; + esac + _u_i="$(_math "$_u_i" + 1)" + done +} + +_ali_nonce() { + #_head_n 1 Date: Thu, 11 Jul 2024 18:41:39 +0800 Subject: [PATCH 392/687] feat(deploy_ali_cdn): improve upper-case --- deploy/ali_cdn.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 0f33ab46..6bbb3b43 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -131,7 +131,7 @@ _url_encode_upper() { encoded=$(_url_encode) for match in $(echo "$encoded" | _egrep_o '%..' | sort -u); do - upper=$(echo "$match" | tr '[:lower:]' '[:upper:]') + upper=$(echo "$match" | _upper_case) encoded=$(echo "$encoded" | sed "s/$match/$upper/g") done From 9bdfd8f4fe1c625aa773b4875bf1fd2d09283ef1 Mon Sep 17 00:00:00 2001 From: Vlad-Stefan Harbuz Date: Fri, 12 Jul 2024 13:04:42 +0100 Subject: [PATCH 393/687] Improve grammar --- acme.sh | 714 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 356 insertions(+), 358 deletions(-) diff --git a/acme.sh b/acme.sh index d154cf77..219a3caa 100755 --- a/acme.sh +++ b/acme.sh @@ -231,11 +231,11 @@ _dlg_versions() { echo "$ACME_OPENSSL_BIN doesn't exist." fi - echo "apache:" + echo "Apache:" if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then $_APACHECTL -V 2>&1 else - echo "apache doesn't exist." + echo "Apache doesn't exist." fi echo "nginx:" @@ -949,7 +949,7 @@ _getfile() { i="$(grep -n -- "$startline" "$filename" | cut -d : -f 1)" if [ -z "$i" ]; then - _err "Can not find start line: $startline" + _err "Cannot find start line: $startline" return 1 fi i="$(_math "$i" + 1)" @@ -957,7 +957,7 @@ _getfile() { j="$(grep -n -- "$endline" "$filename" | cut -d : -f 1)" if [ -z "$j" ]; then - _err "Can not find end line: $endline" + _err "Cannot find end line: $endline" return 1 fi j="$(_math "$j" - 1)" @@ -1065,7 +1065,7 @@ _sign() { if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then _err "Sign failed: $_sign_openssl" _err "Key file: $keyfile" - _err "Key content:$(wc -l <"$keyfile") lines" + _err "Key content: $(wc -l <"$keyfile") lines" return 1 fi _debug3 "_signedECText" "$_signedECText" @@ -1145,14 +1145,14 @@ _createkey() { length=2048 fi - _debug "Use length $length" + _debug "Using length $length" if ! [ -e "$f" ]; then if ! touch "$f" >/dev/null 2>&1; then _f_path="$(dirname "$f")" _debug _f_path "$_f_path" if ! mkdir -p "$_f_path"; then - _err "Can not create path: $_f_path" + _err "Cannot create path: $_f_path" return 1 fi fi @@ -1163,11 +1163,11 @@ _createkey() { fi if _isEccKey "$length"; then - _debug "Using ec name: $eccname" + _debug "Using EC name: $eccname" if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else - _err "error ecc key name: $eccname" + _err "Error encountered for ECC key named $eccname" return 1 fi else @@ -1179,13 +1179,13 @@ _createkey() { if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else - _err "error rsa key: $length" + _err "Error encountered for RSA key of length $length" return 1 fi fi if [ "$?" != "0" ]; then - _err "Create key error." + _err "Key creation error." return 1 fi } @@ -1452,7 +1452,7 @@ toPkcs() { _toPkcs "$CERT_PFX_PATH" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$pfxPassword" if [ "$?" = "0" ]; then - _info "Success, Pfx is exported to: $CERT_PFX_PATH" + _info "Success, PFX has been exported to: $CERT_PFX_PATH" fi } @@ -1496,7 +1496,7 @@ _create_account_key() { length=$1 if [ -z "$length" ] || [ "$length" = "$NO_VALUE" ]; then - _debug "Use default length $DEFAULT_ACCOUNT_KEY_LENGTH" + _debug "Using default length $DEFAULT_ACCOUNT_KEY_LENGTH" length="$DEFAULT_ACCOUNT_KEY_LENGTH" fi @@ -1505,15 +1505,15 @@ _create_account_key() { mkdir -p "$CA_DIR" if [ -s "$ACCOUNT_KEY_PATH" ]; then - _info "Account key exists, skip" + _info "Account key exists, skipping" return 0 else #generate account key if _createkey "$length" "$ACCOUNT_KEY_PATH"; then - _info "Create account key ok." + _info "Account key creation OK." return 0 else - _err "Create account key error." + _err "Account key creation error." return 1 fi fi @@ -1532,7 +1532,7 @@ createDomainKey() { _cdl=$2 if [ -z "$_cdl" ]; then - _debug "Use DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH" + _debug "Using DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH" _cdl="$DEFAULT_DOMAIN_KEY_LENGTH" fi @@ -1544,16 +1544,16 @@ createDomainKey() { _info "The domain key is here: $(__green $CERT_KEY_PATH)" return 0 else - _err "Can not create domain key" + _err "Cannot create domain key" return 1 fi else if [ "$_ACME_IS_RENEW" ]; then - _info "Domain key exists, skip" + _info "Domain key exists, skipping" return 0 else - _err "Domain key exists, do you want to overwrite the key?" - _err "Add '--force', and try again." + _err "Domain key exists, do you want to overwrite it?" + _err "If so, add '--force' and try again." return 1 fi fi @@ -1562,7 +1562,7 @@ createDomainKey() { # domain domainlist isEcc createCSR() { - _info "Creating csr" + _info "Creating CSR" if [ -z "$1" ]; then _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...] [--ecc]" return @@ -1575,13 +1575,13 @@ createCSR() { _initpath "$domain" "$_isEcc" if [ -f "$CSR_PATH" ] && [ "$_ACME_IS_RENEW" ] && [ -z "$FORCE" ]; then - _info "CSR exists, skip" + _info "CSR exists, skipping" return fi if [ ! -f "$CERT_KEY_PATH" ]; then - _err "The key file is not found: $CERT_KEY_PATH" - _err "Please create the key file first." + _err "This key file was not found: $CERT_KEY_PATH" + _err "Please create it first." return 1 fi _createcsr "$domain" "$domainlist" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF" @@ -1725,7 +1725,7 @@ _calcjwk() { __ECC_KEY_LEN=512 ;; *) - _err "ECC oid : $crv_oid" + _err "ECC oid: $crv_oid" return 1 ;; esac @@ -1768,7 +1768,7 @@ _calcjwk() { JWK_HEADERPLACE_PART1='{"nonce": "' JWK_HEADERPLACE_PART2='", "alg": "ES'$__ECC_KEY_LEN'"' else - _err "Only RSA or EC key is supported. keyfile=$keyfile" + _err "Only RSA or EC keys are supported. keyfile=$keyfile" _debug2 "$(cat "$keyfile")" return 1 fi @@ -1802,7 +1802,7 @@ _date2time() { if da="$(echo "$1" | tr -d "Z" | tr "T" ' ')" perl -MTime::Piece -e 'print Time::Piece->strptime($ENV{da}, "%Y-%m-%d %H:%M:%S")->epoch, "\n";' 2>/dev/null; then return fi - _err "Can not parse _date2time $1" + _err "Cannot parse _date2time $1" return 1 } @@ -1826,7 +1826,7 @@ _mktemp() { echo "/$LE_TEMP_DIR/wefADf24sf.$(_time).tmp" return 0 fi - _err "Can not create temp file." + _err "Cannot create temp file." } #clear all the https envs to cause _inithttp() to run next time. @@ -2015,7 +2015,7 @@ _post() { _ret="$?" if [ "$_ret" = "8" ]; then _ret=0 - _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." + _debug "wget returned 8 as the server returned a 'Bad Request' response. Let's process the response later." fi if [ "$_ret" != "0" ]; then _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" @@ -2029,7 +2029,7 @@ _post() { _sed_i 's/^ //g' "$HTTP_HEADER" else _ret="$?" - _err "Neither curl nor wget is found, can not do $httpmethod." + _err "Neither curl nor wget have been found, cannot make $httpmethod request." fi _debug "_ret" "$_ret" printf "%s" "$response" @@ -2098,14 +2098,14 @@ _get() { ret=$? if [ "$ret" = "8" ]; then ret=0 - _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." + _debug "wget returned 8 as the server returned a 'Bad Request' response. Let's process the response later." fi if [ "$ret" != "0" ]; then _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" fi else ret=$? - _err "Neither curl nor wget is found, can not do GET." + _err "Neither curl nor wget have been found, cannot make GET request." fi _debug "ret" "$ret" return $ret @@ -2137,7 +2137,7 @@ _send_signed_request() { if [ -z "$keyfile" ]; then keyfile="$ACCOUNT_KEY_PATH" fi - _debug "=======Begin Send Signed Request=======" + _debug "=======Sending Signed Request=======" _debug url "$url" _debug payload "$payload" @@ -2183,7 +2183,7 @@ _send_signed_request() { fi _debug2 _CACHED_NONCE "$_CACHED_NONCE" if [ "$?" != "0" ]; then - _err "Can not connect to $nonceurl to get nonce." + _err "Cannot connect to $nonceurl to get nonce." return 1 fi else @@ -2226,7 +2226,7 @@ _send_signed_request() { _CACHED_NONCE="" if [ "$?" != "0" ]; then - _err "Can not post to $url" + _err "Cannot make POST request to $url" return 1 fi @@ -2258,21 +2258,21 @@ _send_signed_request() { _sleep_overload_retry_sec=5 fi if [ $_sleep_overload_retry_sec -le 600 ]; then - _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping for $_sleep_overload_retry_sec seconds." _sleep $_sleep_overload_retry_sec continue else - _info "The retryafter=$_retryafter is too large > 600, not retry anymore." + _info "The retryafter=$_retryafter value is too large (> 600), will not retry anymore." fi fi if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then - _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." + _info "It seems the CA server is busy now, let's wait and retry. Sleeping for $_sleep_retry_sec seconds." _CACHED_NONCE="" _sleep $_sleep_retry_sec continue fi if _contains "$_body" "The Replay Nonce is not recognized"; then - _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _info "The replay nonce is not valid, let's get a new one. Sleeping for $_sleep_retry_sec seconds." _CACHED_NONCE="" _sleep $_sleep_retry_sec continue @@ -2344,7 +2344,7 @@ _save_conf() { if [ "$_s_c_f" ]; then _setopt "$_s_c_f" "$_sdkey" "=" "'$_sdvalue'" else - _err "config file is empty, can not save $_sdkey=$_sdvalue" + _err "Config file is empty, cannot save $_sdkey=$_sdvalue" fi } @@ -2356,7 +2356,7 @@ _clear_conf() { _conf_data="$(cat "$_c_c_f")" echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" >"$_c_c_f" else - _err "config file is empty, can not clear" + _err "Config file is empty, cannot clear" fi } @@ -2374,7 +2374,7 @@ _read_conf() { fi printf "%s" "$_sdv" else - _debug "config file is empty, can not read $_sdkey" + _debug "Config file is empty, cannot read $_sdkey" fi } @@ -2592,7 +2592,7 @@ _starttlsserver() { #create key TLS_KEY if ! _createkey "2048" "$TLS_KEY"; then - _err "Create tls validation key error." + _err "Error creating TLS validation key." return 1 fi @@ -2602,13 +2602,13 @@ _starttlsserver() { alt="$alt,$san_b" fi if ! _createcsr "tls.acme.sh" "$alt" "$TLS_KEY" "$TLS_CSR" "$TLS_CONF" "$acmeValidationv1"; then - _err "Create tls validation csr error." + _err "Error creating TLS validation CSR." return 1 fi #self signed if ! _signcsr "$TLS_KEY" "$TLS_CSR" "$TLS_CONF" "$TLS_CERT"; then - _err "Create tls validation cert error." + _err "Error creating TLS validation cert." return 1 fi @@ -2662,7 +2662,7 @@ _conapath() { __initHome() { if [ -z "$_SCRIPT_HOME" ]; then if _exists readlink && _exists dirname; then - _debug "Lets find script dir." + _debug "Let's find the script directory." _debug "_SCRIPT_" "$_SCRIPT_" _script="$(_readlink "$_SCRIPT_")" _debug "_script" "$_script" @@ -2671,7 +2671,7 @@ __initHome() { if [ -d "$_script_home" ]; then export _SCRIPT_HOME="$_script_home" else - _err "It seems the script home is not correct:$_script_home" + _err "It seems the script home is not correct: $_script_home" fi fi fi @@ -2686,7 +2686,7 @@ __initHome() { # fi if [ -z "$LE_WORKING_DIR" ]; then - _debug "Using default home:$DEFAULT_INSTALL_HOME" + _debug "Using default home: $DEFAULT_INSTALL_HOME" LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" fi export LE_WORKING_DIR @@ -2694,7 +2694,7 @@ __initHome() { if [ -z "$LE_CONFIG_HOME" ]; then LE_CONFIG_HOME="$LE_WORKING_DIR" fi - _debug "Using config home:$LE_CONFIG_HOME" + _debug "Using config home: $LE_CONFIG_HOME" export LE_CONFIG_HOME _DEFAULT_ACCOUNT_CONF_PATH="$LE_CONFIG_HOME/account.conf" @@ -2731,7 +2731,7 @@ _clearAPI() { #server _initAPI() { _api_server="${1:-$ACME_DIRECTORY}" - _debug "_init api for server: $_api_server" + _debug "_init API for server: $_api_server" MAX_API_RETRY_TIMES=10 _sleep_retry_sec=10 @@ -2741,8 +2741,8 @@ _initAPI() { response=$(_get "$_api_server") if [ "$?" != "0" ]; then _debug2 "response" "$response" - _info "Can not init api for: $_api_server." - _info "Sleep $_sleep_retry_sec and retry." + _info "Cannot init API for: $_api_server." + _info "Sleeping for $_sleep_retry_sec seconds and retrying." _sleep "$_sleep_retry_sec" continue fi @@ -2780,13 +2780,13 @@ _initAPI() { if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi - _info "Sleep $_sleep_retry_sec and retry." + _info "Sleeping for $_sleep_retry_sec seconds and retrying." _sleep "$_sleep_retry_sec" done if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi - _err "Can not init api, for $_api_server" + _err "Cannot init API for $_api_server" return 1 } @@ -2918,7 +2918,7 @@ _initpath() { DOMAIN_PATH="$domainhomeecc" elif [ -z "$__SELECTED_RSA_KEY" ]; then if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then - _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert." + _info "The domain '$domain' seems to already have an ECC cert, let's use it." DOMAIN_PATH="$domainhomeecc" fi fi @@ -2981,7 +2981,7 @@ _apachePath() { if _exists apache2ctl; then _APACHECTL="apache2ctl" else - _err "'apachectl not found. It seems that apache is not installed, or you are not root user.'" + _err "'apachectl not found. It seems that Apache is not installed or you are not root.'" _err "Please use webroot mode to try again." return 1 fi @@ -3000,7 +3000,7 @@ _apachePath() { _debug httpdconfname "$httpdconfname" if [ -z "$httpdconfname" ]; then - _err "Can not read apache config file." + _err "Cannot read Apache config file." return 1 fi @@ -3017,7 +3017,7 @@ _apachePath() { _debug httpdconf "$httpdconf" _debug httpdconfname "$httpdconfname" if [ ! -f "$httpdconf" ]; then - _err "Apache Config file not found" "$httpdconf" + _err "Apache config file not found" "$httpdconf" return 1 fi return 0 @@ -3040,7 +3040,7 @@ _restoreApache() { cat "$APACHE_CONF_BACKUP_DIR/$httpdconfname" >"$httpdconf" _debug "Restored: $httpdconf." if ! $_APACHECTL -t; then - _err "Sorry, restore apache config error, please contact me." + _err "Sorry, there's been an error restoring the Apache config. Please ask for support on $PROJECT." return 1 fi _debug "Restored successfully." @@ -3055,26 +3055,26 @@ _setApache() { fi #test the conf first - _info "Checking if there is an error in the apache config file before starting." + _info "Checking if there is an error in the Apache config file before starting." if ! $_APACHECTL -t >/dev/null; then - _err "The apache config file has error, please fix it first, then try again." - _err "Don't worry, there is nothing changed to your system." + _err "The Apache config file has errors, please fix them first then try again." + _err "Don't worry, no changes to your system have been made." return 1 else _info "OK" fi #backup the conf - _debug "Backup apache config file" "$httpdconf" + _debug "Backing up Apache config file" "$httpdconf" if ! cp "$httpdconf" "$APACHE_CONF_BACKUP_DIR/"; then - _err "Can not backup apache config file, so abort. Don't worry, the apache config is not changed." - _err "This might be a bug of $PROJECT_NAME , please report issue: $PROJECT" + _err "Cannot backup Apache config file, aborting. Don't worry, the Apache config has not been changed." + _err "This might be an $PROJECT_NAME bug, please open an issue on $PROJECT" return 1 fi - _info "JFYI, Config file $httpdconf is backuped to $APACHE_CONF_BACKUP_DIR/$httpdconfname" - _info "In case there is an error that can not be restored automatically, you may try restore it yourself." - _info "The backup file will be deleted on success, just forget it." + _info "Config file $httpdconf has been backed up to $APACHE_CONF_BACKUP_DIR/$httpdconfname" + _info "In case an error causes it to not be restored automatically, you can restore it yourself." + _info "You do not need to do anything on success, as the backup file will automatically be deleted." #add alias @@ -3104,11 +3104,11 @@ Allow from all _msg="$($_APACHECTL -t 2>&1)" if [ "$?" != "0" ]; then - _err "Sorry, apache config error" + _err "Sorry, an Apache config error has occurred" if _restoreApache; then - _err "The apache config file is restored." + _err "The Apache config file has been restored." else - _err "Sorry, the apache config file can not be restored, please report bug." + _err "Sorry, the Apache config file cannot be restored, please open an issue on $PROJECT." fi return 1 fi @@ -3119,7 +3119,7 @@ Allow from all fi if ! $_APACHECTL graceful; then - _err "$_APACHECTL graceful error, please contact me." + _err "$_APACHECTL graceful error, please open an issue on $PROJECT." _restoreApache return 1 fi @@ -3143,10 +3143,10 @@ _setNginx() { _start_f="$(echo "$_croot" | cut -d : -f 2)" _debug _start_f "$_start_f" if [ -z "$_start_f" ]; then - _debug "find start conf from nginx command" + _debug "Finding config using the nginx command" if [ -z "$NGINX_CONF" ]; then if ! _exists "nginx"; then - _err "nginx command is not found." + _err "nginx command not found." return 1 fi NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "\-\-conf-path=[^ ]* " | tr -d " ")" @@ -3154,7 +3154,7 @@ _setNginx() { NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)" _debug NGINX_CONF "$NGINX_CONF" if [ -z "$NGINX_CONF" ]; then - _err "Can not find nginx conf." + _err "Cannot find nginx config." NGINX_CONF="" return 1 fi @@ -3163,16 +3163,16 @@ _setNginx() { NGINX_CONF="" return 1 fi - _debug "Found nginx conf file:$NGINX_CONF" + _debug "Found nginx config file: $NGINX_CONF" fi _start_f="$NGINX_CONF" fi - _debug "Start detect nginx conf for $_d from:$_start_f" + _debug "Detecting nginx conf for $_d from: $_start_f" if ! _checkConf "$_d" "$_start_f"; then - _err "Can not find conf file for domain $d" + _err "Cannot find config file for domain $d" return 1 fi - _info "Found conf file: $FOUND_REAL_NGINX_CONF" + _info "Found config file: $FOUND_REAL_NGINX_CONF" _ln=$FOUND_REAL_NGINX_CONF_LN _debug "_ln" "$_ln" @@ -3182,7 +3182,7 @@ _setNginx() { _start_tag="$(sed -n "$_lnn,${_lnn}p" "$FOUND_REAL_NGINX_CONF")" _debug "_start_tag" "$_start_tag" if [ "$_start_tag" = "$NGINX_START" ]; then - _info "The domain $_d is already configured, skip" + _info "The domain $_d is already configured, skipping" FOUND_REAL_NGINX_CONF="" return 0 fi @@ -3191,28 +3191,28 @@ _setNginx() { _backup_conf="$DOMAIN_BACKUP_PATH/$_d.nginx.conf" _debug _backup_conf "$_backup_conf" BACKUP_NGINX_CONF="$_backup_conf" - _info "Backup $FOUND_REAL_NGINX_CONF to $_backup_conf" + _info "Backing $FOUND_REAL_NGINX_CONF up to $_backup_conf" if ! cp "$FOUND_REAL_NGINX_CONF" "$_backup_conf"; then - _err "backup error." + _err "Backup error." FOUND_REAL_NGINX_CONF="" return 1 fi if ! _exists "nginx"; then - _err "nginx command is not found." + _err "nginx command not found." return 1 fi - _info "Check the nginx conf before setting up." + _info "Checking the nginx config before setting up." if ! nginx -t >/dev/null 2>&1; then - _err "It seems that nginx conf is not correct, cannot continue." + _err "It seems that the nginx config is not correct, cannot continue." return 1 fi - _info "OK, Set up nginx config file" + _info "OK, setting up the nginx config file" if ! sed -n "1,${_ln}p" "$_backup_conf" >"$FOUND_REAL_NGINX_CONF"; then cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" - _err "write nginx conf error, but don't worry, the file is restored to the original version." + _err "Error writing nginx config. Restoring it to its original version." return 1 fi @@ -3226,20 +3226,20 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { if ! sed -n "${_lnn},99999p" "$_backup_conf" >>"$FOUND_REAL_NGINX_CONF"; then cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" - _err "write nginx conf error, but don't worry, the file is restored." + _err "Error writing nginx config. Restoring it to its original version." return 1 fi _debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)" - _info "nginx conf is done, let's check it again." + _info "nginx config has been written, let's check it again." if ! nginx -t >/dev/null 2>&1; then - _err "It seems that nginx conf was broken, let's restore." + _err "There seems to be a problem with the nginx config, let's restore it to its original version." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi - _info "Reload nginx" + _info "Reloading nginx" if ! nginx -s reload >/dev/null 2>&1; then - _err "It seems that nginx reload error, let's restore." + _err "There seems to be a problem with the nginx config, let's restore it to its original version." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi @@ -3251,7 +3251,7 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { _checkConf() { _d="$1" _c_file="$2" - _debug "Start _checkConf from:$_c_file" + _debug "Starting _checkConf from: $_c_file" if [ ! -f "$2" ] && ! echo "$2" | grep '*$' >/dev/null && echo "$2" | grep '*' >/dev/null; then _debug "wildcard" for _w_f in $2; do @@ -3264,14 +3264,14 @@ _checkConf() { elif [ -f "$2" ]; then _debug "single" if _isRealNginxConf "$1" "$2"; then - _debug "$2 is found." + _debug "$2 found." FOUND_REAL_NGINX_CONF="$2" return 0 fi if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then - _debug "Try include files" + _debug "Trying include files" for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do - _debug "check included $included" + _debug "Checking included $included" if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$2")" _debug "_relpath" "$_relpath" @@ -3347,7 +3347,7 @@ _isRealNginxConf() { #restore all the nginx conf _restoreNginx() { if [ -z "$NGINX_RESTORE_VLIST" ]; then - _debug "No need to restore nginx, skip." + _debug "No need to restore nginx config, skipping." return fi _debug "_restoreNginx" @@ -3362,9 +3362,9 @@ _restoreNginx() { cat "$_ngbackupconf" >"$_ngconf" done - _info "Reload nginx" + _info "Reloading nginx" if ! nginx -s reload >/dev/null; then - _err "It seems that nginx reload error, please report bug." + _err "An error occurred while reloading nginx, please open an issue on $PROJECT." return 1 fi return 0 @@ -3389,7 +3389,7 @@ _clearupdns() { _debug "dns_entries" "$dns_entries" if [ -z "$dns_entries" ]; then - _debug "skip dns." + _debug "Skipping dns." return fi _info "Removing DNS records." @@ -3412,7 +3412,7 @@ _clearupdns() { fi if [ -z "$d_api" ]; then - _info "Not Found domain api file: $d_api" + _info "Domain API file was not found: $d_api" continue fi @@ -3422,21 +3422,21 @@ _clearupdns() { ( if ! . "$d_api"; then - _err "Load file $d_api error. Please check your api file and try again." + _err "Error loading file $d_api. Please check your API file and try again." return 1 fi rmcommand="${_currentRoot}_rm" if ! _exists "$rmcommand"; then - _err "It seems that your api file doesn't define $rmcommand" + _err "It seems that your API file doesn't define $rmcommand" return 1 fi _info "Removing txt: $txt for domain: $txtdomain" if ! $rmcommand "$txtdomain" "$txt"; then - _err "Error removing txt for domain:$txtdomain" + _err "Error removing txt for domain: $txtdomain" return 1 fi - _info "Removed: Success" + _info "Successfully removed" ) done @@ -3446,7 +3446,7 @@ _clearupdns() { _clearupwebbroot() { __webroot="$1" if [ -z "$__webroot" ]; then - _debug "no webroot specified, skip" + _debug "No webroot specified, skipping" return 0 fi @@ -3458,12 +3458,12 @@ _clearupwebbroot() { elif [ "$2" = '3' ]; then _rmpath="$__webroot/.well-known/acme-challenge/$3" else - _debug "Skip for removelevel:$2" + _debug "Skipping for removelevel: $2" fi if [ "$_rmpath" ]; then if [ "$DEBUG" ]; then - _debug "Debugging, skip removing: $_rmpath" + _debug "Debugging, not removing: $_rmpath" else rm -rf "$_rmpath" fi @@ -3484,13 +3484,13 @@ _on_before_issue() { _debug _chk_alt_domains "$_chk_alt_domains" #run pre hook if [ "$_chk_pre_hook" ]; then - _info "Run pre hook:'$_chk_pre_hook'" + _info "Runing pre hook:'$_chk_pre_hook'" if ! ( export Le_Domain="$_chk_main_domain" export Le_Alt="$_chk_alt_domains" cd "$DOMAIN_PATH" && eval "$_chk_pre_hook" ); then - _err "Error when run pre hook." + _err "Error occurred when running pre hook." return 1 fi fi @@ -3515,7 +3515,7 @@ _on_before_issue() { if [ -z "$d" ]; then break fi - _debug "Check for domain" "$d" + _debug "Checking for domain" "$d" _currentRoot="$(_getfield "$_chk_web_roots" $_index)" _debug "_currentRoot" "$_currentRoot" _index=$(_math $_index + 1) @@ -3562,7 +3562,7 @@ _on_before_issue() { if _hasfield "$_chk_web_roots" "apache"; then if ! _setApache; then - _err "set up apache error. Report error to me." + _err "Error setting up Apache. Please open an issue on $PROJECT." return 1 fi else @@ -3579,17 +3579,17 @@ _on_issue_err() { if [ "$LOG_FILE" ]; then _err "Please check log file for more details: $LOG_FILE" else - _err "Please add '--debug' or '--log' to check more details." + _err "Please add '--debug' or '--log' to see more information." _err "See: $_DEBUG_WIKI" fi #run the post hook if [ "$_chk_post_hook" ]; then - _info "Run post hook:'$_chk_post_hook'" + _info "Running post hook: '$_chk_post_hook'" if ! ( cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then - _err "Error when run post hook." + _err "Error encountered while running post hook." return 1 fi fi @@ -3628,7 +3628,7 @@ _on_issue_success() { #run the post hook if [ "$_chk_post_hook" ]; then - _info "Run post hook:'$_chk_post_hook'" + _info "Running post hook:'$_chk_post_hook'" if ! ( export CERT_PATH export CERT_KEY_PATH @@ -3637,14 +3637,14 @@ _on_issue_success() { export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then - _err "Error when run post hook." + _err "Error encountered while running post hook." return 1 fi fi #run renew hook if [ "$_ACME_IS_RENEW" ] && [ "$_chk_renew_hook" ]; then - _info "Run renew hook:'$_chk_renew_hook'" + _info "Running renew hook: '$_chk_renew_hook'" if ! ( export CERT_PATH export CERT_KEY_PATH @@ -3653,7 +3653,7 @@ _on_issue_success() { export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_renew_hook" ); then - _err "Error when run renew hook." + _err "Error encountered while running renew hook." return 1 fi fi @@ -3709,7 +3709,7 @@ _regAccount() { if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if ! _create_account_key "$_reg_length"; then - _err "Create account key error." + _err "Error creating account key." return 1 fi fi @@ -3732,7 +3732,7 @@ _regAccount() { if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then - _info "No EAB credentials found for ZeroSSL, let's get one" + _info "No EAB credentials found for ZeroSSL, let's obtain them" if [ -z "$_email" ]; then _info "$(__green "$PROJECT_NAME is using ZeroSSL as default CA now.")" _info "$(__green "Please update your account with an email address first.")" @@ -3743,20 +3743,20 @@ _regAccount() { _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from ZeroSSL." + _err "Cannot get EAB credentials from ZeroSSL." return 1 fi _secure_debug2 _eabresp "$_eabresp" _eab_id="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then - _err "Can not resolve _eab_id" + _err "Cannot resolve _eab_id" return 1 fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_hmac_key "$_eab_hmac_key" if [ -z "$_eab_hmac_key" ]; then - _err "Can not resolve _eab_hmac_key" + _err "Cannot resolve _eab_hmac_key" return 1 fi _savecaconf CA_EAB_KEY_ID "$_eab_id" @@ -3793,7 +3793,7 @@ _regAccount() { _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then - _err "Register account Error: $response" + _err "Error registering account: $response" return 1 fi @@ -3804,10 +3804,10 @@ _regAccount() { elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then - _info "Already register EAB." + _info "EAB already registered" _eabAlreadyBound=1 else - _err "Register account Error: $response" + _err "Account registration error: $response" return 1 fi @@ -3816,7 +3816,7 @@ _regAccount() { _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" _debug "_accUri" "$_accUri" if [ -z "$_accUri" ]; then - _err "Can not find account id url." + _err "Cannot find account id url." _err "$responseHeaders" return 1 fi @@ -3831,7 +3831,7 @@ _regAccount() { _savecaconf CA_KEY_HASH "$CA_KEY_HASH" if [ "$code" = '403' ]; then - _err "It seems that the account key is already deactivated, please use a new account key." + _err "It seems that the account key has been deactivated, please use a new account key." return 1 fi @@ -3844,7 +3844,7 @@ updateaccount() { _initpath if [ ! -f "$ACCOUNT_KEY_PATH" ]; then - _err "Account key is not found at: $ACCOUNT_KEY_PATH" + _err "Account key not found at: $ACCOUNT_KEY_PATH" return 1 fi @@ -3852,8 +3852,7 @@ updateaccount() { _debug _accUri "$_accUri" if [ -z "$_accUri" ]; then - _err "The account url is empty, please run '--update-account' first to update the account info first," - _err "Then try again." + _err "The account URL is empty, please run '--update-account' first to update the account info, then try again." return 1 fi @@ -3876,7 +3875,7 @@ updateaccount() { echo "$response" >"$ACCOUNT_JSON_PATH" _info "Account update success for $_accUri." else - _info "Error. The account was not updated." + _info "An error occurred and the account was not updated." return 1 fi } @@ -3886,7 +3885,7 @@ deactivateaccount() { _initpath if [ ! -f "$ACCOUNT_KEY_PATH" ]; then - _err "Account key is not found at: $ACCOUNT_KEY_PATH" + _err "Account key not found at: $ACCOUNT_KEY_PATH" return 1 fi @@ -3894,8 +3893,7 @@ deactivateaccount() { _debug _accUri "$_accUri" if [ -z "$_accUri" ]; then - _err "The account url is empty, please run '--update-account' first to update the account info first," - _err "Then try again." + _err "The account URL is empty, please run '--update-account' first to update the account info, then try again." return 1 fi @@ -3907,13 +3905,13 @@ deactivateaccount() { _djson="{\"status\":\"deactivated\"}" if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then - _info "Deactivate account success for $_accUri." + _info "Successfully deactivated account $_accUri." _accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,') elif [ "$code" = "403" ]; then _info "The account is already deactivated." _accid=$(_getfield "$_accUri" "999" "/") else - _err "Deactivate: account failed for $_accUri." + _err "Account deactivation failed for $_accUri." return 1 fi @@ -3927,7 +3925,7 @@ deactivateaccount() { mv "$ACCOUNT_JSON_PATH" "$_deactivated_account_path/" mv "$ACCOUNT_KEY_PATH" "$_deactivated_account_path/" else - _err "Can not create dir: $_deactivated_account_path, try to remove the deactivated account key." + _err "Cannot create dir: $_deactivated_account_path, try to remove the deactivated account key." rm -f "$CA_CONF" rm -f "$ACCOUNT_JSON_PATH" rm -f "$ACCOUNT_KEY_PATH" @@ -3970,28 +3968,28 @@ __get_domain_new_authz() { _Max_new_authz_retry_times=5 _authz_i=0 while [ "$_authz_i" -lt "$_Max_new_authz_retry_times" ]; do - _debug "Try new-authz for the $_authz_i time." + _debug "Trying new-authz, attempt number $_authz_i." if ! _send_signed_request "${ACME_NEW_AUTHZ}" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$(_idn "$_gdnd")\"}}"; then - _err "Can not get domain new authz." + _err "Cannot get new authz for domain." return 1 fi if _contains "$response" "No registration exists matching provided key"; then - _err "It seems there is an error, but it's recovered now, please try again." - _err "If you see this message for a second time, please report bug: $(__green "$PROJECT")" + _err "There has been an error, but it might now be resolved, please try again." + _err "If you see this message for a second time, please report this as a bug: $(__green "$PROJECT")" _clearcaconf "CA_KEY_HASH" break fi if ! _contains "$response" "An error occurred while processing your request"; then - _info "The new-authz request is ok." + _info "new-authz request successful." break fi _authz_i="$(_math "$_authz_i" + 1)" - _info "The server is busy, Sleep $_authz_i to retry." + _info "The server is busy, sleeping for $_authz_i seconds and retrying." _sleep "$_authz_i" done if [ "$_authz_i" = "$_Max_new_authz_retry_times" ]; then - _err "new-authz retry reach the max $_Max_new_authz_retry_times times." + _err "new-authz has been retried $_Max_new_authz_retry_times times, stopping." fi if [ "$code" ] && [ "$code" != '201' ]; then @@ -4047,7 +4045,7 @@ _ns_lookup_cf() { _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" - _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" + _debug "Purging Cloudflare $_cf_d_type record for domain $_cf_d" _cf_purl="https://cloudflare-dns.com/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" @@ -4112,21 +4110,21 @@ _ns_lookup_dp() { _ns_select_doh() { if [ -z "$DOH_USE" ]; then - _debug "Detect dns server first." + _debug "Detecting DNS server first." if _ns_is_available_cf; then - _debug "Use cloudflare doh server" + _debug "Using Cloudflare doh server" export DOH_USE=$DOH_CLOUDFLARE elif _ns_is_available_google; then - _debug "Use google doh server" + _debug "Using Google DOH server" export DOH_USE=$DOH_GOOGLE elif _ns_is_available_ali; then - _debug "Use aliyun doh server" + _debug "Using Aliyun DOH server" export DOH_USE=$DOH_ALI elif _ns_is_available_dp; then - _debug "Use dns pod doh server" + _debug "Using DNS POD DOH server" export DOH_USE=$DOH_DP else - _err "No doh" + _err "No DOH" fi fi } @@ -4143,7 +4141,7 @@ _ns_lookup() { elif [ "$DOH_USE" = "$DOH_DP" ]; then _ns_lookup_dp "$@" else - _err "Unknown doh provider: DOH_USE=$DOH_USE" + _err "Unknown DOH provider: DOH_USE=$DOH_USE" fi } @@ -4169,7 +4167,7 @@ __purge_txt() { if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then _ns_purge_cf "$_p_txtdomain" "TXT" else - _debug "no purge api for this doh api, just sleep 5 secs" + _debug "No purge API for this DOH API, just sleeping for 5 seconds" _sleep 5 fi @@ -4200,17 +4198,17 @@ _check_dns_entries() { _debug "d_api" "$d_api" _info "Checking $d for $aliasDomain" if _contains "$_success_txt" ",$txt,"; then - _info "Already success, continue next one." + _info "Already succeeded, continuing." continue fi if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then - _info "Domain $d '$aliasDomain' success." + _info "Success for domain $d '$aliasDomain'." _success_txt="$_success_txt,$txt," continue fi _left=1 - _info "Not valid yet, let's wait 10 seconds and check next one." + _info "Not valid yet, let's wait for 10 seconds then check the next one." __purge_txt "$txtdomain" if [ "$txtdomain" != "$aliasDomain" ]; then __purge_txt "$aliasDomain" @@ -4218,10 +4216,10 @@ _check_dns_entries() { _sleep 10 done if [ "$_left" ]; then - _info "Let's wait 10 seconds and check again". + _info "Let's wait for 10 seconds and check again". _sleep 10 else - _info "All success, let's return" + _info "All checks succeeded" return 0 fi done @@ -4337,14 +4335,14 @@ _convertValidaty() { elif _endswith "$_dateTo" "d"; then _v_end=$(_math "$_v_begin + 60 * 60 * 24 * $(echo "$_dateTo" | tr -d '+d')") else - _err "Not recognized format for _dateTo: $_dateTo" + _err "Unrecognized format for _dateTo: $_dateTo" return 1 fi _debug2 "_v_end" "$_v_end" _time2str "$_v_end" else if [ "$(_time)" -gt "$(_date2time "$_dateTo")" ]; then - _err "The validaty to is in the past: _dateTo = $_dateTo" + _err "The validity end date is in the past: _dateTo = $_dateTo" return 1 fi echo "$_dateTo" @@ -4408,7 +4406,7 @@ issue() { _valid_to_saved=$(_readdomainconf Le_Valid_to) if [ "$_valid_to_saved" ] && ! _startswith "$_valid_to_saved" "+"; then _info "The domain is set to be valid to: $_valid_to_saved" - _info "It can not be renewed automatically" + _info "It cannot be renewed automatically" _info "See: $_VALIDITY_WIKI" return $RENEW_SKIP fi @@ -4424,8 +4422,8 @@ issue() { if [ "$_normized_saved_domains" = "$_normized_domains" ]; then _info "Domains not changed." - _info "Skip, Next renewal time is: $(__green "$(_readdomainconf Le_NextRenewTimeStr)")" - _info "Add '$(__red '--force')' to force to renew." + _info "Skipping. Next renewal time is: $(__green "$(_readdomainconf Le_NextRenewTimeStr)")" + _info "Add '$(__red '--force')' to force renewal." return $RENEW_SKIP else _info "Domains have changed." @@ -4484,7 +4482,7 @@ issue() { return 1 fi else - _debug "_saved_account_key_hash is not changed, skip register account." + _debug "_saved_account_key_hash was not changed, skipping account registration." fi export Le_Next_Domain_Key="$CERT_KEY_PATH.next" @@ -4498,15 +4496,15 @@ issue() { if [ -z "$_key" ]; then _key=2048 fi - _debug "Read key length:$_key" + _debug "Read key length: $_key" if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then if [ "$Le_ForceNewDomainKey" = "1" ] && [ -f "$Le_Next_Domain_Key" ]; then - _info "Using pre generated key: $Le_Next_Domain_Key" + _info "Using pre-generated key: $Le_Next_Domain_Key" cat "$Le_Next_Domain_Key" >"$CERT_KEY_PATH" echo "" >"$Le_Next_Domain_Key" else if ! createDomainKey "$_main_domain" "$_key_length"; then - _err "Create domain key error." + _err "Error creating domain key." _clearup _on_issue_err "$_post_hook" return 1 @@ -4514,18 +4512,18 @@ issue() { fi fi if [ "$Le_ForceNewDomainKey" ]; then - _info "Generate next pre-generate key." + _info "Generating next pre-generate key." if [ ! -e "$Le_Next_Domain_Key" ]; then touch "$Le_Next_Domain_Key" chmod 600 "$Le_Next_Domain_Key" fi if ! _createkey "$_key_length" "$Le_Next_Domain_Key"; then - _err "Can not pre generate domain key" + _err "Cannot pre-generate domain key" return 1 fi fi if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then - _err "Create CSR error." + _err "Error creating CSR." _clearup _on_issue_err "$_post_hook" return 1 @@ -4561,7 +4559,7 @@ issue() { _debug2 "_valid_from" "$_valid_from" _notBefore="$(_convertValidaty "" "$_valid_from")" if [ "$?" != "0" ]; then - _err "Can not parse _valid_from: $_valid_from" + _err "Cannot parse _valid_from: $_valid_from" return 1 fi if [ "$(_time)" -gt "$(_date2time "$_notBefore")" ]; then @@ -4577,7 +4575,7 @@ issue() { _savedomainconf "Le_Valid_To" "$_valid_to" _notAfter="$(_convertValidaty "$_notBefore" "$_valid_to")" if [ "$?" != "0" ]; then - _err "Can not parse _valid_to: $_valid_to" + _err "Cannot parse _valid_to: $_valid_to" return 1 fi else @@ -4594,7 +4592,7 @@ issue() { fi _debug "STEP 1, Ordering a Certificate" if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then - _err "Create new order error." + _err "Error creating new order." _clearup _on_issue_err "$_post_hook" return 1 @@ -4614,7 +4612,7 @@ issue() { Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_OrderFinalize "$Le_OrderFinalize" if [ -z "$Le_OrderFinalize" ]; then - _err "Create new order error. Le_OrderFinalize not found. $response" + _err "Error creating new order. Le_OrderFinalize not found. $response" _clearup _on_issue_err "$_post_hook" return 1 @@ -4638,7 +4636,7 @@ issue() { for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do _debug2 "_authz_url" "$_authz_url" if ! _send_signed_request "$_authz_url"; then - _err "get to authz error." + _err "Error getting authz." _err "_authorizations_seg" "$_authorizations_seg" _err "_authz_url" "$_authz_url" _err "$response" @@ -4711,7 +4709,7 @@ $_authorizations_map" response="$(echo "$_candidates" | sed "s/$_idn_d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then - _err "get to authz error." + _err "Error getting authz." _err "_authorizations_map" "$_authorizations_map" _clearup _on_issue_err "$_post_hook" @@ -4735,10 +4733,10 @@ $_authorizations_map" _debug entry "$entry" if [ -z "$keyauthorization" -a -z "$entry" ]; then - _err "Error, can not get domain token entry $d for $vtype" + _err "Cannot get domain token entry $d for $vtype" _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + _err "Supported validation types are: $_supported_vtypes, but you specified: $vtype" fi _clearup _on_issue_err "$_post_hook" @@ -4750,7 +4748,7 @@ $_authorizations_map" _debug token "$token" if [ -z "$token" ]; then - _err "Error, can not get domain token $entry" + _err "Cannot get domain token $entry" _clearup _on_issue_err "$_post_hook" return 1 @@ -4761,7 +4759,7 @@ $_authorizations_map" _debug uri "$uri" if [ -z "$uri" ]; then - _err "Error, can not get domain uri. $entry" + _err "Cannot get domain URI $entry" _clearup _on_issue_err "$_post_hook" return 1 @@ -4790,7 +4788,7 @@ $_authorizations_map" _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) _debug d "$d" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _debug "$d is already verified, skip $vtype." + _debug "$d has already been verified, skipping $vtype." _alias_index="$(_math "$_alias_index" + 1)" continue fi @@ -4827,37 +4825,37 @@ $_authorizations_map" dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api" _debug2 dns_entry "$dns_entry" if [ "$d_api" ]; then - _debug "Found domain api file: $d_api" + _debug "Found domain API file: $d_api" else if [ "$_currentRoot" != "$W_DNS" ]; then - _err "Can not find dns api hook for: $_currentRoot" - _info "You need to add the txt record manually." + _err "Cannot find DNS API hook for: $_currentRoot" + _info "You need to add the TXT record manually." fi _info "$(__red "Add the following TXT record:")" _info "$(__red "Domain: '$(__green "$txtdomain")'")" _info "$(__red "TXT value: '$(__green "$txt")'")" - _info "$(__red "Please be aware that you prepend _acme-challenge. before your domain")" - _info "$(__red "so the resulting subdomain will be: $txtdomain")" + _info "$(__red "Please make sure to prepend '_acme-challenge.' to your domain")" + _info "$(__red "so that the resulting subdomain is: $txtdomain")" continue fi ( if ! . "$d_api"; then - _err "Load file $d_api error. Please check your api file and try again." + _err "Error loading file $d_api. Please check your API file and try again." return 1 fi addcommand="${_currentRoot}_add" if ! _exists "$addcommand"; then - _err "It seems that your api file is not correct, it must have a function named: $addcommand" + _err "It seems that your API file is incorrect. Make sure it has a function named: $addcommand" return 1 fi - _info "Adding txt value: $txt for domain: $txtdomain" + _info "Adding TXT value: $txt for domain: $txtdomain" if ! $addcommand "$txtdomain" "$txt"; then - _err "Error add txt for domain:$txtdomain" + _err "Error adding TXT record to domain: $txtdomain" return 1 fi - _info "The txt record is added: Success." + _info "The TXT record has been successfully added." ) if [ "$?" != "0" ]; then @@ -4874,7 +4872,7 @@ $_authorizations_map" if [ "$dnsadded" = '0' ]; then _savedomainconf "Le_Vlist" "$vlist" - _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit." + _debug "DNS record not yet added. Will save to $DOMAIN_CONF and exit." _err "Please add the TXT records to the domains, and re-run with --renew." _on_issue_err "$_post_hook" _clearup @@ -4887,23 +4885,23 @@ $_authorizations_map" if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - _info "Let's check each DNS record now. Sleep 20 seconds first." + _info "Let's check each DNS record now. Sleeping for 20 seconds first." _sleep 20 if ! _check_dns_entries; then - _err "check dns error." + _err "Error checking DNS." _on_issue_err "$_post_hook" _clearup return 1 fi else _savedomainconf "Le_DNSSleep" "$Le_DNSSleep" - _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" + _info "Sleeping for $(__green $Le_DNSSleep) seconds to wait for the the TXT records to take effect" _sleep "$Le_DNSSleep" fi fi NGINX_RESTORE_VLIST="" - _debug "ok, let's start to verify" + _debug "OK, let's start verification" _ncIndex=1 ventries=$(echo "$vlist" | tr "$dvsep" ' ') @@ -4915,7 +4913,7 @@ $_authorizations_map" _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _info "$d is already verified, skip $vtype." + _info "$d is already verified, skipping $vtype." continue fi @@ -4943,10 +4941,10 @@ $_authorizations_map" sleep 1 _debug serverproc "$serverproc" elif [ "$_currentRoot" = "$MODE_STATELESS" ]; then - _info "Stateless mode for domain:$d" + _info "Stateless mode for domain: $d" _sleep 1 elif _startswith "$_currentRoot" "$NGINX"; then - _info "Nginx mode for domain:$d" + _info "Nginx mode for domain: $d" #set up nginx server FOUND_REAL_NGINX_CONF="" BACKUP_NGINX_CONF="" @@ -4979,26 +4977,26 @@ $_authorizations_map" _debug wellknown_path "$wellknown_path" - _debug "writing token:$token to $wellknown_path/$token" + _debug "Writing token: $token to $wellknown_path/$token" mkdir -p "$wellknown_path" if ! printf "%s" "$keyauthorization" >"$wellknown_path/$token"; then - _err "$d:Can not write token to file : $wellknown_path/$token" + _err "$d: Cannot write token to file: $wellknown_path/$token" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" return 1 fi if ! chmod a+r "$wellknown_path/$token"; then - _debug "chmod failed, but we just continue." + _debug "chmod failed, will just continue." fi fi elif [ "$vtype" = "$VTYPE_ALPN" ]; then acmevalidationv1="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" _debug acmevalidationv1 "$acmevalidationv1" if ! _starttlsserver "$d" "" "$Le_TLSPort" "$keyauthorization" "$_ncaddr" "$acmevalidationv1"; then - _err "Start tls server error." + _err "Error starting TLS server." _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5007,7 +5005,7 @@ $_authorizations_map" fi if ! __trigger_validation "$uri" "$keyauthorization" "$vtype"; then - _err "$d:Can not get challenge: $response" + _err "$d: Cannot get challenge: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5016,9 +5014,9 @@ $_authorizations_map" if [ "$code" ] && [ "$code" != '202' ]; then if [ "$code" = '200' ]; then - _debug "trigger validation code: $code" + _debug "Trigger validation code: $code" else - _err "$d:Challenge error: $response" + _err "$d: Challenge error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5031,11 +5029,11 @@ $_authorizations_map" MAX_RETRY_TIMES=30 fi - _debug "Lets check the status of the authz" + _debug "Let's check the authz status" while true; do waittimes=$(_math "$waittimes" + 1) if [ "$waittimes" -ge "$MAX_RETRY_TIMES" ]; then - _err "$d:Timeout" + _err "$d: Timeout" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5055,13 +5053,13 @@ $_authorizations_map" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" _debug2 errordetail "$errordetail" if [ "$errordetail" ]; then - _err "Invalid status, $d:Verify error detail:$errordetail" + _err "$d: Invalid status. Verification error details: $errordetail" else - _err "Invalid status, $d:Verify error:$error" + _err "$d: Invalid status, Verification error: $error" fi if [ "$DEBUG" ]; then if [ "$vtype" = "$VTYPE_HTTP" ]; then - _debug "Debug: get token url." + _debug "Debug: GET token URL." _get "http://$d/.well-known/acme-challenge/$token" "" 1 fi fi @@ -5080,24 +5078,24 @@ $_authorizations_map" fi if _contains "$status" "pending"; then - _info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" + _info "Pending. The CA is processing your order, please wait. ($waittimes/$MAX_RETRY_TIMES)" elif _contains "$status" "processing"; then - _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" + _info "Processing. The CA is processing your order, please wait. ($waittimes/$MAX_RETRY_TIMES)" else - _err "Unknown status: $status, $d:Verify error:$response" + _err "$d: Unknown status: $status. Verification error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" return 1 fi - _debug "sleep 2 secs to verify again" + _debug "Sleep 2 seconds before verifying again" _sleep 2 - _debug "checking" + _debug "Checking" _send_signed_request "$_authz_url" if [ "$?" != "0" ]; then - _err "Invalid code, $d:Verify error:$response" + _err "$d: Invalid code. Verification error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5108,18 +5106,18 @@ $_authorizations_map" done _clearup - _info "Verify finished, start to sign." + _info "Verification finished, beginning signing." der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" - _info "Lets finalize the order." + _info "Let's finalize the order." _info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then - _err "Sign failed." + _err "Signing failed." _on_issue_err "$_post_hook" return 1 fi if [ "$code" != "200" ]; then - _err "Sign failed, finalize code is not 200." + _err "Signing failed. Finalize code was not 200." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5138,38 +5136,38 @@ $_authorizations_map" Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_LinkCert "$Le_LinkCert" if [ -z "$Le_LinkCert" ]; then - _err "Sign error, can not find Le_LinkCert" + _err "A signing error occurred: could not find Le_LinkCert" _err "$response" _on_issue_err "$_post_hook" return 1 fi break elif _contains "$response" "\"processing\""; then - _info "Order status is processing, lets sleep and retry." + _info "Order status is 'processing', let's sleep and retry." _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') _debug "_retryafter" "$_retryafter" if [ "$_retryafter" ]; then - _info "Retry after: $_retryafter" + _info "Sleeping for $_retryafter seconds then retrying" _sleep $_retryafter else _sleep 2 fi else - _err "Sign error, wrong status" + _err "Signing error: wrong status" _err "$response" _on_issue_err "$_post_hook" return 1 fi #the order is processing, so we are going to poll order status if [ -z "$Le_LinkOrder" ]; then - _err "Sign error, can not get order link location header" + _err "Signing error: could not get order link location header" _err "responseHeaders" "$responseHeaders" _on_issue_err "$_post_hook" return 1 fi _info "Polling order status: $Le_LinkOrder" if ! _send_signed_request "$Le_LinkOrder"; then - _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." + _err "Signing failed. Could not make POST request to Le_LinkOrder for cert: $Le_LinkOrder." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5178,7 +5176,7 @@ $_authorizations_map" done if [ -z "$Le_LinkCert" ]; then - _err "Sign failed, can not get Le_LinkCert, retry time limit." + _err "Signing failed. Could not get Le_LinkCert, and stopped retrying after reaching the retry limit." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5186,7 +5184,7 @@ $_authorizations_map" _info "Downloading cert." _info "Le_LinkCert" "$Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then - _err "Sign failed, can not download cert:$Le_LinkCert." + _err "Signing failed. Could not download cert: $Le_LinkCert." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5199,15 +5197,15 @@ $_authorizations_map" fi if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then if [ "$DEBUG" ]; then - _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + _debug "Default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" for rel in $rels; do - _info "Try rel: $rel" + _info "Trying rel: $rel" if ! _send_signed_request "$rel"; then - _err "Sign failed, can not download cert:$rel" + _err "Signing failed, could not download cert: $rel" _err "$response" continue fi @@ -5241,7 +5239,7 @@ $_authorizations_map" if [ -z "$Le_LinkCert" ] || ! _checkcert "$CERT_PATH"; then response="$(echo "$response" | _dbase64 "multiline" | tr -d '\0' | _normalizeJson)" - _err "Sign failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')" + _err "Signing failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')" _on_issue_err "$_post_hook" return 1 fi @@ -5263,9 +5261,9 @@ $_authorizations_map" fi [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")" - [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")" + [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full-chain cert is in: $(__green "$CERT_FULLCHAIN_PATH")" if [ "$Le_ForceNewDomainKey" ] && [ -e "$Le_Next_Domain_Key" ]; then - _info "Your pre-generated next key for future cert key change is in: $(__green "$Le_Next_Domain_Key")" + _info "Your pre-generated key for future cert key changes is in: $(__green "$Le_Next_Domain_Key")" fi Le_CertCreateTime=$(_time) @@ -5315,8 +5313,8 @@ $_authorizations_map" Le_NextRenewTime=$(_date2time "$_notAfter") Le_NextRenewTimeStr="$_notAfter" if [ "$_valid_to" ] && ! _startswith "$_valid_to" "+"; then - _info "The domain is set to be valid to: $_valid_to" - _info "It can not be renewed automatically" + _info "The domain is set to be valid until: $_valid_to" + _info "It cannot be renewed automatically" _info "See: $_VALIDITY_WIKI" else _now=$(_time) @@ -5359,7 +5357,7 @@ $_authorizations_map" fi if ! _on_issue_success "$_post_hook" "$_renew_hook"; then - _err "Call hook error." + _err "Error calling hook." return 1 fi } @@ -5395,9 +5393,9 @@ renew() { _initpath "$Le_Domain" "$_isEcc" _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} - _info "$(__green "Renew: '$Le_Domain'")" + _info "$(__green "Renewing: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then - _info "'$Le_Domain' is not an issued domain, skip." + _info "'$Le_Domain' is not an issued domain, skipping." return $RENEW_SKIP fi @@ -5426,7 +5424,7 @@ renew() { if [ "$_server" ]; then Le_API="$_server" fi - _info "Renew to Le_API=$Le_API" + _info "Renewing using Le_API=$Le_API" _clearAPI _clearCA @@ -5437,8 +5435,8 @@ renew() { _initpath "$Le_Domain" "$_isEcc" if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then - _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" - _info "Add '$(__red '--force')' to force to renew." + _info "Skipping. Next renewal time is: $(__green "$Le_NextRenewTimeStr")" + _info "Add '$(__red '--force')' to force renewal." if [ -z "$_ACME_IN_RENEWALL" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then _send_notify "Renew $Le_Domain skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" @@ -5448,7 +5446,7 @@ renew() { fi if [ "$_ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then - _info "Skip invalid cert for: $Le_Domain" + _info "Skipping invalid cert for: $Le_Domain" return $RENEW_SKIP fi @@ -5514,7 +5512,7 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then - _debug "Not a directory, skip: $di" + _debug "Not a directory, skipping: $di" continue fi d=$(basename "$di") @@ -5572,12 +5570,12 @@ renewAll() { _error_msg="${_error_msg} $d " if [ "$_stopRenewOnError" ]; then - _err "Error renew $d, stop now." + _err "Error renewing $d, stopping." _ret="$rc" break else _ret="$rc" - _err "Error renew $d." + _err "Error renewing $d." fi fi done @@ -5588,13 +5586,13 @@ renewAll() { _msg_subject="Renew" if [ "$_error_msg" ]; then _msg_subject="${_msg_subject} Error" - _msg_data="Error certs: + _msg_data="Errored certs: ${_error_msg} " fi if [ "$_success_msg" ]; then _msg_subject="${_msg_subject} Success" - _msg_data="${_msg_data}Success certs: + _msg_data="${_msg_data}Successful certs: ${_success_msg} " fi @@ -5635,18 +5633,18 @@ signcsr() { _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi _debug _csrsubj "$_csrsubj" if _contains "$_csrsubj" ' ' || ! _contains "$_csrsubj" '.'; then - _info "It seems that the subject: $_csrsubj is not a valid domain name. Drop it." + _info "It seems that the subject $_csrsubj is not a valid domain name. Dropping it." _csrsubj="" fi _csrdomainlist=$(_readSubjectAltNamesFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read domain list from csr: $_csrfile" + _err "Cannot read domain list from CSR: $_csrfile" return 1 fi _debug "_csrdomainlist" "$_csrdomainlist" @@ -5659,20 +5657,20 @@ signcsr() { fi if [ -z "$_csrsubj" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi _csrkeylength=$(_readKeyLengthFromCSR "$_csrfile") if [ "$?" != "0" ] || [ -z "$_csrkeylength" ]; then - _err "Can not read key length from csr: $_csrfile" + _err "Cannot read key length from CSR: $_csrfile" return 1 fi _initpath "$_csrsubj" "$_csrkeylength" mkdir -p "$DOMAIN_PATH" - _info "Copy csr to: $CSR_PATH" + _info "Copying CSR to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" @@ -5691,18 +5689,18 @@ showcsr() { _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi if [ -z "$_csrsubj" ]; then - _info "The Subject is empty" + _info "The subject is empty" fi _info "Subject=$_csrsubj" _csrdomainlist=$(_readSubjectAltNamesFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read domain list from csr: $_csrfile" + _err "Cannot read domain list from CSR: $_csrfile" return 1 fi _debug "_csrdomainlist" "$_csrdomainlist" @@ -5711,7 +5709,7 @@ showcsr() { _csrkeylength=$(_readKeyLengthFromCSR "$_csrfile") if [ "$?" != "0" ] || [ -z "$_csrkeylength" ]; then - _err "Can not read key length from csr: $_csrfile" + _err "Cannot read key length from CSR: $_csrfile" return 1 fi _info "KeyLength=$_csrkeylength" @@ -5767,29 +5765,29 @@ _deploy() { for _d_api in $(echo "$_hooks" | tr ',' " "); do _deployApi="$(_findHook "$_d" $_SUB_FOLDER_DEPLOY "$_d_api")" if [ -z "$_deployApi" ]; then - _err "The deploy hook $_d_api is not found." + _err "The deploy hook $_d_api was not found." return 1 fi _debug _deployApi "$_deployApi" if ! ( if ! . "$_deployApi"; then - _err "Load file $_deployApi error. Please check your api file and try again." + _err "Error loading file $_deployApi. Please check your API file and try again." return 1 fi d_command="${_d_api}_deploy" if ! _exists "$d_command"; then - _err "It seems that your api file is not correct, it must have a function named: $d_command" + _err "It seems that your API file is not correct. Make sure it has a function named: $d_command" return 1 fi if ! $d_command "$_d" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$CERT_FULLCHAIN_PATH"; then - _err "Error deploy for domain:$_d" + _err "Error deploying for domain: $_d" return 1 fi ); then - _err "Deploy error." + _err "Error encountered while deploying." return 1 else _info "$(__green Success)" @@ -5810,7 +5808,7 @@ deploy() { _initpath "$_d" "$_isEcc" if [ ! -d "$DOMAIN_PATH" ]; then _err "The domain '$_d' is not a cert name. You must use the cert name to specify the cert to install." - _err "Can not find path:'$DOMAIN_PATH'" + _err "Cannot find path: '$DOMAIN_PATH'" return 1 fi @@ -5839,7 +5837,7 @@ installcert() { _initpath "$_main_domain" "$_isEcc" if [ ! -d "$DOMAIN_PATH" ]; then _err "The domain '$_main_domain' is not a cert name. You must use the cert name to specify the cert to install." - _err "Can not find path:'$DOMAIN_PATH'" + _err "Cannot find path: '$DOMAIN_PATH'" return 1 fi @@ -5934,7 +5932,7 @@ _installcert() { fi if [ "$_reload_cmd" ]; then - _info "Run reload cmd: $_reload_cmd" + _info "Running reload cmd: $_reload_cmd" if ( export CERT_PATH export CERT_KEY_PATH @@ -5945,9 +5943,9 @@ _installcert() { export Le_Next_Domain_Key cd "$DOMAIN_PATH" && eval "$_reload_cmd" ); then - _info "$(__green "Reload success")" + _info "$(__green "Reload successful")" else - _err "Reload error for :$Le_Domain" + _err "Reload error for: $Le_Domain" fi fi @@ -5975,25 +5973,25 @@ _install_win_taskscheduler() { return 1 fi if ! _exists schtasks; then - _err "schtasks.exe is not found, are you on Windows?" + _err "schtasks.exe was not found, are you on Windows?" return 1 fi _winbash="$(cygpath -w $(which bash))" _debug _winbash "$_winbash" if [ -z "$_winbash" ]; then - _err "can not find bash path" + _err "Cannot find bash path" return 1 fi _myname="$(whoami)" _debug "_myname" "$_myname" if [ -z "$_myname" ]; then - _err "can not find my user name" + _err "Can not find own username" return 1 fi _debug "_lesh" "$_lesh" - _info "To install scheduler task in your Windows account, you must input your windows password." - _info "$PROJECT_NAME doesn't save your password." + _info "To install the scheduler task to your Windows account, you must input your Windows password." + _info "$PROJECT_NAME will not save your password." _info "Please input your Windows password for: $(__green "$_myname")" _password="$(__read_password)" #SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'" >/dev/null @@ -6004,11 +6002,11 @@ _install_win_taskscheduler() { _uninstall_win_taskscheduler() { if ! _exists schtasks; then - _err "schtasks.exe is not found, are you on Windows?" + _err "schtasks.exe was not found, are you on Windows?" return 1 fi if ! echo SCHTASKS /query /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null; then - _debug "scheduler $_WINDOWS_SCHEDULER_NAME is not found." + _debug "scheduler $_WINDOWS_SCHEDULER_NAME was not found." else _info "Removing $_WINDOWS_SCHEDULER_NAME" echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null @@ -6027,10 +6025,10 @@ installcronjob() { _script="$(_readlink "$_SCRIPT_")" _debug _script "$_script" if [ -f "$_script" ]; then - _info "Using the current script from: $_script" + _info "Usinging the current script from: $_script" lesh="$_script" else - _err "Can not install cronjob, $PROJECT_ENTRY not found." + _err "Cannot install cronjob, $PROJECT_ENTRY not found." return 1 fi fi @@ -6047,18 +6045,18 @@ installcronjob() { if ! _exists "$_CRONTAB"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, let's install Windows scheduler task." + _info "It seems you are on Windows, let's install the Windows scheduler task." if _install_win_taskscheduler "$lesh" "$_c_entry" "$random_minute"; then - _info "Install Windows scheduler task success." + _info "Successfully installed Windows scheduler task." return 0 else - _err "Install Windows scheduler task failed." + _err "Failed to install Windows scheduler task." return 1 fi fi - _err "crontab/fcrontab doesn't exist, so, we can not install cron jobs." - _err "All your certs will not be renewed automatically." - _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday." + _err "crontab/fcrontab doesn't exist, so we cannot install cron jobs." + _err "Your certs will not be renewed automatically." + _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' every day." return 1 fi _info "Installing cron job" @@ -6074,8 +6072,8 @@ installcronjob() { } | $_CRONTAB_STDIN fi if [ "$?" != "0" ]; then - _err "Install cron job failed. You need to manually renew your certs." - _err "Or you can add cronjob by yourself:" + _err "Failed to install cron job. You need to manually renew your certs." + _err "Alternatively, you can add a cron job by yourself:" _err "$lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" return 1 fi @@ -6089,12 +6087,12 @@ uninstallcronjob() { if ! _exists "$_CRONTAB"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, let's uninstall Windows scheduler task." + _info "It seems you are on Windows, let's uninstall the Windows scheduler task." if _uninstall_win_taskscheduler; then - _info "Uninstall Windows scheduler task success." + _info "Successfully uninstalled Windows scheduler task." return 0 else - _err "Uninstall Windows scheduler task failed." + _err "Failed to uninstall Windows scheduler task." return 1 fi fi @@ -6134,12 +6132,12 @@ revoke() { fi _initpath "$Le_Domain" "$_isEcc" if [ ! -f "$DOMAIN_CONF" ]; then - _err "$Le_Domain is not a issued domain, skip." + _err "$Le_Domain is not an issued domain, skipping." return 1 fi if [ ! -f "$CERT_PATH" ]; then - _err "Cert for $Le_Domain $CERT_PATH is not found, skip." + _err "Cert for $Le_Domain $CERT_PATH was not found, skipping." return 1 fi @@ -6163,7 +6161,7 @@ revoke() { cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then - _err "Cert for $Le_Domain is empty found, skip." + _err "Cert for $Le_Domain is empty, skipping." return 1 fi @@ -6173,31 +6171,31 @@ revoke() { uri="${ACME_REVOKE_CERT}" - _info "Try account key first." + _info "Trying account key first." if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then if [ -z "$response" ]; then - _info "Revoke success." + _info "Successfully revoked." rm -f "$CERT_PATH" cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else - _err "Revoke error." + _err "Error revoking." _debug "$response" fi fi if [ -f "$CERT_KEY_PATH" ]; then - _info "Try domain key." + _info "Trying domain key." if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then if [ -z "$response" ]; then - _info "Revoke success." + _info "Successfully revoked." rm -f "$CERT_PATH" cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else - _err "Revoke error by domain key." + _err "Error revoking using domain key." _err "$response" fi fi @@ -6221,19 +6219,19 @@ remove() { _removed_conf="$DOMAIN_CONF.removed" if [ ! -f "$DOMAIN_CONF" ]; then if [ -f "$_removed_conf" ]; then - _err "$Le_Domain is already removed, You can remove the folder by yourself: $DOMAIN_PATH" + _err "$Le_Domain has already been removed. You can remove the folder by yourself: $DOMAIN_PATH" else - _err "$Le_Domain is not a issued domain, skip." + _err "$Le_Domain is not an issued domain, skipping." fi return 1 fi if mv "$DOMAIN_CONF" "$_removed_conf"; then - _info "$Le_Domain is removed, the key and cert files are in $(__green $DOMAIN_PATH)" + _info "$Le_Domain has been removed. The key and cert files are in $(__green $DOMAIN_PATH)" _info "You can remove them by yourself." return 0 else - _err "Remove $Le_Domain failed." + _err "Failed to remove $Le_Domain." return 1 fi } @@ -6263,7 +6261,7 @@ _deactivate() { _identifiers="{\"type\":\"$(_getIdType "$_d_domain")\",\"value\":\"$_d_domain\"}" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then - _err "Can not get domain new order." + _err "Cannot get new order for domain." return 1 fi _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" @@ -6278,7 +6276,7 @@ _deactivate() { authzUri="$_authorizations_seg" _debug2 "authzUri" "$authzUri" if ! _send_signed_request "$authzUri"; then - _err "get to authz error." + _err "Error making GET request for authz." _err "_authorizations_seg" "$_authorizations_seg" _err "authzUri" "$authzUri" _clearup @@ -6301,7 +6299,7 @@ _deactivate() { entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then - _err "Error, can not get domain token $d" + _err "$d: Cannot get domain token" return 1 fi token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" @@ -6319,13 +6317,13 @@ _deactivate() { _d_i=0 _d_max_retry=$(echo "$entries" | wc -l) while [ "$_d_i" -lt "$_d_max_retry" ]; do - _info "Deactivate: $_d_domain" + _info "Deactivating $_d_domain" _d_i="$(_math $_d_i + 1)" entry="$(echo "$entries" | sed -n "${_d_i}p")" _debug entry "$entry" if [ -z "$entry" ]; then - _info "No more valid entry found." + _info "No more valid entries found." break fi @@ -6337,27 +6335,27 @@ _deactivate() { _debug uri "$uri" if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then - _info "Skip $_vtype" + _info "Skipping $_vtype" continue fi - _info "Deactivate: $_vtype" + _info "Deactivating $_vtype" _djson="{\"status\":\"deactivated\"}" if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then - _info "Deactivate: $_vtype success." + _info "Successfully deactivated $_vtype." else - _err "Can not deactivate $_vtype." + _err "Could not deactivate $_vtype." break fi done _debug "$_d_i" if [ "$_d_i" -eq "$_d_max_retry" ]; then - _info "Deactivated success!" + _info "Successfully deactivated!" else - _err "Deactivate failed." + _err "Deactivation failed." fi } @@ -6438,17 +6436,17 @@ _precheck() { _nocron="$1" if ! _exists "curl" && ! _exists "wget"; then - _err "Please install curl or wget first, we need to access http resources." + _err "Please install curl or wget first to enable access to HTTP resources." return 1 fi if [ -z "$_nocron" ]; then if ! _exists "crontab" && ! _exists "fcrontab"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, we will install Windows scheduler task." + _info "It seems you are on Windows, we will install the Windows scheduler task." else - _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." - _err "We need to set cron job to renew the certs automatically." + _err "It is recommended to install crontab first. Try to install 'cron', 'crontab', 'crontabs' or 'vixie-cron'." + _err "We need to set a cron job to renew the certs automatically." _err "Otherwise, your certs will not be able to be renewed automatically." if [ -z "$FORCE" ]; then _err "Please add '--force' and try install again to go without crontab." @@ -6467,8 +6465,8 @@ _precheck() { if ! _exists "socat"; then _err "It is recommended to install socat first." - _err "We use socat for standalone server if you use standalone mode." - _err "If you don't use standalone mode, just ignore this warning." + _err "We use socat for the standalone server, which is used for standalone mode." + _err "If you don't want to use standalone mode, you may ignore this warning." fi return 0 @@ -6516,9 +6514,9 @@ _installalias() { _debug "Found profile: $_profile" _info "Installing alias to '$_profile'" _setopt "$_profile" ". \"$_envfile\"" - _info "OK, Close and reopen your terminal to start using $PROJECT_NAME" + _info "Close and reopen your terminal to start using $PROJECT_NAME" else - _info "No profile is found, you will need to go into $LE_WORKING_DIR to use $PROJECT_NAME" + _info "No profile has been found, you will need to change your working directory to $LE_WORKING_DIR to use $PROJECT_NAME" fi #for csh @@ -6567,12 +6565,12 @@ install() { return 1 fi if [ "$_nocron" ]; then - _debug "Skip install cron job" + _debug "Skipping cron job installation" fi if [ "$_ACME_IN_CRON" != "1" ]; then if ! _precheck "$_nocron"; then - _err "Pre-check failed, can not install." + _err "Pre-check failed, cannot install." return 1 fi fi @@ -6602,7 +6600,7 @@ install() { if [ ! -d "$LE_WORKING_DIR" ]; then if ! mkdir -p "$LE_WORKING_DIR"; then - _err "Can not create working dir: $LE_WORKING_DIR" + _err "Cannot create working dir: $LE_WORKING_DIR" return 1 fi @@ -6611,7 +6609,7 @@ install() { if [ ! -d "$LE_CONFIG_HOME" ]; then if ! mkdir -p "$LE_CONFIG_HOME"; then - _err "Can not create config dir: $LE_CONFIG_HOME" + _err "Cannot create config dir: $LE_CONFIG_HOME" return 1 fi @@ -6621,7 +6619,7 @@ install() { cp "$PROJECT_ENTRY" "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/$PROJECT_ENTRY" if [ "$?" != "0" ]; then - _err "Install failed, can not copy $PROJECT_ENTRY" + _err "Installation failed, cannot copy $PROJECT_ENTRY" return 1 fi @@ -6667,7 +6665,7 @@ install() { fi fi if [ "$_bash_path" ]; then - _info "Good, bash is found, so change the shebang to use bash as preferred." + _info "bash has been found. Changing the shebang to use bash as preferred." _shebang='#!'"$_bash_path" _setShebang "$LE_WORKING_DIR/$PROJECT_ENTRY" "$_shebang" for subf in $_SUB_FOLDERS; do @@ -6698,7 +6696,7 @@ uninstall() { _uninstallalias rm -f "$LE_WORKING_DIR/$PROJECT_ENTRY" - _info "The keys and certs are in \"$(__green "$LE_CONFIG_HOME")\", you can remove them by yourself." + _info "The keys and certs are in \"$(__green "$LE_CONFIG_HOME")\". You can remove them by yourself." } @@ -6736,7 +6734,7 @@ cron() { export LE_WORKING_DIR ( if ! upgrade; then - _err "Cron:Upgrade failed!" + _err "Cron: Upgrade failed!" return 1 fi ) @@ -6746,7 +6744,7 @@ cron() { __INTERACTIVE="1" fi - _info "Auto upgraded to: $VER" + _info "Automatically upgraded to: $VER" fi renewAll _ret="$?" @@ -6768,12 +6766,12 @@ _send_notify() { _nerror="$4" if [ "$NOTIFY_LEVEL" = "$NOTIFY_LEVEL_DISABLE" ]; then - _debug "The NOTIFY_LEVEL is $NOTIFY_LEVEL, disabled, just return." + _debug "The NOTIFY_LEVEL is $NOTIFY_LEVEL, which means it's disabled, so will just return." return 0 fi if [ -z "$_nhooks" ]; then - _debug "The NOTIFY_HOOK is empty, just return." + _debug "The NOTIFY_HOOK is empty, will just return." return 0 fi @@ -6790,29 +6788,29 @@ _send_notify() { _info "Sending via: $_n_hook" _debug "Found $_n_hook_file for $_n_hook" if [ -z "$_n_hook_file" ]; then - _err "Can not find the hook file for $_n_hook" + _err "Cannot find the hook file for $_n_hook" continue fi if ! ( if ! . "$_n_hook_file"; then - _err "Load file $_n_hook_file error. Please check your api file and try again." + _err "Error loading file $_n_hook_file. Please check your API file and try again." return 1 fi d_command="${_n_hook}_send" if ! _exists "$d_command"; then - _err "It seems that your api file is not correct, it must have a function named: $d_command" + _err "It seems that your API file is not correct. Make sure it has a function named: $d_command" return 1 fi if ! $d_command "$_nsubject" "$_ncontent" "$_nerror"; then - _err "Error send message by $d_command" + _err "Error sending message using $d_command" return 1 fi return 0 ); then - _err "Set $_n_hook_file error." + _err "Error setting $_n_hook_file." _send_err=1 else _info "$_n_hook $(__green Success)" @@ -6869,7 +6867,7 @@ setnotify() { if [ "$_nhook" ]; then _info "Set notify hook to: $_nhook" if [ "$_nhook" = "$NO_VALUE" ]; then - _info "Clear notify hook" + _info "Clearing notify hook" _clearaccountconf "NOTIFY_HOOK" else if _set_notify_hook "$_nhook"; then @@ -6877,7 +6875,7 @@ setnotify() { _saveaccountconf "NOTIFY_HOOK" "$NOTIFY_HOOK" return 0 else - _err "Can not set notify hook to: $_nhook" + _err "Cannot set notify hook to: $_nhook" return 1 fi fi @@ -6897,7 +6895,7 @@ Commands: --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. --issue Issue a cert. --deploy Deploy the cert to your server. - -i, --install-cert Install the issued cert to apache/nginx or any other server. + -i, --install-cert Install the issued cert to Apache/nginx or any other server. -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. @@ -6953,7 +6951,7 @@ Parameters: --stateless Use stateless mode. See: $_STATELESS_WIKI - --apache Use apache mode. + --apache Use Apache mode. --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI @@ -6968,7 +6966,7 @@ Parameters: --eab-hmac-key HMAC key for External Account Binding. - These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: + These parameters are to install the cert to nginx/Apache or any other server after issue/renew a cert: --cert-file Path to copy the cert file to after issue/renew. --key-file Path to copy the key file to after issue/renew. @@ -7092,12 +7090,12 @@ _getUpgradeHash() { upgrade() { if ( _initpath - [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 + [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already up to date!" && exit 0 export LE_WORKING_DIR cd "$LE_WORKING_DIR" installOnline "--nocron" "--noprofile" ); then - _info "Upgrade success!" + _info "Upgrade successful!" exit 0 else _err "Upgrade failed!" @@ -7213,7 +7211,7 @@ _getCAShortName() { #set default ca to $ACME_DIRECTORY setdefaultca() { if [ -z "$ACME_DIRECTORY" ]; then - _err "Please give a --server parameter." + _err "Please provide a --server parameter." return 1 fi _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" @@ -7225,7 +7223,7 @@ setdefaultchain() { _initpath _preferred_chain="$1" if [ -z "$_preferred_chain" ]; then - _err "Please give a '--preferred-chain value' value." + _err "Please provide a value for '--preferred-chain'." return 1 fi mkdir -p "$CA_DIR" @@ -7423,7 +7421,7 @@ _process() { return 1 fi if _is_idn "$_dvalue" && ! _exists idn; then - _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." + _err "It seems that $_dvalue is an IDN (Internationalized Domain Names), please install the 'idn' command first." return 1 fi @@ -7785,7 +7783,7 @@ _process() { --notify-level) _nlevel="$2" if _startswith "$_nlevel" "-"; then - _err "'$_nlevel' is not a integer for '$1'" + _err "'$_nlevel' is not an integer for '$1'" return 1 fi _notify_level="$_nlevel" @@ -7794,7 +7792,7 @@ _process() { --notify-mode) _nmode="$2" if _startswith "$_nmode" "-"; then - _err "'$_nmode' is not a integer for '$1'" + _err "'$_nmode' is not an integer for '$1'" return 1 fi _notify_mode="$_nmode" @@ -7803,7 +7801,7 @@ _process() { --notify-source) _nsource="$2" if _startswith "$_nsource" "-"; then - _err "'$_nsource' is not valid host name for '$1'" + _err "'$_nsource' is not a valid host name for '$1'" return 1 fi _notify_source="$_nsource" @@ -7812,7 +7810,7 @@ _process() { --revoke-reason) _revoke_reason="$2" if _startswith "$_revoke_reason" "-"; then - _err "'$_revoke_reason' is not a integer for '$1'" + _err "'$_revoke_reason' is not an integer for '$1'" return 1 fi shift @@ -7830,7 +7828,7 @@ _process() { shift ;; *) - _err "Unknown parameter : $1" + _err "Unknown parameter: $1" return 1 ;; esac @@ -7847,7 +7845,7 @@ _process() { if [ "$__INTERACTIVE" ] && ! _checkSudo; then if [ -z "$FORCE" ]; then #Use "echo" here, instead of _info. it's too early - echo "It seems that you are using sudo, please read this link first:" + echo "It seems that you are using sudo, please read this page first:" echo "$_SUDO_WIKI" return 1 fi @@ -7877,7 +7875,7 @@ _process() { fi SYS_LOG="$_syslog" else - _err "The 'logger' command is not found, can not enable syslog." + _err "The 'logger' command was not found, cannot enable syslog." _clearaccountconf "SYS_LOG" SYS_LOG="" fi @@ -8004,7 +8002,7 @@ _process() { _saveaccountconf "SYS_LOG" "$_syslog" fi else - _err "The 'logger' command is not found, can not enable syslog." + _err "The 'logger' command was not found, cannot enable syslog." _clearaccountconf "SYS_LOG" SYS_LOG="" fi From d81fc155cb01360e273c15447226a415d90aa950 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 14 Jul 2024 13:50:35 +0800 Subject: [PATCH 394/687] add timeout for _getRepoHash https://github.com/acmesh-official/acme.sh/issues/5200 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 7134a633..c3564e68 100755 --- a/acme.sh +++ b/acme.sh @@ -7082,7 +7082,7 @@ _getRepoHash() { _hash_path=$1 shift _hash_url="${PROJECT_API:-https://api.github.com/repos/acmesh-official}/$PROJECT_NAME/git/refs/$_hash_path" - _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 + _get "$_hash_url" "" 30 | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 } _getUpgradeHash() { From 60569fdd8375d5a8f67d3a965e604e494c0d9e0e Mon Sep 17 00:00:00 2001 From: Scruel Tao Date: Sun, 14 Jul 2024 15:04:43 +0800 Subject: [PATCH 395/687] fix(deploy): respect api path with synology Auth API fix #5184 --- deploy/synology_dsm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 342fb32e..b98105c2 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -169,7 +169,7 @@ synology_dsm_deploy() { _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/$api_path?enable_syno_token=yes") _debug3 response "$response" # ## END ## - DEPRECATED, for backward compatibility # If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP. @@ -218,7 +218,7 @@ synology_dsm_deploy() { otp_enforce_option="" fi fi - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") if [ -n "$SYNO_USE_TEMP_ADMIN" ] && [ -n "$otp_enforce_option" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option" _info "Restored previous enforce 2FA-OTP option." From 7ae0d0caa30a882f320028d4e2943ab060b40897 Mon Sep 17 00:00:00 2001 From: allddd <117767298+allddd@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:57:22 +0200 Subject: [PATCH 396/687] dns_porkbun: remove stray backslashes --- dnsapi/dns_porkbun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index c260c898..0a443855 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -93,7 +93,7 @@ dns_porkbun_rm() { _err "Delete record error." return 1 fi - echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null + echo "$response" | tr -d " " | grep '"status":"SUCCESS"' >/dev/null fi } From 37f9fd3498ca9d2138502acf51f6d6787c83398b Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Sat, 20 Jul 2024 05:38:51 +0300 Subject: [PATCH 397/687] The old Yandex DNS API was discontinued #4555 --- dnsapi/dns_yandex.sh | 121 ------------------------------------------- 1 file changed, 121 deletions(-) delete mode 100755 dnsapi/dns_yandex.sh diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh deleted file mode 100755 index d780459f..00000000 --- a/dnsapi/dns_yandex.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env sh -# shellcheck disable=SC2034 -dns_yandex_info='Yandex Domains -Site: tech.Yandex.com/domain/ -Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_yandex -Options: - PDD_Token API Token -Issues: github.com/non7top/acme.sh/issues -Author: -' - -######## Public functions ##################### - -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_yandex_add() { - fulldomain="${1}" - txtvalue="${2}" - _debug "Calling: dns_yandex_add() '${fulldomain}' '${txtvalue}'" - - _PDD_credentials || return 1 - - _PDD_get_domain || return 1 - _debug "Found suitable domain: $domain" - - _PDD_get_record_ids || return 1 - _debug "Record_ids: $record_ids" - - if [ -n "$record_ids" ]; then - _info "All existing $subdomain records from $domain will be removed at the very end." - fi - - data="domain=${domain}&type=TXT&subdomain=${subdomain}&ttl=300&content=${txtvalue}" - uri="https://pddimp.yandex.ru/api2/admin/dns/add" - result="$(_post "${data}" "${uri}" | _normalizeJson)" - _debug "Result: $result" - - if ! _contains "$result" '"success":"ok"'; then - if _contains "$result" '"success":"error"' && _contains "$result" '"error":"record_exists"'; then - _info "Record already exists." - else - _err "Can't add $subdomain to $domain." - return 1 - fi - fi -} - -#Usage: dns_myapi_rm _acme-challenge.www.domain.com -dns_yandex_rm() { - fulldomain="${1}" - _debug "Calling: dns_yandex_rm() '${fulldomain}'" - - _PDD_credentials || return 1 - - _PDD_get_domain "$fulldomain" || return 1 - _debug "Found suitable domain: $domain" - - _PDD_get_record_ids "${domain}" "${subdomain}" || return 1 - _debug "Record_ids: $record_ids" - - for record_id in $record_ids; do - data="domain=${domain}&record_id=${record_id}" - uri="https://pddimp.yandex.ru/api2/admin/dns/del" - result="$(_post "${data}" "${uri}" | _normalizeJson)" - _debug "Result: $result" - - if ! _contains "$result" '"success":"ok"'; then - _info "Can't remove $subdomain from $domain." - fi - done -} - -#################### Private functions below ################################## - -_PDD_get_domain() { - subdomain_start=1 - while true; do - domain_start=$(_math $subdomain_start + 1) - domain=$(echo "$fulldomain" | cut -d . -f "$domain_start"-) - subdomain=$(echo "$fulldomain" | cut -d . -f -"$subdomain_start") - - _debug "Checking domain $domain" - if [ -z "$domain" ]; then - return 1 - fi - - uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=$domain" - result="$(_get "${uri}" | _normalizeJson)" - _debug "Result: $result" - - if _contains "$result" '"success":"ok"'; then - return 0 - fi - subdomain_start=$(_math $subdomain_start + 1) - done -} - -_PDD_credentials() { - if [ -z "${PDD_Token}" ]; then - PDD_Token="" - _err "You need to export PDD_Token=xxxxxxxxxxxxxxxxx." - _err "You can get it at https://pddimp.yandex.ru/api2/admin/get_token." - return 1 - else - _saveaccountconf PDD_Token "${PDD_Token}" - fi - export _H1="PddToken: $PDD_Token" -} - -_PDD_get_record_ids() { - _debug "Check existing records for $subdomain" - - uri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${domain}" - result="$(_get "${uri}" | _normalizeJson)" - _debug "Result: $result" - - if ! _contains "$result" '"success":"ok"'; then - return 1 - fi - - record_ids=$(echo "$result" | _egrep_o "{[^{]*\"subdomain\":\"${subdomain}\"[^}]*}" | sed -n -e 's#.*"record_id": \([0-9]*\).*#\1#p') -} From f84577bcda887f87c2db944fb54e544a9f0edbda Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Sat, 20 Jul 2024 05:41:54 +0300 Subject: [PATCH 398/687] Support for the Yandex 360 for Business DNS API --- dnsapi/dns_yandex360.sh | 334 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 dnsapi/dns_yandex360.sh diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh new file mode 100644 index 00000000..3e879c52 --- /dev/null +++ b/dnsapi/dns_yandex360.sh @@ -0,0 +1,334 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_yandex360_info='Yandex 360 for Business DNS API. +Yandex 360 for Business is a digital environment for effective collaboration. +Site: https://360.yandex.com/ +Docs: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360 +Options: + YANDEX360_CLIENT_ID OAuth 2.0 ClientID + YANDEX360_CLIENT_SECRET OAuth 2.0 Client secret + YANDEX360_ORG_ID Organization ID +OptionsAlt: + YANDEX360_ACCESS_TOKEN OAuth 2.0 Access token. Optional. +Issues: https://github.com/acmesh-official/acme.sh/issues/5213 +Author: +' + +YANDEX360_API_BASE='https://api360.yandex.net/directory/v1/org' +YANDEX360_OAUTH_BASE='https://oauth.yandex.ru' + +######## Public functions ##################### + +dns_yandex360_add() { + fulldomain=$1 + txtvalue=$2 + _info 'Using Yandex 360 DNS API' + + if ! _check_yandex360_variables; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + sub_domain=$(echo "$fulldomain" | sed "s/\.$root_domain$//") + + _debug 'Adding Yandex 360 DNS record for subdomain' "$sub_domain" + dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns" + data='{"name":"'"$sub_domain"'","type":"TXT","ttl":60,"text":"'"$txtvalue"'"}' + + response="$(_post "$data" "$dns_api_url" '' 'POST' 'application/json')" + response="$(echo "$response" | _normalizeJson)" + _debug 'Response' "$response" + + if _contains "$response" 'recordId'; then + return 0 + else + return 1 + fi +} + +dns_yandex360_rm() { + fulldomain=$1 + txtvalue=$2 + _info 'Using Yandex 360 DNS API' + + if ! _check_yandex360_variables; then + return 1 + fi + + if ! _get_root "$fulldomain"; then + return 1 + fi + + _debug 'Retrieving 100 records from Yandex 360 DNS' + dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns?perPage=100" + response="$(_get "$dns_api_url" '' '')" + response="$(echo "$response" | _normalizeJson)" + _debug 'Response' "$response" + + if ! _contains "$response" "$txtvalue"; then + _info 'DNS record not found. Nothing to remove.' + return 1 + fi + + record_id=$( + echo "$response" | + sed -En 's/.*"recordId":([0-9]+).*"text":"'"${txtvalue}"'".*$/\1/p' + ) + + if [ -z "$record_id" ]; then + _err 'Unable to get record ID to remove' + return 1 + fi + + _debug 'Removing DNS record' "$record_id" + delete_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns/${record_id}" + + response="$(_post '' "$delete_url" '' 'DELETE')" + response="$(echo "$response" | _normalizeJson)" + _debug 'Response' "$response" + + if _contains "$response" '{}'; then + return 0 + else + return 1 + fi +} + +#################### Private functions below ################################## + +_check_yandex360_variables() { + YANDEX360_CLIENT_ID="${YANDEX360_CLIENT_ID:-$(_readaccountconf_mutable YANDEX360_CLIENT_ID)}" + YANDEX360_CLIENT_SECRET="${YANDEX360_CLIENT_SECRET:-$(_readaccountconf_mutable YANDEX360_CLIENT_SECRET)}" + YANDEX360_ORG_ID="${YANDEX360_ORG_ID:-$(_readaccountconf_mutable YANDEX360_ORG_ID)}" + YANDEX360_ACCESS_TOKEN="${YANDEX360_ACCESS_TOKEN:-$(_readaccountconf_mutable YANDEX360_ACCESS_TOKEN)}" + YANDEX360_REFRESH_TOKEN="${YANDEX360_REFRESH_TOKEN:-$(_readaccountconf_mutable YANDEX360_REFRESH_TOKEN)}" + + if [ -z "$YANDEX360_ORG_ID" ]; then + _err '=========================================' + _err ' ERROR' + _err '=========================================' + _err "A required environment variable YANDEX360_ORG_ID is not set" + _err 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _err '=========================================' + return 1 + fi + + _saveaccountconf_mutable YANDEX360_ORG_ID "$YANDEX360_ORG_ID" + + if [ -n "$YANDEX360_ACCESS_TOKEN" ]; then + _info '=========================================' + _info ' ATTENTION' + _info '=========================================' + _info 'A manually provided Yandex 360 access token has been detected, which is not recommended.' + _info 'Please note that this token is valid for a limited time after issuance.' + _info 'It is recommended to obtain the token interactively using acme.sh for one-time setup.' + _info 'Subsequent token renewals will be handled automatically.' + _info 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _info '=========================================' + + _saveaccountconf_mutable YANDEX360_ACCESS_TOKEN "$YANDEX360_ACCESS_TOKEN" + export _H1="Authorization: OAuth $YANDEX360_ACCESS_TOKEN" + return 0 + fi + + if [ -z "$YANDEX360_CLIENT_ID" ] || [ -z "$YANDEX360_CLIENT_SECRET" ]; then + _err '=========================================' + _err ' ERROR' + _err '=========================================' + _err 'The preferred environment variables YANDEX360_CLIENT_ID, YANDEX360_CLIENT_SECRET, and YANDEX360_ORG_ID, or alternatively YANDEX360_ACCESS_TOKEN, is not set.' + _err 'It is recommended to export the first three variables over the latter before running acme.sh.' + _err 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _err '=========================================' + return 1 + fi + + _saveaccountconf_mutable YANDEX360_CLIENT_ID "$YANDEX360_CLIENT_ID" + _saveaccountconf_mutable YANDEX360_CLIENT_SECRET "$YANDEX360_CLIENT_SECRET" + + if [ -n "$YANDEX360_REFRESH_TOKEN" ]; then + _debug 'Refresh token found. Attempting to refresh access token.' + if _refresh_token; then + return 0 + fi + fi + + if ! _get_token; then + return 1 + fi + + return 0 +} + +_get_token() { + _info "$(_red '=========================================')" + _info "$(_red ' NOTICE')" + _info "$(_red '=========================================')" + _info "$(_red 'Before using the Yandex 360 API, you need to complete an authorization procedure.')" + _info "$(_red 'The initial access token is obtained interactively and is a one-time operation.')" + _info "$(_red 'Subsequent API requests will be handled automatically.')" + _info "$(_red '=========================================')" + + _info 'Initiating device authorization flow' + device_code_url="${YANDEX360_OAUTH_BASE}/device/code" + + hostname=$(uname -n) + data="client_id=$YANDEX360_CLIENT_ID&device_id=acme.sh ${hostname}&device_name=acme.sh ${hostname}" + + response="$(_post "$data" "$device_code_url" '' 'POST')" + response="$(echo "$response" | _normalizeJson)" + _debug 'Response' "$response" + + if ! _contains "$response" 'device_code'; then + _err 'Failed to get device code' + return 1 + fi + + device_code=$( + echo "$response" | + _egrep_o '"device_code":"[^"]*"' | + cut -d: -f2 | + tr -d '"' + ) + _debug 'Device code' "$device_code" + + user_code=$( + echo "$response" | + _egrep_o '"user_code":"[^"]*"' | + cut -d: -f2 | + tr -d '"' + ) + _debug 'User code' "$user_code" + + verification_url=$( + echo "$response" | + _egrep_o '"verification_url":"[^"]*"' | + cut -d: -f2- | + tr -d '"' + ) + _debug 'Verification URL' "$verification_url" + + interval=$( + echo "$response" | + _egrep_o '"interval":[[:space:]]*[0-9]+' | + cut -d: -f2 + ) + _debug 'Polling interval' "$interval" + + _info "$(__red 'Please visit '"$verification_url"' and log in as an organization administrator')" + _info "$(__red 'Once logged in, enter the code: '"$user_code"' on the page from the previous step')" + _info "$(__red 'Waiting for authorization...')" + + _debug 'Polling for token' + token_url="${YANDEX360_OAUTH_BASE}/token" + + while true; do + data="grant_type=device_code&code=$device_code&client_id=$YANDEX360_CLIENT_ID&client_secret=$YANDEX360_CLIENT_SECRET" + + response="$(_post "$data" "$token_url" '' 'POST')" + response="$(echo "$response" | _normalizeJson)" + + if _contains "$response" 'access_token'; then + YANDEX360_ACCESS_TOKEN=$( + echo "$response" | + _egrep_o '"access_token":"[^"]*"' | + cut -d: -f2- | + tr -d '"' + ) + YANDEX360_REFRESH_TOKEN=$( + echo "$response" | + _egrep_o '"refresh_token":"[^"]*"' | + cut -d: -f2- | + tr -d '"' + ) + + _secure_debug 'Response' "$response" + _secure_debug 'Received access token' "$YANDEX360_ACCESS_TOKEN" + _secure_debug 'Received refresh token' "$YANDEX360_REFRESH_TOKEN" + + _saveaccountconf_mutable YANDEX360_REFRESH_TOKEN "$YANDEX360_REFRESH_TOKEN" + + export _H1="Authorization: OAuth $YANDEX360_ACCESS_TOKEN" + + _info 'Access token obtained successfully' + return 0 + elif _contains "$response" 'authorization_pending'; then + _debug 'Response' "$response" + _debug "Authorization pending. Waiting $interval seconds before next attempt." + _sleep "$interval" + else + _debug 'Response' "$response" + _err 'Failed to get access token' + return 1 + fi + done +} + +_refresh_token() { + token_url="${YANDEX360_OAUTH_BASE}/token" + + data="grant_type=refresh_token&refresh_token=$YANDEX360_REFRESH_TOKEN&client_id=$YANDEX360_CLIENT_ID&client_secret=$YANDEX360_CLIENT_SECRET" + + response="$(_post "$data" "$token_url" '' 'POST')" + response="$(echo "$response" | _normalizeJson)" + + if _contains "$response" 'access_token'; then + YANDEX360_ACCESS_TOKEN=$( + echo "$response" | + _egrep_o '"access_token":"[^"]*"' | + cut -d: -f2 | + tr -d '"' + ) + YANDEX360_REFRESH_TOKEN=$( + echo "$response" | + _egrep_o '"refresh_token":"[^"]*"' | + cut -d: -f2- | + tr -d '"' + ) + + _secure_debug 'Response' "$response" + _secure_debug 'Received access token' "$YANDEX360_ACCESS_TOKEN" + _secure_debug 'Received refresh token' "$YANDEX360_REFRESH_TOKEN" + + _saveaccountconf_mutable YANDEX360_REFRESH_TOKEN "$YANDEX360_REFRESH_TOKEN" + + export _H1="Authorization: OAuth $YANDEX360_ACCESS_TOKEN" + + _info 'Access token refreshed successfully' + return 0 + else + _debug 'Response' "$response" + _info 'Failed to refresh token. Will attempt to obtain a new one.' + return 1 + fi +} + +_get_root() { + domain="$1" + i=1 + while true; do + h=$(echo "$domain" | cut -d . -f "$i"-) + _debug "Checking domain: $h" + + if [ -z "$h" ]; then + _err "Could not determine root domain" + return 1 + fi + + dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${h}/dns" + + response="$(_get "$dns_api_url" '' '')" + response="$(echo "$response" | _normalizeJson)" + _debug 'Response' "$response" + + if _contains "$response" '"total":'; then + root_domain="$h" + _debug 'Root domain found' "$root_domain" + return 0 + fi + + i=$(_math "$i" + 1) + done +} From 6b6faa8129281f03ce160c30af2c02dfe3050a26 Mon Sep 17 00:00:00 2001 From: oittaa <8972248+oittaa@users.noreply.github.com> Date: Sat, 20 Jul 2024 13:31:53 +0200 Subject: [PATCH 399/687] _checkSudo: [ -z "__INTERACTIVE" ] should be [ -z "$__INTERACTIVE" ] Fixes #5216 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c3564e68..ee2517c2 100755 --- a/acme.sh +++ b/acme.sh @@ -7139,7 +7139,7 @@ _processAccountConf() { } _checkSudo() { - if [ -z "__INTERACTIVE" ]; then + if [ -z "$__INTERACTIVE" ]; then #don't check if it's not in an interactive shell return 0 fi From 7ca861805dc78a1167b520cb8562d3d76b7e7c3b Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Sat, 20 Jul 2024 19:03:38 +0300 Subject: [PATCH 400/687] Fixed incorrect links in informational messages --- dnsapi/dns_yandex360.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 3e879c52..91eff6d2 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -111,7 +111,7 @@ _check_yandex360_variables() { _err ' ERROR' _err '=========================================' _err "A required environment variable YANDEX360_ORG_ID is not set" - _err 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _err 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' _err '=========================================' return 1 fi @@ -126,7 +126,7 @@ _check_yandex360_variables() { _info 'Please note that this token is valid for a limited time after issuance.' _info 'It is recommended to obtain the token interactively using acme.sh for one-time setup.' _info 'Subsequent token renewals will be handled automatically.' - _info 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _info 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' _info '=========================================' _saveaccountconf_mutable YANDEX360_ACCESS_TOKEN "$YANDEX360_ACCESS_TOKEN" @@ -140,7 +140,7 @@ _check_yandex360_variables() { _err '=========================================' _err 'The preferred environment variables YANDEX360_CLIENT_ID, YANDEX360_CLIENT_SECRET, and YANDEX360_ORG_ID, or alternatively YANDEX360_ACCESS_TOKEN, is not set.' _err 'It is recommended to export the first three variables over the latter before running acme.sh.' - _err 'For more details, please visit: https://wiki.acme.sh/dnsapi#30-use-pddyandexru-api' + _err 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' _err '=========================================' return 1 fi From dd582c030610446606a7789d58ecd06315aea89b Mon Sep 17 00:00:00 2001 From: Felix Schmidt Date: Tue, 23 Jul 2024 12:59:42 +0200 Subject: [PATCH 401/687] Changed the direct call of `tr` to cast to lower case to the function `_lower_case` which is already provided. --- dnsapi/dns_dynv6.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index b15fe36f..6fbb23ca 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -16,7 +16,7 @@ dynv6_api="https://dynv6.com/api/v2" # Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_dynv6_add() { - fulldomain=$(echo "$1" | tr '[:upper:]' '[:lower:]') + fulldomain="$(echo "$1" | _lower_case)" txtvalue="$2" _info "Using dynv6 api" _debug fulldomain "$fulldomain" @@ -50,7 +50,7 @@ dns_dynv6_add() { #Usage: fulldomain txtvalue #Remove the txt record after validation. dns_dynv6_rm() { - fulldomain=$(echo "$1" | tr '[:upper:]' '[:lower:]') + fulldomain="$(echo "$1" | _lower_case)" txtvalue="$2" _info "Using dynv6 API" _debug fulldomain "$fulldomain" From 7aaa9583fa4a2055702edfe2bc61d0689e139cdc Mon Sep 17 00:00:00 2001 From: Joris van den Dries Date: Wed, 24 Jul 2024 12:05:57 +0200 Subject: [PATCH 402/687] Update teams notify script to support new notification setup using workflows instead of connectors being fased out. Color support has been dropped since this has no support inside adaptive-card --- notify/teams.sh | 69 +++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) mode change 100644 => 100755 notify/teams.sh diff --git a/notify/teams.sh b/notify/teams.sh old mode 100644 new mode 100755 index 1bc5ed08..aa4d2a4e --- a/notify/teams.sh +++ b/notify/teams.sh @@ -3,10 +3,6 @@ #Support Microsoft Teams webhooks #TEAMS_WEBHOOK_URL="" -#TEAMS_THEME_COLOR="" -#TEAMS_SUCCESS_COLOR="" -#TEAMS_ERROR_COLOR="" -#TEAMS_SKIP_COLOR="" teams_send() { _subject="$1" @@ -14,9 +10,9 @@ teams_send() { _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" - _color_success="2cbe4e" # green - _color_danger="cb2431" # red - _color_muted="586069" # gray + _color_success="Good" # green + _color_danger="Attention" # red + _color_muted="Accent" # gray TEAMS_WEBHOOK_URL="${TEAMS_WEBHOOK_URL:-$(_readaccountconf_mutable TEAMS_WEBHOOK_URL)}" if [ -z "$TEAMS_WEBHOOK_URL" ]; then @@ -26,26 +22,6 @@ teams_send() { fi _saveaccountconf_mutable TEAMS_WEBHOOK_URL "$TEAMS_WEBHOOK_URL" - TEAMS_THEME_COLOR="${TEAMS_THEME_COLOR:-$(_readaccountconf_mutable TEAMS_THEME_COLOR)}" - if [ -n "$TEAMS_THEME_COLOR" ]; then - _saveaccountconf_mutable TEAMS_THEME_COLOR "$TEAMS_THEME_COLOR" - fi - - TEAMS_SUCCESS_COLOR="${TEAMS_SUCCESS_COLOR:-$(_readaccountconf_mutable TEAMS_SUCCESS_COLOR)}" - if [ -n "$TEAMS_SUCCESS_COLOR" ]; then - _saveaccountconf_mutable TEAMS_SUCCESS_COLOR "$TEAMS_SUCCESS_COLOR" - fi - - TEAMS_ERROR_COLOR="${TEAMS_ERROR_COLOR:-$(_readaccountconf_mutable TEAMS_ERROR_COLOR)}" - if [ -n "$TEAMS_ERROR_COLOR" ]; then - _saveaccountconf_mutable TEAMS_ERROR_COLOR "$TEAMS_ERROR_COLOR" - fi - - TEAMS_SKIP_COLOR="${TEAMS_SKIP_COLOR:-$(_readaccountconf_mutable TEAMS_SKIP_COLOR)}" - if [ -n "$TEAMS_SKIP_COLOR" ]; then - _saveaccountconf_mutable TEAMS_SKIP_COLOR "$TEAMS_SKIP_COLOR" - fi - export _H1="Content-Type: application/json" _subject=$(echo "$_subject" | _json_encode) @@ -63,16 +39,35 @@ teams_send() { ;; esac - _color=$(echo "$_color" | tr -cd 'a-fA-F0-9') - if [ -z "$_color" ]; then - _color=$(echo "${TEAMS_THEME_COLOR:-$_color_muted}" | tr -cd 'a-fA-F0-9') - fi - - _data="{\"title\": \"$_subject\"," - if [ -n "$_color" ]; then - _data="$_data\"themeColor\": \"$_color\", " - fi - _data="$_data\"text\": \"$_content\"}" + _data="{ + \"type\": \"message\", + \"attachments\": [ + { + \"contentType\": \"application/vnd.microsoft.card.adaptive\", + \"contentUrl\": null, + \"content\": { + \"$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\", + \"type\": \"AdaptiveCard\", + \"version\": \"1.2\", + \"body\": [ + { + \"type\": \"TextBlock\", + \"size\": \"large\", + \"weight\": \"bolder\", + \"wrap\": true, + \"color\": \"$_color\", + \"text\": \"$_subject\" + }, + { + \"type\": \"TextBlock\", + \"text\": \"$_content\", + \"wrap\": true + } + ] + } + } + ] +}" if response=$(_post "$_data" "$TEAMS_WEBHOOK_URL"); then if ! _contains "$response" error; then From 4cd187181673b1e9a94fe30f0eecabd239d03c55 Mon Sep 17 00:00:00 2001 From: Joris van den Dries Date: Wed, 24 Jul 2024 12:23:17 +0200 Subject: [PATCH 403/687] Removed obsolete documentation --- notify/teams.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notify/teams.sh b/notify/teams.sh index aa4d2a4e..f1b11d5b 100755 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -10,9 +10,9 @@ teams_send() { _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped _debug "_statusCode" "$_statusCode" - _color_success="Good" # green - _color_danger="Attention" # red - _color_muted="Accent" # gray + _color_success="Good" + _color_danger="Attention" + _color_muted="Accent" TEAMS_WEBHOOK_URL="${TEAMS_WEBHOOK_URL:-$(_readaccountconf_mutable TEAMS_WEBHOOK_URL)}" if [ -z "$TEAMS_WEBHOOK_URL" ]; then From 3cefcd8204167910ad05db860e428de4e5e34120 Mon Sep 17 00:00:00 2001 From: Joris van den Dries Date: Wed, 24 Jul 2024 15:02:48 +0200 Subject: [PATCH 404/687] change reference to static value --- notify/teams.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify/teams.sh b/notify/teams.sh index f1b11d5b..5e8fe6c0 100755 --- a/notify/teams.sh +++ b/notify/teams.sh @@ -46,7 +46,7 @@ teams_send() { \"contentType\": \"application/vnd.microsoft.card.adaptive\", \"contentUrl\": null, \"content\": { - \"$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\", + \"schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\", \"type\": \"AdaptiveCard\", \"version\": \"1.2\", \"body\": [ From bcb7e5f2c88e18eb4d7b7373fd05286e86994a76 Mon Sep 17 00:00:00 2001 From: gmanic <30374118+gmanic@users.noreply.github.com> Date: Wed, 24 Jul 2024 20:28:39 +0000 Subject: [PATCH 405/687] Update dns_nsupdate.sh Corrected required variable double quote --- dnsapi/dns_nsupdate.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 4161ad5b..7c68f343 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -29,13 +29,13 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then - nsupdate -k "${NSUPDATE_KEY}" $nsdebug ${NSUPDATE_OPT} < Date: Sat, 27 Jul 2024 14:23:07 +0200 Subject: [PATCH 406/687] Update dockerhub.yml --- .github/workflows/dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index ea446d84..e8e496f1 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -51,7 +51,7 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE=neilpang/acme.sh + DOCKER_IMAGE=${{ secrets.DOCKER_USERNAME }}/acme.sh if [[ $GITHUB_REF == refs/tags/* ]]; then DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} From b6f771062109b64007d5f97e24250c8f8aac899d Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Sat, 27 Jul 2024 14:28:07 +0200 Subject: [PATCH 407/687] Update bark.sh Bark API v2 is now fully implemented. BARK_SOUND is now also optional, as intended by the API. --- notify/bark.sh | 103 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/notify/bark.sh b/notify/bark.sh index bbd5bf34..fd9ebd76 100644 --- a/notify/bark.sh +++ b/notify/bark.sh @@ -1,32 +1,40 @@ #!/usr/bin/env sh -#Support iOS Bark Notification +# Support iOS Bark Notification -#BARK_API_URL="https://api.day.app/xxxx" -#BARK_SOUND="yyyy" -#BARK_GROUP="zzzz" +# Every parameter explained: https://github.com/Finb/bark-server/blob/master/docs/API_V2.md#push -# subject content statusCode +# BARK_API_URL="https://api.day.app/xxxx" (required) +# BARK_GROUP="ACME" (optional) +# BARK_SOUND="alarm" (optional) +# BARK_LEVEL="active" (optional) +# BARK_BADGE=0 (optional) +# BARK_AUTOMATICALLYCOPY="1" (optional) +# BARK_COPY="My clipboard Content" (optional) +# BARK_ICON="https://example.com/icon.png" (optional) +# BARK_ISARCHIVE="1" (optional) +# BARK_URL="https://example.com" (optional) + +# subject content statusCode bark_send() { _subject="$1" _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _statusCode="$3" # 0: success, 1: error, 2: skipped _debug "_subject" "$_subject" _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" + _content=$(echo "$_content" | _url_encode) + _subject=$(echo "$_subject" | _url_encode) + BARK_API_URL="${BARK_API_URL:-$(_readaccountconf_mutable BARK_API_URL)}" if [ -z "$BARK_API_URL" ]; then - BARK_API_URL="" _err "You didn't specify a Bark API URL BARK_API_URL yet." _err "You can download Bark from App Store and get yours." return 1 fi _saveaccountconf_mutable BARK_API_URL "$BARK_API_URL" - BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}" - _saveaccountconf_mutable BARK_SOUND "$BARK_SOUND" - BARK_GROUP="${BARK_GROUP:-$(_readaccountconf_mutable BARK_GROUP)}" if [ -z "$BARK_GROUP" ]; then BARK_GROUP="ACME" @@ -35,10 +43,79 @@ bark_send() { _saveaccountconf_mutable BARK_GROUP "$BARK_GROUP" fi - _content=$(echo "$_content" | _url_encode) - _subject=$(echo "$_subject" | _url_encode) + BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}" + if [ -n "$BARK_SOUND" ]; then + _saveaccountconf_mutable BARK_SOUND "$BARK_SOUND" + fi + + BARK_LEVEL="${BARK_LEVEL:-$(_readaccountconf_mutable BARK_LEVEL)}" + if [ -n "$BARK_LEVEL" ]; then + _saveaccountconf_mutable BARK_LEVEL "$BARK_LEVEL" + fi + + BARK_BADGE="${BARK_BADGE:-$(_readaccountconf_mutable BARK_BADGE)}" + if [ -n "$BARK_BADGE" ]; then + _saveaccountconf_mutable BARK_BADGE "$BARK_BADGE" + fi + + BARK_AUTOMATICALLYCOPY="${BARK_AUTOMATICALLYCOPY:-$(_readaccountconf_mutable BARK_AUTOMATICALLYCOPY)}" + if [ -n "$BARK_AUTOMATICALLYCOPY" ]; then + _saveaccountconf_mutable BARK_AUTOMATICALLYCOPY "$BARK_AUTOMATICALLYCOPY" + fi + + BARK_COPY="${BARK_COPY:-$(_readaccountconf_mutable BARK_COPY)}" + if [ -n "$BARK_COPY" ]; then + _saveaccountconf_mutable BARK_COPY "$BARK_COPY" + fi + + BARK_ICON="${BARK_ICON:-$(_readaccountconf_mutable BARK_ICON)}" + if [ -n "$BARK_ICON" ]; then + _saveaccountconf_mutable BARK_ICON "$BARK_ICON" + fi + + BARK_ISARCHIVE="${BARK_ISARCHIVE:-$(_readaccountconf_mutable BARK_ISARCHIVE)}" + if [ -n "$BARK_ISARCHIVE" ]; then + _saveaccountconf_mutable BARK_ISARCHIVE "$BARK_ISARCHIVE" + fi + + BARK_URL="${BARK_URL:-$(_readaccountconf_mutable BARK_URL)}" + if [ -n "$BARK_URL" ]; then + _saveaccountconf_mutable BARK_URL "$BARK_URL" + fi + + _params="" + + if [ -n "$BARK_SOUND" ]; then + _params="$_params&sound=$BARK_SOUND" + fi + if [ -n "$BARK_GROUP" ]; then + _params="$_params&group=$BARK_GROUP" + fi + if [ -n "$BARK_LEVEL" ]; then + _params="$_params&level=$BARK_LEVEL" + fi + if [ -n "$BARK_BADGE" ]; then + _params="$_params&badge=$BARK_BADGE" + fi + if [ -n "$BARK_AUTOMATICALLYCOPY" ]; then + _params="$_params&automaticallyCopy=$BARK_AUTOMATICALLYCOPY" + fi + if [ -n "$BARK_COPY" ]; then + _params="$_params©=$BARK_COPY" + fi + if [ -n "$BARK_ICON" ]; then + _params="$_params&icon=$BARK_ICON" + fi + if [ -n "$BARK_ISARCHIVE" ]; then + _params="$_params&isArchive=$BARK_ISARCHIVE" + fi + if [ -n "$BARK_URL" ]; then + _params="$_params&url=$BARK_URL" + fi + + _params=$(echo "$_params" | sed 's/^&//') # remove leading '&' if exists - response="$(_get "$BARK_API_URL/$_subject/$_content?sound=$BARK_SOUND&group=$BARK_GROUP")" + response="$(_get "$BARK_API_URL/$_subject/$_content?$_params")" if [ "$?" = "0" ] && _contains "$response" "success"; then _info "Bark API fired success." From cb5eae888d010ef7d7374d46514f7cf52379b70b Mon Sep 17 00:00:00 2001 From: Mickael Date: Wed, 31 Jul 2024 16:22:12 +0200 Subject: [PATCH 408/687] Update dns_ispconfig.sh Add permissions to: - Client functions - DNS zone functions --- dnsapi/dns_ispconfig.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 7fd0d99c..edc789e1 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -14,6 +14,8 @@ Options: # User must provide login data and URL to the ISPConfig installation incl. port. # The remote user in ISPConfig must have access to: # - DNS txt Functions +# - DNS zone functions +# - Client functions ######## Public functions ##################### From a6488ff9accd5b72854a34e6b007e25730b8f359 Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Thu, 1 Aug 2024 02:18:48 +0000 Subject: [PATCH 409/687] Optimizing debug output --- dnsapi/dns_yandex360.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 91eff6d2..e5f48bff 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -40,11 +40,11 @@ dns_yandex360_add() { response="$(_post "$data" "$dns_api_url" '' 'POST' 'application/json')" response="$(echo "$response" | _normalizeJson)" - _debug 'Response' "$response" if _contains "$response" 'recordId'; then return 0 else + _debug 'Response' "$response" return 1 fi } @@ -66,10 +66,10 @@ dns_yandex360_rm() { dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns?perPage=100" response="$(_get "$dns_api_url" '' '')" response="$(echo "$response" | _normalizeJson)" - _debug 'Response' "$response" if ! _contains "$response" "$txtvalue"; then _info 'DNS record not found. Nothing to remove.' + _debug 'Response' "$response" return 1 fi @@ -88,11 +88,11 @@ dns_yandex360_rm() { response="$(_post '' "$delete_url" '' 'DELETE')" response="$(echo "$response" | _normalizeJson)" - _debug 'Response' "$response" if _contains "$response" '{}'; then return 0 else + _debug 'Response' "$response" return 1 fi } @@ -179,10 +179,10 @@ _get_token() { response="$(_post "$data" "$device_code_url" '' 'POST')" response="$(echo "$response" | _normalizeJson)" - _debug 'Response' "$response" if ! _contains "$response" 'device_code'; then _err 'Failed to get device code' + _debug 'Response' "$response" return 1 fi @@ -244,9 +244,8 @@ _get_token() { tr -d '"' ) - _secure_debug 'Response' "$response" - _secure_debug 'Received access token' "$YANDEX360_ACCESS_TOKEN" - _secure_debug 'Received refresh token' "$YANDEX360_REFRESH_TOKEN" + _secure_debug 'Obtained access token' "$YANDEX360_ACCESS_TOKEN" + _secure_debug 'Obtained refresh token' "$YANDEX360_REFRESH_TOKEN" _saveaccountconf_mutable YANDEX360_REFRESH_TOKEN "$YANDEX360_REFRESH_TOKEN" @@ -288,7 +287,6 @@ _refresh_token() { tr -d '"' ) - _secure_debug 'Response' "$response" _secure_debug 'Received access token' "$YANDEX360_ACCESS_TOKEN" _secure_debug 'Received refresh token' "$YANDEX360_REFRESH_TOKEN" @@ -299,8 +297,8 @@ _refresh_token() { _info 'Access token refreshed successfully' return 0 else - _debug 'Response' "$response" _info 'Failed to refresh token. Will attempt to obtain a new one.' + _debug 'Response' "$response" return 1 fi } From 2f1ca949f0d4225c80198bf474c624c252330f04 Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Thu, 1 Aug 2024 02:33:09 +0000 Subject: [PATCH 410/687] Fix: Make record_id extraction independent of JSON key order --- dnsapi/dns_yandex360.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index e5f48bff..c4b5dbf4 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -75,7 +75,9 @@ dns_yandex360_rm() { record_id=$( echo "$response" | - sed -En 's/.*"recordId":([0-9]+).*"text":"'"${txtvalue}"'".*$/\1/p' + _egrep_o '\{[^}]*'"${txtvalue}"'[^}]*\}' | + _egrep_o '"recordId":[0-9]*' | + cut -d':' -f2 ) if [ -z "$record_id" ]; then From c7d78f45942d25b405f724c4543fbc45730df64b Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Thu, 1 Aug 2024 02:44:22 +0000 Subject: [PATCH 411/687] Fix: Corrected the entry point for Yandex 360 API --- dnsapi/dns_yandex360.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index c4b5dbf4..815f2bce 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -14,7 +14,7 @@ Issues: https://github.com/acmesh-official/acme.sh/issues/5213 Author: ' -YANDEX360_API_BASE='https://api360.yandex.net/directory/v1/org' +YANDEX360_API_BASE='https://api360.yandex.net/directory/v1' YANDEX360_OAUTH_BASE='https://oauth.yandex.ru' ######## Public functions ##################### @@ -35,7 +35,7 @@ dns_yandex360_add() { sub_domain=$(echo "$fulldomain" | sed "s/\.$root_domain$//") _debug 'Adding Yandex 360 DNS record for subdomain' "$sub_domain" - dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns" + dns_api_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${root_domain}/dns" data='{"name":"'"$sub_domain"'","type":"TXT","ttl":60,"text":"'"$txtvalue"'"}' response="$(_post "$data" "$dns_api_url" '' 'POST' 'application/json')" @@ -63,7 +63,7 @@ dns_yandex360_rm() { fi _debug 'Retrieving 100 records from Yandex 360 DNS' - dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns?perPage=100" + dns_api_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${root_domain}/dns?perPage=100" response="$(_get "$dns_api_url" '' '')" response="$(echo "$response" | _normalizeJson)" @@ -86,7 +86,7 @@ dns_yandex360_rm() { fi _debug 'Removing DNS record' "$record_id" - delete_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${root_domain}/dns/${record_id}" + delete_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${root_domain}/dns/${record_id}" response="$(_post '' "$delete_url" '' 'DELETE')" response="$(echo "$response" | _normalizeJson)" @@ -317,7 +317,7 @@ _get_root() { return 1 fi - dns_api_url="${YANDEX360_API_BASE}/${YANDEX360_ORG_ID}/domains/${h}/dns" + dns_api_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${h}/dns" response="$(_get "$dns_api_url" '' '')" response="$(echo "$response" | _normalizeJson)" From 13c68cd7994a13d5ab7b0242ad2c9607234ed185 Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Thu, 1 Aug 2024 03:04:23 +0000 Subject: [PATCH 412/687] Refactor: Rename _check_yandex360_variables to _check_variables and improve error handling --- dnsapi/dns_yandex360.sh | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 815f2bce..2abeede1 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -24,7 +24,7 @@ dns_yandex360_add() { txtvalue=$2 _info 'Using Yandex 360 DNS API' - if ! _check_yandex360_variables; then + if ! _check_variables; then return 1 fi @@ -54,7 +54,7 @@ dns_yandex360_rm() { txtvalue=$2 _info 'Using Yandex 360 DNS API' - if ! _check_yandex360_variables; then + if ! _check_variables; then return 1 fi @@ -101,7 +101,7 @@ dns_yandex360_rm() { #################### Private functions below ################################## -_check_yandex360_variables() { +_check_variables() { YANDEX360_CLIENT_ID="${YANDEX360_CLIENT_ID:-$(_readaccountconf_mutable YANDEX360_CLIENT_ID)}" YANDEX360_CLIENT_SECRET="${YANDEX360_CLIENT_SECRET:-$(_readaccountconf_mutable YANDEX360_CLIENT_SECRET)}" YANDEX360_ORG_ID="${YANDEX360_ORG_ID:-$(_readaccountconf_mutable YANDEX360_ORG_ID)}" @@ -133,32 +133,33 @@ _check_yandex360_variables() { _saveaccountconf_mutable YANDEX360_ACCESS_TOKEN "$YANDEX360_ACCESS_TOKEN" export _H1="Authorization: OAuth $YANDEX360_ACCESS_TOKEN" - return 0 - fi - if [ -z "$YANDEX360_CLIENT_ID" ] || [ -z "$YANDEX360_CLIENT_SECRET" ]; then + elif [ -z "$YANDEX360_CLIENT_ID" ] || [ -z "$YANDEX360_CLIENT_SECRET" ]; then _err '=========================================' _err ' ERROR' _err '=========================================' - _err 'The preferred environment variables YANDEX360_CLIENT_ID, YANDEX360_CLIENT_SECRET, and YANDEX360_ORG_ID, or alternatively YANDEX360_ACCESS_TOKEN, is not set.' - _err 'It is recommended to export the first three variables over the latter before running acme.sh.' + _err 'The required environment variables YANDEX360_CLIENT_ID and YANDEX360_CLIENT_SECRET are not set.' + _err 'Alternatively, you can set YANDEX360_ACCESS_TOKEN environment variable.' _err 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' _err '=========================================' return 1 - fi + else _saveaccountconf_mutable YANDEX360_CLIENT_ID "$YANDEX360_CLIENT_ID" _saveaccountconf_mutable YANDEX360_CLIENT_SECRET "$YANDEX360_CLIENT_SECRET" if [ -n "$YANDEX360_REFRESH_TOKEN" ]; then _debug 'Refresh token found. Attempting to refresh access token.' - if _refresh_token; then - return 0 + if ! _refresh_token; then + if ! _get_token; then + return 1 fi fi - + else if ! _get_token; then return 1 + fi + fi fi return 0 From 2f08bd1965eebd1abf28ac88f97c85020ff8d176 Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Thu, 1 Aug 2024 03:28:32 +0000 Subject: [PATCH 413/687] Refactor: Improve Yandex360 DNS API integration: - Make YANDEX360_ORG_ID optional and auto-retrieve if not provided. - Refactor _get_root function to search across multiple organizations. --- dnsapi/dns_yandex360.sh | 103 ++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 36 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 2abeede1..2c8fc89f 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -7,8 +7,8 @@ Docs: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360 Options: YANDEX360_CLIENT_ID OAuth 2.0 ClientID YANDEX360_CLIENT_SECRET OAuth 2.0 Client secret - YANDEX360_ORG_ID Organization ID OptionsAlt: + YANDEX360_ORG_ID Organization ID. Optional. YANDEX360_ACCESS_TOKEN OAuth 2.0 Access token. Optional. Issues: https://github.com/acmesh-official/acme.sh/issues/5213 Author: @@ -108,18 +108,6 @@ _check_variables() { YANDEX360_ACCESS_TOKEN="${YANDEX360_ACCESS_TOKEN:-$(_readaccountconf_mutable YANDEX360_ACCESS_TOKEN)}" YANDEX360_REFRESH_TOKEN="${YANDEX360_REFRESH_TOKEN:-$(_readaccountconf_mutable YANDEX360_REFRESH_TOKEN)}" - if [ -z "$YANDEX360_ORG_ID" ]; then - _err '=========================================' - _err ' ERROR' - _err '=========================================' - _err "A required environment variable YANDEX360_ORG_ID is not set" - _err 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' - _err '=========================================' - return 1 - fi - - _saveaccountconf_mutable YANDEX360_ORG_ID "$YANDEX360_ORG_ID" - if [ -n "$YANDEX360_ACCESS_TOKEN" ]; then _info '=========================================' _info ' ATTENTION' @@ -145,20 +133,43 @@ _check_variables() { return 1 else - _saveaccountconf_mutable YANDEX360_CLIENT_ID "$YANDEX360_CLIENT_ID" - _saveaccountconf_mutable YANDEX360_CLIENT_SECRET "$YANDEX360_CLIENT_SECRET" + _saveaccountconf_mutable YANDEX360_CLIENT_ID "$YANDEX360_CLIENT_ID" + _saveaccountconf_mutable YANDEX360_CLIENT_SECRET "$YANDEX360_CLIENT_SECRET" - if [ -n "$YANDEX360_REFRESH_TOKEN" ]; then - _debug 'Refresh token found. Attempting to refresh access token.' + if [ -n "$YANDEX360_REFRESH_TOKEN" ]; then + _debug 'Refresh token found. Attempting to refresh access token.' if ! _refresh_token; then if ! _get_token; then return 1 + fi + fi + else + if ! _get_token; then + return 1 + fi fi fi + + if [ -z "$YANDEX360_ORG_ID" ]; then + org_response="$(_get "${YANDEX360_API_BASE}/org" '' '')" + org_response="$(echo "$org_response" | _normalizeJson)" + + if _contains "$org_response" '"organizations":'; then + YANDEX360_ORG_ID=$( + echo "$org_response" | + _egrep_o '"id":[[:space:]]*[0-9]+' | + cut -d: -f2 + ) + _debug 'Automatically retrieved YANDEX360_ORG_ID' "$YANDEX360_ORG_ID" else - if ! _get_token; then - return 1 - fi + _err '=========================================' + _err ' ERROR' + _err '=========================================' + _err "Failed to retrieve YANDEX360_ORG_ID automatically." + _err 'For more details, please visit: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360' + _err '=========================================' + _debug 'Response' "$org_response" + return 1 fi fi @@ -308,28 +319,48 @@ _refresh_token() { _get_root() { domain="$1" - i=1 - while true; do - h=$(echo "$domain" | cut -d . -f "$i"-) - _debug "Checking domain: $h" - if [ -z "$h" ]; then - _err "Could not determine root domain" - return 1 + for org_id in $YANDEX360_ORG_ID; do + _debug 'Checking organization ID' "$org_id" + domains_api_url="${YANDEX360_API_BASE}/org/${org_id}/domains" + + domains_response="$(_get "$domains_api_url" '' '')" + domains_response="$(echo "$domains_response" | _normalizeJson)" + + if ! _contains "$domains_response" '"domains":'; then + _debug 'No domains found for organization' "$org_id" + _debug 'Response' "$domains_response" + continue fi - dns_api_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${h}/dns" + domain_names=$( + echo "$domains_response" | + _egrep_o '"name":"[^"]*"' | + cut -d'"' -f4 + ) - response="$(_get "$dns_api_url" '' '')" - response="$(echo "$response" | _normalizeJson)" - _debug 'Response' "$response" + for d in $domain_names; do + d="$(_idn "$d")" + _debug 'Checking domain' "$d" + + if _endswith "$domain" "$d"; then + root_domain="$d" + break + fi + done + + if [ -n "$root_domain" ]; then + _debug "Root domain found: $root_domain in organization $org_id" + + YANDEX360_ORG_ID="$org_id" + _saveaccountconf_mutable YANDEX360_ORG_ID "$YANDEX360_ORG_ID" - if _contains "$response" '"total":'; then - root_domain="$h" - _debug 'Root domain found' "$root_domain" return 0 fi - - i=$(_math "$i" + 1) done + + if [ -z "$root_domain" ]; then + _err "Could not find a matching root domain for $domain in any organization" + return 1 + fi } From de902166a83b4d1d0701f2909942f8a6b203f86a Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Thu, 1 Aug 2024 08:15:16 -0700 Subject: [PATCH 414/687] Replaced keytool with openssl pkcs12. Added backup of original certificates. --- deploy/unifi.sh | 69 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index a864135e..04ac047a 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -5,6 +5,16 @@ # - self-hosted Unifi Controller # - Unifi Cloud Key (Gen1/2/2+) # - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# See below regarding keytool. Not tested. +# - Unifi Dream Machine +# This has not been tested on other "all-in-one" devices such as +# UDM Pro or Unifi Express. +# +# OS Version v2.0.0+ +# Network Application version 7.0.0+ +# OS version ~3.1 removed java and keytool from the UnifiOS. +# Using PKCS12 format keystore appears to work fine. +# # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. @@ -74,15 +84,12 @@ unifi_deploy() { _reload_cmd="" # Unifi Controller environment (self hosted or any Cloud Key) -- - # auto-detect by file /usr/lib/unifi/data/keystore: + # auto-detect by file /usr/lib/unifi/data/keystore _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" if [ -f "$_unifi_keystore" ]; then - _info "Installing certificate for Unifi Controller (Java keystore)" _debug _unifi_keystore "$_unifi_keystore" - if ! _exists keytool; then - _err "keytool not found" - return 1 - fi + _info "Installing certificate for Unifi Controller (PKCS12 keystore)." + if [ ! -w "$_unifi_keystore" ]; then _err "The file $_unifi_keystore is not writable, please change the permission." return 1 @@ -92,6 +99,7 @@ unifi_deploy() { _debug "Generate import pkcs12" _import_pkcs12="$(_mktemp)" + _debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root" _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root # shellcheck disable=SC2181 if [ "$?" != "0" ]; then @@ -99,22 +107,40 @@ unifi_deploy() { return 1 fi - _debug "Import into keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _debug "Import keystore success!" - rm "$_import_pkcs12" - else - _err "Error importing into Unifi Java keystore." - _err "Please re-run with --debug and report a bug." - rm "$_import_pkcs12" - return 1 + # Save the existing keystore in case something goes wrong. + mv -f "${_unifi_keystore}" "${_unifi_keystore}"_original + _info "Previous keystore saved to ${_unifi_keystore}_original." + + _debug "Copying new keystore to $_unifi_keystore" + cp -f "$_import_pkcs12" "$_unifi_keystore" + + # Update unifi service for certificate cipher compatibility + if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \ + -in "$_import_pkcs12" \ + -password pass:aircontrolenterprise \ + -nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \ + -noout | grep -i "signature" | grep -iq ecdsa >/dev/null 2>&1; then + cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original + _info "Updating system configuration for cipher compatibility." + _info "Saved original system config to /usr/lib/unifi/data/system.properties_original" + sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>/usr/lib/unifi/data/system.properties + sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>/usr/lib/unifi/data/system.properties + _info "System configuration updated." fi + rm "$_import_pkcs12" + + # Restarting unifi-core will bring up unifi, doing it out of order results in + # a certificate error. + # Restart if we aren't doing unifi-core, otherwise stop for later restart. if systemctl -q is-active unifi; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" + else + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" + fi fi _services_updated="${_services_updated} unifi" _info "Install Unifi Controller certificate success!" @@ -165,6 +191,11 @@ unifi_deploy() { return 1 fi + # Save the existing certs in case something goes wrong. + cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt + cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key + _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" From 1700f064b3dc208071d85d123d6e5b3be9d93616 Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Sat, 3 Aug 2024 18:59:29 +0000 Subject: [PATCH 415/687] Fix: Support for IDN --- dnsapi/dns_yandex360.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 2c8fc89f..05563f90 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -20,7 +20,7 @@ YANDEX360_OAUTH_BASE='https://oauth.yandex.ru' ######## Public functions ##################### dns_yandex360_add() { - fulldomain=$1 + fulldomain="$(_idn "$1")" txtvalue=$2 _info 'Using Yandex 360 DNS API' @@ -50,7 +50,7 @@ dns_yandex360_add() { } dns_yandex360_rm() { - fulldomain=$1 + fulldomain="$(_idn "$1")" txtvalue=$2 _info 'Using Yandex 360 DNS API' From 5214a7c3ec32cdffc3ff3497c163bf235bd7eaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:19:21 +0300 Subject: [PATCH 416/687] Add dnsapi script for HE DDNS --- dnsapi/dns_he_ddns.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 dnsapi/dns_he_ddns.sh diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh new file mode 100644 index 00000000..7338ab18 --- /dev/null +++ b/dnsapi/dns_he_ddns.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env sh +dns_he_ddns_info='Hurricane Electric HE.net DDNS +Site: dns.he.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he_ddns +Options: + HE_DDNS_KEY The DDNS key for updating the TXT record +Author: Markku Leiniö +' + +HE_DDNS_URL="https://dyn.dns.he.net/nic/update" + +######## Public functions ##################### + +#Usage: dns_he_ddns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_he_ddns_add() { + fulldomain=$1 + txtvalue=$2 + HE_DDNS_KEY="${HE_DDNS_KEY:-$(_readaccountconf_mutable HE_DDNS_KEY)}" + if [ -z "$HE_DDNS_KEY" ]; then + HE_DDNS_KEY="" + _err "You didn't specify a DDNS key for accessing the TXT record in HE API." + return 1 + fi + #Save the DDNS key to the account conf file. + _saveaccountconf_mutable HE_DDNS_KEY "$HE_DDNS_KEY" + + _info "Using Hurricane Electric DDNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + response="$(_post "hostname=$fulldomain&password=$HE_DDNS_KEY&txt=$txtvalue" "$HE_DDNS_URL")" + _info "Response: $response" + _contains "$response" "good" && return 0 || return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_he_ddns_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" +} From c96fcf319a8667115baaad335f8820b1fba93735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:25:20 +0300 Subject: [PATCH 417/687] Remove dns_he_ddns_rm(), not used --- dnsapi/dns_he_ddns.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 7338ab18..44e6783e 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -33,11 +33,5 @@ dns_he_ddns_add() { _contains "$response" "good" && return 0 || return 1 } -#Usage: fulldomain txtvalue -#Remove the txt record after validation. -dns_he_ddns_rm() { - fulldomain=$1 - txtvalue=$2 - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" -} +# dns_he_ddns_rm() is not implemented because the API call always updates the +# contents of the existing record (that the API key gives access to). From abc76299c0c74faa265933f532c8d1ec59a27b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:58:59 +0300 Subject: [PATCH 418/687] Fix documentation link --- dnsapi/dns_he_ddns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 44e6783e..95ec290b 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh dns_he_ddns_info='Hurricane Electric HE.net DDNS Site: dns.he.net -Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he_ddns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns Options: HE_DDNS_KEY The DDNS key for updating the TXT record Author: Markku Leiniö From 833632eee3d8aa9b562297cf6a8c13fee9d81b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:15:11 +0300 Subject: [PATCH 419/687] Add shellcheck disable=SC2034 for the info variable --- dnsapi/dns_he_ddns.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 95ec290b..0893f938 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -1,4 +1,5 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 dns_he_ddns_info='Hurricane Electric HE.net DDNS Site: dns.he.net Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns From e711d168df314790a7c88b744a57ae6eca46fb18 Mon Sep 17 00:00:00 2001 From: Nathan Johnson Date: Fri, 9 Aug 2024 16:38:09 -0500 Subject: [PATCH 420/687] RouterOS - make deploy more resilient In the case where importing the cert and key removes the files from disk the existing deploy will fail when it tries to remove those files. This still attempts to remove the files but catches the error and moves on instead of bombing like before. Similarly, if the deploy had failed before, subsequent deploys would fail because the script already existed, so it would not be able to create the script. This first attempts to remove the script if it exists, and then creates the script. --- deploy/routeros.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/deploy/routeros.sh b/deploy/routeros.sh index d1779b8d..90f0ad1a 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -137,7 +137,8 @@ routeros_deploy() { return $_err_code fi - DEPLOY_SCRIPT_CMD="/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \ + DEPLOY_SCRIPT_CMD=":do {/system script remove \"LECertDeploy-$_cdomain\" } on-error={ }; \ +/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \ comment=\"generated by routeros deploy script in acme.sh\" \ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\ @@ -146,8 +147,8 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\ \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\ \ndelay 1;\ -\n/file remove $_cdomain.cer;\ -\n/file remove $_cdomain.key;\ +\n:do {/file remove $_cdomain.cer; } on-error={ }\ +\n:do {/file remove $_cdomain.key; } on-error={ }\ \ndelay 2;\ \n/ip service set www-ssl certificate=$_cdomain.cer_0;\ \n$ROUTER_OS_ADDITIONAL_SERVICES;\ From 57da04b5ec7b76f45ad82ac5035a2d6dffe5ce1c Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Sun, 11 Aug 2024 22:39:47 -0400 Subject: [PATCH 421/687] Updated Unifi deploy hook to use openssl's pkcs12 instead of Java Keytool after Ubiquiti removed it, update system configuration for stronger ciphers, and back up existing certificates prior to change. --- deploy/unifi.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index 0a574e0d..e06f3505 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -104,6 +104,7 @@ unifi_deploy() { _debug "Generate import pkcs12" _import_pkcs12="$(_mktemp)" + _debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root" _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root # shellcheck disable=SC2181 if [ "$?" != "0" ]; then @@ -153,9 +154,9 @@ unifi_deploy() { rm "$_import_pkcs12" - # Restarting unifi-core will bring up unifi, doing it out of order results in - # a certificate error, and may break wifiman. (unconfirmed) - # Restart if we aren't doing unifi-core, otherwise stop and let unifi-core restart it. + # Restarting unifi-core will bring up unifi, doing it out of order results in + # a certificate error, and breaks wifiman. + # Restart if we aren't doing unifi-core, otherwise stop for later restart. if systemctl -q is-active unifi; then if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" From adfafe5c548705db19ddfb9fcb9c681a17d1c8f8 Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Sun, 11 Aug 2024 22:48:44 -0400 Subject: [PATCH 422/687] reverted bad merge --- deploy/unifi.sh | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index 83c4c432..e06f3505 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -15,16 +15,6 @@ # OS version ~3.1 removed java and keytool from the UnifiOS. # Using PKCS12 format keystore appears to work fine. # -# See below regarding keytool. Not tested. -# - Unifi Dream Machine -# This has not been tested on other "all-in-one" devices such as -# UDM Pro or Unifi Express. -# -# OS Version v2.0.0+ -# Network Application version 7.0.0+ -# OS version ~3.1 removed java and keytool from the UnifiOS. -# Using PKCS12 format keystore appears to work fine. -# # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. @@ -95,7 +85,6 @@ unifi_deploy() { # Unifi Controller environment (self hosted or any Cloud Key) -- # auto-detect by file /usr/lib/unifi/data/keystore - # auto-detect by file /usr/lib/unifi/data/keystore _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" if [ -f "$_unifi_keystore" ]; then _debug _unifi_keystore "$_unifi_keystore" @@ -174,11 +163,6 @@ unifi_deploy() { else _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" fi - if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" - else - _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" - fi fi _services_updated="${_services_updated} unifi" _info "Install Unifi Controller certificate success!" @@ -234,11 +218,6 @@ unifi_deploy() { cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." - # Save the existing certs in case something goes wrong. - cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt - cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key - _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." - cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" From ca6226359bd6843e26b8871a7f490aa662f5c707 Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Sun, 11 Aug 2024 22:49:20 -0400 Subject: [PATCH 423/687] removed old comment --- deploy/unifi.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index e06f3505..cdf7eea5 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -5,7 +5,6 @@ # - self-hosted Unifi Controller # - Unifi Cloud Key (Gen1/2/2+) # - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) -# See below regarding keytool. Not tested. # - Unifi Dream Machine # This has not been tested on other "all-in-one" devices such as # UDM Pro or Unifi Express. From de99d6d9fcbf35bf095b3fa4040ca24782a2126a Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Thu, 15 Aug 2024 11:09:40 -0400 Subject: [PATCH 424/687] fixed shfmt --- deploy/unifi.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index cdf7eea5..4d8c058e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -103,7 +103,7 @@ unifi_deploy() { _debug "Generate import pkcs12" _import_pkcs12="$(_mktemp)" - _debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root" + _debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root" _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root # shellcheck disable=SC2181 if [ "$?" != "0" ]; then @@ -153,7 +153,7 @@ unifi_deploy() { rm "$_import_pkcs12" - # Restarting unifi-core will bring up unifi, doing it out of order results in + # Restarting unifi-core will bring up unifi, doing it out of order results in # a certificate error, and breaks wifiman. # Restart if we aren't doing unifi-core, otherwise stop for later restart. if systemctl -q is-active unifi; then From d8637b2c0fa0ac28c9b75a05d6163accdfa84553 Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Thu, 15 Aug 2024 11:25:23 -0400 Subject: [PATCH 425/687] fixes #3359 Ubiquiti removed keytool (and java) from recent releases of Unifi OS. This moves from keytool to openssl's native pkcs12. Tested on Unifi Dream Machine which runs Unifi OS and a built-in Unifi controller. Also added backup of existing files prior to change in case anything goes wrong, and update system configuration with compatible ciphers. --- .github/workflows/DragonFlyBSD.yml | 2 +- .github/workflows/FreeBSD.yml | 4 +- .github/workflows/Linux.yml | 4 +- .github/workflows/MacOS.yml | 2 +- .github/workflows/NetBSD.yml | 2 +- .github/workflows/Omnios.yml | 4 +- .github/workflows/OpenBSD.yml | 4 +- .github/workflows/Solaris.yml | 4 +- .github/workflows/Ubuntu.yml | 4 +- .github/workflows/Windows.yml | 2 +- acme.sh | 734 +++++++++++++++-------------- deploy/routeros.sh | 7 +- deploy/synology_dsm.sh | 52 +- deploy/unifi.sh | 84 +++- deploy/vault.sh | 8 +- dnsapi/dns_1984hosting.sh | 31 +- dnsapi/dns_acmedns.sh | 28 +- dnsapi/dns_acmeproxy.sh | 18 +- dnsapi/dns_active24.sh | 11 +- dnsapi/dns_ad.sh | 17 +- dnsapi/dns_ali.sh | 12 +- dnsapi/dns_anx.sh | 13 +- dnsapi/dns_artfiles.sh | 23 +- dnsapi/dns_arvan.sh | 15 +- dnsapi/dns_aurora.sh | 16 +- dnsapi/dns_autodns.sh | 23 +- dnsapi/dns_aws.sh | 20 +- dnsapi/dns_azion.sh | 14 +- dnsapi/dns_azure.sh | 13 +- dnsapi/dns_bookmyname.sh | 21 +- dnsapi/dns_bunny.sh | 21 +- dnsapi/dns_cf.sh | 21 +- dnsapi/dns_clouddns.sh | 17 +- dnsapi/dns_cloudns.sh | 17 +- dnsapi/dns_cn.sh | 13 +- dnsapi/dns_conoha.sh | 11 + dnsapi/dns_constellix.sh | 14 +- dnsapi/dns_cpanel.sh | 26 +- dnsapi/dns_curanet.sh | 16 +- dnsapi/dns_cyon.sh | 28 +- dnsapi/dns_da.sh | 37 +- dnsapi/dns_ddnss.sh | 21 +- dnsapi/dns_desec.sh | 16 +- dnsapi/dns_df.sh | 25 +- dnsapi/dns_dgon.sh | 20 +- dnsapi/dns_dnsexit.sh | 19 +- dnsapi/dns_dnshome.sh | 21 +- dnsapi/dns_dnsimple.sh | 16 +- dnsapi/dns_dnsservices.sh | 17 +- dnsapi/dns_doapi.sh | 19 +- dnsapi/dns_domeneshop.sh | 9 + dnsapi/dns_dp.sh | 14 +- dnsapi/dns_dpi.sh | 14 +- dnsapi/dns_dreamhost.sh | 14 +- dnsapi/dns_duckdns.sh | 18 +- dnsapi/dns_durabledns.sh | 12 +- dnsapi/dns_dyn.sh | 25 +- dnsapi/dns_dynu.sh | 21 +- dnsapi/dns_dynv6.sh | 15 +- dnsapi/dns_easydns.sh | 19 +- dnsapi/dns_edgedns.sh | 25 +- dnsapi/dns_euserv.sh | 24 +- dnsapi/dns_exoscale.sh | 8 + dnsapi/dns_fornex.sh | 11 +- dnsapi/dns_freedns.sh | 19 +- dnsapi/dns_gandi_livedns.sh | 17 +- dnsapi/dns_gcloud.sh | 10 +- dnsapi/dns_gcore.sh | 12 +- dnsapi/dns_gd.sh | 16 +- dnsapi/dns_geoscaling.sh | 16 +- dnsapi/dns_googledomains.sh | 15 +- dnsapi/dns_he.sh | 21 +- dnsapi/dns_hetzner.sh | 12 +- dnsapi/dns_hexonet.sh | 14 +- dnsapi/dns_hostingde.sh | 15 +- dnsapi/dns_huaweicloud.sh | 14 +- dnsapi/dns_infoblox.sh | 14 +- dnsapi/dns_infomaniak.sh | 15 +- dnsapi/dns_internetbs.sh | 18 +- dnsapi/dns_inwx.sh | 13 +- dnsapi/dns_ionos.sh | 19 +- dnsapi/dns_ionos_cloud.sh | 145 ++++++ dnsapi/dns_ipv64.sh | 18 +- dnsapi/dns_ispconfig.sh | 21 +- dnsapi/dns_jd.sh | 15 +- dnsapi/dns_joker.sh | 33 +- dnsapi/dns_kappernet.sh | 26 +- dnsapi/dns_kas.sh | 27 +- dnsapi/dns_kinghost.sh | 19 +- dnsapi/dns_knot.sh | 10 + dnsapi/dns_la.sh | 12 +- dnsapi/dns_leaseweb.sh | 12 +- dnsapi/dns_lexicon.sh | 10 +- dnsapi/dns_linode.sh | 10 +- dnsapi/dns_linode_v4.sh | 11 +- dnsapi/dns_loopia.sh | 16 +- dnsapi/dns_lua.sh | 17 +- dnsapi/dns_maradns.sh | 9 + dnsapi/dns_me.sh | 14 +- dnsapi/dns_miab.sh | 23 +- dnsapi/dns_misaka.sh | 15 +- dnsapi/dns_myapi.sh | 17 +- dnsapi/dns_mydevil.sh | 21 +- dnsapi/dns_mydnsjp.sh | 18 +- dnsapi/dns_mythic_beasts.sh | 9 + dnsapi/dns_namecheap.sh | 15 +- dnsapi/dns_namecom.sh | 13 +- dnsapi/dns_namesilo.sh | 14 +- dnsapi/dns_nanelo.sh | 13 +- dnsapi/dns_nederhost.sh | 10 +- dnsapi/dns_neodigit.sh | 16 +- dnsapi/dns_netcup.sh | 12 +- dnsapi/dns_netlify.sh | 10 +- dnsapi/dns_nic.sh | 17 +- dnsapi/dns_njalla.sh | 11 +- dnsapi/dns_nm.sh | 20 +- dnsapi/dns_nsd.sh | 12 +- dnsapi/dns_nsone.sh | 15 +- dnsapi/dns_nsupdate.sh | 10 + dnsapi/dns_nw.sh | 27 +- dnsapi/dns_oci.sh | 17 +- dnsapi/dns_one.sh | 14 +- dnsapi/dns_online.sh | 11 +- dnsapi/dns_openprovider.sh | 21 +- dnsapi/dns_openstack.sh | 27 +- dnsapi/dns_opnsense.sh | 24 +- dnsapi/dns_ovh.sh | 20 +- dnsapi/dns_pdns.sh | 18 +- dnsapi/dns_pleskxml.sh | 32 +- dnsapi/dns_pointhq.sh | 14 +- dnsapi/dns_porkbun.sh | 17 +- dnsapi/dns_rackcorp.sh | 22 +- dnsapi/dns_rackspace.sh | 14 +- dnsapi/dns_rage4.sh | 14 +- dnsapi/dns_rcode0.sh | 14 +- dnsapi/dns_regru.sh | 15 +- dnsapi/dns_scaleway.sh | 10 +- dnsapi/dns_schlundtech.sh | 22 +- dnsapi/dns_selectel.sh | 12 +- dnsapi/dns_selfhost.sh | 15 +- dnsapi/dns_servercow.sh | 25 +- dnsapi/dns_simply.sh | 13 +- dnsapi/dns_tele3.sh | 19 +- dnsapi/dns_tencent.sh | 12 +- dnsapi/dns_transip.sh | 10 + dnsapi/dns_udr.sh | 20 +- dnsapi/dns_ultra.sh | 14 +- dnsapi/dns_unoeuro.sh | 14 +- dnsapi/dns_variomedia.sh | 11 +- dnsapi/dns_veesp.sh | 16 +- dnsapi/dns_vercel.sh | 11 +- dnsapi/dns_vscale.sh | 14 +- dnsapi/dns_vultr.sh | 12 +- dnsapi/dns_websupport.sh | 22 +- dnsapi/dns_world4you.sh | 13 +- dnsapi/dns_yandex.sh | 18 +- dnsapi/dns_yc.sh | 19 +- dnsapi/dns_zilore.sh | 8 +- dnsapi/dns_zone.sh | 10 +- dnsapi/dns_zonomi.sh | 12 +- notify/ntfy.sh | 37 ++ 161 files changed, 2085 insertions(+), 1417 deletions(-) mode change 100644 => 100755 dnsapi/dns_acmeproxy.sh create mode 100644 dnsapi/dns_ionos_cloud.sh create mode 100644 notify/ntfy.sh diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml index f360f85c..5c56168f 100644 --- a/.github/workflows/DragonFlyBSD.yml +++ b/.github/workflows/DragonFlyBSD.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml index b90c9ccd..961907e8 100644 --- a/.github/workflows/FreeBSD.yml +++ b/.github/workflows/FreeBSD.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 33e43483..c74e9d3e 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -26,11 +26,11 @@ jobs: Linux: strategy: matrix: - os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:7", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] + os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] runs-on: ubuntu-latest env: TEST_LOCAL: 1 - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) TEST_ACME_Server: "LetsEncrypt.org_test" steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml index c3f046ab..f5d73ec9 100644 --- a/.github/workflows/MacOS.yml +++ b/.github/workflows/MacOS.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml index 4574bef5..a4f90f68 100644 --- a/.github/workflows/NetBSD.yml +++ b/.github/workflows/NetBSD.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/.github/workflows/Omnios.yml b/.github/workflows/Omnios.yml index e3da0be8..882cedf6 100644 --- a/.github/workflows/Omnios.yml +++ b/.github/workflows/Omnios.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml index e141c47b..d5697c10 100644 --- a/.github/workflows/OpenBSD.yml +++ b/.github/workflows/OpenBSD.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml index bdd3f040..95bcd8d1 100644 --- a/.github/workflows/Solaris.yml +++ b/.github/workflows/Solaris.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 53cc1060..e580828f 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -29,12 +29,12 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) - TEST_ACME_Server: "LetsEncrypt.org_test" CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) ACME_USE_WGET: 1 - TEST_ACME_Server: "ZeroSSL.com" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 61ef5ad8..c1fd1085 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -29,7 +29,7 @@ jobs: CA_ECDSA: "" CA: "" CA_EMAIL: "" - TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1 + TEST_PREFERRED_CHAIN: (STAGING) #- TEST_ACME_Server: "ZeroSSL.com" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA" diff --git a/acme.sh b/acme.sh index d154cf77..ee2517c2 100755 --- a/acme.sh +++ b/acme.sh @@ -231,11 +231,11 @@ _dlg_versions() { echo "$ACME_OPENSSL_BIN doesn't exist." fi - echo "apache:" + echo "Apache:" if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then $_APACHECTL -V 2>&1 else - echo "apache doesn't exist." + echo "Apache doesn't exist." fi echo "nginx:" @@ -949,7 +949,7 @@ _getfile() { i="$(grep -n -- "$startline" "$filename" | cut -d : -f 1)" if [ -z "$i" ]; then - _err "Can not find start line: $startline" + _err "Cannot find start line: $startline" return 1 fi i="$(_math "$i" + 1)" @@ -957,7 +957,7 @@ _getfile() { j="$(grep -n -- "$endline" "$filename" | cut -d : -f 1)" if [ -z "$j" ]; then - _err "Can not find end line: $endline" + _err "Cannot find end line: $endline" return 1 fi j="$(_math "$j" - 1)" @@ -1065,7 +1065,7 @@ _sign() { if ! _signedECText="$($_sign_openssl -sha$__ECC_KEY_LEN | ${ACME_OPENSSL_BIN:-openssl} asn1parse -inform DER)"; then _err "Sign failed: $_sign_openssl" _err "Key file: $keyfile" - _err "Key content:$(wc -l <"$keyfile") lines" + _err "Key content: $(wc -l <"$keyfile") lines" return 1 fi _debug3 "_signedECText" "$_signedECText" @@ -1145,14 +1145,14 @@ _createkey() { length=2048 fi - _debug "Use length $length" + _debug "Using length $length" if ! [ -e "$f" ]; then if ! touch "$f" >/dev/null 2>&1; then _f_path="$(dirname "$f")" _debug _f_path "$_f_path" if ! mkdir -p "$_f_path"; then - _err "Can not create path: $_f_path" + _err "Cannot create path: $_f_path" return 1 fi fi @@ -1163,11 +1163,11 @@ _createkey() { fi if _isEccKey "$length"; then - _debug "Using ec name: $eccname" + _debug "Using EC name: $eccname" if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then echo "$_opkey" >"$f" else - _err "error ecc key name: $eccname" + _err "Error encountered for ECC key named $eccname" return 1 fi else @@ -1179,13 +1179,13 @@ _createkey() { if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then echo "$_opkey" >"$f" else - _err "error rsa key: $length" + _err "Error encountered for RSA key of length $length" return 1 fi fi if [ "$?" != "0" ]; then - _err "Create key error." + _err "Key creation error." return 1 fi } @@ -1243,7 +1243,14 @@ _createcsr() { _debug2 csr "$csr" _debug2 csrconf "$csrconf" - printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\nextendedKeyUsage=serverAuth,clientAuth\n" >"$csrconf" + printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]" >"$csrconf" + + if [ "$Le_ExtKeyUse" ]; then + _savedomainconf Le_ExtKeyUse "$Le_ExtKeyUse" + printf "\nextendedKeyUsage=$Le_ExtKeyUse\n" >>"$csrconf" + else + printf "\nextendedKeyUsage=serverAuth,clientAuth\n" >>"$csrconf" + fi if [ "$acmeValidationv1" ]; then domainlist="$(_idn "$domainlist")" @@ -1452,7 +1459,7 @@ toPkcs() { _toPkcs "$CERT_PFX_PATH" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$pfxPassword" if [ "$?" = "0" ]; then - _info "Success, Pfx is exported to: $CERT_PFX_PATH" + _info "Success, PFX has been exported to: $CERT_PFX_PATH" fi } @@ -1496,7 +1503,7 @@ _create_account_key() { length=$1 if [ -z "$length" ] || [ "$length" = "$NO_VALUE" ]; then - _debug "Use default length $DEFAULT_ACCOUNT_KEY_LENGTH" + _debug "Using default length $DEFAULT_ACCOUNT_KEY_LENGTH" length="$DEFAULT_ACCOUNT_KEY_LENGTH" fi @@ -1505,15 +1512,15 @@ _create_account_key() { mkdir -p "$CA_DIR" if [ -s "$ACCOUNT_KEY_PATH" ]; then - _info "Account key exists, skip" + _info "Account key exists, skipping" return 0 else #generate account key if _createkey "$length" "$ACCOUNT_KEY_PATH"; then - _info "Create account key ok." + _info "Account key creation OK." return 0 else - _err "Create account key error." + _err "Account key creation error." return 1 fi fi @@ -1532,7 +1539,7 @@ createDomainKey() { _cdl=$2 if [ -z "$_cdl" ]; then - _debug "Use DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH" + _debug "Using DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH" _cdl="$DEFAULT_DOMAIN_KEY_LENGTH" fi @@ -1544,16 +1551,16 @@ createDomainKey() { _info "The domain key is here: $(__green $CERT_KEY_PATH)" return 0 else - _err "Can not create domain key" + _err "Cannot create domain key" return 1 fi else if [ "$_ACME_IS_RENEW" ]; then - _info "Domain key exists, skip" + _info "Domain key exists, skipping" return 0 else - _err "Domain key exists, do you want to overwrite the key?" - _err "Add '--force', and try again." + _err "Domain key exists, do you want to overwrite it?" + _err "If so, add '--force' and try again." return 1 fi fi @@ -1562,7 +1569,7 @@ createDomainKey() { # domain domainlist isEcc createCSR() { - _info "Creating csr" + _info "Creating CSR" if [ -z "$1" ]; then _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...] [--ecc]" return @@ -1575,13 +1582,13 @@ createCSR() { _initpath "$domain" "$_isEcc" if [ -f "$CSR_PATH" ] && [ "$_ACME_IS_RENEW" ] && [ -z "$FORCE" ]; then - _info "CSR exists, skip" + _info "CSR exists, skipping" return fi if [ ! -f "$CERT_KEY_PATH" ]; then - _err "The key file is not found: $CERT_KEY_PATH" - _err "Please create the key file first." + _err "This key file was not found: $CERT_KEY_PATH" + _err "Please create it first." return 1 fi _createcsr "$domain" "$domainlist" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF" @@ -1725,7 +1732,7 @@ _calcjwk() { __ECC_KEY_LEN=512 ;; *) - _err "ECC oid : $crv_oid" + _err "ECC oid: $crv_oid" return 1 ;; esac @@ -1768,7 +1775,7 @@ _calcjwk() { JWK_HEADERPLACE_PART1='{"nonce": "' JWK_HEADERPLACE_PART2='", "alg": "ES'$__ECC_KEY_LEN'"' else - _err "Only RSA or EC key is supported. keyfile=$keyfile" + _err "Only RSA or EC keys are supported. keyfile=$keyfile" _debug2 "$(cat "$keyfile")" return 1 fi @@ -1802,7 +1809,7 @@ _date2time() { if da="$(echo "$1" | tr -d "Z" | tr "T" ' ')" perl -MTime::Piece -e 'print Time::Piece->strptime($ENV{da}, "%Y-%m-%d %H:%M:%S")->epoch, "\n";' 2>/dev/null; then return fi - _err "Can not parse _date2time $1" + _err "Cannot parse _date2time $1" return 1 } @@ -1826,7 +1833,7 @@ _mktemp() { echo "/$LE_TEMP_DIR/wefADf24sf.$(_time).tmp" return 0 fi - _err "Can not create temp file." + _err "Cannot create temp file." } #clear all the https envs to cause _inithttp() to run next time. @@ -2015,7 +2022,7 @@ _post() { _ret="$?" if [ "$_ret" = "8" ]; then _ret=0 - _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." + _debug "wget returned 8 as the server returned a 'Bad Request' response. Let's process the response later." fi if [ "$_ret" != "0" ]; then _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" @@ -2029,7 +2036,7 @@ _post() { _sed_i 's/^ //g' "$HTTP_HEADER" else _ret="$?" - _err "Neither curl nor wget is found, can not do $httpmethod." + _err "Neither curl nor wget have been found, cannot make $httpmethod request." fi _debug "_ret" "$_ret" printf "%s" "$response" @@ -2098,14 +2105,14 @@ _get() { ret=$? if [ "$ret" = "8" ]; then ret=0 - _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." + _debug "wget returned 8 as the server returned a 'Bad Request' response. Let's process the response later." fi if [ "$ret" != "0" ]; then _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" fi else ret=$? - _err "Neither curl nor wget is found, can not do GET." + _err "Neither curl nor wget have been found, cannot make GET request." fi _debug "ret" "$ret" return $ret @@ -2137,7 +2144,7 @@ _send_signed_request() { if [ -z "$keyfile" ]; then keyfile="$ACCOUNT_KEY_PATH" fi - _debug "=======Begin Send Signed Request=======" + _debug "=======Sending Signed Request=======" _debug url "$url" _debug payload "$payload" @@ -2183,7 +2190,7 @@ _send_signed_request() { fi _debug2 _CACHED_NONCE "$_CACHED_NONCE" if [ "$?" != "0" ]; then - _err "Can not connect to $nonceurl to get nonce." + _err "Cannot connect to $nonceurl to get nonce." return 1 fi else @@ -2226,7 +2233,7 @@ _send_signed_request() { _CACHED_NONCE="" if [ "$?" != "0" ]; then - _err "Can not post to $url" + _err "Cannot make POST request to $url" return 1 fi @@ -2258,21 +2265,21 @@ _send_signed_request() { _sleep_overload_retry_sec=5 fi if [ $_sleep_overload_retry_sec -le 600 ]; then - _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds." + _info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping for $_sleep_overload_retry_sec seconds." _sleep $_sleep_overload_retry_sec continue else - _info "The retryafter=$_retryafter is too large > 600, not retry anymore." + _info "The retryafter=$_retryafter value is too large (> 600), will not retry anymore." fi fi if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then - _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." + _info "It seems the CA server is busy now, let's wait and retry. Sleeping for $_sleep_retry_sec seconds." _CACHED_NONCE="" _sleep $_sleep_retry_sec continue fi if _contains "$_body" "The Replay Nonce is not recognized"; then - _info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds." + _info "The replay nonce is not valid, let's get a new one. Sleeping for $_sleep_retry_sec seconds." _CACHED_NONCE="" _sleep $_sleep_retry_sec continue @@ -2344,7 +2351,7 @@ _save_conf() { if [ "$_s_c_f" ]; then _setopt "$_s_c_f" "$_sdkey" "=" "'$_sdvalue'" else - _err "config file is empty, can not save $_sdkey=$_sdvalue" + _err "Config file is empty, cannot save $_sdkey=$_sdvalue" fi } @@ -2356,7 +2363,7 @@ _clear_conf() { _conf_data="$(cat "$_c_c_f")" echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" >"$_c_c_f" else - _err "config file is empty, can not clear" + _err "Config file is empty, cannot clear" fi } @@ -2374,7 +2381,7 @@ _read_conf() { fi printf "%s" "$_sdv" else - _debug "config file is empty, can not read $_sdkey" + _debug "Config file is empty, cannot read $_sdkey" fi } @@ -2592,7 +2599,7 @@ _starttlsserver() { #create key TLS_KEY if ! _createkey "2048" "$TLS_KEY"; then - _err "Create tls validation key error." + _err "Error creating TLS validation key." return 1 fi @@ -2602,13 +2609,13 @@ _starttlsserver() { alt="$alt,$san_b" fi if ! _createcsr "tls.acme.sh" "$alt" "$TLS_KEY" "$TLS_CSR" "$TLS_CONF" "$acmeValidationv1"; then - _err "Create tls validation csr error." + _err "Error creating TLS validation CSR." return 1 fi #self signed if ! _signcsr "$TLS_KEY" "$TLS_CSR" "$TLS_CONF" "$TLS_CERT"; then - _err "Create tls validation cert error." + _err "Error creating TLS validation cert." return 1 fi @@ -2662,7 +2669,7 @@ _conapath() { __initHome() { if [ -z "$_SCRIPT_HOME" ]; then if _exists readlink && _exists dirname; then - _debug "Lets find script dir." + _debug "Let's find the script directory." _debug "_SCRIPT_" "$_SCRIPT_" _script="$(_readlink "$_SCRIPT_")" _debug "_script" "$_script" @@ -2671,7 +2678,7 @@ __initHome() { if [ -d "$_script_home" ]; then export _SCRIPT_HOME="$_script_home" else - _err "It seems the script home is not correct:$_script_home" + _err "It seems the script home is not correct: $_script_home" fi fi fi @@ -2686,7 +2693,7 @@ __initHome() { # fi if [ -z "$LE_WORKING_DIR" ]; then - _debug "Using default home:$DEFAULT_INSTALL_HOME" + _debug "Using default home: $DEFAULT_INSTALL_HOME" LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" fi export LE_WORKING_DIR @@ -2694,7 +2701,7 @@ __initHome() { if [ -z "$LE_CONFIG_HOME" ]; then LE_CONFIG_HOME="$LE_WORKING_DIR" fi - _debug "Using config home:$LE_CONFIG_HOME" + _debug "Using config home: $LE_CONFIG_HOME" export LE_CONFIG_HOME _DEFAULT_ACCOUNT_CONF_PATH="$LE_CONFIG_HOME/account.conf" @@ -2731,7 +2738,7 @@ _clearAPI() { #server _initAPI() { _api_server="${1:-$ACME_DIRECTORY}" - _debug "_init api for server: $_api_server" + _debug "_init API for server: $_api_server" MAX_API_RETRY_TIMES=10 _sleep_retry_sec=10 @@ -2741,8 +2748,8 @@ _initAPI() { response=$(_get "$_api_server") if [ "$?" != "0" ]; then _debug2 "response" "$response" - _info "Can not init api for: $_api_server." - _info "Sleep $_sleep_retry_sec and retry." + _info "Cannot init API for: $_api_server." + _info "Sleeping for $_sleep_retry_sec seconds and retrying." _sleep "$_sleep_retry_sec" continue fi @@ -2780,13 +2787,13 @@ _initAPI() { if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi - _info "Sleep $_sleep_retry_sec and retry." + _info "Sleeping for $_sleep_retry_sec seconds and retrying." _sleep "$_sleep_retry_sec" done if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then return 0 fi - _err "Can not init api, for $_api_server" + _err "Cannot init API for $_api_server" return 1 } @@ -2918,7 +2925,7 @@ _initpath() { DOMAIN_PATH="$domainhomeecc" elif [ -z "$__SELECTED_RSA_KEY" ]; then if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then - _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert." + _info "The domain '$domain' seems to already have an ECC cert, let's use it." DOMAIN_PATH="$domainhomeecc" fi fi @@ -2981,7 +2988,7 @@ _apachePath() { if _exists apache2ctl; then _APACHECTL="apache2ctl" else - _err "'apachectl not found. It seems that apache is not installed, or you are not root user.'" + _err "'apachectl not found. It seems that Apache is not installed or you are not root.'" _err "Please use webroot mode to try again." return 1 fi @@ -3000,7 +3007,7 @@ _apachePath() { _debug httpdconfname "$httpdconfname" if [ -z "$httpdconfname" ]; then - _err "Can not read apache config file." + _err "Cannot read Apache config file." return 1 fi @@ -3017,7 +3024,7 @@ _apachePath() { _debug httpdconf "$httpdconf" _debug httpdconfname "$httpdconfname" if [ ! -f "$httpdconf" ]; then - _err "Apache Config file not found" "$httpdconf" + _err "Apache config file not found" "$httpdconf" return 1 fi return 0 @@ -3040,7 +3047,7 @@ _restoreApache() { cat "$APACHE_CONF_BACKUP_DIR/$httpdconfname" >"$httpdconf" _debug "Restored: $httpdconf." if ! $_APACHECTL -t; then - _err "Sorry, restore apache config error, please contact me." + _err "Sorry, there's been an error restoring the Apache config. Please ask for support on $PROJECT." return 1 fi _debug "Restored successfully." @@ -3055,26 +3062,26 @@ _setApache() { fi #test the conf first - _info "Checking if there is an error in the apache config file before starting." + _info "Checking if there is an error in the Apache config file before starting." if ! $_APACHECTL -t >/dev/null; then - _err "The apache config file has error, please fix it first, then try again." - _err "Don't worry, there is nothing changed to your system." + _err "The Apache config file has errors, please fix them first then try again." + _err "Don't worry, no changes to your system have been made." return 1 else _info "OK" fi #backup the conf - _debug "Backup apache config file" "$httpdconf" + _debug "Backing up Apache config file" "$httpdconf" if ! cp "$httpdconf" "$APACHE_CONF_BACKUP_DIR/"; then - _err "Can not backup apache config file, so abort. Don't worry, the apache config is not changed." - _err "This might be a bug of $PROJECT_NAME , please report issue: $PROJECT" + _err "Cannot backup Apache config file, aborting. Don't worry, the Apache config has not been changed." + _err "This might be an $PROJECT_NAME bug, please open an issue on $PROJECT" return 1 fi - _info "JFYI, Config file $httpdconf is backuped to $APACHE_CONF_BACKUP_DIR/$httpdconfname" - _info "In case there is an error that can not be restored automatically, you may try restore it yourself." - _info "The backup file will be deleted on success, just forget it." + _info "Config file $httpdconf has been backed up to $APACHE_CONF_BACKUP_DIR/$httpdconfname" + _info "In case an error causes it to not be restored automatically, you can restore it yourself." + _info "You do not need to do anything on success, as the backup file will automatically be deleted." #add alias @@ -3104,11 +3111,11 @@ Allow from all _msg="$($_APACHECTL -t 2>&1)" if [ "$?" != "0" ]; then - _err "Sorry, apache config error" + _err "Sorry, an Apache config error has occurred" if _restoreApache; then - _err "The apache config file is restored." + _err "The Apache config file has been restored." else - _err "Sorry, the apache config file can not be restored, please report bug." + _err "Sorry, the Apache config file cannot be restored, please open an issue on $PROJECT." fi return 1 fi @@ -3119,7 +3126,7 @@ Allow from all fi if ! $_APACHECTL graceful; then - _err "$_APACHECTL graceful error, please contact me." + _err "$_APACHECTL graceful error, please open an issue on $PROJECT." _restoreApache return 1 fi @@ -3143,10 +3150,10 @@ _setNginx() { _start_f="$(echo "$_croot" | cut -d : -f 2)" _debug _start_f "$_start_f" if [ -z "$_start_f" ]; then - _debug "find start conf from nginx command" + _debug "Finding config using the nginx command" if [ -z "$NGINX_CONF" ]; then if ! _exists "nginx"; then - _err "nginx command is not found." + _err "nginx command not found." return 1 fi NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "\-\-conf-path=[^ ]* " | tr -d " ")" @@ -3154,7 +3161,7 @@ _setNginx() { NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)" _debug NGINX_CONF "$NGINX_CONF" if [ -z "$NGINX_CONF" ]; then - _err "Can not find nginx conf." + _err "Cannot find nginx config." NGINX_CONF="" return 1 fi @@ -3163,16 +3170,16 @@ _setNginx() { NGINX_CONF="" return 1 fi - _debug "Found nginx conf file:$NGINX_CONF" + _debug "Found nginx config file: $NGINX_CONF" fi _start_f="$NGINX_CONF" fi - _debug "Start detect nginx conf for $_d from:$_start_f" + _debug "Detecting nginx conf for $_d from: $_start_f" if ! _checkConf "$_d" "$_start_f"; then - _err "Can not find conf file for domain $d" + _err "Cannot find config file for domain $d" return 1 fi - _info "Found conf file: $FOUND_REAL_NGINX_CONF" + _info "Found config file: $FOUND_REAL_NGINX_CONF" _ln=$FOUND_REAL_NGINX_CONF_LN _debug "_ln" "$_ln" @@ -3182,7 +3189,7 @@ _setNginx() { _start_tag="$(sed -n "$_lnn,${_lnn}p" "$FOUND_REAL_NGINX_CONF")" _debug "_start_tag" "$_start_tag" if [ "$_start_tag" = "$NGINX_START" ]; then - _info "The domain $_d is already configured, skip" + _info "The domain $_d is already configured, skipping" FOUND_REAL_NGINX_CONF="" return 0 fi @@ -3191,28 +3198,28 @@ _setNginx() { _backup_conf="$DOMAIN_BACKUP_PATH/$_d.nginx.conf" _debug _backup_conf "$_backup_conf" BACKUP_NGINX_CONF="$_backup_conf" - _info "Backup $FOUND_REAL_NGINX_CONF to $_backup_conf" + _info "Backing $FOUND_REAL_NGINX_CONF up to $_backup_conf" if ! cp "$FOUND_REAL_NGINX_CONF" "$_backup_conf"; then - _err "backup error." + _err "Backup error." FOUND_REAL_NGINX_CONF="" return 1 fi if ! _exists "nginx"; then - _err "nginx command is not found." + _err "nginx command not found." return 1 fi - _info "Check the nginx conf before setting up." + _info "Checking the nginx config before setting up." if ! nginx -t >/dev/null 2>&1; then - _err "It seems that nginx conf is not correct, cannot continue." + _err "It seems that the nginx config is not correct, cannot continue." return 1 fi - _info "OK, Set up nginx config file" + _info "OK, setting up the nginx config file" if ! sed -n "1,${_ln}p" "$_backup_conf" >"$FOUND_REAL_NGINX_CONF"; then cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" - _err "write nginx conf error, but don't worry, the file is restored to the original version." + _err "Error writing nginx config. Restoring it to its original version." return 1 fi @@ -3226,20 +3233,20 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { if ! sed -n "${_lnn},99999p" "$_backup_conf" >>"$FOUND_REAL_NGINX_CONF"; then cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" - _err "write nginx conf error, but don't worry, the file is restored." + _err "Error writing nginx config. Restoring it to its original version." return 1 fi _debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)" - _info "nginx conf is done, let's check it again." + _info "nginx config has been written, let's check it again." if ! nginx -t >/dev/null 2>&1; then - _err "It seems that nginx conf was broken, let's restore." + _err "There seems to be a problem with the nginx config, let's restore it to its original version." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi - _info "Reload nginx" + _info "Reloading nginx" if ! nginx -s reload >/dev/null 2>&1; then - _err "It seems that nginx reload error, let's restore." + _err "There seems to be a problem with the nginx config, let's restore it to its original version." cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" return 1 fi @@ -3251,7 +3258,7 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" { _checkConf() { _d="$1" _c_file="$2" - _debug "Start _checkConf from:$_c_file" + _debug "Starting _checkConf from: $_c_file" if [ ! -f "$2" ] && ! echo "$2" | grep '*$' >/dev/null && echo "$2" | grep '*' >/dev/null; then _debug "wildcard" for _w_f in $2; do @@ -3264,14 +3271,14 @@ _checkConf() { elif [ -f "$2" ]; then _debug "single" if _isRealNginxConf "$1" "$2"; then - _debug "$2 is found." + _debug "$2 found." FOUND_REAL_NGINX_CONF="$2" return 0 fi if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then - _debug "Try include files" + _debug "Trying include files" for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do - _debug "check included $included" + _debug "Checking included $included" if ! _startswith "$included" "/" && _exists dirname; then _relpath="$(dirname "$2")" _debug "_relpath" "$_relpath" @@ -3347,7 +3354,7 @@ _isRealNginxConf() { #restore all the nginx conf _restoreNginx() { if [ -z "$NGINX_RESTORE_VLIST" ]; then - _debug "No need to restore nginx, skip." + _debug "No need to restore nginx config, skipping." return fi _debug "_restoreNginx" @@ -3362,9 +3369,9 @@ _restoreNginx() { cat "$_ngbackupconf" >"$_ngconf" done - _info "Reload nginx" + _info "Reloading nginx" if ! nginx -s reload >/dev/null; then - _err "It seems that nginx reload error, please report bug." + _err "An error occurred while reloading nginx, please open an issue on $PROJECT." return 1 fi return 0 @@ -3389,7 +3396,7 @@ _clearupdns() { _debug "dns_entries" "$dns_entries" if [ -z "$dns_entries" ]; then - _debug "skip dns." + _debug "Skipping dns." return fi _info "Removing DNS records." @@ -3412,7 +3419,7 @@ _clearupdns() { fi if [ -z "$d_api" ]; then - _info "Not Found domain api file: $d_api" + _info "Domain API file was not found: $d_api" continue fi @@ -3422,21 +3429,21 @@ _clearupdns() { ( if ! . "$d_api"; then - _err "Load file $d_api error. Please check your api file and try again." + _err "Error loading file $d_api. Please check your API file and try again." return 1 fi rmcommand="${_currentRoot}_rm" if ! _exists "$rmcommand"; then - _err "It seems that your api file doesn't define $rmcommand" + _err "It seems that your API file doesn't define $rmcommand" return 1 fi _info "Removing txt: $txt for domain: $txtdomain" if ! $rmcommand "$txtdomain" "$txt"; then - _err "Error removing txt for domain:$txtdomain" + _err "Error removing txt for domain: $txtdomain" return 1 fi - _info "Removed: Success" + _info "Successfully removed" ) done @@ -3446,7 +3453,7 @@ _clearupdns() { _clearupwebbroot() { __webroot="$1" if [ -z "$__webroot" ]; then - _debug "no webroot specified, skip" + _debug "No webroot specified, skipping" return 0 fi @@ -3458,12 +3465,12 @@ _clearupwebbroot() { elif [ "$2" = '3' ]; then _rmpath="$__webroot/.well-known/acme-challenge/$3" else - _debug "Skip for removelevel:$2" + _debug "Skipping for removelevel: $2" fi if [ "$_rmpath" ]; then if [ "$DEBUG" ]; then - _debug "Debugging, skip removing: $_rmpath" + _debug "Debugging, not removing: $_rmpath" else rm -rf "$_rmpath" fi @@ -3484,13 +3491,13 @@ _on_before_issue() { _debug _chk_alt_domains "$_chk_alt_domains" #run pre hook if [ "$_chk_pre_hook" ]; then - _info "Run pre hook:'$_chk_pre_hook'" + _info "Runing pre hook:'$_chk_pre_hook'" if ! ( export Le_Domain="$_chk_main_domain" export Le_Alt="$_chk_alt_domains" cd "$DOMAIN_PATH" && eval "$_chk_pre_hook" ); then - _err "Error when run pre hook." + _err "Error occurred when running pre hook." return 1 fi fi @@ -3515,7 +3522,7 @@ _on_before_issue() { if [ -z "$d" ]; then break fi - _debug "Check for domain" "$d" + _debug "Checking for domain" "$d" _currentRoot="$(_getfield "$_chk_web_roots" $_index)" _debug "_currentRoot" "$_currentRoot" _index=$(_math $_index + 1) @@ -3562,7 +3569,7 @@ _on_before_issue() { if _hasfield "$_chk_web_roots" "apache"; then if ! _setApache; then - _err "set up apache error. Report error to me." + _err "Error setting up Apache. Please open an issue on $PROJECT." return 1 fi else @@ -3579,17 +3586,17 @@ _on_issue_err() { if [ "$LOG_FILE" ]; then _err "Please check log file for more details: $LOG_FILE" else - _err "Please add '--debug' or '--log' to check more details." + _err "Please add '--debug' or '--log' to see more information." _err "See: $_DEBUG_WIKI" fi #run the post hook if [ "$_chk_post_hook" ]; then - _info "Run post hook:'$_chk_post_hook'" + _info "Running post hook: '$_chk_post_hook'" if ! ( cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then - _err "Error when run post hook." + _err "Error encountered while running post hook." return 1 fi fi @@ -3628,7 +3635,7 @@ _on_issue_success() { #run the post hook if [ "$_chk_post_hook" ]; then - _info "Run post hook:'$_chk_post_hook'" + _info "Running post hook:'$_chk_post_hook'" if ! ( export CERT_PATH export CERT_KEY_PATH @@ -3637,14 +3644,14 @@ _on_issue_success() { export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_post_hook" ); then - _err "Error when run post hook." + _err "Error encountered while running post hook." return 1 fi fi #run renew hook if [ "$_ACME_IS_RENEW" ] && [ "$_chk_renew_hook" ]; then - _info "Run renew hook:'$_chk_renew_hook'" + _info "Running renew hook: '$_chk_renew_hook'" if ! ( export CERT_PATH export CERT_KEY_PATH @@ -3653,7 +3660,7 @@ _on_issue_success() { export Le_Domain="$_main_domain" cd "$DOMAIN_PATH" && eval "$_chk_renew_hook" ); then - _err "Error when run renew hook." + _err "Error encountered while running renew hook." return 1 fi fi @@ -3709,7 +3716,7 @@ _regAccount() { if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if ! _create_account_key "$_reg_length"; then - _err "Create account key error." + _err "Error creating account key." return 1 fi fi @@ -3732,7 +3739,7 @@ _regAccount() { if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then - _info "No EAB credentials found for ZeroSSL, let's get one" + _info "No EAB credentials found for ZeroSSL, let's obtain them" if [ -z "$_email" ]; then _info "$(__green "$PROJECT_NAME is using ZeroSSL as default CA now.")" _info "$(__green "Please update your account with an email address first.")" @@ -3743,20 +3750,20 @@ _regAccount() { _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) if [ "$?" != "0" ]; then _debug2 "$_eabresp" - _err "Can not get EAB credentials from ZeroSSL." + _err "Cannot get EAB credentials from ZeroSSL." return 1 fi _secure_debug2 _eabresp "$_eabresp" _eab_id="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_id "$_eab_id" if [ -z "$_eab_id" ]; then - _err "Can not resolve _eab_id" + _err "Cannot resolve _eab_id" return 1 fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" _secure_debug2 _eab_hmac_key "$_eab_hmac_key" if [ -z "$_eab_hmac_key" ]; then - _err "Can not resolve _eab_hmac_key" + _err "Cannot resolve _eab_hmac_key" return 1 fi _savecaconf CA_EAB_KEY_ID "$_eab_id" @@ -3793,7 +3800,7 @@ _regAccount() { _info "Registering account: $ACME_DIRECTORY" if ! _send_signed_request "${ACME_NEW_ACCOUNT}" "$regjson"; then - _err "Register account Error: $response" + _err "Error registering account: $response" return 1 fi @@ -3804,10 +3811,10 @@ _regAccount() { elif [ "$code" = '409' ] || [ "$code" = '200' ]; then _info "Already registered" elif [ "$code" = '400' ] && _contains "$response" 'The account is not awaiting external account binding'; then - _info "Already register EAB." + _info "EAB already registered" _eabAlreadyBound=1 else - _err "Register account Error: $response" + _err "Account registration error: $response" return 1 fi @@ -3816,7 +3823,7 @@ _regAccount() { _accUri="$(echo "$responseHeaders" | grep -i "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n ")" _debug "_accUri" "$_accUri" if [ -z "$_accUri" ]; then - _err "Can not find account id url." + _err "Cannot find account id url." _err "$responseHeaders" return 1 fi @@ -3831,7 +3838,7 @@ _regAccount() { _savecaconf CA_KEY_HASH "$CA_KEY_HASH" if [ "$code" = '403' ]; then - _err "It seems that the account key is already deactivated, please use a new account key." + _err "It seems that the account key has been deactivated, please use a new account key." return 1 fi @@ -3844,7 +3851,7 @@ updateaccount() { _initpath if [ ! -f "$ACCOUNT_KEY_PATH" ]; then - _err "Account key is not found at: $ACCOUNT_KEY_PATH" + _err "Account key not found at: $ACCOUNT_KEY_PATH" return 1 fi @@ -3852,8 +3859,7 @@ updateaccount() { _debug _accUri "$_accUri" if [ -z "$_accUri" ]; then - _err "The account url is empty, please run '--update-account' first to update the account info first," - _err "Then try again." + _err "The account URL is empty, please run '--update-account' first to update the account info, then try again." return 1 fi @@ -3876,7 +3882,7 @@ updateaccount() { echo "$response" >"$ACCOUNT_JSON_PATH" _info "Account update success for $_accUri." else - _info "Error. The account was not updated." + _info "An error occurred and the account was not updated." return 1 fi } @@ -3886,7 +3892,7 @@ deactivateaccount() { _initpath if [ ! -f "$ACCOUNT_KEY_PATH" ]; then - _err "Account key is not found at: $ACCOUNT_KEY_PATH" + _err "Account key not found at: $ACCOUNT_KEY_PATH" return 1 fi @@ -3894,8 +3900,7 @@ deactivateaccount() { _debug _accUri "$_accUri" if [ -z "$_accUri" ]; then - _err "The account url is empty, please run '--update-account' first to update the account info first," - _err "Then try again." + _err "The account URL is empty, please run '--update-account' first to update the account info, then try again." return 1 fi @@ -3907,13 +3912,13 @@ deactivateaccount() { _djson="{\"status\":\"deactivated\"}" if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then - _info "Deactivate account success for $_accUri." + _info "Successfully deactivated account $_accUri." _accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,') elif [ "$code" = "403" ]; then _info "The account is already deactivated." _accid=$(_getfield "$_accUri" "999" "/") else - _err "Deactivate: account failed for $_accUri." + _err "Account deactivation failed for $_accUri." return 1 fi @@ -3927,7 +3932,7 @@ deactivateaccount() { mv "$ACCOUNT_JSON_PATH" "$_deactivated_account_path/" mv "$ACCOUNT_KEY_PATH" "$_deactivated_account_path/" else - _err "Can not create dir: $_deactivated_account_path, try to remove the deactivated account key." + _err "Cannot create dir: $_deactivated_account_path, try to remove the deactivated account key." rm -f "$CA_CONF" rm -f "$ACCOUNT_JSON_PATH" rm -f "$ACCOUNT_KEY_PATH" @@ -3970,28 +3975,28 @@ __get_domain_new_authz() { _Max_new_authz_retry_times=5 _authz_i=0 while [ "$_authz_i" -lt "$_Max_new_authz_retry_times" ]; do - _debug "Try new-authz for the $_authz_i time." + _debug "Trying new-authz, attempt number $_authz_i." if ! _send_signed_request "${ACME_NEW_AUTHZ}" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$(_idn "$_gdnd")\"}}"; then - _err "Can not get domain new authz." + _err "Cannot get new authz for domain." return 1 fi if _contains "$response" "No registration exists matching provided key"; then - _err "It seems there is an error, but it's recovered now, please try again." - _err "If you see this message for a second time, please report bug: $(__green "$PROJECT")" + _err "There has been an error, but it might now be resolved, please try again." + _err "If you see this message for a second time, please report this as a bug: $(__green "$PROJECT")" _clearcaconf "CA_KEY_HASH" break fi if ! _contains "$response" "An error occurred while processing your request"; then - _info "The new-authz request is ok." + _info "new-authz request successful." break fi _authz_i="$(_math "$_authz_i" + 1)" - _info "The server is busy, Sleep $_authz_i to retry." + _info "The server is busy, sleeping for $_authz_i seconds and retrying." _sleep "$_authz_i" done if [ "$_authz_i" = "$_Max_new_authz_retry_times" ]; then - _err "new-authz retry reach the max $_Max_new_authz_retry_times times." + _err "new-authz has been retried $_Max_new_authz_retry_times times, stopping." fi if [ "$code" ] && [ "$code" != '201' ]; then @@ -4047,7 +4052,7 @@ _ns_lookup_cf() { _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" - _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" + _debug "Purging Cloudflare $_cf_d_type record for domain $_cf_d" _cf_purl="https://cloudflare-dns.com/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" @@ -4112,21 +4117,21 @@ _ns_lookup_dp() { _ns_select_doh() { if [ -z "$DOH_USE" ]; then - _debug "Detect dns server first." + _debug "Detecting DNS server first." if _ns_is_available_cf; then - _debug "Use cloudflare doh server" + _debug "Using Cloudflare doh server" export DOH_USE=$DOH_CLOUDFLARE elif _ns_is_available_google; then - _debug "Use google doh server" + _debug "Using Google DOH server" export DOH_USE=$DOH_GOOGLE elif _ns_is_available_ali; then - _debug "Use aliyun doh server" + _debug "Using Aliyun DOH server" export DOH_USE=$DOH_ALI elif _ns_is_available_dp; then - _debug "Use dns pod doh server" + _debug "Using DNS POD DOH server" export DOH_USE=$DOH_DP else - _err "No doh" + _err "No DOH" fi fi } @@ -4143,7 +4148,7 @@ _ns_lookup() { elif [ "$DOH_USE" = "$DOH_DP" ]; then _ns_lookup_dp "$@" else - _err "Unknown doh provider: DOH_USE=$DOH_USE" + _err "Unknown DOH provider: DOH_USE=$DOH_USE" fi } @@ -4169,7 +4174,7 @@ __purge_txt() { if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then _ns_purge_cf "$_p_txtdomain" "TXT" else - _debug "no purge api for this doh api, just sleep 5 secs" + _debug "No purge API for this DOH API, just sleeping for 5 seconds" _sleep 5 fi @@ -4200,17 +4205,17 @@ _check_dns_entries() { _debug "d_api" "$d_api" _info "Checking $d for $aliasDomain" if _contains "$_success_txt" ",$txt,"; then - _info "Already success, continue next one." + _info "Already succeeded, continuing." continue fi if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then - _info "Domain $d '$aliasDomain' success." + _info "Success for domain $d '$aliasDomain'." _success_txt="$_success_txt,$txt," continue fi _left=1 - _info "Not valid yet, let's wait 10 seconds and check next one." + _info "Not valid yet, let's wait for 10 seconds then check the next one." __purge_txt "$txtdomain" if [ "$txtdomain" != "$aliasDomain" ]; then __purge_txt "$aliasDomain" @@ -4218,10 +4223,10 @@ _check_dns_entries() { _sleep 10 done if [ "$_left" ]; then - _info "Let's wait 10 seconds and check again". + _info "Let's wait for 10 seconds and check again". _sleep 10 else - _info "All success, let's return" + _info "All checks succeeded" return 0 fi done @@ -4337,14 +4342,14 @@ _convertValidaty() { elif _endswith "$_dateTo" "d"; then _v_end=$(_math "$_v_begin + 60 * 60 * 24 * $(echo "$_dateTo" | tr -d '+d')") else - _err "Not recognized format for _dateTo: $_dateTo" + _err "Unrecognized format for _dateTo: $_dateTo" return 1 fi _debug2 "_v_end" "$_v_end" _time2str "$_v_end" else if [ "$(_time)" -gt "$(_date2time "$_dateTo")" ]; then - _err "The validaty to is in the past: _dateTo = $_dateTo" + _err "The validity end date is in the past: _dateTo = $_dateTo" return 1 fi echo "$_dateTo" @@ -4408,7 +4413,7 @@ issue() { _valid_to_saved=$(_readdomainconf Le_Valid_to) if [ "$_valid_to_saved" ] && ! _startswith "$_valid_to_saved" "+"; then _info "The domain is set to be valid to: $_valid_to_saved" - _info "It can not be renewed automatically" + _info "It cannot be renewed automatically" _info "See: $_VALIDITY_WIKI" return $RENEW_SKIP fi @@ -4424,8 +4429,8 @@ issue() { if [ "$_normized_saved_domains" = "$_normized_domains" ]; then _info "Domains not changed." - _info "Skip, Next renewal time is: $(__green "$(_readdomainconf Le_NextRenewTimeStr)")" - _info "Add '$(__red '--force')' to force to renew." + _info "Skipping. Next renewal time is: $(__green "$(_readdomainconf Le_NextRenewTimeStr)")" + _info "Add '$(__red '--force')' to force renewal." return $RENEW_SKIP else _info "Domains have changed." @@ -4484,7 +4489,7 @@ issue() { return 1 fi else - _debug "_saved_account_key_hash is not changed, skip register account." + _debug "_saved_account_key_hash was not changed, skipping account registration." fi export Le_Next_Domain_Key="$CERT_KEY_PATH.next" @@ -4498,15 +4503,15 @@ issue() { if [ -z "$_key" ]; then _key=2048 fi - _debug "Read key length:$_key" + _debug "Read key length: $_key" if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then if [ "$Le_ForceNewDomainKey" = "1" ] && [ -f "$Le_Next_Domain_Key" ]; then - _info "Using pre generated key: $Le_Next_Domain_Key" + _info "Using pre-generated key: $Le_Next_Domain_Key" cat "$Le_Next_Domain_Key" >"$CERT_KEY_PATH" echo "" >"$Le_Next_Domain_Key" else if ! createDomainKey "$_main_domain" "$_key_length"; then - _err "Create domain key error." + _err "Error creating domain key." _clearup _on_issue_err "$_post_hook" return 1 @@ -4514,18 +4519,18 @@ issue() { fi fi if [ "$Le_ForceNewDomainKey" ]; then - _info "Generate next pre-generate key." + _info "Generating next pre-generate key." if [ ! -e "$Le_Next_Domain_Key" ]; then touch "$Le_Next_Domain_Key" chmod 600 "$Le_Next_Domain_Key" fi if ! _createkey "$_key_length" "$Le_Next_Domain_Key"; then - _err "Can not pre generate domain key" + _err "Cannot pre-generate domain key" return 1 fi fi if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then - _err "Create CSR error." + _err "Error creating CSR." _clearup _on_issue_err "$_post_hook" return 1 @@ -4561,7 +4566,7 @@ issue() { _debug2 "_valid_from" "$_valid_from" _notBefore="$(_convertValidaty "" "$_valid_from")" if [ "$?" != "0" ]; then - _err "Can not parse _valid_from: $_valid_from" + _err "Cannot parse _valid_from: $_valid_from" return 1 fi if [ "$(_time)" -gt "$(_date2time "$_notBefore")" ]; then @@ -4577,7 +4582,7 @@ issue() { _savedomainconf "Le_Valid_To" "$_valid_to" _notAfter="$(_convertValidaty "$_notBefore" "$_valid_to")" if [ "$?" != "0" ]; then - _err "Can not parse _valid_to: $_valid_to" + _err "Cannot parse _valid_to: $_valid_to" return 1 fi else @@ -4594,7 +4599,7 @@ issue() { fi _debug "STEP 1, Ordering a Certificate" if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then - _err "Create new order error." + _err "Error creating new order." _clearup _on_issue_err "$_post_hook" return 1 @@ -4614,7 +4619,7 @@ issue() { Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_OrderFinalize "$Le_OrderFinalize" if [ -z "$Le_OrderFinalize" ]; then - _err "Create new order error. Le_OrderFinalize not found. $response" + _err "Error creating new order. Le_OrderFinalize not found. $response" _clearup _on_issue_err "$_post_hook" return 1 @@ -4638,7 +4643,7 @@ issue() { for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do _debug2 "_authz_url" "$_authz_url" if ! _send_signed_request "$_authz_url"; then - _err "get to authz error." + _err "Error getting authz." _err "_authorizations_seg" "$_authorizations_seg" _err "_authz_url" "$_authz_url" _err "$response" @@ -4711,7 +4716,7 @@ $_authorizations_map" response="$(echo "$_candidates" | sed "s/$_idn_d,//")" _debug2 "response" "$response" if [ -z "$response" ]; then - _err "get to authz error." + _err "Error getting authz." _err "_authorizations_map" "$_authorizations_map" _clearup _on_issue_err "$_post_hook" @@ -4735,10 +4740,10 @@ $_authorizations_map" _debug entry "$entry" if [ -z "$keyauthorization" -a -z "$entry" ]; then - _err "Error, can not get domain token entry $d for $vtype" + _err "Cannot get domain token entry $d for $vtype" _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" if [ "$_supported_vtypes" ]; then - _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + _err "Supported validation types are: $_supported_vtypes, but you specified: $vtype" fi _clearup _on_issue_err "$_post_hook" @@ -4750,7 +4755,7 @@ $_authorizations_map" _debug token "$token" if [ -z "$token" ]; then - _err "Error, can not get domain token $entry" + _err "Cannot get domain token $entry" _clearup _on_issue_err "$_post_hook" return 1 @@ -4761,7 +4766,7 @@ $_authorizations_map" _debug uri "$uri" if [ -z "$uri" ]; then - _err "Error, can not get domain uri. $entry" + _err "Cannot get domain URI $entry" _clearup _on_issue_err "$_post_hook" return 1 @@ -4790,7 +4795,7 @@ $_authorizations_map" _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) _debug d "$d" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _debug "$d is already verified, skip $vtype." + _debug "$d has already been verified, skipping $vtype." _alias_index="$(_math "$_alias_index" + 1)" continue fi @@ -4827,37 +4832,37 @@ $_authorizations_map" dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api" _debug2 dns_entry "$dns_entry" if [ "$d_api" ]; then - _debug "Found domain api file: $d_api" + _debug "Found domain API file: $d_api" else if [ "$_currentRoot" != "$W_DNS" ]; then - _err "Can not find dns api hook for: $_currentRoot" - _info "You need to add the txt record manually." + _err "Cannot find DNS API hook for: $_currentRoot" + _info "You need to add the TXT record manually." fi _info "$(__red "Add the following TXT record:")" _info "$(__red "Domain: '$(__green "$txtdomain")'")" _info "$(__red "TXT value: '$(__green "$txt")'")" - _info "$(__red "Please be aware that you prepend _acme-challenge. before your domain")" - _info "$(__red "so the resulting subdomain will be: $txtdomain")" + _info "$(__red "Please make sure to prepend '_acme-challenge.' to your domain")" + _info "$(__red "so that the resulting subdomain is: $txtdomain")" continue fi ( if ! . "$d_api"; then - _err "Load file $d_api error. Please check your api file and try again." + _err "Error loading file $d_api. Please check your API file and try again." return 1 fi addcommand="${_currentRoot}_add" if ! _exists "$addcommand"; then - _err "It seems that your api file is not correct, it must have a function named: $addcommand" + _err "It seems that your API file is incorrect. Make sure it has a function named: $addcommand" return 1 fi - _info "Adding txt value: $txt for domain: $txtdomain" + _info "Adding TXT value: $txt for domain: $txtdomain" if ! $addcommand "$txtdomain" "$txt"; then - _err "Error add txt for domain:$txtdomain" + _err "Error adding TXT record to domain: $txtdomain" return 1 fi - _info "The txt record is added: Success." + _info "The TXT record has been successfully added." ) if [ "$?" != "0" ]; then @@ -4874,7 +4879,7 @@ $_authorizations_map" if [ "$dnsadded" = '0' ]; then _savedomainconf "Le_Vlist" "$vlist" - _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit." + _debug "DNS record not yet added. Will save to $DOMAIN_CONF and exit." _err "Please add the TXT records to the domains, and re-run with --renew." _on_issue_err "$_post_hook" _clearup @@ -4887,23 +4892,23 @@ $_authorizations_map" if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - _info "Let's check each DNS record now. Sleep 20 seconds first." + _info "Let's check each DNS record now. Sleeping for 20 seconds first." _sleep 20 if ! _check_dns_entries; then - _err "check dns error." + _err "Error checking DNS." _on_issue_err "$_post_hook" _clearup return 1 fi else _savedomainconf "Le_DNSSleep" "$Le_DNSSleep" - _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" + _info "Sleeping for $(__green $Le_DNSSleep) seconds to wait for the the TXT records to take effect" _sleep "$Le_DNSSleep" fi fi NGINX_RESTORE_VLIST="" - _debug "ok, let's start to verify" + _debug "OK, let's start verification" _ncIndex=1 ventries=$(echo "$vlist" | tr "$dvsep" ' ') @@ -4915,7 +4920,7 @@ $_authorizations_map" _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) _authz_url=$(echo "$ventry" | cut -d "$sep" -f 6) if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _info "$d is already verified, skip $vtype." + _info "$d is already verified, skipping $vtype." continue fi @@ -4943,10 +4948,10 @@ $_authorizations_map" sleep 1 _debug serverproc "$serverproc" elif [ "$_currentRoot" = "$MODE_STATELESS" ]; then - _info "Stateless mode for domain:$d" + _info "Stateless mode for domain: $d" _sleep 1 elif _startswith "$_currentRoot" "$NGINX"; then - _info "Nginx mode for domain:$d" + _info "Nginx mode for domain: $d" #set up nginx server FOUND_REAL_NGINX_CONF="" BACKUP_NGINX_CONF="" @@ -4979,26 +4984,26 @@ $_authorizations_map" _debug wellknown_path "$wellknown_path" - _debug "writing token:$token to $wellknown_path/$token" + _debug "Writing token: $token to $wellknown_path/$token" mkdir -p "$wellknown_path" if ! printf "%s" "$keyauthorization" >"$wellknown_path/$token"; then - _err "$d:Can not write token to file : $wellknown_path/$token" + _err "$d: Cannot write token to file: $wellknown_path/$token" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" return 1 fi if ! chmod a+r "$wellknown_path/$token"; then - _debug "chmod failed, but we just continue." + _debug "chmod failed, will just continue." fi fi elif [ "$vtype" = "$VTYPE_ALPN" ]; then acmevalidationv1="$(printf "%s" "$keyauthorization" | _digest "sha256" "hex")" _debug acmevalidationv1 "$acmevalidationv1" if ! _starttlsserver "$d" "" "$Le_TLSPort" "$keyauthorization" "$_ncaddr" "$acmevalidationv1"; then - _err "Start tls server error." + _err "Error starting TLS server." _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5007,7 +5012,7 @@ $_authorizations_map" fi if ! __trigger_validation "$uri" "$keyauthorization" "$vtype"; then - _err "$d:Can not get challenge: $response" + _err "$d: Cannot get challenge: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5016,9 +5021,9 @@ $_authorizations_map" if [ "$code" ] && [ "$code" != '202' ]; then if [ "$code" = '200' ]; then - _debug "trigger validation code: $code" + _debug "Trigger validation code: $code" else - _err "$d:Challenge error: $response" + _err "$d: Challenge error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5031,11 +5036,11 @@ $_authorizations_map" MAX_RETRY_TIMES=30 fi - _debug "Lets check the status of the authz" + _debug "Let's check the authz status" while true; do waittimes=$(_math "$waittimes" + 1) if [ "$waittimes" -ge "$MAX_RETRY_TIMES" ]; then - _err "$d:Timeout" + _err "$d: Timeout" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5055,13 +5060,13 @@ $_authorizations_map" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" _debug2 errordetail "$errordetail" if [ "$errordetail" ]; then - _err "Invalid status, $d:Verify error detail:$errordetail" + _err "$d: Invalid status. Verification error details: $errordetail" else - _err "Invalid status, $d:Verify error:$error" + _err "$d: Invalid status, Verification error: $error" fi if [ "$DEBUG" ]; then if [ "$vtype" = "$VTYPE_HTTP" ]; then - _debug "Debug: get token url." + _debug "Debug: GET token URL." _get "http://$d/.well-known/acme-challenge/$token" "" 1 fi fi @@ -5080,24 +5085,24 @@ $_authorizations_map" fi if _contains "$status" "pending"; then - _info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" + _info "Pending. The CA is processing your order, please wait. ($waittimes/$MAX_RETRY_TIMES)" elif _contains "$status" "processing"; then - _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)" + _info "Processing. The CA is processing your order, please wait. ($waittimes/$MAX_RETRY_TIMES)" else - _err "Unknown status: $status, $d:Verify error:$response" + _err "$d: Unknown status: $status. Verification error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" return 1 fi - _debug "sleep 2 secs to verify again" + _debug "Sleep 2 seconds before verifying again" _sleep 2 - _debug "checking" + _debug "Checking" _send_signed_request "$_authz_url" if [ "$?" != "0" ]; then - _err "Invalid code, $d:Verify error:$response" + _err "$d: Invalid code. Verification error: $response" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearup _on_issue_err "$_post_hook" "$vlist" @@ -5108,18 +5113,18 @@ $_authorizations_map" done _clearup - _info "Verify finished, start to sign." + _info "Verification finished, beginning signing." der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" - _info "Lets finalize the order." + _info "Let's finalize the order." _info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then - _err "Sign failed." + _err "Signing failed." _on_issue_err "$_post_hook" return 1 fi if [ "$code" != "200" ]; then - _err "Sign failed, finalize code is not 200." + _err "Signing failed. Finalize code was not 200." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5138,38 +5143,38 @@ $_authorizations_map" Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" _debug Le_LinkCert "$Le_LinkCert" if [ -z "$Le_LinkCert" ]; then - _err "Sign error, can not find Le_LinkCert" + _err "A signing error occurred: could not find Le_LinkCert" _err "$response" _on_issue_err "$_post_hook" return 1 fi break elif _contains "$response" "\"processing\""; then - _info "Order status is processing, lets sleep and retry." + _info "Order status is 'processing', let's sleep and retry." _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') _debug "_retryafter" "$_retryafter" if [ "$_retryafter" ]; then - _info "Retry after: $_retryafter" + _info "Sleeping for $_retryafter seconds then retrying" _sleep $_retryafter else _sleep 2 fi else - _err "Sign error, wrong status" + _err "Signing error: wrong status" _err "$response" _on_issue_err "$_post_hook" return 1 fi #the order is processing, so we are going to poll order status if [ -z "$Le_LinkOrder" ]; then - _err "Sign error, can not get order link location header" + _err "Signing error: could not get order link location header" _err "responseHeaders" "$responseHeaders" _on_issue_err "$_post_hook" return 1 fi _info "Polling order status: $Le_LinkOrder" if ! _send_signed_request "$Le_LinkOrder"; then - _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." + _err "Signing failed. Could not make POST request to Le_LinkOrder for cert: $Le_LinkOrder." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5178,7 +5183,7 @@ $_authorizations_map" done if [ -z "$Le_LinkCert" ]; then - _err "Sign failed, can not get Le_LinkCert, retry time limit." + _err "Signing failed. Could not get Le_LinkCert, and stopped retrying after reaching the retry limit." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5186,7 +5191,7 @@ $_authorizations_map" _info "Downloading cert." _info "Le_LinkCert" "$Le_LinkCert" if ! _send_signed_request "$Le_LinkCert"; then - _err "Sign failed, can not download cert:$Le_LinkCert." + _err "Signing failed. Could not download cert: $Le_LinkCert." _err "$response" _on_issue_err "$_post_hook" return 1 @@ -5199,15 +5204,15 @@ $_authorizations_map" fi if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then if [ "$DEBUG" ]; then - _debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" + _debug "Default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")" fi if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)" _debug2 "rels" "$rels" for rel in $rels; do - _info "Try rel: $rel" + _info "Trying rel: $rel" if ! _send_signed_request "$rel"; then - _err "Sign failed, can not download cert:$rel" + _err "Signing failed, could not download cert: $rel" _err "$response" continue fi @@ -5241,7 +5246,7 @@ $_authorizations_map" if [ -z "$Le_LinkCert" ] || ! _checkcert "$CERT_PATH"; then response="$(echo "$response" | _dbase64 "multiline" | tr -d '\0' | _normalizeJson)" - _err "Sign failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')" + _err "Signing failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')" _on_issue_err "$_post_hook" return 1 fi @@ -5263,9 +5268,9 @@ $_authorizations_map" fi [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")" - [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")" + [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full-chain cert is in: $(__green "$CERT_FULLCHAIN_PATH")" if [ "$Le_ForceNewDomainKey" ] && [ -e "$Le_Next_Domain_Key" ]; then - _info "Your pre-generated next key for future cert key change is in: $(__green "$Le_Next_Domain_Key")" + _info "Your pre-generated key for future cert key changes is in: $(__green "$Le_Next_Domain_Key")" fi Le_CertCreateTime=$(_time) @@ -5315,8 +5320,8 @@ $_authorizations_map" Le_NextRenewTime=$(_date2time "$_notAfter") Le_NextRenewTimeStr="$_notAfter" if [ "$_valid_to" ] && ! _startswith "$_valid_to" "+"; then - _info "The domain is set to be valid to: $_valid_to" - _info "It can not be renewed automatically" + _info "The domain is set to be valid until: $_valid_to" + _info "It cannot be renewed automatically" _info "See: $_VALIDITY_WIKI" else _now=$(_time) @@ -5359,7 +5364,7 @@ $_authorizations_map" fi if ! _on_issue_success "$_post_hook" "$_renew_hook"; then - _err "Call hook error." + _err "Error calling hook." return 1 fi } @@ -5395,9 +5400,9 @@ renew() { _initpath "$Le_Domain" "$_isEcc" _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT} - _info "$(__green "Renew: '$Le_Domain'")" + _info "$(__green "Renewing: '$Le_Domain'")" if [ ! -f "$DOMAIN_CONF" ]; then - _info "'$Le_Domain' is not an issued domain, skip." + _info "'$Le_Domain' is not an issued domain, skipping." return $RENEW_SKIP fi @@ -5426,7 +5431,7 @@ renew() { if [ "$_server" ]; then Le_API="$_server" fi - _info "Renew to Le_API=$Le_API" + _info "Renewing using Le_API=$Le_API" _clearAPI _clearCA @@ -5437,8 +5442,8 @@ renew() { _initpath "$Le_Domain" "$_isEcc" if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then - _info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")" - _info "Add '$(__red '--force')' to force to renew." + _info "Skipping. Next renewal time is: $(__green "$Le_NextRenewTimeStr")" + _info "Add '$(__red '--force')' to force renewal." if [ -z "$_ACME_IN_RENEWALL" ]; then if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then _send_notify "Renew $Le_Domain skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP" @@ -5448,7 +5453,7 @@ renew() { fi if [ "$_ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then - _info "Skip invalid cert for: $Le_Domain" + _info "Skipping invalid cert for: $Le_Domain" return $RENEW_SKIP fi @@ -5514,7 +5519,7 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" if ! [ -d "$di" ]; then - _debug "Not a directory, skip: $di" + _debug "Not a directory, skipping: $di" continue fi d=$(basename "$di") @@ -5572,12 +5577,12 @@ renewAll() { _error_msg="${_error_msg} $d " if [ "$_stopRenewOnError" ]; then - _err "Error renew $d, stop now." + _err "Error renewing $d, stopping." _ret="$rc" break else _ret="$rc" - _err "Error renew $d." + _err "Error renewing $d." fi fi done @@ -5588,13 +5593,13 @@ renewAll() { _msg_subject="Renew" if [ "$_error_msg" ]; then _msg_subject="${_msg_subject} Error" - _msg_data="Error certs: + _msg_data="Errored certs: ${_error_msg} " fi if [ "$_success_msg" ]; then _msg_subject="${_msg_subject} Success" - _msg_data="${_msg_data}Success certs: + _msg_data="${_msg_data}Successful certs: ${_success_msg} " fi @@ -5635,18 +5640,18 @@ signcsr() { _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi _debug _csrsubj "$_csrsubj" if _contains "$_csrsubj" ' ' || ! _contains "$_csrsubj" '.'; then - _info "It seems that the subject: $_csrsubj is not a valid domain name. Drop it." + _info "It seems that the subject $_csrsubj is not a valid domain name. Dropping it." _csrsubj="" fi _csrdomainlist=$(_readSubjectAltNamesFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read domain list from csr: $_csrfile" + _err "Cannot read domain list from CSR: $_csrfile" return 1 fi _debug "_csrdomainlist" "$_csrdomainlist" @@ -5659,20 +5664,20 @@ signcsr() { fi if [ -z "$_csrsubj" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi _csrkeylength=$(_readKeyLengthFromCSR "$_csrfile") if [ "$?" != "0" ] || [ -z "$_csrkeylength" ]; then - _err "Can not read key length from csr: $_csrfile" + _err "Cannot read key length from CSR: $_csrfile" return 1 fi _initpath "$_csrsubj" "$_csrkeylength" mkdir -p "$DOMAIN_PATH" - _info "Copy csr to: $CSR_PATH" + _info "Copying CSR to: $CSR_PATH" cp "$_csrfile" "$CSR_PATH" issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" @@ -5691,18 +5696,18 @@ showcsr() { _csrsubj=$(_readSubjectFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read subject from csr: $_csrfile" + _err "Cannot read subject from CSR: $_csrfile" return 1 fi if [ -z "$_csrsubj" ]; then - _info "The Subject is empty" + _info "The subject is empty" fi _info "Subject=$_csrsubj" _csrdomainlist=$(_readSubjectAltNamesFromCSR "$_csrfile") if [ "$?" != "0" ]; then - _err "Can not read domain list from csr: $_csrfile" + _err "Cannot read domain list from CSR: $_csrfile" return 1 fi _debug "_csrdomainlist" "$_csrdomainlist" @@ -5711,7 +5716,7 @@ showcsr() { _csrkeylength=$(_readKeyLengthFromCSR "$_csrfile") if [ "$?" != "0" ] || [ -z "$_csrkeylength" ]; then - _err "Can not read key length from csr: $_csrfile" + _err "Cannot read key length from CSR: $_csrfile" return 1 fi _info "KeyLength=$_csrkeylength" @@ -5767,29 +5772,29 @@ _deploy() { for _d_api in $(echo "$_hooks" | tr ',' " "); do _deployApi="$(_findHook "$_d" $_SUB_FOLDER_DEPLOY "$_d_api")" if [ -z "$_deployApi" ]; then - _err "The deploy hook $_d_api is not found." + _err "The deploy hook $_d_api was not found." return 1 fi _debug _deployApi "$_deployApi" if ! ( if ! . "$_deployApi"; then - _err "Load file $_deployApi error. Please check your api file and try again." + _err "Error loading file $_deployApi. Please check your API file and try again." return 1 fi d_command="${_d_api}_deploy" if ! _exists "$d_command"; then - _err "It seems that your api file is not correct, it must have a function named: $d_command" + _err "It seems that your API file is not correct. Make sure it has a function named: $d_command" return 1 fi if ! $d_command "$_d" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$CERT_FULLCHAIN_PATH"; then - _err "Error deploy for domain:$_d" + _err "Error deploying for domain: $_d" return 1 fi ); then - _err "Deploy error." + _err "Error encountered while deploying." return 1 else _info "$(__green Success)" @@ -5810,7 +5815,7 @@ deploy() { _initpath "$_d" "$_isEcc" if [ ! -d "$DOMAIN_PATH" ]; then _err "The domain '$_d' is not a cert name. You must use the cert name to specify the cert to install." - _err "Can not find path:'$DOMAIN_PATH'" + _err "Cannot find path: '$DOMAIN_PATH'" return 1 fi @@ -5839,7 +5844,7 @@ installcert() { _initpath "$_main_domain" "$_isEcc" if [ ! -d "$DOMAIN_PATH" ]; then _err "The domain '$_main_domain' is not a cert name. You must use the cert name to specify the cert to install." - _err "Can not find path:'$DOMAIN_PATH'" + _err "Cannot find path: '$DOMAIN_PATH'" return 1 fi @@ -5934,7 +5939,7 @@ _installcert() { fi if [ "$_reload_cmd" ]; then - _info "Run reload cmd: $_reload_cmd" + _info "Running reload cmd: $_reload_cmd" if ( export CERT_PATH export CERT_KEY_PATH @@ -5945,9 +5950,9 @@ _installcert() { export Le_Next_Domain_Key cd "$DOMAIN_PATH" && eval "$_reload_cmd" ); then - _info "$(__green "Reload success")" + _info "$(__green "Reload successful")" else - _err "Reload error for :$Le_Domain" + _err "Reload error for: $Le_Domain" fi fi @@ -5975,25 +5980,25 @@ _install_win_taskscheduler() { return 1 fi if ! _exists schtasks; then - _err "schtasks.exe is not found, are you on Windows?" + _err "schtasks.exe was not found, are you on Windows?" return 1 fi _winbash="$(cygpath -w $(which bash))" _debug _winbash "$_winbash" if [ -z "$_winbash" ]; then - _err "can not find bash path" + _err "Cannot find bash path" return 1 fi _myname="$(whoami)" _debug "_myname" "$_myname" if [ -z "$_myname" ]; then - _err "can not find my user name" + _err "Can not find own username" return 1 fi _debug "_lesh" "$_lesh" - _info "To install scheduler task in your Windows account, you must input your windows password." - _info "$PROJECT_NAME doesn't save your password." + _info "To install the scheduler task to your Windows account, you must input your Windows password." + _info "$PROJECT_NAME will not save your password." _info "Please input your Windows password for: $(__green "$_myname")" _password="$(__read_password)" #SCHTASKS.exe '/create' '/SC' 'DAILY' '/TN' "$_WINDOWS_SCHEDULER_NAME" '/F' '/ST' "00:$_randomminute" '/RU' "$_myname" '/RP' "$_password" '/TR' "$_winbash -l -c '$_lesh --cron --home \"$LE_WORKING_DIR\" $_centry'" >/dev/null @@ -6004,11 +6009,11 @@ _install_win_taskscheduler() { _uninstall_win_taskscheduler() { if ! _exists schtasks; then - _err "schtasks.exe is not found, are you on Windows?" + _err "schtasks.exe was not found, are you on Windows?" return 1 fi if ! echo SCHTASKS /query /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null; then - _debug "scheduler $_WINDOWS_SCHEDULER_NAME is not found." + _debug "scheduler $_WINDOWS_SCHEDULER_NAME was not found." else _info "Removing $_WINDOWS_SCHEDULER_NAME" echo SCHTASKS /delete /f /tn "$_WINDOWS_SCHEDULER_NAME" | cmd.exe >/dev/null @@ -6027,10 +6032,10 @@ installcronjob() { _script="$(_readlink "$_SCRIPT_")" _debug _script "$_script" if [ -f "$_script" ]; then - _info "Using the current script from: $_script" + _info "Usinging the current script from: $_script" lesh="$_script" else - _err "Can not install cronjob, $PROJECT_ENTRY not found." + _err "Cannot install cronjob, $PROJECT_ENTRY not found." return 1 fi fi @@ -6047,18 +6052,18 @@ installcronjob() { if ! _exists "$_CRONTAB"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, let's install Windows scheduler task." + _info "It seems you are on Windows, let's install the Windows scheduler task." if _install_win_taskscheduler "$lesh" "$_c_entry" "$random_minute"; then - _info "Install Windows scheduler task success." + _info "Successfully installed Windows scheduler task." return 0 else - _err "Install Windows scheduler task failed." + _err "Failed to install Windows scheduler task." return 1 fi fi - _err "crontab/fcrontab doesn't exist, so, we can not install cron jobs." - _err "All your certs will not be renewed automatically." - _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday." + _err "crontab/fcrontab doesn't exist, so we cannot install cron jobs." + _err "Your certs will not be renewed automatically." + _err "You must add your own cron job to call '$PROJECT_ENTRY --cron' every day." return 1 fi _info "Installing cron job" @@ -6074,8 +6079,8 @@ installcronjob() { } | $_CRONTAB_STDIN fi if [ "$?" != "0" ]; then - _err "Install cron job failed. You need to manually renew your certs." - _err "Or you can add cronjob by yourself:" + _err "Failed to install cron job. You need to manually renew your certs." + _err "Alternatively, you can add a cron job by yourself:" _err "$lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" return 1 fi @@ -6089,12 +6094,12 @@ uninstallcronjob() { if ! _exists "$_CRONTAB"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, let's uninstall Windows scheduler task." + _info "It seems you are on Windows, let's uninstall the Windows scheduler task." if _uninstall_win_taskscheduler; then - _info "Uninstall Windows scheduler task success." + _info "Successfully uninstalled Windows scheduler task." return 0 else - _err "Uninstall Windows scheduler task failed." + _err "Failed to uninstall Windows scheduler task." return 1 fi fi @@ -6134,12 +6139,12 @@ revoke() { fi _initpath "$Le_Domain" "$_isEcc" if [ ! -f "$DOMAIN_CONF" ]; then - _err "$Le_Domain is not a issued domain, skip." + _err "$Le_Domain is not an issued domain, skipping." return 1 fi if [ ! -f "$CERT_PATH" ]; then - _err "Cert for $Le_Domain $CERT_PATH is not found, skip." + _err "Cert for $Le_Domain $CERT_PATH was not found, skipping." return 1 fi @@ -6163,7 +6168,7 @@ revoke() { cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then - _err "Cert for $Le_Domain is empty found, skip." + _err "Cert for $Le_Domain is empty, skipping." return 1 fi @@ -6173,31 +6178,31 @@ revoke() { uri="${ACME_REVOKE_CERT}" - _info "Try account key first." + _info "Trying account key first." if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then if [ -z "$response" ]; then - _info "Revoke success." + _info "Successfully revoked." rm -f "$CERT_PATH" cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else - _err "Revoke error." + _err "Error revoking." _debug "$response" fi fi if [ -f "$CERT_KEY_PATH" ]; then - _info "Try domain key." + _info "Trying domain key." if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then if [ -z "$response" ]; then - _info "Revoke success." + _info "Successfully revoked." rm -f "$CERT_PATH" cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked" cat "$CSR_PATH" >"$CSR_PATH.revoked" return 0 else - _err "Revoke error by domain key." + _err "Error revoking using domain key." _err "$response" fi fi @@ -6221,19 +6226,19 @@ remove() { _removed_conf="$DOMAIN_CONF.removed" if [ ! -f "$DOMAIN_CONF" ]; then if [ -f "$_removed_conf" ]; then - _err "$Le_Domain is already removed, You can remove the folder by yourself: $DOMAIN_PATH" + _err "$Le_Domain has already been removed. You can remove the folder by yourself: $DOMAIN_PATH" else - _err "$Le_Domain is not a issued domain, skip." + _err "$Le_Domain is not an issued domain, skipping." fi return 1 fi if mv "$DOMAIN_CONF" "$_removed_conf"; then - _info "$Le_Domain is removed, the key and cert files are in $(__green $DOMAIN_PATH)" + _info "$Le_Domain has been removed. The key and cert files are in $(__green $DOMAIN_PATH)" _info "You can remove them by yourself." return 0 else - _err "Remove $Le_Domain failed." + _err "Failed to remove $Le_Domain." return 1 fi } @@ -6263,7 +6268,7 @@ _deactivate() { _identifiers="{\"type\":\"$(_getIdType "$_d_domain")\",\"value\":\"$_d_domain\"}" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then - _err "Can not get domain new order." + _err "Cannot get new order for domain." return 1 fi _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" @@ -6278,7 +6283,7 @@ _deactivate() { authzUri="$_authorizations_seg" _debug2 "authzUri" "$authzUri" if ! _send_signed_request "$authzUri"; then - _err "get to authz error." + _err "Error making GET request for authz." _err "_authorizations_seg" "$_authorizations_seg" _err "authzUri" "$authzUri" _clearup @@ -6301,7 +6306,7 @@ _deactivate() { entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then - _err "Error, can not get domain token $d" + _err "$d: Cannot get domain token" return 1 fi token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" @@ -6319,13 +6324,13 @@ _deactivate() { _d_i=0 _d_max_retry=$(echo "$entries" | wc -l) while [ "$_d_i" -lt "$_d_max_retry" ]; do - _info "Deactivate: $_d_domain" + _info "Deactivating $_d_domain" _d_i="$(_math $_d_i + 1)" entry="$(echo "$entries" | sed -n "${_d_i}p")" _debug entry "$entry" if [ -z "$entry" ]; then - _info "No more valid entry found." + _info "No more valid entries found." break fi @@ -6337,27 +6342,27 @@ _deactivate() { _debug uri "$uri" if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then - _info "Skip $_vtype" + _info "Skipping $_vtype" continue fi - _info "Deactivate: $_vtype" + _info "Deactivating $_vtype" _djson="{\"status\":\"deactivated\"}" if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then - _info "Deactivate: $_vtype success." + _info "Successfully deactivated $_vtype." else - _err "Can not deactivate $_vtype." + _err "Could not deactivate $_vtype." break fi done _debug "$_d_i" if [ "$_d_i" -eq "$_d_max_retry" ]; then - _info "Deactivated success!" + _info "Successfully deactivated!" else - _err "Deactivate failed." + _err "Deactivation failed." fi } @@ -6438,17 +6443,17 @@ _precheck() { _nocron="$1" if ! _exists "curl" && ! _exists "wget"; then - _err "Please install curl or wget first, we need to access http resources." + _err "Please install curl or wget first to enable access to HTTP resources." return 1 fi if [ -z "$_nocron" ]; then if ! _exists "crontab" && ! _exists "fcrontab"; then if _exists cygpath && _exists schtasks.exe; then - _info "It seems you are on Windows, we will install Windows scheduler task." + _info "It seems you are on Windows, we will install the Windows scheduler task." else - _err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'." - _err "We need to set cron job to renew the certs automatically." + _err "It is recommended to install crontab first. Try to install 'cron', 'crontab', 'crontabs' or 'vixie-cron'." + _err "We need to set a cron job to renew the certs automatically." _err "Otherwise, your certs will not be able to be renewed automatically." if [ -z "$FORCE" ]; then _err "Please add '--force' and try install again to go without crontab." @@ -6467,8 +6472,8 @@ _precheck() { if ! _exists "socat"; then _err "It is recommended to install socat first." - _err "We use socat for standalone server if you use standalone mode." - _err "If you don't use standalone mode, just ignore this warning." + _err "We use socat for the standalone server, which is used for standalone mode." + _err "If you don't want to use standalone mode, you may ignore this warning." fi return 0 @@ -6516,9 +6521,9 @@ _installalias() { _debug "Found profile: $_profile" _info "Installing alias to '$_profile'" _setopt "$_profile" ". \"$_envfile\"" - _info "OK, Close and reopen your terminal to start using $PROJECT_NAME" + _info "Close and reopen your terminal to start using $PROJECT_NAME" else - _info "No profile is found, you will need to go into $LE_WORKING_DIR to use $PROJECT_NAME" + _info "No profile has been found, you will need to change your working directory to $LE_WORKING_DIR to use $PROJECT_NAME" fi #for csh @@ -6567,12 +6572,12 @@ install() { return 1 fi if [ "$_nocron" ]; then - _debug "Skip install cron job" + _debug "Skipping cron job installation" fi if [ "$_ACME_IN_CRON" != "1" ]; then if ! _precheck "$_nocron"; then - _err "Pre-check failed, can not install." + _err "Pre-check failed, cannot install." return 1 fi fi @@ -6602,7 +6607,7 @@ install() { if [ ! -d "$LE_WORKING_DIR" ]; then if ! mkdir -p "$LE_WORKING_DIR"; then - _err "Can not create working dir: $LE_WORKING_DIR" + _err "Cannot create working dir: $LE_WORKING_DIR" return 1 fi @@ -6611,7 +6616,7 @@ install() { if [ ! -d "$LE_CONFIG_HOME" ]; then if ! mkdir -p "$LE_CONFIG_HOME"; then - _err "Can not create config dir: $LE_CONFIG_HOME" + _err "Cannot create config dir: $LE_CONFIG_HOME" return 1 fi @@ -6621,7 +6626,7 @@ install() { cp "$PROJECT_ENTRY" "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/$PROJECT_ENTRY" if [ "$?" != "0" ]; then - _err "Install failed, can not copy $PROJECT_ENTRY" + _err "Installation failed, cannot copy $PROJECT_ENTRY" return 1 fi @@ -6667,7 +6672,7 @@ install() { fi fi if [ "$_bash_path" ]; then - _info "Good, bash is found, so change the shebang to use bash as preferred." + _info "bash has been found. Changing the shebang to use bash as preferred." _shebang='#!'"$_bash_path" _setShebang "$LE_WORKING_DIR/$PROJECT_ENTRY" "$_shebang" for subf in $_SUB_FOLDERS; do @@ -6698,7 +6703,7 @@ uninstall() { _uninstallalias rm -f "$LE_WORKING_DIR/$PROJECT_ENTRY" - _info "The keys and certs are in \"$(__green "$LE_CONFIG_HOME")\", you can remove them by yourself." + _info "The keys and certs are in \"$(__green "$LE_CONFIG_HOME")\". You can remove them by yourself." } @@ -6736,7 +6741,7 @@ cron() { export LE_WORKING_DIR ( if ! upgrade; then - _err "Cron:Upgrade failed!" + _err "Cron: Upgrade failed!" return 1 fi ) @@ -6746,7 +6751,7 @@ cron() { __INTERACTIVE="1" fi - _info "Auto upgraded to: $VER" + _info "Automatically upgraded to: $VER" fi renewAll _ret="$?" @@ -6768,12 +6773,12 @@ _send_notify() { _nerror="$4" if [ "$NOTIFY_LEVEL" = "$NOTIFY_LEVEL_DISABLE" ]; then - _debug "The NOTIFY_LEVEL is $NOTIFY_LEVEL, disabled, just return." + _debug "The NOTIFY_LEVEL is $NOTIFY_LEVEL, which means it's disabled, so will just return." return 0 fi if [ -z "$_nhooks" ]; then - _debug "The NOTIFY_HOOK is empty, just return." + _debug "The NOTIFY_HOOK is empty, will just return." return 0 fi @@ -6790,29 +6795,29 @@ _send_notify() { _info "Sending via: $_n_hook" _debug "Found $_n_hook_file for $_n_hook" if [ -z "$_n_hook_file" ]; then - _err "Can not find the hook file for $_n_hook" + _err "Cannot find the hook file for $_n_hook" continue fi if ! ( if ! . "$_n_hook_file"; then - _err "Load file $_n_hook_file error. Please check your api file and try again." + _err "Error loading file $_n_hook_file. Please check your API file and try again." return 1 fi d_command="${_n_hook}_send" if ! _exists "$d_command"; then - _err "It seems that your api file is not correct, it must have a function named: $d_command" + _err "It seems that your API file is not correct. Make sure it has a function named: $d_command" return 1 fi if ! $d_command "$_nsubject" "$_ncontent" "$_nerror"; then - _err "Error send message by $d_command" + _err "Error sending message using $d_command" return 1 fi return 0 ); then - _err "Set $_n_hook_file error." + _err "Error setting $_n_hook_file." _send_err=1 else _info "$_n_hook $(__green Success)" @@ -6869,7 +6874,7 @@ setnotify() { if [ "$_nhook" ]; then _info "Set notify hook to: $_nhook" if [ "$_nhook" = "$NO_VALUE" ]; then - _info "Clear notify hook" + _info "Clearing notify hook" _clearaccountconf "NOTIFY_HOOK" else if _set_notify_hook "$_nhook"; then @@ -6877,7 +6882,7 @@ setnotify() { _saveaccountconf "NOTIFY_HOOK" "$NOTIFY_HOOK" return 0 else - _err "Can not set notify hook to: $_nhook" + _err "Cannot set notify hook to: $_nhook" return 1 fi fi @@ -6897,7 +6902,7 @@ Commands: --upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT. --issue Issue a cert. --deploy Deploy the cert to your server. - -i, --install-cert Install the issued cert to apache/nginx or any other server. + -i, --install-cert Install the issued cert to Apache/nginx or any other server. -r, --renew Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. @@ -6953,7 +6958,7 @@ Parameters: --stateless Use stateless mode. See: $_STATELESS_WIKI - --apache Use apache mode. + --apache Use Apache mode. --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted. See: $_DNS_API_WIKI @@ -6968,7 +6973,7 @@ Parameters: --eab-hmac-key HMAC key for External Account Binding. - These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert: + These parameters are to install the cert to nginx/Apache or any other server after issue/renew a cert: --cert-file Path to copy the cert file to after issue/renew. --key-file Path to copy the key file to after issue/renew. @@ -7007,6 +7012,7 @@ Parameters: --post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed. --renew-hook Command to be run after each successfully renewed certificate. --deploy-hook The hook file to deploy cert + --extended-key-usage Manually define the CSR extended key usage value. The default is serverAuth,clientAuth. --ocsp, --ocsp-must-staple Generate OCSP-Must-Staple extension. --always-force-new-domain-key Generate new domain key on renewal. Otherwise, the domain key is not changed by default. --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted. @@ -7075,8 +7081,8 @@ installOnline() { _getRepoHash() { _hash_path=$1 shift - _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" - _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 + _hash_url="${PROJECT_API:-https://api.github.com/repos/acmesh-official}/$PROJECT_NAME/git/refs/$_hash_path" + _get "$_hash_url" "" 30 | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4 } _getUpgradeHash() { @@ -7092,12 +7098,12 @@ _getUpgradeHash() { upgrade() { if ( _initpath - [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0 + [ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already up to date!" && exit 0 export LE_WORKING_DIR cd "$LE_WORKING_DIR" installOnline "--nocron" "--noprofile" ); then - _info "Upgrade success!" + _info "Upgrade successful!" exit 0 else _err "Upgrade failed!" @@ -7133,7 +7139,7 @@ _processAccountConf() { } _checkSudo() { - if [ -z "__INTERACTIVE" ]; then + if [ -z "$__INTERACTIVE" ]; then #don't check if it's not in an interactive shell return 0 fi @@ -7213,7 +7219,7 @@ _getCAShortName() { #set default ca to $ACME_DIRECTORY setdefaultca() { if [ -z "$ACME_DIRECTORY" ]; then - _err "Please give a --server parameter." + _err "Please provide a --server parameter." return 1 fi _saveaccountconf "DEFAULT_ACME_SERVER" "$ACME_DIRECTORY" @@ -7225,7 +7231,7 @@ setdefaultchain() { _initpath _preferred_chain="$1" if [ -z "$_preferred_chain" ]; then - _err "Please give a '--preferred-chain value' value." + _err "Please provide a value for '--preferred-chain'." return 1 fi mkdir -p "$CA_DIR" @@ -7423,7 +7429,7 @@ _process() { return 1 fi if _is_idn "$_dvalue" && ! _exists idn; then - _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first." + _err "It seems that $_dvalue is an IDN (Internationalized Domain Names), please install the 'idn' command first." return 1 fi @@ -7698,6 +7704,10 @@ _process() { _deploy_hook="$_deploy_hook$2," shift ;; + --extended-key-usage) + Le_ExtKeyUse="$2" + shift + ;; --ocsp-must-staple | --ocsp) Le_OCSP_Staple="1" ;; @@ -7785,7 +7795,7 @@ _process() { --notify-level) _nlevel="$2" if _startswith "$_nlevel" "-"; then - _err "'$_nlevel' is not a integer for '$1'" + _err "'$_nlevel' is not an integer for '$1'" return 1 fi _notify_level="$_nlevel" @@ -7794,7 +7804,7 @@ _process() { --notify-mode) _nmode="$2" if _startswith "$_nmode" "-"; then - _err "'$_nmode' is not a integer for '$1'" + _err "'$_nmode' is not an integer for '$1'" return 1 fi _notify_mode="$_nmode" @@ -7803,7 +7813,7 @@ _process() { --notify-source) _nsource="$2" if _startswith "$_nsource" "-"; then - _err "'$_nsource' is not valid host name for '$1'" + _err "'$_nsource' is not a valid host name for '$1'" return 1 fi _notify_source="$_nsource" @@ -7812,7 +7822,7 @@ _process() { --revoke-reason) _revoke_reason="$2" if _startswith "$_revoke_reason" "-"; then - _err "'$_revoke_reason' is not a integer for '$1'" + _err "'$_revoke_reason' is not an integer for '$1'" return 1 fi shift @@ -7830,7 +7840,7 @@ _process() { shift ;; *) - _err "Unknown parameter : $1" + _err "Unknown parameter: $1" return 1 ;; esac @@ -7847,7 +7857,7 @@ _process() { if [ "$__INTERACTIVE" ] && ! _checkSudo; then if [ -z "$FORCE" ]; then #Use "echo" here, instead of _info. it's too early - echo "It seems that you are using sudo, please read this link first:" + echo "It seems that you are using sudo, please read this page first:" echo "$_SUDO_WIKI" return 1 fi @@ -7877,7 +7887,7 @@ _process() { fi SYS_LOG="$_syslog" else - _err "The 'logger' command is not found, can not enable syslog." + _err "The 'logger' command was not found, cannot enable syslog." _clearaccountconf "SYS_LOG" SYS_LOG="" fi @@ -8004,7 +8014,7 @@ _process() { _saveaccountconf "SYS_LOG" "$_syslog" fi else - _err "The 'logger' command is not found, can not enable syslog." + _err "The 'logger' command was not found, cannot enable syslog." _clearaccountconf "SYS_LOG" SYS_LOG="" fi diff --git a/deploy/routeros.sh b/deploy/routeros.sh index d1779b8d..90f0ad1a 100644 --- a/deploy/routeros.sh +++ b/deploy/routeros.sh @@ -137,7 +137,8 @@ routeros_deploy() { return $_err_code fi - DEPLOY_SCRIPT_CMD="/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \ + DEPLOY_SCRIPT_CMD=":do {/system script remove \"LECertDeploy-$_cdomain\" } on-error={ }; \ +/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \ comment=\"generated by routeros deploy script in acme.sh\" \ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\ @@ -146,8 +147,8 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\ \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\ \ndelay 1;\ -\n/file remove $_cdomain.cer;\ -\n/file remove $_cdomain.key;\ +\n:do {/file remove $_cdomain.cer; } on-error={ }\ +\n:do {/file remove $_cdomain.key; } on-error={ }\ \ndelay 2;\ \n/ip service set www-ssl certificate=$_cdomain.cer_0;\ \n$ROUTER_OS_ADDITIONAL_SERVICES;\ diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index b3bd6197..3ddb8de1 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -39,7 +39,7 @@ ################################################################################ # Dependencies: # - curl -# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set) +# - synouser & synogroup & synosetkeyvalue (Required for SYNO_USE_TEMP_ADMIN=1) ################################################################################ # Return value: # 0 means success, otherwise error. @@ -66,14 +66,18 @@ synology_dsm_deploy() { _getdeployconf SYNO_DEVICE_NAME # Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set - _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" _getdeployconf SYNO_USE_TEMP_ADMIN _check2cleardeployconfexp SYNO_USE_TEMP_ADMIN _debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN" if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then - if ! _exists synouser || ! _exists synogroup; then - _err "Tools are missing for creating temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." + if ! _exists synouser || ! _exists synogroup || ! _exists synosetkeyvalue; then + _err "Missing required tools to creat temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead." + _err "Notice: temp admin user authorization method only supports local deployment on DSM." + return 1 + fi + if synouser --help 2>&1 | grep -q 'Permission denied'; then + _err "For creating temp admin user, the deploy script must be run as root." return 1 fi @@ -169,7 +173,7 @@ synology_dsm_deploy() { _debug3 H1 "${_H1}" fi - response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") + response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/$api_path?enable_syno_token=yes") _debug3 response "$response" # ## END ## - DEPRECATED, for backward compatibility # If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP. @@ -184,7 +188,7 @@ synology_dsm_deploy() { _debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}" if [ "$SYNO_LOCAL_HOSTNAME" != "1" ] && [ "$SYNO_LOCAL_HOSTNAME" == "$SYNO_HOSTNAME" ]; then if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then - _err "SYNO_USE_TEMP_ADMIN=1 Only support locally deployment, if you are sure that hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." + _err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun." return 1 fi fi @@ -201,24 +205,27 @@ synology_dsm_deploy() { # shellcheck disable=SC2086 synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null else - _err "Tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead." + _err "The tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead." return 1 fi else _err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead." return 1 fi - # havig a workaround to temporary disable enforce 2FA-OTP + # havig a workaround to temporary disable enforce 2FA-OTP, will restore + # it soon (after a single request), though if any accident occurs like + # unexpected interruption, this setting can be easily reverted manually. otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option) if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none - _info "Temporary disabled enforce 2FA-OTP to complete authentication." + _info "Enforcing 2FA-OTP has been disabled to complete temp admin authentication." + _info "Notice: it will be restored soon, if not, you can restore it manually via Control Panel." _info "previous_otp_enforce_option" "$otp_enforce_option" else otp_enforce_option="" fi fi - response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") + response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes") if [ -n "$SYNO_USE_TEMP_ADMIN" ] && [ -n "$otp_enforce_option" ]; then synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option" _info "Restored previous enforce 2FA-OTP option." @@ -227,9 +234,10 @@ synology_dsm_deploy() { fi fi - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" # Account has 2FA-OTP enabled, since error 403 reported. - # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf + # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf if [ "$error_code" == "403" ]; then if [ -z "$SYNO_DEVICE_NAME" ]; then printf "Enter device name or leave empty for default (CertRenewal): " @@ -261,7 +269,8 @@ synology_dsm_deploy() { _secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID" fi fi - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" fi if [ -n "$error_code" ]; then @@ -272,12 +281,16 @@ synology_dsm_deploy() { _err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window." elif [ "$error_code" == "406" ]; then if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then - _err "SYNO_USE_TEMP_ADMIN=1 is not supported if enforce auth with 2FA-OTP is enabled." + _err "Failed with unexcepted error, please report this by providing full log with '--debug 3'." else _err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue." fi - elif [ "$error_code" == "400" ] || [ "$error_code" == "401" ] || [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then - _err "Failed to authenticate with a non-existent or disabled account, or the account password is incorrect or has expired." + elif [ "$error_code" == "400" ]; then + _err "Failed to authenticate, no such account or incorrect password." + elif [ "$error_code" == "401" ]; then + _err "Failed to authenticate with a non-existent account." + elif [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then + _err "Failed to authenticate, the account password has expired or must be changed." else _err "Failed to authenticate with error: $error_code." fi @@ -291,7 +304,7 @@ synology_dsm_deploy() { _debug SynoToken "$token" if [ -z "$sid" ] || [ -z "$token" ]; then # Still can't get necessary info even got no errors, may Synology have API updated? - _err "Unable to authenticate to $_base_url, you may report the full log to the community." + _err "Unable to authenticate to $_base_url, you may report this by providing full log with '--debug 3'." _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 fi @@ -323,12 +336,13 @@ synology_dsm_deploy() { id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") _debug2 id "$id" - error_code=$(echo "$response" | grep '"error"' | grep -oP '(?<="code":)\d+') + error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') + _debug2 error_code "$error_code" if [ -n "$error_code" ]; then if [ "$error_code" -eq 105 ]; then _err "Current user is not administrator and does not have sufficient permission for deploying." else - _err "Failed to fetch certificate info with error: $error_code, please try again or contact Synology to learn more." + _err "Failed to fetch certificate info: $error_code, please try again or contact Synology to learn more." fi _temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" return 1 diff --git a/deploy/unifi.sh b/deploy/unifi.sh index a864135e..4d8c058e 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -5,6 +5,15 @@ # - self-hosted Unifi Controller # - Unifi Cloud Key (Gen1/2/2+) # - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# - Unifi Dream Machine +# This has not been tested on other "all-in-one" devices such as +# UDM Pro or Unifi Express. +# +# OS Version v2.0.0+ +# Network Application version 7.0.0+ +# OS version ~3.1 removed java and keytool from the UnifiOS. +# Using PKCS12 format keystore appears to work fine. +# # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. @@ -74,14 +83,16 @@ unifi_deploy() { _reload_cmd="" # Unifi Controller environment (self hosted or any Cloud Key) -- - # auto-detect by file /usr/lib/unifi/data/keystore: + # auto-detect by file /usr/lib/unifi/data/keystore _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" if [ -f "$_unifi_keystore" ]; then - _info "Installing certificate for Unifi Controller (Java keystore)" _debug _unifi_keystore "$_unifi_keystore" if ! _exists keytool; then - _err "keytool not found" - return 1 + _do_keytool=0 + _info "Installing certificate for Unifi Controller (PKCS12 keystore)." + else + _do_keytool=1 + _info "Installing certificate for Unifi Controller (Java keystore)" fi if [ ! -w "$_unifi_keystore" ]; then _err "The file $_unifi_keystore is not writable, please change the permission." @@ -92,6 +103,7 @@ unifi_deploy() { _debug "Generate import pkcs12" _import_pkcs12="$(_mktemp)" + _debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root" _toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root # shellcheck disable=SC2181 if [ "$?" != "0" ]; then @@ -99,22 +111,57 @@ unifi_deploy() { return 1 fi - _debug "Import into keystore: $_unifi_keystore" - if keytool -importkeystore \ - -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ - -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ - -alias unifi -noprompt; then - _debug "Import keystore success!" - rm "$_import_pkcs12" + # Save the existing keystore in case something goes wrong. + mv -f "${_unifi_keystore}" "${_unifi_keystore}"_original + _info "Previous keystore saved to ${_unifi_keystore}_original." + + if [ "$_do_keytool" -eq 1 ]; then + _debug "Import into keystore: $_unifi_keystore" + if keytool -importkeystore \ + -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ + -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ + -alias unifi -noprompt; then + _debug "Import keystore success!" + else + _err "Error importing into Unifi Java keystore." + _err "Please re-run with --debug and report a bug." + _info "Restoring original keystore." + mv -f "${_unifi_keystore}"_original "${_unifi_keystore}" + rm "$_import_pkcs12" + return 1 + fi else - _err "Error importing into Unifi Java keystore." - _err "Please re-run with --debug and report a bug." - rm "$_import_pkcs12" - return 1 + _debug "Copying new keystore to $_unifi_keystore" + cp -f "$_import_pkcs12" "$_unifi_keystore" + fi + + # Update unifi service for certificate cipher compatibility + if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \ + -in "$_import_pkcs12" \ + -password pass:aircontrolenterprise \ + -nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \ + -noout | grep -i "signature" | grep -iq ecdsa >/dev/null 2>&1; then + cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original + _info "Updating system configuration for cipher compatibility." + _info "Saved original system config to /usr/lib/unifi/data/system.properties_original" + sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>/usr/lib/unifi/data/system.properties + sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>/usr/lib/unifi/data/system.properties + _info "System configuration updated." fi + rm "$_import_pkcs12" + + # Restarting unifi-core will bring up unifi, doing it out of order results in + # a certificate error, and breaks wifiman. + # Restart if we aren't doing unifi-core, otherwise stop for later restart. if systemctl -q is-active unifi; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" + else + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" + fi fi _services_updated="${_services_updated} unifi" _info "Install Unifi Controller certificate success!" @@ -165,6 +212,11 @@ unifi_deploy() { return 1 fi + # Save the existing certs in case something goes wrong. + cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt + cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key + _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" diff --git a/deploy/vault.sh b/deploy/vault.sh index 569faba2..03a0de83 100644 --- a/deploy/vault.sh +++ b/deploy/vault.sh @@ -70,10 +70,10 @@ vault_deploy() { # JSON does not allow multiline strings. # So replacing new-lines with "\n" here - _ckey=$(sed -z 's/\n/\\n/g' <"$2") - _ccert=$(sed -z 's/\n/\\n/g' <"$3") - _cca=$(sed -z 's/\n/\\n/g' <"$4") - _cfullchain=$(sed -z 's/\n/\\n/g' <"$5") + _ckey=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$2") + _ccert=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$3") + _cca=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$4") + _cfullchain=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$5") export _H1="X-Vault-Token: $VAULT_TOKEN" diff --git a/dnsapi/dns_1984hosting.sh b/dnsapi/dns_1984hosting.sh index e4ef2e4b..906ea443 100755 --- a/dnsapi/dns_1984hosting.sh +++ b/dnsapi/dns_1984hosting.sh @@ -1,22 +1,18 @@ #!/usr/bin/env sh -# This file name is "dns_1984hosting.sh" -# So, here must be a method dns_1984hosting_add() -# Which will be called by acme.sh to add the txt record to your api system. -# returns 0 means success, otherwise error. - -# Author: Adrian Fedoreanu -# Report Bugs here: https://github.com/acmesh-official/acme.sh -# or here... https://github.com/acmesh-official/acme.sh/issues/2851 +# shellcheck disable=SC2034 +dns_1984hosting_info='1984.hosting +Domains: 1984.is +Site: 1984.hosting +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_1984hosting +Options: + One984HOSTING_Username Username + One984HOSTING_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2851 +Author: Adrian Fedoreanu +' ######## Public functions ##################### -# Export 1984HOSTING username and password in following variables -# -# One984HOSTING_Username=username -# One984HOSTING_Password=password -# -# username/password and csrftoken/sessionid cookies are saved in ~/.acme.sh/account.conf - # Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Add a text record. dns_1984hosting_add() { @@ -215,8 +211,8 @@ _get_root() { return 1 fi - _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is." - if _contains "$_response" "serial" && ! _contains "$_response" "null"; then + _authget "https://1984.hosting/domains/zonestatus/$h/?cached=no" + if _contains "$_response" '"ok": true'; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 @@ -250,7 +246,6 @@ _authget() { } # Truncate huge HTML response -# Echo: Argument list too long _htmlget() { export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" _response=$(_get "$1" | grep "$2") diff --git a/dnsapi/dns_acmedns.sh b/dnsapi/dns_acmedns.sh index 057f9742..f3f50233 100755 --- a/dnsapi/dns_acmedns.sh +++ b/dnsapi/dns_acmedns.sh @@ -1,18 +1,18 @@ #!/usr/bin/env sh -# -#Author: Wolfgang Ebner -#Author: Sven Neubuaer -#Report Bugs here: https://github.com/dampfklon/acme.sh -# -# Usage: -# export ACMEDNS_BASE_URL="https://auth.acme-dns.io" -# -# You can optionally define an already existing account: -# -# export ACMEDNS_USERNAME="" -# export ACMEDNS_PASSWORD="" -# export ACMEDNS_SUBDOMAIN="" -# +# shellcheck disable=SC2034 +dns_acmedns_info='acme-dns Server API + The acme-dns is a limited DNS server with RESTful API to handle ACME DNS challenges. +Site: github.com/joohoi/acme-dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_acmedns +Options: + ACMEDNS_USERNAME Username. Optional. + ACMEDNS_PASSWORD Password. Optional. + ACMEDNS_SUBDOMAIN Subdomain. Optional. + ACMEDNS_BASE_URL API endpoint. Default: "https://auth.acme-dns.io". +Issues: github.com/dampfklon/acme.sh +Author: Wolfgang Ebner, Sven Neubuaer +' + ######## Public functions ##################### #Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh old mode 100644 new mode 100755 index 9d5533f9..a699f645 --- a/dnsapi/dns_acmeproxy.sh +++ b/dnsapi/dns_acmeproxy.sh @@ -1,9 +1,17 @@ #!/usr/bin/env sh - -## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy) -## API integration by Maarten den Braber -## -## Report any bugs via https://github.com/mdbraber/acme.sh +# shellcheck disable=SC2034 +dns_acmeproxy_info='AcmeProxy Server API + AcmeProxy can be used to as a single host in your network to request certificates through a DNS API. + Clients can connect with the one AcmeProxy host so you do not need to store DNS API credentials on every single host. +Site: github.com/mdbraber/acmeproxy +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_acmeproxy +Options: + ACMEPROXY_ENDPOINT API Endpoint + ACMEPROXY_USERNAME Username + ACMEPROXY_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2251 +Author: Maarten den Braber +' dns_acmeproxy_add() { fulldomain="${1}" diff --git a/dnsapi/dns_active24.sh b/dnsapi/dns_active24.sh index 862f734f..1a6f97f0 100755 --- a/dnsapi/dns_active24.sh +++ b/dnsapi/dns_active24.sh @@ -1,6 +1,13 @@ #!/usr/bin/env sh - -#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_active24_info='Active24.com +Site: Active24.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_active24 +Options: + ACTIVE24_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2059 +Author: Milan Pála +' ACTIVE24_Api="https://api.active24.com" diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index fc4a664b..ccd8226f 100755 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -1,12 +1,13 @@ #!/usr/bin/env sh - -# -#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" - -#This is the Alwaysdata api wrapper for acme.sh -# -#Author: Paul Koppen -#Report Bugs here: https://github.com/wpk-/acme.sh +# shellcheck disable=SC2034 +dns_ad_info='AlwaysData.com +Site: AlwaysData.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ad +Options: + AD_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/pull/503 +Author: Paul Koppen +' AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index c69839dc..9bdfc20b 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_ali_info='AlibabaCloud.com +Domains: Aliyun.com +Site: AlibabaCloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ali +Options: + Ali_Key API Key + Ali_Secret API Secret +' Ali_API="https://alidns.aliyuncs.com/" -#Ali_Key="LTqIA87hOKdjevsf5" -#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2" - #Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_ali_add() { fulldomain=$1 diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index c1a1130a..9e5737c9 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -1,9 +1,12 @@ #!/usr/bin/env sh - -# Anexia CloudDNS acme.sh hook -# Author: MA - -#ANX_Token="xxxx" +# shellcheck disable=SC2034 +dns_anx_info='Anexia.com CloudDNS +Site: Anexia.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_anx +Options: + ANX_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/3238 +' ANX_API='https://engine.anexia-it.com/api/clouddns/v1' diff --git a/dnsapi/dns_artfiles.sh b/dnsapi/dns_artfiles.sh index a762837e..abd088f6 100644 --- a/dnsapi/dns_artfiles.sh +++ b/dnsapi/dns_artfiles.sh @@ -1,17 +1,14 @@ #!/usr/bin/env sh - -################################################################################ -# ACME.sh 3rd party DNS API plugin for ArtFiles.de -################################################################################ -# Author: Martin Arndt, https://troublezone.net/ -# Released: 2022-02-27 -# Issues: https://github.com/acmesh-official/acme.sh/issues/4718 -################################################################################ -# Usage: -# 1. export AF_API_USERNAME='api12345678' -# 2. export AF_API_PASSWORD='apiPassword' -# 3. acme.sh --issue -d example.com --dns dns_artfiles -################################################################################ +# shellcheck disable=SC2034 +dns_artfiles_info='ArtFiles.de +Site: ArtFiles.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_artfiles +Options: + AF_API_USERNAME API Username + AF_API_PASSWORD API Password +Issues: github.com/acmesh-official/acme.sh/issues/4718 +Author: Martin Arndt +' ########## API configuration ################################################### diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 4ca5b685..ed3b1314 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -1,11 +1,16 @@ #!/usr/bin/env sh - -# Arvan_Token="Apikey xxxx" +# shellcheck disable=SC2034 +dns_arvan_info='ArvanCloud.ir +Site: ArvanCloud.ir +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_arvan +Options: + Arvan_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2796 +Author: Vahid Fardi +' ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains" -# Author: Vahid Fardi -# Report Bugs here: https://github.com/Neilpang/acme.sh -# + ######## Public functions ##################### #Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_aurora.sh b/dnsapi/dns_aurora.sh index 00f44739..746fce54 100644 --- a/dnsapi/dns_aurora.sh +++ b/dnsapi/dns_aurora.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh - -# -#AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_aurora_info='versio.nl AuroraDNS +Domains: pcextreme.nl +Site: versio.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_aurora +Options: + AURORA_Key API Key + AURORA_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3459 +Author: Jasper Zonneveld +' AURORA_Api="https://api.auroradns.eu" diff --git a/dnsapi/dns_autodns.sh b/dnsapi/dns_autodns.sh index 92534489..309e5f27 100644 --- a/dnsapi/dns_autodns.sh +++ b/dnsapi/dns_autodns.sh @@ -1,16 +1,15 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - -# This is the InternetX autoDNS xml api wrapper for acme.sh -# Author: auerswald@gmail.com -# Created: 2018-01-14 -# -# export AUTODNS_USER="username" -# export AUTODNS_PASSWORD="password" -# export AUTODNS_CONTEXT="context" -# -# Usage: -# acme.sh --issue --dns dns_autodns -d example.com +# shellcheck disable=SC2034 +dns_autodns_info='InternetX autoDNS + InternetX autoDNS XML API +Site: InternetX.com/autodns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_autodns +Options: + AUTODNS_USER Username + AUTODNS_PASSWORD Password + AUTODNS_CONTEXT Context +Author: +' AUTODNS_API="https://gateway.autodns.com" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 27923b64..c599b4e0 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -1,13 +1,15 @@ #!/usr/bin/env sh - -# -#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#AWS_SECRET_ACCESS_KEY="xxxxxxx" - -#This is the Amazon Route53 api wrapper for acme.sh -#All `_sleep` commands are included to avoid Route53 throttling, see -#https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests +# shellcheck disable=SC2034 +dns_aws_info='Amazon AWS Route53 domain API +Site: docs.aws.amazon.com/route53/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws +Options: + AWS_ACCESS_KEY_ID API Key ID + AWS_SECRET_ACCESS_KEY API Secret +' + +# All `_sleep` commands are included to avoid Route53 throttling, see +# https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests AWS_HOST="route53.amazonaws.com" AWS_URL="https://$AWS_HOST" diff --git a/dnsapi/dns_azion.sh b/dnsapi/dns_azion.sh index f215686d..2371833e 100644 --- a/dnsapi/dns_azion.sh +++ b/dnsapi/dns_azion.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#AZION_Email="" -#AZION_Password="" -# +# shellcheck disable=SC2034 +dns_azion_info='Azion.om +Site: Azion.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_azion +Options: + AZION_Email Email + AZION_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/3555 +' AZION_Api="https://api.azionapi.net" diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 1c33c13a..00ccd798 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -1,6 +1,15 @@ #!/usr/bin/env sh - -WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS" +# shellcheck disable=SC2034 +dns_azure_info='Azure +Site: Azure.microsoft.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_azure +Options: + AZUREDNS_SUBSCRIPTIONID Subscription ID + AZUREDNS_TENANTID Tenant ID + AZUREDNS_APPID App ID. App ID of the service principal + AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal + AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false" +' ######## Public functions ##################### diff --git a/dnsapi/dns_bookmyname.sh b/dnsapi/dns_bookmyname.sh index 62548fd0..668cf074 100644 --- a/dnsapi/dns_bookmyname.sh +++ b/dnsapi/dns_bookmyname.sh @@ -1,18 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_bookmyname_info='BookMyName.com +Site: BookMyName.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bookmyname +Options: + BOOKMYNAME_USERNAME Username + BOOKMYNAME_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/3209 +Author: Neilpang +' -#Here is a sample custom api script. -#This file name is "dns_bookmyname.sh" -#So, here must be a method dns_bookmyname_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: Neilpang -#Report Bugs here: https://github.com/acmesh-official/acme.sh -# ######## Public functions ##################### -# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - # BookMyName urls: # https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"' # https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"' diff --git a/dnsapi/dns_bunny.sh b/dnsapi/dns_bunny.sh index a9b1ea5a..681f748a 100644 --- a/dnsapi/dns_bunny.sh +++ b/dnsapi/dns_bunny.sh @@ -1,16 +1,13 @@ #!/usr/bin/env sh - -## Will be called by acme.sh to add the TXT record via the Bunny DNS API. -## returns 0 means success, otherwise error. - -## Author: nosilver4u -## GitHub: https://github.com/nosilver4u/acme.sh - -## -## Environment Variables Required: -## -## BUNNY_API_KEY="75310dc4-ca77-9ac3-9a19-f6355db573b49ce92ae1-2655-3ebd-61ac-3a3ae34834cc" -## +# shellcheck disable=SC2034 +dns_bunny_info='Bunny.net +Site: Bunny.net/dns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bunny +Options: + BUNNY_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/4296 +Author: +' ##################### Public functions ##################### diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cd8d9a8d..da63e771 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -1,13 +1,16 @@ #!/usr/bin/env sh - -# -#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#CF_Email="xxxx@sss.com" - -#CF_Token="xxxx" -#CF_Account_ID="xxxx" -#CF_Zone_ID="xxxx" +# shellcheck disable=SC2034 +dns_cf_info='CloudFlare +Site: CloudFlare.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf +Options: + CF_Key API Key + CF_Email Your account email +OptionsAlt: + CF_Token API Token + CF_Account_ID Account ID + CF_Zone_ID Zone ID. Optional. +' CF_Api="https://api.cloudflare.com/client/v4" diff --git a/dnsapi/dns_clouddns.sh b/dnsapi/dns_clouddns.sh index 31ae4ee9..b78d70a4 100755 --- a/dnsapi/dns_clouddns.sh +++ b/dnsapi/dns_clouddns.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh - -# Author: Radek Sprta - -#CLOUDDNS_EMAIL=XXXXX -#CLOUDDNS_PASSWORD="YYYYYYYYY" -#CLOUDDNS_CLIENT_ID=XXXXX +# shellcheck disable=SC2034 +dns_clouddns_info='vshosting.cz CloudDNS +Site: github.com/vshosting/clouddns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_clouddns +Options: + CLOUDDNS_EMAIL Email + CLOUDDNS_PASSWORD Password + CLOUDDNS_CLIENT_ID Client ID +Issues: github.com/acmesh-official/acme.sh/issues/2699 +Author: Radek Sprta +' CLOUDDNS_API='https://admin.vshosting.cloud/clouddns' CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login' diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index 8d7fd437..145a85be 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_cloudns_info='ClouDNS.net +Site: ClouDNS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cloudns +Options: + CLOUDNS_AUTH_ID Regular auth ID + CLOUDNS_SUB_AUTH_ID Sub auth ID + CLOUDNS_AUTH_PASSWORD Auth Password +Author: Boyan Peychev +' -# Author: Boyan Peychev -# Repository: https://github.com/ClouDNS/acme.sh/ -# Editor: I Komang Suryadana - -#CLOUDNS_AUTH_ID=XXXXX -#CLOUDNS_SUB_AUTH_ID=XXXXX -#CLOUDNS_AUTH_PASSWORD="YYYYYYYYY" CLOUDNS_API="https://api.cloudns.net" DOMAIN_TYPE= DOMAIN_MASTER= diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh index 38d1f4aa..797f788e 100644 --- a/dnsapi/dns_cn.sh +++ b/dnsapi/dns_cn.sh @@ -1,7 +1,14 @@ #!/usr/bin/env sh - -# DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/). -# created by 5ll and francis +# shellcheck disable=SC2034 +dns_cn_info='Core-Networks.de +Site: beta.api.Core-Networks.de/doc/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cn +Options: + CN_User User + CN_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2142 +Author: 5ll, francis +' CN_API="https://beta.api.core-networks.de" diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index ddc32074..6ceca829 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -1,4 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_conoha_info='ConoHa.jp +Domains: ConoHa.io +Site: ConoHa.jp +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_conoha +Options: + CONOHA_Username Username + CONOHA_Password Password + CONOHA_TenantId TenantId + CONOHA_IdentityServiceApi Identity Service API. E.g. "https://identity.xxxx.conoha.io/v2.0" +' CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\." diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 69d216f0..0376dda1 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh - -# Author: Wout Decre +# shellcheck disable=SC2034 +dns_constellix_info='Constellix.com +Site: Constellix.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix +Options: + CONSTELLIX_Key API Key + CONSTELLIX_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/2724 +Author: Wout Decre +' CONSTELLIX_Api="https://api.dns.constellix.com/v1" -#CONSTELLIX_Key="XXX" -#CONSTELLIX_Secret="XXX" ######## Public functions ##################### diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh index f6126bcb..a6991403 100755 --- a/dnsapi/dns_cpanel.sh +++ b/dnsapi/dns_cpanel.sh @@ -1,18 +1,18 @@ #!/usr/bin/env sh -# -#Author: Bjarne Saltbaek -#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732 -# -# +# shellcheck disable=SC2034 +dns_cpanel_info='cPanel Server API + Manage DNS via cPanel Dashboard. +Site: cPanel.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_cpanel +Options: + cPanel_Username Username + cPanel_Apitoken API Token + cPanel_Hostname Server URL. E.g. "https://hostname:port" +Issues: github.com/acmesh-official/acme.sh/issues/3732 +Author: Bjarne Saltbaek +' + ######## Public functions ##################### -# -# Export CPANEL username,api token and hostname in the following variables -# -# cPanel_Username=username -# cPanel_Apitoken=apitoken -# cPanel_Hostname=hostname -# -# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record dns_cpanel_add() { diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index 4b39f365..a530d304 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh - -#Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management. -#Requires api credentials with scope: dns -#Author: Peter L. Hansen -#Version 1.0 +# shellcheck disable=SC2034 +dns_curanet_info='Curanet.dk +Domains: scannet.dk wannafind.dk dandomain.dk +Site: Curanet.dk +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_curanet +Options: + CURANET_AUTHCLIENTID Auth ClientID. Requires scope dns + CURANET_AUTHSECRET Auth Secret +Issues: github.com/acmesh-official/acme.sh/issues/3933 +Author: Peter L. Hansen +' CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token" diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index 830e8831..04a515aa 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -1,21 +1,15 @@ #!/usr/bin/env sh - -######## -# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/acmesh-official/acme.sh) -# -# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com -# -# Dependencies: -# ------------- -# - oathtool (When using 2 Factor Authentication) -# -# Issues: -# ------- -# Any issues / questions / suggestions can be posted here: -# https://github.com/noplanman/cyon-api/issues -# -# Author: Armando Lüscher -######## +# shellcheck disable=SC2034 +dns_cyon_info='cyon.ch +Site: cyon.ch +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cyon +Options: + CY_Username Username + CY_Password API Token + CY_OTP_Secret OTP token. Only required if using 2FA +Issues: github.com/noplanman/cyon-api/issues +Author: Armando Lüscher +' dns_cyon_add() { _cyon_load_credentials && diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index 4d3e09b1..b2789a6f 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -1,31 +1,14 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- -# vim: et ts=2 sw=2 -# -# DirectAdmin 1.41.0 API -# The DirectAdmin interface has it's own Let's encrypt functionality, but this -# script can be used to generate certificates for names which are not hosted on -# DirectAdmin -# -# User must provide login data and URL to DirectAdmin incl. port. -# You can create login key, by using the Login Keys function -# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to -# - CMD_API_DNS_CONTROL -# - CMD_API_SHOW_DOMAINS -# -# See also https://www.directadmin.com/api.php and -# https://www.directadmin.com/features.php?id=1298 -# -# Report bugs to https://github.com/TigerP/acme.sh/issues -# -# Values to export: -# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443" -# export DA_Api_Insecure=1 -# -# Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is -# whether ssl cert is checked for validity (0) or whether it is just accepted -# (1) -# +# shellcheck disable=SC2034 +dns_da_info='DirectAdmin Server API +Site: DirectAdmin.com/api.php +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_da +Options: + DA_Api API Server URL. E.g. "https://remoteUser:remotePassword@da.domain.tld:8443" + DA_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +Issues: github.com/TigerP/acme.sh/issues +' + ######## Public functions ##################### # Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index b9da33ff..118b148b 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -1,16 +1,13 @@ #!/usr/bin/env sh - -#Created by RaidenII, to use DuckDNS's API to add/remove text records -#modified by helbgd @ 03/13/2018 to support ddnss.de -#modified by mod242 @ 04/24/2018 to support different ddnss domains -#Please note: the Wildcard Feature must be turned on for the Host record -#and the checkbox for TXT needs to be enabled - -# Pass credentials before "acme.sh --issue --dns dns_ddnss ..." -# -- -# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" -# -- -# +# shellcheck disable=SC2034 +dns_ddnss_info='DDNSS.de +Site: DDNSS.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ddnss +Options: + DDNSS_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2230 +Author: RaidenII, helbgd, mod242 +' DDNSS_DNS_API="https://ddnss.de/upd.php" diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 495a6780..0d6a6c2f 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh -# -# deSEC.io Domain API -# -# Author: Zheng Qian -# -# deSEC API doc -# https://desec.readthedocs.io/en/latest/ +# shellcheck disable=SC2034 +dns_desec_info='deSEC.io +Site: desec.readthedocs.io/en/latest/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_desec +Options: + DDNSS_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2180 +Author: Zheng Qian +' REST_API="https://desec.io/api/v1/domains" diff --git a/dnsapi/dns_df.sh b/dnsapi/dns_df.sh index c0499ddf..513e350c 100644 --- a/dnsapi/dns_df.sh +++ b/dnsapi/dns_df.sh @@ -1,18 +1,15 @@ #!/usr/bin/env sh - -######################################################################## -# https://dyndnsfree.de hook script for acme.sh -# -# Environment variables: -# -# - $DF_user (your dyndnsfree.de username) -# - $DF_password (your dyndnsfree.de password) -# -# Author: Thilo Gass -# Git repo: https://github.com/ThiloGa/acme.sh - -#-- dns_df_add() - Add TXT record -------------------------------------- -# Usage: dns_df_add _acme-challenge.subdomain.domain.com "XyZ123..." +# shellcheck disable=SC2034 +dns_df_info='DynDnsFree.de +Domains: dynup.de +Site: DynDnsFree.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_df +Options: + DF_user Username + DF_password Password +Issues: github.com/acmesh-official/acme.sh/issues/2897 +Author: Thilo Gass +' dyndnsfree_api="https://dynup.de/acme.php" diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index afe1b32e..9aaa9606 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -1,16 +1,12 @@ #!/usr/bin/env sh - -## Will be called by acme.sh to add the txt record to your api system. -## returns 0 means success, otherwise error. - -## Author: thewer -## GitHub: https://github.com/gitwer/acme.sh - -## -## Environment Variables Required: -## -## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc" -## +# shellcheck disable=SC2034 +dns_dgon_info='DigitalOcean.com +Site: DigitalOcean.com/help/api/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dgon +Options: + DO_API_KEY API Key +Author: +' ##################### Public functions ##################### diff --git a/dnsapi/dns_dnsexit.sh b/dnsapi/dns_dnsexit.sh index 62d7d757..9f2871b4 100644 --- a/dnsapi/dns_dnsexit.sh +++ b/dnsapi/dns_dnsexit.sh @@ -1,13 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dnsexit_info='DNSExit.com +Site: DNSExit.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsexit +Options: + DNSEXIT_API_KEY API Key + DNSEXIT_AUTH_USER Username + DNSEXIT_AUTH_PASS Password +Issues: github.com/acmesh-official/acme.sh/issues/4719 +Author: Samuel Jimenez +' -#use dns-01 at DNSExit.com - -#Author: Samuel Jimenez -#Report Bugs here: https://github.com/acmesh-official/acme.sh - -#DNSEXIT_API_KEY=ABCDEFGHIJ0123456789abcdefghij -#DNSEXIT_AUTH_USER=login@email.address -#DNSEXIT_AUTH_PASS=aStrongPassword DNSEXIT_API_URL="https://api.dnsexit.com/dns/" DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp" diff --git a/dnsapi/dns_dnshome.sh b/dnsapi/dns_dnshome.sh index 99608769..59828796 100755 --- a/dnsapi/dns_dnshome.sh +++ b/dnsapi/dns_dnshome.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -# dnsHome.de API for acme.sh -# -# This Script adds the necessary TXT record to a Subdomain -# -# Author dnsHome.de (https://github.com/dnsHome-de) -# -# Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819 -# -# export DNSHOME_Subdomain="" -# export DNSHOME_SubdomainPassword="" +# shellcheck disable=SC2034 +dns_dnshome_info='dnsHome.de +Site: dnsHome.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnshome +Options: + DNSHOME_Subdomain Subdomain + DNSHOME_SubdomainPassword Subdomain Password +Issues: github.com/acmesh-official/acme.sh/issues/3819 +Author: dnsHome.de https://github.com/dnsHome-de +' # Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index d831eb2b..e080ecf0 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -# DNSimple domain api -# https://github.com/pho3nixf1re/acme.sh/issues -# -# This is your oauth token which can be acquired on the account page. Please -# note that this must be an _account_ token and not a _user_ token. -# https://dnsimple.com/a//account/access_tokens -# DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_dnsimple_info='DNSimple.com +Site: DNSimple.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dnsimple +Options: + DNSimple_OAUTH_TOKEN OAuth Token +Issues: github.com/pho3nixf1re/acme.sh/issues +' DNSimple_API="https://api.dnsimple.com/v2" diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh index 008153a4..44cc6f45 100755 --- a/dnsapi/dns_dnsservices.sh +++ b/dnsapi/dns_dnsservices.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dnsservices_info='DNS.Services +Site: DNS.Services +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsservices +Options: + DnsServices_Username Username + DnsServices_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/4152 +Author: Bjarke Bruun +' -#This file name is "dns_dnsservices.sh" -#Script for Danish DNS registra and DNS hosting provider https://dns.services - -#Author: Bjarke Bruun -#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152 - -# Global variable to connect to the DNS.Services API DNSServices_API=https://dns.services/api ######## Public functions ##################### diff --git a/dnsapi/dns_doapi.sh b/dnsapi/dns_doapi.sh index a001d52c..9bc6a4a4 100755 --- a/dnsapi/dns_doapi.sh +++ b/dnsapi/dns_doapi.sh @@ -1,12 +1,15 @@ #!/usr/bin/env sh - -# Official Let's Encrypt API for do.de / Domain-Offensive -# -# This is different from the dns_do adapter, because dns_do is only usable for enterprise customers -# This API is also available to private customers/individuals -# -# Provide the required LetsEncrypt token like this: -# DO_LETOKEN="FmD408PdqT1E269gUK57" +# shellcheck disable=SC2034 +dns_doapi_info='Domain-Offensive do.de + Official LetsEncrypt API for do.de / Domain-Offensive. + This is different from the dns_do adapter, because dns_do is only usable for enterprise customers. + This API is also available to private customers/individuals. +Site: do.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_doapi +Options: + DO_LETOKEN LetsEncrypt Token +Issues: github.com/acmesh-official/acme.sh/issues/2057 +' DO_API="https://www.do.de/api/letsencrypt" diff --git a/dnsapi/dns_domeneshop.sh b/dnsapi/dns_domeneshop.sh index 9a3791f4..16d3dbe5 100644 --- a/dnsapi/dns_domeneshop.sh +++ b/dnsapi/dns_domeneshop.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_domeneshop_info='DomeneShop.no +Site: DomeneShop.no +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_domeneshop +Options: + DOMENESHOP_Token Token + DOMENESHOP_Secret Secret +Issues: github.com/acmesh-official/acme.sh/issues/2457 +' DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0" diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 9b8b7a8b..29d32c27 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -1,10 +1,12 @@ #!/usr/bin/env sh - -# Dnspod.cn Domain api -# -#DP_Id="1234" -# -#DP_Key="sADDsdasdgdsf" +# shellcheck disable=SC2034 +dns_dp_info='DNSPod.cn +Site: DNSPod.cn +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dp +Options: + DP_Id Id + DP_Key Key +' REST_API="https://dnsapi.cn" diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh index 2955effd..521f2d69 100755 --- a/dnsapi/dns_dpi.sh +++ b/dnsapi/dns_dpi.sh @@ -1,10 +1,12 @@ #!/usr/bin/env sh - -# Dnspod.com Domain api -# -#DPI_Id="1234" -# -#DPI_Key="sADDsdasdgdsf" +# shellcheck disable=SC2034 +dns_dpi_info='DNSPod.com +Site: DNSPod.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dpi +Options: + DPI_Id Id + DPI_Key Key +' REST_API="https://api.dnspod.com" diff --git a/dnsapi/dns_dreamhost.sh b/dnsapi/dns_dreamhost.sh index a4017938..ce4fff87 100644 --- a/dnsapi/dns_dreamhost.sh +++ b/dnsapi/dns_dreamhost.sh @@ -1,10 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dreamhost_info='DreamHost.com +Site: DreamHost.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dreamhost +Options: + DH_API_KEY API Key +Issues: github.com/RhinoLance/acme.sh +Author: RhinoLance +' -#Author: RhinoLance -#Report Bugs here: https://github.com/RhinoLance/acme.sh -# - -#define the api endpoint DH_API_ENDPOINT="https://api.dreamhost.com/" querystring="" diff --git a/dnsapi/dns_duckdns.sh b/dnsapi/dns_duckdns.sh index d6e1dbdc..71594873 100755 --- a/dnsapi/dns_duckdns.sh +++ b/dnsapi/dns_duckdns.sh @@ -1,14 +1,12 @@ #!/usr/bin/env sh - -#Created by RaidenII, to use DuckDNS's API to add/remove text records -#06/27/2017 - -# Pass credentials before "acme.sh --issue --dns dns_duckdns ..." -# -- -# export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" -# -- -# -# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure may need to be used with acme.sh +# shellcheck disable=SC2034 +dns_duckdns_info='DuckDNS.org +Site: www.DuckDNS.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + DuckDNS_Token API Token +Author: RaidenII +' DuckDNS_API="https://www.duckdns.org/update" diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh index 677ae24d..cd4bd2eb 100644 --- a/dnsapi/dns_durabledns.sh +++ b/dnsapi/dns_durabledns.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#DD_API_User="xxxxx" -#DD_API_Key="xxxxxx" +# shellcheck disable=SC2034 +dns_durabledns_info='DurableDNS.com +Site: DurableDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_durabledns +Options: + DD_API_User API User + DD_API_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2281 +' _DD_BASE="https://durabledns.com/services/dns" diff --git a/dnsapi/dns_dyn.sh b/dnsapi/dns_dyn.sh index 024e0a38..94201923 100644 --- a/dnsapi/dns_dyn.sh +++ b/dnsapi/dns_dyn.sh @@ -1,10 +1,16 @@ #!/usr/bin/env sh -# -# Dyn.com Domain API -# -# Author: Gerd Naschenweng -# https://github.com/magicdude4eva -# +# shellcheck disable=SC2034 +dns_dyn_info='Dyn.com +Domains: dynect.net +Site: Dyn.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dyn +Options: + DYN_Customer Customer + DYN_Username API Username + DYN_Password Secret +Author: Gerd Naschenweng +' + # Dyn Managed DNS API # https://help.dyn.com/dns-api-knowledge-base/ # @@ -20,13 +26,6 @@ # ZoneRemoveNode # ZonePublish # -- -# -# Pass credentials before "acme.sh --issue --dns dns_dyn ..." -# -- -# export DYN_Customer="customer" -# export DYN_Username="apiuser" -# export DYN_Password="secret" -# -- DYN_API="https://api.dynect.net/REST" diff --git a/dnsapi/dns_dynu.sh b/dnsapi/dns_dynu.sh index 406ef17d..0dbeda24 100644 --- a/dnsapi/dns_dynu.sh +++ b/dnsapi/dns_dynu.sh @@ -1,20 +1,21 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_dynu_info='Dynu.com +Site: Dynu.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dynu +Options: + Dynu_ClientId Client ID + Dynu_Secret Secret +Issues: github.com/shar0119/acme.sh +Author: Dynu Systems Inc +' -#Client ID -#Dynu_ClientId="0b71cae7-a099-4f6b-8ddf-94571cdb760d" -# -#Secret -#Dynu_Secret="aCUEY4BDCV45KI8CSIC3sp2LKQ9" -# #Token Dynu_Token="" # #Endpoint Dynu_EndPoint="https://api.dynu.com/v2" -# -#Author: Dynu Systems, Inc. -#Report Bugs here: https://github.com/shar0119/acme.sh -# + ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 90814b1b..8b94dae7 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -1,8 +1,15 @@ #!/usr/bin/env sh -#Author StefanAbl -#Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"' -#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value" -#if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub +# shellcheck disable=SC2034 +dns_dynv6_info='DynV6.com +Site: DynV6.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dynv6 +Options: + DYNV6_TOKEN REST API token. Get from https://DynV6.com/keys +OptionsAlt: + KEY Path to SSH private key file. E.g. "/root/.ssh/dynv6" +Issues: github.com/acmesh-official/acme.sh/issues/2702 +Author: StefanAbl +' dynv6_api="https://dynv6.com/api/v2" ######## Public functions ##################### diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index ab47a0bc..d168054a 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -1,14 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_easydns_info='easyDNS.net +Site: easyDNS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_easydns +Options: + EASYDNS_Token API Token + EASYDNS_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2647 +Author: Neilpang, wurzelpanzer +' -####################################################### -# -# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh -# # API Documentation: https://sandbox.rest.easydns.net:3001/ -# -# Author: wurzelpanzer [wurzelpanzer@maximolider.net] -# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647 -# + #################### Public functions ################# #EASYDNS_Key="xxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh index 27650eb1..e88a1483 100755 --- a/dnsapi/dns_edgedns.sh +++ b/dnsapi/dns_edgedns.sh @@ -1,4 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_edgedns_info='Akamai.com Edge DNS +Site: techdocs.Akamai.com/edge-dns/reference/edge-dns-api +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_edgedns +Options: Specify individual credentials + AKAMAI_HOST Host + AKAMAI_ACCESS_TOKEN Access token + AKAMAI_CLIENT_TOKEN Client token + AKAMAI_CLIENT_SECRET Client secret +Issues: github.com/acmesh-official/acme.sh/issues/3157 +' # Akamai Edge DNS v2 API # User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to @@ -6,18 +17,10 @@ # Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support -# Values to export: -# --EITHER-- # *** TBD. NOT IMPLEMENTED YET *** -# specify Edgegrid credentials file and section -# AKAMAI_EDGERC= -# AKAMAI_EDGERC_SECTION="default" -## --OR-- -# specify indiviual credentials -# export AKAMAI_HOST = -# export AKAMAI_ACCESS_TOKEN = -# export AKAMAI_CLIENT_TOKEN = -# export AKAMAI_CLIENT_SECRET = +# Specify Edgegrid credentials file and section. +# AKAMAI_EDGERC Edge RC. Full file path +# AKAMAI_EDGERC_SECTION Edge RC Section. E.g. "default" ACME_EDGEDNS_VERSION="0.1.0" diff --git a/dnsapi/dns_euserv.sh b/dnsapi/dns_euserv.sh index cfb4b814..2da00c3d 100644 --- a/dnsapi/dns_euserv.sh +++ b/dnsapi/dns_euserv.sh @@ -1,18 +1,14 @@ #!/usr/bin/env sh - -#This is the euserv.eu api wrapper for acme.sh -# -#Author: Michael Brueckner -#Report Bugs: https://www.github.com/initit/acme.sh or mbr@initit.de - -# -#EUSERV_Username="username" -# -#EUSERV_Password="password" -# -# Dependencies: -# ------------- -# - none - +# shellcheck disable=SC2034 +dns_euserv_info='EUserv.com +Domains: EUserv.eu +Site: EUserv.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_euserv +Options: + EUSERV_Username Username + EUSERV_Password Password +Author: Michael Brueckner +' EUSERV_Api="https://api.euserv.net" diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index ccf05fc5..4cc5a513 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -1,4 +1,12 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_exoscale_info='Exoscale.com +Site: Exoscale.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_exoscale +Options: + EXOSCALE_API_KEY API Key + EXOSCALE_SECRET_KEY API Secret key +' EXOSCALE_API=https://api.exoscale.com/dns/v1 diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index 53be307a..38cdf5e6 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -1,6 +1,13 @@ #!/usr/bin/env sh - -#Author: Timur Umarov +# shellcheck disable=SC2034 +dns_fornex_info='Fornex.com +Site: Fornex.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_fornex +Options: + FORNEX_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/3998 +Author: Timur Umarov +' FORNEX_API_URL="https://fornex.com/api/dns/v0.1" diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 29cee430..114f30e0 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -1,14 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_freedns_info='FreeDNS +Site: FreeDNS.afraid.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_freedns +Options: + FREEDNS_User Username + FREEDNS_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2305 +Author: David Kerr +' -#This file name is "dns_freedns.sh" -#So, here must be a method dns_freedns_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: David Kerr -#Report Bugs here: https://github.com/dkerr64/acme.sh -#or here... https://github.com/acmesh-official/acme.sh/issues/2305 -# ######## Public functions ##################### # Export FreeDNS userid and password in following variables... diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index 6092f45c..141ddccf 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -1,16 +1,19 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_gandi_livedns_info='Gandi.net LiveDNS +Site: Gandi.net/domain/dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gandi_livedns +Options: + GANDI_LIVEDNS_KEY API Key +Issues: github.com/fcrozat/acme.sh +Author: Frédéric Crozat , Dominik Röttsches +' # Gandi LiveDNS v5 API # https://api.gandi.net/docs/livedns/ # https://api.gandi.net/docs/authentication/ for token + apikey (deprecated) authentication # currently under beta -# -# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable -# -#Author: Frédéric Crozat -# Dominik Röttsches -#Report Bugs here: https://github.com/fcrozat/acme.sh -# + ######## Public functions ##################### GANDI_LIVEDNS_API="https://api.gandi.net/v5/livedns" diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index dc82c09d..a6016abc 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -# Author: Janos Lenart +# shellcheck disable=SC2034 +dns_gcloud_info='Google Cloud DNS +Site: Cloud.Google.com/dns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcloud +Options: + CLOUDSDK_ACTIVE_CONFIG_NAME Active config name. E.g. "default" +Author: Janos Lenart +' ######## Public functions ##################### diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh index 5f7f037e..ac2e614c 100755 --- a/dnsapi/dns_gcore.sh +++ b/dnsapi/dns_gcore.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb' -# +# shellcheck disable=SC2034 +dns_gcore_info='Gcore.com +Site: Gcore.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcore +Options: + GCORE_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/4460 +' GCORE_Api="https://api.gcore.com/dns/v2" GCORE_Doc="https://api.gcore.com/docs/dns" diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 1729115e..08afa8f5 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -#Godaddy domain api -# Get API key and secret from https://developer.godaddy.com/ -# -# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# GD_Secret="asdfsdfsfsdfsdfdfsdf" -# -# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com" +# shellcheck disable=SC2034 +dns_gd_info='GoDaddy.com +Site: GoDaddy.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gd +Options: + GD_Key API Key + GD_Secret API Secret +' GD_Api="https://api.godaddy.com/v1" diff --git a/dnsapi/dns_geoscaling.sh b/dnsapi/dns_geoscaling.sh index 6ccf4daf..96b3e218 100755 --- a/dnsapi/dns_geoscaling.sh +++ b/dnsapi/dns_geoscaling.sh @@ -1,12 +1,12 @@ #!/usr/bin/env sh - -######################################################################## -# Geoscaling hook script for acme.sh -# -# Environment variables: -# -# - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address) -# - $GEOSCALING_Password (your Geoscaling password) +# shellcheck disable=SC2034 +dns_geoscaling_info='GeoScaling.com +Site: GeoScaling.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_geoscaling +Options: + GEOSCALING_Username Username. This is usually NOT an email address + GEOSCALING_Password Password +' #-- dns_geoscaling_add() - Add TXT record -------------------------------------- # Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_googledomains.sh b/dnsapi/dns_googledomains.sh index 63e3073b..7d241ab6 100755 --- a/dnsapi/dns_googledomains.sh +++ b/dnsapi/dns_googledomains.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_googledomains_info='Google Domains +Site: Domains.Google.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_googledomains +Options: + GOOGLEDOMAINS_ACCESS_TOKEN API Access Token + GOOGLEDOMAINS_ZONE Zone +Issues: github.com/acmesh-official/acme.sh/issues/4545 +Author: Alex Leigh +' -# Author: Alex Leigh -# Created: 2023-03-02 - -#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx" -#GOOGLEDOMAINS_ZONE="xxxx" GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets" ######## Public functions ######## diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index bf4a5030..cfb6efb8 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -######################################################################## -# Hurricane Electric hook script for acme.sh -# -# Environment variables: -# -# - $HE_Username (your dns.he.net username) -# - $HE_Password (your dns.he.net password) -# -# Author: Ondrej Simek -# Git repo: https://github.com/angel333/acme.sh +# shellcheck disable=SC2034 +dns_he_info='Hurricane Electric HE.net +Site: dns.he.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he +Options: + HE_Username Username + HE_Password Password +Issues: github.com/angel333/acme.sh/issues/ +Author: Ondrej Simek +' #-- dns_he_add() - Add TXT record -------------------------------------- # Usage: dns_he_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index 911d4a35..a60bd55d 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#HETZNER_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_hetzner_info='Hetzner.com +Site: Hetzner.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hetzner +Options: + HETZNER_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2943 +' HETZNER_Api="https://dns.hetzner.com/api/v1" diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index 525efe73..6c86e6a4 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -# Hexonet_Login="username!roleId" -# -# Hexonet_Password="rolePassword" +# shellcheck disable=SC2034 +dns_hexonet_info='Hexonet.com +Site: Hexonet.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_hexonet +Options: + Hexonet_Login Login. E.g. "username!roleId" + Hexonet_Password Role Password +Issues: github.com/acmesh-official/acme.sh/issues/2389 +' Hexonet_Api="https://coreapi.1api.net/api/call.cgi" diff --git a/dnsapi/dns_hostingde.sh b/dnsapi/dns_hostingde.sh index 9e3e5664..41ccab2b 100644 --- a/dnsapi/dns_hostingde.sh +++ b/dnsapi/dns_hostingde.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# hosting.de API - -# Values to export: -# export HOSTINGDE_ENDPOINT='https://secure.hosting.de' -# export HOSTINGDE_APIKEY='xxxxx' +# shellcheck disable=SC2034 +dns_hostingde_info='Hosting.de +Site: Hosting.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hostingde +Options: + HOSTINGDE_ENDPOINT Endpoint. E.g. "https://secure.hosting.de" + HOSTINGDE_APIKEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2058 +' ######## Public functions ##################### diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index b61c1d43..f3df41f4 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -# HUAWEICLOUD_Username -# HUAWEICLOUD_Password -# HUAWEICLOUD_DomainName +# shellcheck disable=SC2034 +dns_huaweicloud_info='HuaweiCloud.com +Site: HuaweiCloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_huaweicloud +Options: + HUAWEICLOUD_Username Username + HUAWEICLOUD_Password Password + HUAWEICLOUD_DomainName DomainName +Issues: github.com/acmesh-official/acme.sh/issues/3265 +' iam_api="https://iam.myhuaweicloud.com" dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work diff --git a/dnsapi/dns_infoblox.sh b/dnsapi/dns_infoblox.sh index 6bfd36ee..27f1e61e 100644 --- a/dnsapi/dns_infoblox.sh +++ b/dnsapi/dns_infoblox.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -## Infoblox API integration by Jason Keller and Elijah Tenai -## -## Report any bugs via https://github.com/jasonkeller/acme.sh +# shellcheck disable=SC2034 +dns_infoblox_info='Infoblox.com +Site: Infoblox.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_infoblox +Options: + Infoblox_Creds Credentials. E.g. "username:password" + Infoblox_Server Server hostname. IP or FQDN of infoblox appliance +Issues: github.com/jasonkeller/acme.sh +Author: Jason Keller, Elijah Tenai +' dns_infoblox_add() { diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh index a005132c..ea5ef461 100755 --- a/dnsapi/dns_infomaniak.sh +++ b/dnsapi/dns_infomaniak.sh @@ -1,19 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_infomaniak_info='Infomaniak.com +Site: Infomaniak.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_infomaniak +Options: + INFOMANIAK_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3188 +' -############################################################################### -# Infomaniak API integration -# # To use this API you need visit the API dashboard of your account # once logged into https://manager.infomaniak.com add /api/dashboard to the URL # -# Please report bugs to -# https://github.com/acmesh-official/acme.sh/issues/3188 -# # Note: the URL looks like this: # https://manager.infomaniak.com/v3//api/dashboard # Then generate a token with the scope Domain # this is given as an environment variable INFOMANIAK_API_TOKEN -############################################################################### # base variables diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index ae6b9e1e..84dfd70f 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -1,12 +1,14 @@ #!/usr/bin/env sh - -#This is the Internet.BS api wrapper for acme.sh -# -#Author: Ne-Lexa -#Report Bugs here: https://github.com/Ne-Lexa/acme.sh - -#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" -#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_internetbs_info='InternetBS.net +Site: InternetBS.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_internetbs +Options: + INTERNETBS_API_KEY API Key + INTERNETBS_API_PASSWORD API Password +Issues: github.com/acmesh-official/acme.sh/issues/2261 +Author: Ne-Lexa +' INTERNETBS_API_URL="https://api.internet.bs" diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index e483c0e8..8c89a697 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_inwx_info='INWX.de +Site: INWX.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_inwx +Options: + INWX_User Username + INWX_Password Password +' -# -#INWX_User="username" -# -#INWX_Password="password" -# # Dependencies: # ------------- # - oathtool (When using 2 Factor Authentication) diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e4ad3318..e4d28e11 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -1,14 +1,13 @@ #!/usr/bin/env sh - -# Supports IONOS DNS API v1.0.1 -# -# Usage: -# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: -# -# $ export IONOS_PREFIX="..." -# $ export IONOS_SECRET="..." -# -# $ acme.sh --issue --dns dns_ionos ... +# shellcheck disable=SC2034 +dns_ionos_info='IONOS.de +Site: IONOS.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ionos +Options: + IONOS_PREFIX Prefix + IONOS_SECRET Secret +Issues: github.com/acmesh-official/acme.sh/issues/3379 +' IONOS_API="https://api.hosting.ionos.com/dns" IONOS_ROUTE_ZONES="/v1/zones" diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh new file mode 100644 index 00000000..fa229e03 --- /dev/null +++ b/dnsapi/dns_ionos_cloud.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh + +# Supports IONOS Cloud DNS API v1.15.4 +# +# Usage: +# Export IONOS_TOKEN before calling acme.sh: +# $ export IONOS_TOKEN="..." +# +# $ acme.sh --issue --dns dns_ionos_cloud ... + +IONOS_CLOUD_API="https://dns.de-fra.ionos.com" +IONOS_CLOUD_ROUTE_ZONES="/zones" + +dns_ionos_cloud_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _ionos_init; then + return 1 + fi + + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1) + _body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}" + + if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then + _info "TXT record has been created successfully." + return 0 + fi + + return 1 +} + +dns_ionos_cloud_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _ionos_init; then + return 1 + fi + + if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then + _err "Could not find _acme-challenge TXT record." + return 1 + fi + + if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then + _info "TXT record has been deleted successfully." + return 0 + fi + + return 1 +} + +_ionos_init() { + IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}" + + if [ -z "$IONOS_TOKEN" ]; then + _err "You didn't specify an IONOS token yet." + _err "Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token." + _err "You need to set it before calling acme.sh:" + _err "\$ export IONOS_TOKEN=\"...\"" + _err "\$ acme.sh --issue -d ... --dns dns_ionos_cloud" + return 1 + fi + + _saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN" + + if ! _get_cloud_zone "$fulldomain"; then + _err "Cannot find zone $zone in your IONOS account." + return 1 + fi + + return 0 +} + +_get_cloud_zone() { + domain=$1 + zone=$(printf "%s" "$domain" | cut -d . -f 2-) + + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then + _response="$(echo "$_response" | tr -d "\n")" + + _zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*") + + _zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + if [ "$_zone_id" ]; then + return 0 + fi + fi + + return 1 +} + +_ionos_cloud_get_record() { + zone_id=$1 + txtrecord=$2 + # this is to transform the domain to lower case + fulldomain=$(printf "%s" "$3" | _lower_case) + # this is to transform record name to lower case + # IONOS Cloud API transforms all record names to lower case + _record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | _lower_case) + + if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then + _response="$(echo "$_response" | tr -d "\n")" + + pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}" + + _record="$(echo "$_response" | _egrep_o "$pattern")" + if [ "$_record" ]; then + _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') + return 0 + fi + fi + + return 1 +} + +_ionos_cloud_rest() { + method="$1" + route="$2" + data="$3" + + export _H1="Authorization: Bearer $IONOS_TOKEN" + + # clear headers + : >"$HTTP_HEADER" + + if [ "$method" != "GET" ]; then + _response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")" + else + _response="$(_get "$IONOS_CLOUD_API$route")" + fi + + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + + if [ "$?" != "0" ]; then + _err "Error $route: $_response" + return 1 + fi + + _debug2 "_response" "$_response" + _debug2 "_code" "$_code" + + return 0 +} diff --git a/dnsapi/dns_ipv64.sh b/dnsapi/dns_ipv64.sh index 54470119..51025d1e 100755 --- a/dnsapi/dns_ipv64.sh +++ b/dnsapi/dns_ipv64.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh - -#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records -#2022/11/29 - -# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..." -# -- -# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa" -# -- -# +# shellcheck disable=SC2034 +dns_ipv64_info='IPv64.net +Site: IPv64.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ipv64 +Options: + IPv64_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/4419 +Author: Roman Lumetsberger +' IPv64_API="https://ipv64.net/api" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 560f073e..7fd0d99c 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -1,17 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_ispconfig_info='ISPConfig Server API +Site: ISPConfig.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ispconfig +Options: + ISPC_User Remote User + ISPC_Password Remote Password + ISPC_Api API URL. E.g. "https://ispc.domain.tld:8080/remote/json.php" + ISPC_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +' # ISPConfig 3.1 API -# User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: +# User must provide login data and URL to the ISPConfig installation incl. port. +# The remote user in ISPConfig must have access to: # - DNS txt Functions -# Report bugs to https://github.com/sjau/acme.sh - -# Values to export: -# export ISPC_User="remoteUser" -# export ISPC_Password="remotePassword" -# export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" -# export ISPC_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index d0f2a501..a45aa2ca 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -1,9 +1,14 @@ #!/usr/bin/env sh - -# -#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" -#JD_ACCESS_KEY_SECRET="xxxxxxx" -#JD_REGION="cn-north-1" +# shellcheck disable=SC2034 +dns_jd_info='jdcloud.com +Site: jdcloud.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_jd +Options: + JD_ACCESS_KEY_ID Access key ID + JD_ACCESS_KEY_SECRET Access key secret + JD_REGION Region. E.g. "cn-north-1" +Issues: github.com/acmesh-official/acme.sh/issues/2388 +' _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 78399a1d..49c544b9 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -1,27 +1,14 @@ #!/usr/bin/env sh - -# Joker.com API for acme.sh -# -# This script adds the necessary TXT record to a domain in Joker.com. -# -# You must activate Dynamic DNS in Joker.com DNS configuration first. -# Username and password below refer to Dynamic DNS authentication, -# not your Joker.com login credentials. -# See: https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html -# -# NOTE: This script does not support wildcard certificates, because -# Joker.com API does not support adding two TXT records with the same -# subdomain. Adding the second record will overwrite the first one. -# See: https://joker.com/faq/content/6/496/en/let_s-encrypt-support.html -# "... this request will replace all TXT records for the specified -# label by the provided content" -# -# Author: aattww (https://github.com/aattww/) -# -# Report bugs to https://github.com/acmesh-official/acme.sh/issues/2840 -# -# JOKER_USERNAME="xxxx" -# JOKER_PASSWORD="xxxx" +# shellcheck disable=SC2034 +dns_joker_info='Joker.com +Site: Joker.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_joker +Options: + JOKER_USERNAME Username + JOKER_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2840 +Author: +' JOKER_API="https://svc.joker.com/nic/replace" diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index e9ea0a4d..7b6fb8a6 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh - -# kapper.net domain api -# for further questions please contact: support@kapper.net -# please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977 - -#KAPPERNETDNS_Key="yourKAPPERNETapikey" -#KAPPERNETDNS_Secret="yourKAPPERNETapisecret" - -KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" +# shellcheck disable=SC2034 +dns_kappernet_info='kapper.net +Site: kapper.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_kappernet +Options: + KAPPERNETDNS_Key API Key + KAPPERNETDNS_Secret API Secret +Issues: github.com/acmesh-official/acme.sh/issues/2977 +' ############################################################################### # called with @@ -19,10 +19,9 @@ dns_kappernet_add() { KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then - KAPPERNETDNS_Key="" - KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" _err "support@kapper.net to get your key and secret." @@ -66,10 +65,9 @@ dns_kappernet_rm() { KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}" KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}" + KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret" if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then - KAPPERNETDNS_Key="" - KAPPERNETDNS_Secret="" _err "Please specify your kapper.net api key and secret." _err "If you have not received yours - send your mail to" _err "support@kapper.net to get your key and secret." @@ -141,7 +139,7 @@ _kappernet_api() { if [ "$method" = "GET" ]; then response="$(_get "$url")" else - _err "Unsupported method" + _err "Unsupported method or missing Secret/Key" return 1 fi diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh index 1253cf27..2164a8e8 100755 --- a/dnsapi/dns_kas.sh +++ b/dnsapi/dns_kas.sh @@ -1,19 +1,16 @@ #!/usr/bin/env sh -######################################################################## -# All-inkl Kasserver hook script for acme.sh -# -# Environment variables: -# -# - $KAS_Login (Kasserver API login name) -# - $KAS_Authtype (Kasserver API auth type. Default: plain) -# - $KAS_Authdata (Kasserver API auth data.) -# -# Last update: squared GmbH -# Credits: -# - dns_he.sh. Thanks a lot man! -# - Martin Kammerlander, Phlegx Systems OG -# - Marc-Oliver Lange -# - https://github.com/o1oo11oo/kasapi.sh +# shellcheck disable=SC2034 +dns_kas_info='All-inkl Kas Server +Site: kas.all-inkl.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_kas +Options: + KAS_Login API login name + KAS_Authtype API auth type. Default: "plain" + KAS_Authdata API auth data +Issues: github.com/acmesh-official/acme.sh/issues/2715 +Author: squared GmbH , Martin Kammerlander , Marc-Oliver Lange +' + ######################################################################## KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")" KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "//g")" diff --git a/dnsapi/dns_kinghost.sh b/dnsapi/dns_kinghost.sh index f640242f..0496008e 100644 --- a/dnsapi/dns_kinghost.sh +++ b/dnsapi/dns_kinghost.sh @@ -1,16 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_kinghost_info='King.host +Domains: KingHost.net KingHost.com.br +Site: King.host +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_kinghost +Options: + KINGHOST_Username Username + KINGHOST_Password Password +Author: Felipe Keller Braz +' -############################################################ # KingHost API support # # https://api.kinghost.net/doc/ # -# # -# Author: Felipe Keller Braz # -# Report Bugs here: https://github.com/kinghost/acme.sh # -# # -# Values to export: # -# export KINGHOST_Username="email@provider.com" # -# export KINGHOST_Password="xxxxxxxxxx" # -############################################################ KING_Api="https://api.kinghost.net/acme" diff --git a/dnsapi/dns_knot.sh b/dnsapi/dns_knot.sh index 729a89cb..5636804a 100644 --- a/dnsapi/dns_knot.sh +++ b/dnsapi/dns_knot.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_knot_info='Knot Server knsupdate +Site: www.knot-dns.cz/docs/2.5/html/man_knsupdate.html +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_knot +Options: + KNOT_SERVER Server hostname. Default: "localhost". + KNOT_KEY File path to TSIG key +' + +# See also dns_nsupdate.sh ######## Public functions ##################### diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 674df410..7a1c0a1c 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#LA_Id="test123" -#LA_Key="d1j2fdo4dee3948" +# shellcheck disable=SC2034 +dns_la_info='dns.la +Site: dns.la +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_la +Options: + LA_Id API ID + LA_Key API key +Issues: github.com/acmesh-official/acme.sh/issues/4257 +' LA_Api="https://api.dns.la/api" diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh index 4cd3a8f8..66b1f61f 100644 --- a/dnsapi/dns_leaseweb.sh +++ b/dnsapi/dns_leaseweb.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_leaseweb_info='Leaseweb.com +Site: Leaseweb.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_leaseweb +Options: + LSW_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2558 +Author: Rolph Haspers +' -#Author: Rolph Haspers -#Utilize leaseweb.com API to finish dns-01 verifications. -#Requires a Leaseweb API Key (export LSW_Key="Your Key") #See https://developer.leaseweb.com for more information. ######## Public functions ##################### diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 19702343..a4b2a801 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_lexicon_info='Lexicon DNS client +Site: github.com/AnalogJ/lexicon +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-lexicon-DNS-API +Options: + PROVIDER Provider +' -# dns api wrapper of lexicon for acme.sh - -# https://github.com/AnalogJ/lexicon lexicon_cmd="lexicon" wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-lexicon-dns-api" diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index ead5b164..5e4c694b 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#Author: Philipp Grosswiler +# shellcheck disable=SC2034 +dns_linode_info='Linode.com (Old) + Deprecated. Use dns_linode_v4 +Site: Linode.com +Options: + LINODE_API_KEY API Key +Author: Philipp Grosswiler +' LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 9504afbf..e562f80f 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -#Original Author: Philipp Grosswiler -#v4 Update Author: Aaron W. Swenson +# shellcheck disable=SC2034 +dns_linode_v4_info='Linode.com +Site: Linode.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 +Options: + LINODE_V4_API_KEY API Key +Author: Philipp Grosswiler , Aaron W. Swenson +' LINODE_V4_API_URL="https://api.linode.com/v4/domains" diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 60d072e0..1f943e51 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh - -# -#LOOPIA_User="username" -# -#LOOPIA_Password="password" -# -#LOOPIA_Api="https://api.loopia./RPCSERV" +# shellcheck disable=SC2034 +dns_loopia_info='Loopia.se +Site: Loopia.se +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_loopia +Options: + LOOPIA_Api API URL. E.g. "https://api.loopia./RPCSERV" where the is one of: com, no, rs, se. Default: "se". + LOOPIA_User Username + LOOPIA_Password Password +' LOOPIA_Api_Default="https://api.loopia.se/RPCSERV" diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 30c15579..b037e90f 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -1,11 +1,14 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# -#LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#LUA_Email="user@luadns.net" +# shellcheck disable=SC2034 +dns_lua_info='LuaDNS.com +Domains: LuaDNS.net +Site: LuaDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_lua +Options: + LUA_Key API key + LUA_Email Email +Author: +' LUA_Api="https://api.luadns.com/v1" diff --git a/dnsapi/dns_maradns.sh b/dnsapi/dns_maradns.sh index 4ff6ca2d..09d7248e 100755 --- a/dnsapi/dns_maradns.sh +++ b/dnsapi/dns_maradns.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_maradns_info='MaraDNS Server +Site: MaraDNS.samiam.org +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_maradns +Options: + MARA_ZONE_FILE Zone file path. E.g. "/etc/maradns/db.domain.com" + MARA_DUENDE_PID_PATH Duende PID Path. E.g. "/run/maradns/etc_maradns_mararc.pid" +Issues: github.com/acmesh-official/acme.sh/issues/2072 +' #Usage: dns_maradns_add _acme-challenge.www.domain.com "token" dns_maradns_add() { diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 49007402..66545c46 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# ME_Key=qmlkdjflmkqdjf -# ME_Secret=qmsdlkqmlksdvnnpae +# shellcheck disable=SC2034 +dns_me_info='DnsMadeEasy.com +Site: DnsMadeEasy.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_me +Options: + ME_Key API Key + ME_Secret API Secret +Author: +' ME_Api=https://api.dnsmadeeasy.com/V2.0/dns/managed diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index dad69bde..ec9867db 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -1,17 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_miab_info='Mail-in-a-Box +Site: MailInaBox.email +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_miab +Options: + MIAB_Username Admin username + MIAB_Password Admin password + MIAB_Server Server hostname. FQDN of your_MIAB Server +Issues: github.com/acmesh-official/acme.sh/issues/2550 +Author: Darven Dissek, William Gertz +' -# Name: dns_miab.sh -# -# Authors: -# Darven Dissek 2018 -# William Gertz 2019 -# -# Thanks to Neil Pang and other developers here for code reused from acme.sh from DNS-01 -# used to communicate with the MailinaBox Custom DNS API -# Report Bugs here: -# https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh) -# https://github.com/acmesh-official/acme.sh (for acme.sh) -# ######## Public functions ##################### #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index 36ba5cfd..c6c0f5f3 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -1,11 +1,12 @@ #!/usr/bin/env sh - -# bug reports to support+acmesh@misaka.io -# based on dns_nsone.sh by dev@1e.ca - -# -#Misaka_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_misaka_info='Misaka.io +Site: Misaka.io +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_misaka +Options: + Misaka_Key API Key +Author: +' Misaka_Api="https://dnsapi.misaka.io/dns" diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index 7f3c5a86..c9f5eb9f 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -1,14 +1,21 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_myapi_info='Custom API Example + A sample custom DNS API script. +Domains: example.com +Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + MYAPI_Token API Token. Get API Token from https://example.com/api/. Optional. +Issues: github.com/acmesh-official/acme.sh +Author: Neil Pang +' -#Here is a sample custom api script. #This file name is "dns_myapi.sh" #So, here must be a method dns_myapi_add() #Which will be called by acme.sh to add the txt record to your api system. #returns 0 means success, otherwise error. -# -#Author: Neilpang -#Report Bugs here: https://github.com/acmesh-official/acme.sh -# + ######## Public functions ##################### # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh index 953290af..e9b3d3c8 100755 --- a/dnsapi/dns_mydevil.sh +++ b/dnsapi/dns_mydevil.sh @@ -1,15 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mydevil_info='MyDevil.net + MyDevil.net already supports automatic Lets Encrypt certificates, + except for wildcard domains. + This script depends on devil command that MyDevil.net provides, + which means that it works only on server side. +Site: MyDevil.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_mydevil +Issues: github.com/acmesh-official/acme.sh/issues/2079 +Author: Marcin Konicki +' -# MyDevil.net API (2019-02-03) -# -# MyDevil.net already supports automatic Let's Encrypt certificates, -# except for wildcard domains. -# -# This script depends on `devil` command that MyDevil.net provides, -# which means that it works only on server side. -# -# Author: Marcin Konicki -# ######## Public functions ##################### #Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh index 13866f70..4fa646e8 100755 --- a/dnsapi/dns_mydnsjp.sh +++ b/dnsapi/dns_mydnsjp.sh @@ -1,14 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mydnsjp_info='MyDNS.JP +Site: MyDNS.JP +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_mydnsjp +Options: + MYDNSJP_MasterID Master ID + MYDNSJP_Password Password +Author: epgdatacapbon +' -#Here is a api script for MyDNS.JP. -#This file name is "dns_mydnsjp.sh" -#So, here must be a method dns_mydnsjp_add() -#Which will be called by acme.sh to add the txt record to your api system. -#returns 0 means success, otherwise error. -# -#Author: epgdatacapbon -#Report Bugs here: https://github.com/epgdatacapbon/acme.sh -# ######## Public functions ##################### # Export MyDNS.JP MasterID and Password in following variables... diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index 294ae84c..b85401f4 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -1,4 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mythic_beasts_info='Mythic-Beasts.com +Site: Mythic-Beasts.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_mythic_beasts +Options: + MB_AK API Key + MB_AS API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3848 +' # Mythic Beasts is a long-standing UK service provider using standards-based OAuth2 authentication # To test: ./acme.sh --dns dns_mythic_beasts --test --debug 1 --output-insecure --issue --domain domain.com # Cannot retest once cert is issued diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index a5f667a9..abe64d09 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -1,12 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_namecheap_info='NameCheap.com +Site: NameCheap.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namecheap +Options: + NAMECHEAP_API_KEY API Key + NAMECHEAP_USERNAME Username + NAMECHEAP_SOURCEIP Source IP +Issues: github.com/acmesh-official/acme.sh/issues/2107 +' # Namecheap API # https://www.namecheap.com/support/api/intro.aspx -# -# Requires Namecheap API key set in -#NAMECHEAP_API_KEY, -#NAMECHEAP_USERNAME, -#NAMECHEAP_SOURCEIP # Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. ######## Public functions ##################### diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index 0d5dd2c4..2d146974 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -1,9 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_namecom_info='Name.com +Site: Name.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namecom +Options: + Namecom_Username Username + Namecom_Token API Token +Author: RaidenII +' -#Author: RaidenII -#Created 06/28/2017 -#Updated 03/01/2018, rewrote to support name.com API v4 -#Utilize name.com API to finish dns-01 verifications. ######## Public functions ##################### Namecom_API="https://api.name.com/v4" diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index f961d0bd..2995e7dc 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -1,8 +1,14 @@ #!/usr/bin/env sh - -#Author: meowthink -#Created 01/14/2017 -#Utilize namesilo.com API to finish dns-01 verifications. +# shellcheck disable=SC2034 +dns_namesilo_info='NameSilo.com +Site: NameSilo.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namesilo +Options: + Namesilo_Key API Key +Author: meowthink +' + +#Utilize API to finish dns-01 verifications. Namesilo_API="https://www.namesilo.com/api" diff --git a/dnsapi/dns_nanelo.sh b/dnsapi/dns_nanelo.sh index 8ccc8c29..1ab47a89 100644 --- a/dnsapi/dns_nanelo.sh +++ b/dnsapi/dns_nanelo.sh @@ -1,9 +1,12 @@ #!/usr/bin/env sh - -# Official DNS API for Nanelo.com - -# Provide the required API Key like this: -# NANELO_TOKEN="FmD408PdqT1E269gUK57" +# shellcheck disable=SC2034 +dns_nanelo_info='Nanelo.com +Site: Nanelo.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nanelo +Options: + NANELO_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/4519 +' NANELO_API="https://api.nanelo.com/v1/" diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index abaae42b..d0b97d3c 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghj" +# shellcheck disable=SC2034 +dns_nederhost_info='NederHost.nl +Site: NederHost.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nederhost +Options: + NederHost_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2089 +' NederHost_Api="https://api.nederhost.nl/dns/v1" diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh index 64ea8786..1119f916 100644 --- a/dnsapi/dns_neodigit.sh +++ b/dnsapi/dns_neodigit.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_neodigit_info='Neodigit.net +Site: Neodigit.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_neodigit +Options: + NEODIGIT_API_TOKEN API Token +Author: Adrian Almenar +' -# -# NEODIGIT_API_TOKEN="jasdfhklsjadhflnhsausdfas" - -# This is Neodigit.net api wrapper for acme.sh -# -# Author: Adrian Almenar -# Report Bugs here: https://github.com/tecnocratica/acme.sh -# NEODIGIT_API_URL="https://api.neodigit.net/v1" # ######## Public functions ##################### diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 776fa02d..687b99bc 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -1,5 +1,15 @@ #!/usr/bin/env sh -#developed by linux-insideDE +# shellcheck disable=SC2034 +dns_netcup_info='netcup.eu +Domains: netcup.de netcup.net +Site: netcup.eu/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_netcup +Options: + NC_Apikey API Key + NC_Apipw API Password + NC_CID Customer Number +Author: linux-insideDE +' NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}" NC_Apipw="${NC_Apipw:-$(_readaccountconf_mutable NC_Apipw)}" diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 0e5dc327..bb5f5809 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -1,6 +1,12 @@ #!/usr/bin/env sh - -#NETLIFY_ACCESS_TOKEN="xxxx" +# shellcheck disable=SC2034 +dns_netlify_info='Netlify.com +Site: Netlify.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_netlify +Options: + NETLIFY_ACCESS_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3088 +' NETLIFY_HOST="api.netlify.com/api/v1/" NETLIFY_URL="https://$NETLIFY_HOST" diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 56170f87..42f35cb0 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -1,10 +1,15 @@ #!/usr/bin/env sh - -# -#NIC_ClientID='0dc0xxxxxxxxxxxxxxxxxxxxxxxxce88' -#NIC_ClientSecret='3LTtxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnuW8' -#NIC_Username="000000/NIC-D" -#NIC_Password="xxxxxxx" +# shellcheck disable=SC2034 +dns_nic_info='nic.ru +Site: nic.ru +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nic +Options: + NIC_ClientID Client ID + NIC_ClientSecret Client Secret + NIC_Username Username + NIC_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2547 +' NIC_Api="https://api.nic.ru" diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index e9243288..5d241ebf 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -# -#NJALLA_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" +# shellcheck disable=SC2034 +dns_njalla_info='Njalla +Site: Njal.la +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_njalla +Options: + NJALLA_Token API Token +Issues: github.com/acmesh-official/acme.sh/issues/2913 +' NJALLA_Api="https://njal.la/api/1/" diff --git a/dnsapi/dns_nm.sh b/dnsapi/dns_nm.sh index 4dfcc777..1f818a29 100644 --- a/dnsapi/dns_nm.sh +++ b/dnsapi/dns_nm.sh @@ -1,15 +1,13 @@ #!/usr/bin/env sh - -######################################################################## -# https://namemaster.de hook script for acme.sh -# -# Environment variables: -# -# - $NM_user (your namemaster.de API username) -# - $NM_sha256 (your namemaster.de API password_as_sha256hash) -# -# Author: Thilo Gass -# Git repo: https://github.com/ThiloGa/acme.sh +# shellcheck disable=SC2034 +dns_nm_info='NameMaster.de +Site: NameMaster.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_nm +Options: + NM_user API Username + NM_sha256 API Password as SHA256 hash +Author: Thilo Gass +' #-- dns_nm_add() - Add TXT record -------------------------------------- # Usage: dns_nm_add _acme-challenge.subdomain.domain.com "XyZ123..." diff --git a/dnsapi/dns_nsd.sh b/dnsapi/dns_nsd.sh index 0d29a485..3ddaa98c 100644 --- a/dnsapi/dns_nsd.sh +++ b/dnsapi/dns_nsd.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -#Nsd_ZoneFile="/etc/nsd/zones/example.com.zone" -#Nsd_Command="sudo nsd-control reload" +# shellcheck disable=SC2034 +dns_nsd_info='NLnetLabs NSD Server +Site: github.com/NLnetLabs/nsd +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#nsd +Options: + Nsd_ZoneFile Zone File path. E.g. "/etc/nsd/zones/example.com.zone" + Nsd_Command Command. E.g. "sudo nsd-control reload" +Issues: github.com/acmesh-official/acme.sh/issues/2245 +' # args: fulldomain txtvalue dns_nsd_add() { diff --git a/dnsapi/dns_nsone.sh b/dnsapi/dns_nsone.sh index 9a998341..2a073950 100644 --- a/dnsapi/dns_nsone.sh +++ b/dnsapi/dns_nsone.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# bug reports to dev@1e.ca - -# -#NS1_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_nsone_info='ns1.com +Domains: ns1.net +Site: ns1.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nsone +Options: + NS1_Key API Key +Author: +' NS1_Api="https://api.nsone.net/v1" diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index cd4b7140..9df6262e 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_nsupdate_info='nsupdate RFC 2136 DynDNS client +Site: bind9.readthedocs.io/en/v9.18.19/manpages.html#nsupdate-dynamic-dns-update-utility +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nsupdate +Options: + NSUPDATE_SERVER Server hostname. Default: "localhost". + NSUPDATE_SERVER_PORT Server port. Default: "53". + NSUPDATE_KEY File path to TSIG key. + NSUPDATE_ZONE Domain zone to update. Optional. +' ######## Public functions ##################### diff --git a/dnsapi/dns_nw.sh b/dnsapi/dns_nw.sh index c57d27c2..8c68ead8 100644 --- a/dnsapi/dns_nw.sh +++ b/dnsapi/dns_nw.sh @@ -1,17 +1,16 @@ #!/usr/bin/env sh -######################################################################## -# NocWorx script for acme.sh -# -# Handles DNS Updates for the Following vendors: -# - Nexcess.net -# - Thermo.io -# - Futurehosting.com -# -# Environment variables: -# -# - NW_API_TOKEN (Your API Token) -# - NW_API_ENDPOINT (One of the following listed below) -# +# shellcheck disable=SC2034 +dns_nw_info='Nexcess.net (NocWorx) +Domains: Thermo.io Futurehosting.com +Site: Nexcess.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_nw +Options: + NW_API_TOKEN API Token + NW_API_ENDPOINT API Endpoint. Default: "https://portal.nexcess.net". +Issues: github.com/acmesh-official/acme.sh/issues/2088 +Author: Frank Laszlo +' + # Endpoints: # - https://portal.nexcess.net (default) # - https://core.thermo.io @@ -22,8 +21,6 @@ # - https://portal.nexcess.net/api-token # - https://core.thermo.io/api-token # - https://my.futurehosting.com/api-token -# -# Author: Frank Laszlo NW_API_VERSION="0" diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index 3b81143f..f1138efa 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -1,6 +1,19 @@ #!/usr/bin/env sh -# -# Acme.sh DNS API plugin for Oracle Cloud Infrastructure +# shellcheck disable=SC2034 +dns_oci_info='Oracle Cloud Infrastructure (OCI) + If OCI CLI configuration file ~/.oci/config has a DEFAULT profile then it will be used. +Site: Cloud.Oracle.com +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-Oracle-Cloud-Infrastructure-DNS +Options: + OCI_CLI_TENANCY OCID of tenancy that contains the target DNS zone. Optional. + OCI_CLI_USER OCID of user with permission to add/remove records from zones. Optional. + OCI_CLI_REGION Should point to the tenancy home region. Optional. + OCI_CLI_KEY_FILE Path to private API signing key file in PEM format. Optional. + OCI_CLI_KEY The private API signing key in PEM format. Optional. +Issues: github.com/acmesh-official/acme.sh/issues/3540 +Author: Avi Miller +' + # Copyright (c) 2021, Oracle and/or its affiliates # # The plugin will automatically use the default profile from an OCI SDK and CLI diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 1565b767..b2adf253 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh -# one.com ui wrapper for acme.sh - -# -# export ONECOM_User="username" -# export ONECOM_Password="password" +# shellcheck disable=SC2034 +dns_one_info='one.com +Site: one.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_one +Options: + ONECOM_User Username + ONECOM_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2103 +' dns_one_add() { fulldomain=$1 diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index 9158c268..c83cd458 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -1,9 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_online_info='online.net +Domains: scaleway.com +Site: online.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_online +Options: + ONLINE_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2093 +' # Online API # https://console.online.net/en/api/ -# -# Requires Online API key set in ONLINE_API_KEY ######## Public functions ##################### diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 0a9e5ade..0e93ecf8 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -1,15 +1,14 @@ #!/usr/bin/env sh - -# This is the OpenProvider API wrapper for acme.sh -# -# Author: Sylvia van Os -# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2104 -# -# export OPENPROVIDER_USER="username" -# export OPENPROVIDER_PASSWORDHASH="hashed_password" -# -# Usage: -# acme.sh --issue --dns dns_openprovider -d example.com +# shellcheck disable=SC2034 +dns_openprovider_info='OpenProvider.eu +Site: OpenProvider.eu +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_openprovider +Options: + OPENPROVIDER_USER Username + OPENPROVIDER_PASSWORDHASH Password hash +Issues: github.com/acmesh-official/acme.sh/issues/2104 +Author: Sylvia van Os +' OPENPROVIDER_API="https://api.openprovider.eu/" #OPENPROVIDER_API="https://api.cte.openprovider.eu/" # Test API diff --git a/dnsapi/dns_openstack.sh b/dnsapi/dns_openstack.sh index fcc1dc2e..fa38bc0b 100755 --- a/dnsapi/dns_openstack.sh +++ b/dnsapi/dns_openstack.sh @@ -1,14 +1,21 @@ #!/usr/bin/env sh - -# OpenStack Designate API plugin -# -# This requires you to have OpenStackClient and python-desginateclient -# installed. -# -# You will require Keystone V3 credentials loaded into your environment, which -# could be either password or v3applicationcredential type. -# -# Author: Andy Botting +# shellcheck disable=SC2034 +dns_openstack_info='OpenStack Designate API + Depends on OpenStackClient and python-desginateclient. + You will require Keystone V3 credentials loaded into your environment, + which could be either password or v3 application credential type. +Site: docs.openstack.org/api-ref/dns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_openstack +Options: + OS_AUTH_URL Auth URL. E.g. "https://keystone.example.com:5000/" + OS_USERNAME Username + OS_PASSWORD Password + OS_PROJECT_NAME Project name + OS_PROJECT_DOMAIN_NAME Project domain name. E.g. "Default" + OS_USER_DOMAIN_NAME User domain name. E.g. "Default" +Issues: github.com/acmesh-official/acme.sh/issues/3054 +Author: Andy Botting +' ######## Public functions ##################### diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index d40cbe28..6d3d3eec 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -1,16 +1,16 @@ #!/usr/bin/env sh - -#OPNsense Bind API -#https://docs.opnsense.org/development/api.html -# -#OPNs_Host="opnsense.example.com" -#OPNs_Port="443" -# optional, defaults to 443 if unset -#OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA" -#OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv" -#OPNs_Api_Insecure=0 -# optional, defaults to 0 if unset -# Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) +# shellcheck disable=SC2034 +dns_opnsense_info='OPNsense Server +Site: docs.opnsense.org/development/api.html +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_opnsense +Options: + OPNs_Host Server Hostname. E.g. "opnsense.example.com" + OPNs_Port Port. Default: "443". + OPNs_Key API Key + OPNs_Token API Token + OPNs_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept +Issues: github.com/acmesh-official/acme.sh/issues/2480 +' ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index e1a958f6..7f62c05e 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -1,13 +1,15 @@ #!/usr/bin/env sh - -#Application Key -#OVH_AK="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#Application Secret -#OVH_AS="sdfsafsdfsdfdsfsdfsa" -# -#Consumer Key -#OVH_CK="sdfsdfsdfsdfsdfdsf" +# shellcheck disable=SC2034 +dns_ovh_info='OVH.com +Domains: kimsufi.com soyoustart.com +Site: OVH.com +Docs: github.com/acmesh-official/acme.sh/wiki/How-to-use-OVH-domain-api +Options: + OVH_END_POINT Endpoint. "ovh-eu", "ovh-us", "ovh-ca", "kimsufi-eu", "kimsufi-ca", "soyoustart-eu", "soyoustart-ca" or raw URL. Default: "ovh-eu". + OVH_AK Application Key + OVH_AS Application Secret + OVH_CK Consumer Key +' #OVH_END_POINT=ovh-eu diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 6aa2e953..cde3b1a6 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -1,12 +1,14 @@ #!/usr/bin/env sh - -#PowerDNS Embedded API -#https://doc.powerdns.com/md/httpapi/api_spec/ -# -#PDNS_Url="http://ns.example.com:8081" -#PDNS_ServerId="localhost" -#PDNS_Token="0123456789ABCDEF" -#PDNS_Ttl=60 +# shellcheck disable=SC2034 +dns_pdns_info='PowerDNS Server API +Site: PowerDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_pdns +Options: + PDNS_Url API URL. E.g. "http://ns.example.com:8081" + PDNS_ServerId Server ID. E.g. "localhost" + PDNS_Token API Token + PDNS_Ttl=60 Domain TTL. Default: "60". +' DEFAULT_PDNS_TTL=60 diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh index 81973e07..6b38abcb 100644 --- a/dnsapi/dns_pleskxml.sh +++ b/dnsapi/dns_pleskxml.sh @@ -1,10 +1,17 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_pleskxml_info='Plesk Server API +Site: Plesk.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_pleskxml +Options: + pleskxml_uri Plesk server API URL. E.g. "https://your-plesk-server.net:8443/enterprise/control/agent.php" + pleskxml_user Username + pleskxml_pass Password +Issues: github.com/acmesh-official/acme.sh/issues/2577 +Author: Stilez, +' -## Name: dns_pleskxml.sh -## Created by Stilez. -## Also uses some code from PR#1832 by @romanlum (https://github.com/acmesh-official/acme.sh/pull/1832/files) - -## This DNS-01 method uses the Plesk XML API described at: +## Plesk XML API described at: ## https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 ## and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 @@ -16,21 +23,6 @@ ## For ACME v2 purposes, new TXT records are appended when added, and removing one TXT record will not affect any other TXT records. ## The user credentials (username+password) and URL/URI for the Plesk XML API must be set by the user -## before this module is called (case sensitive): -## -## ``` -## export pleskxml_uri="https://address-of-my-plesk-server.net:8443/enterprise/control/agent.php" -## (or probably something similar) -## export pleskxml_user="my plesk username" -## export pleskxml_pass="my plesk password" -## ``` - -## Ok, let's issue a cert now: -## ``` -## acme.sh --issue --dns dns_pleskxml -d example.com -d www.example.com -## ``` -## -## The `pleskxml_uri`, `pleskxml_user` and `pleskxml_pass` will be saved in `~/.acme.sh/account.conf` and reused when needed. #################### INTERNAL VARIABLES + NEWLINE + API TEMPLATES ################################## diff --git a/dnsapi/dns_pointhq.sh b/dnsapi/dns_pointhq.sh index 62313109..fe95cd52 100644 --- a/dnsapi/dns_pointhq.sh +++ b/dnsapi/dns_pointhq.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#PointHQ_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#PointHQ_Email="xxxx@sss.com" +# shellcheck disable=SC2034 +dns_pointhq_info='pointhq.com PointDNS +Site: pointhq.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_pointhq +Options: + PointHQ_Key API Key + PointHQ_Email Email +Issues: github.com/acmesh-official/acme.sh/issues/2060 +' PointHQ_Api="https://api.pointhq.com" diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index ad4455b6..0a443855 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -1,8 +1,13 @@ #!/usr/bin/env sh - -# -#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" -#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" +# shellcheck disable=SC2034 +dns_porkbun_info='Porkbun.com +Site: Porkbun.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_porkbun +Options: + PORKBUN_API_KEY API Key + PORKBUN_SECRET_API_KEY API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3450 +' PORKBUN_Api="https://porkbun.com/api/json/v3" @@ -88,7 +93,7 @@ dns_porkbun_rm() { _err "Delete record error." return 1 fi - echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null + echo "$response" | tr -d " " | grep '"status":"SUCCESS"' >/dev/null fi } @@ -134,7 +139,7 @@ _porkbun_rest() { api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"') secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"') - test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1)," + test -z "$data" && data="{" || data="$(echo "$data" | cut -d'}' -f1)," data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}" export _H1="Content-Type: application/json" diff --git a/dnsapi/dns_rackcorp.sh b/dnsapi/dns_rackcorp.sh index 6aabfddc..e1e4f27d 100644 --- a/dnsapi/dns_rackcorp.sh +++ b/dnsapi/dns_rackcorp.sh @@ -1,16 +1,14 @@ #!/usr/bin/env sh - -# Provider: RackCorp (www.rackcorp.com) -# Author: Stephen Dendtler (sdendtler@rackcorp.com) -# Report Bugs here: https://github.com/senjoo/acme.sh -# Alternate email contact: support@rackcorp.com -# -# You'll need an API key (Portal: ADMINISTRATION -> API) -# Set the environment variables as below: -# -# export RACKCORP_APIUUID="UUIDHERE" -# export RACKCORP_APISECRET="SECRETHERE" -# +# shellcheck disable=SC2034 +dns_rackcorp_info='RackCorp.com +Site: RackCorp.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_rackcorp +Options: + RACKCORP_APIUUID API UUID. See Portal: ADMINISTRATION -> API + RACKCORP_APISECRET API Secret +Issues: github.com/acmesh-official/acme.sh/issues/3351 +Author: Stephen Dendtler +' RACKCORP_API_ENDPOINT="https://api.rackcorp.net/api/rest/v2.4/json.php" diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index b50d9168..03edce0d 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh -# -# -#RACKSPACE_Username="" -# -#RACKSPACE_Apikey="" +# shellcheck disable=SC2034 +dns_rackspace_info='RackSpace.com +Site: RackSpace.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_rackspace +Options: + RACKSPACE_Apikey API Key + RACKSPACE_Username Username +Issues: github.com/acmesh-official/acme.sh/issues/2091 +' RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" diff --git a/dnsapi/dns_rage4.sh b/dnsapi/dns_rage4.sh index 4af4541d..ad312759 100755 --- a/dnsapi/dns_rage4.sh +++ b/dnsapi/dns_rage4.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#RAGE4_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#RAGE4_USERNAME="xxxx@sss.com" +# shellcheck disable=SC2034 +dns_rage4_info='rage4.com +Site: rage4.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_rage4 +Options: + RAGE4_TOKEN API Key + RAGE4_USERNAME Username +Issues: github.com/acmesh-official/acme.sh/issues/4306 +' RAGE4_Api="https://rage4.com/rapi/" diff --git a/dnsapi/dns_rcode0.sh b/dnsapi/dns_rcode0.sh index d3f7f219..131a22b1 100755 --- a/dnsapi/dns_rcode0.sh +++ b/dnsapi/dns_rcode0.sh @@ -1,14 +1,20 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_rcode0_info='Rcode0 rcodezero.at +Site: rcodezero.at +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_rcode0 +Options: + RCODE0_URL API URL. E.g. "https://my.rcodezero.at" + RCODE0_API_TOKEN API Token + RCODE0_TTL TTL. Default: "60". +Issues: github.com/acmesh-official/acme.sh/issues/2490 +' #Rcode0 API Integration #https://my.rcodezero.at/api-doc # # log into https://my.rcodezero.at/enableapi and get your ACME API Token (the ACME API token has limited # access to the REST calls needed for acme.sh only) -# -#RCODE0_URL="https://my.rcodezero.at" -#RCODE0_API_TOKEN="0123456789ABCDEF" -#RCODE0_TTL=60 DEFAULT_RCODE0_URL="https://my.rcodezero.at" DEFAULT_RCODE0_TTL=60 diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh index 8ff380f0..be5ae117 100644 --- a/dnsapi/dns_regru.sh +++ b/dnsapi/dns_regru.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh - -# -# REGRU_API_Username="test" -# -# REGRU_API_Password="test" -# +# shellcheck disable=SC2034 +dns_regru_info='reg.ru +Site: reg.ru +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_regru +Options: + REGRU_API_Username Username + REGRU_API_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/2336 +' REGRU_API_URL="https://api.reg.ru/api/regru2" diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index a0a0f318..64bfcc38 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_scaleway_info='ScaleWay.com +Site: ScaleWay.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_scaleway +Options: + SCALEWAY_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/3295 +' # Scaleway API # https://developers.scaleway.com/en/products/domain/dns/api/ -# -# Requires Scaleway API token set in SCALEWAY_API_TOKEN ######## Public functions ##################### diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index 399c50e0..02146494 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -1,16 +1,14 @@ #!/usr/bin/env sh -# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*- - -# Schlundtech DNS API -# Author: mod242 -# Created: 2019-40-29 -# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com -# -# export SCHLUNDTECH_USER="username" -# export SCHLUNDTECH_PASSWORD="password" -# -# Usage: -# acme.sh --issue --dns dns_schlundtech -d example.com +# shellcheck disable=SC2034 +dns_schlundtech_info='SchlundTech.de +Site: SchlundTech.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_schlundtech +Options: + SCHLUNDTECH_USER Username + SCHLUNDTECH_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/2246 +Author: +' SCHLUNDTECH_API="https://gateway.schlundtech.de" diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1b09882d..32b0737f 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,8 +1,12 @@ #!/usr/bin/env sh - -# -#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# shellcheck disable=SC2034 +dns_selectel_info='Selectel.com +Domains: Selectel.ru +Site: Selectel.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel +Options: + SL_Key API Key +' SL_Api="https://api.selectel.ru/domains/v1" diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh index a6ef1f94..4912dfdf 100644 --- a/dnsapi/dns_selfhost.sh +++ b/dnsapi/dns_selfhost.sh @@ -1,8 +1,15 @@ #!/usr/bin/env sh -# -# Author: Marvin Edeler -# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1 -# Last Edit: 17.02.2022 +# shellcheck disable=SC2034 +dns_selfhost_info='SelfHost.de +Site: SelfHost.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_selfhost +Options: + SELFHOSTDNS_USERNAME Username + SELFHOSTDNS_PASSWORD Password + SELFHOSTDNS_MAP Subdomain name +Issues: github.com/acmesh-official/acme.sh/issues/4291 +Author: Marvin Edeler +' dns_selfhost_add() { fulldomain=$1 diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 52137905..37c2a97b 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -1,19 +1,14 @@ #!/usr/bin/env sh - -########## -# Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/acmesh-official/acme.sh) -# -# Usage: -# export SERVERCOW_API_Username=username -# export SERVERCOW_API_Password=password -# acme.sh --issue -d example.com --dns dns_servercow -# -# Issues: -# Any issues / questions / suggestions can be posted here: -# https://github.com/jhartlep/servercow-dns-api/issues -# -# Author: Jens Hartlep -########## +# shellcheck disable=SC2034 +dns_servercow_info='ServerCow.de +Site: ServerCow.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_servercow +Options: + SERVERCOW_API_Username Username + SERVERCOW_API_Password Password +Issues: github.com/jhartlep/servercow-dns-api/issues +Author: Jens Hartlep +' SERVERCOW_API="https://api.servercow.de/dns/v1/domains" diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 6a8d0e18..9fac3ef7 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -1,10 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_simply_info='Simply.com +Site: Simply.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_simply +Options: + SIMPLY_AccountName Account name + SIMPLY_ApiKey API Key +' -# API-integration for Simply.com (https://www.simply.com) - -#SIMPLY_AccountName="accountname" -#SIMPLY_ApiKey="apikey" -# #SIMPLY_Api="https://api.simply.com/2/" SIMPLY_Api_Default="https://api.simply.com/2" diff --git a/dnsapi/dns_tele3.sh b/dnsapi/dns_tele3.sh index 76c90913..e5974951 100644 --- a/dnsapi/dns_tele3.sh +++ b/dnsapi/dns_tele3.sh @@ -1,14 +1,13 @@ #!/usr/bin/env sh -# -# tele3.cz DNS API -# -# Author: Roman Blizik -# Report Bugs here: https://github.com/par-pa/acme.sh -# -# -- -# export TELE3_Key="MS2I4uPPaI..." -# export TELE3_Secret="kjhOIHGJKHg" -# -- +# shellcheck disable=SC2034 +dns_tele3_info='tele3.cz +Site: tele3.cz +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#tele3 +Options: + TELE3_Key API Key + TELE3_Secret API Secret +Author: Roman Blizik +' TELE3_API="https://www.tele3.cz/acme/" diff --git a/dnsapi/dns_tencent.sh b/dnsapi/dns_tencent.sh index 2f8d3b67..d82768b9 100644 --- a/dnsapi/dns_tencent.sh +++ b/dnsapi/dns_tencent.sh @@ -1,9 +1,15 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_tencent_info='Tencent.com +Site: cloud.Tencent.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_tencent +Options: + Tencent_SecretId Secret ID + Tencent_SecretKey Secret Key +Issues: github.com/acmesh-official/acme.sh/issues/4781 +' Tencent_API="https://dnspod.tencentcloudapi.com" -#Tencent_SecretId="AKIDz81d2cd22cdcdc2dcd1cc1d1A" -#Tencent_SecretKey="Gu5t9abcabcaabcbabcbbbcbcbbccbbcb" - #Usage: dns_tencent_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_tencent_add() { fulldomain=$1 diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 64a256ec..6171678e 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -1,4 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_transip_info='TransIP.nl +Site: TransIP.nl +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_transip +Options: + TRANSIP_Username Username + TRANSIP_Key_File Private key file path +Issues: github.com/acmesh-official/acme.sh/issues/2949 +' + TRANSIP_Api_Url="https://api.transip.nl/v6" TRANSIP_Token_Read_Only="false" TRANSIP_Token_Expiration="30 minutes" diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh index caada826..24a843b9 100644 --- a/dnsapi/dns_udr.sh +++ b/dnsapi/dns_udr.sh @@ -1,14 +1,14 @@ #!/usr/bin/env sh - -# united-domains Reselling (https://www.ud-reselling.com/) DNS API -# Author: Andreas Scherer (https://github.com/andischerer) -# Created: 2021-02-01 -# -# Set the environment variables as below: -# -# export UDR_USER="your_username_goes_here" -# export UDR_PASS="some_password_goes_here" -# +# shellcheck disable=SC2034 +dns_udr_info='united-domains Reselling +Site: ud-reselling.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_udr +Options: + UDR_USER Username + UDR_PASS Password +Issues: github.com/acmesh-official/acme.sh/issues/3923 +Author: Andreas Scherer +' UDR_API="https://api.domainreselling.de/api/call.cgi" UDR_TTL="30" diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh index 0f26bd97..8b8c9122 100644 --- a/dnsapi/dns_ultra.sh +++ b/dnsapi/dns_ultra.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -# ULTRA_USR="your_user_goes_here" -# -# ULTRA_PWD="some_password_goes_here" +# shellcheck disable=SC2034 +dns_ultra_info='UltraDNS.com +Site: UltraDNS.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ultra +Options: + ULTRA_USR Username + ULTRA_PWD Password +Issues: github.com/acmesh-official/acme.sh/issues/2118 +' ULTRA_API="https://api.ultradns.com/v3/" ULTRA_AUTH_API="https://api.ultradns.com/v2/" diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index 13ba8a00..a1263abe 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -1,9 +1,13 @@ #!/usr/bin/env sh - -# -#UNO_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#UNO_User="UExxxxxx" +# shellcheck disable=SC2034 +dns_unoeuro_info='unoeuro.com + Deprecated. The unoeuro.com is now simply.com +Site: unoeuro.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_unoeuro +Options: + UNO_Key API Key + UNO_User Username +' Uno_Api="https://api.simply.com/1" diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index aa743807..23ec29bf 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -1,7 +1,12 @@ #!/usr/bin/env sh - -# -#VARIOMEDIA_API_TOKEN=000011112222333344445555666677778888 +# shellcheck disable=SC2034 +dns_variomedia_info='variomedia.de +Site: variomedia.de +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_variomedia +Options: + VARIOMEDIA_API_TOKEN API Token +Issues: github.com/acmesh-official/acme.sh/issues/2564 +' VARIOMEDIA_API="https://api.variomedia.de" diff --git a/dnsapi/dns_veesp.sh b/dnsapi/dns_veesp.sh index b8a41d00..5ea6e718 100644 --- a/dnsapi/dns_veesp.sh +++ b/dnsapi/dns_veesp.sh @@ -1,10 +1,14 @@ #!/usr/bin/env sh - -# bug reports to stepan@plyask.in - -# -# export VEESP_User="username" -# export VEESP_Password="password" +# shellcheck disable=SC2034 +dns_veesp_info='veesp.com +Site: veesp.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_veesp +Options: + VEESP_User Username + VEESP_Password Password +Issues: github.com/acmesh-official/acme.sh/issues/3712 +Author: +' VEESP_Api="https://secure.veesp.com/api" diff --git a/dnsapi/dns_vercel.sh b/dnsapi/dns_vercel.sh index 7bf6b0e5..46a4cb7e 100644 --- a/dnsapi/dns_vercel.sh +++ b/dnsapi/dns_vercel.sh @@ -1,11 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_vercel_info='Vercel.com +Site: Vercel.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_vercel +Options: + VERCEL_TOKEN API Token +' -# Vercel DNS API -# # This is your API token which can be acquired on the account page. # https://vercel.com/account/tokens -# -# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" VERCEL_API="https://api.vercel.com" diff --git a/dnsapi/dns_vscale.sh b/dnsapi/dns_vscale.sh index d717d6e2..54abb439 100755 --- a/dnsapi/dns_vscale.sh +++ b/dnsapi/dns_vscale.sh @@ -1,11 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_vscale_info='vscale.io +Site: vscale.io +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_vscale +Options: + VSCALE_API_KEY API Key +Author: Alex Loban +' -#This is the vscale.io api wrapper for acme.sh -# -#Author: Alex Loban -#Report Bugs here: https://github.com/LAV45/acme.sh - -#VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" VSCALE_API_URL="https://api.vscale.io/v1" ######## Public functions ##################### diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 54e5b6ce..94d14f02 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh - -# -#VULTR_API_KEY=000011112222333344445555666677778888 +# shellcheck disable=SC2034 +dns_vultr_info='vultr.com +Site: vultr.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_vultr +Options: + VULTR_API_KEY API Key +Issues: github.com/acmesh-official/acme.sh/issues/2374 +Author: +' VULTR_Api="https://api.vultr.com/v2" diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index e824c9c0..3df8d81c 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -1,18 +1,16 @@ #!/usr/bin/env sh - -# Acme.sh DNS API wrapper for websupport.sk -# -# Original author: trgo.sk (https://github.com/trgosk) -# Tweaks by: akulumbeg (https://github.com/akulumbeg) -# Report Bugs here: https://github.com/akulumbeg/acme.sh +# shellcheck disable=SC2034 +dns_websupport_info='Websupport.sk +Site: Websupport.sk +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_websupport +Options: + WS_ApiKey API Key. Called "Identifier" in the WS Admin + WS_ApiSecret API Secret. Called "Secret key" in the WS Admin +Issues: github.com/acmesh-official/acme.sh/issues/3486 +Author: trgo.sk , akulumbeg +' # Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey -# -# WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -# (called "Identifier" in the WS Admin) -# -# WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -# (called "Secret key" in the WS Admin) WS_Api="https://rest.websupport.sk" diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index dfda4efd..be6ef5c8 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -1,7 +1,14 @@ #!/usr/bin/env sh - -# World4You - www.world4you.com -# Lorenz Stechauner, 2020 - https://www.github.com/NerLOR +# shellcheck disable=SC2034 +dns_world4you_info='World4You.com +Site: World4You.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_world4you +Options: + WORLD4YOU_USERNAME Username + WORLD4YOU_PASSWORD Password +Issues: github.com/acmesh-official/acme.sh/issues/3269 +Author: Lorenz Stechauner +' WORLD4YOU_API="https://my.world4you.com/en" PAKETNR='' diff --git a/dnsapi/dns_yandex.sh b/dnsapi/dns_yandex.sh index 0a2c3330..d780459f 100755 --- a/dnsapi/dns_yandex.sh +++ b/dnsapi/dns_yandex.sh @@ -1,13 +1,13 @@ #!/usr/bin/env sh -# Author: non7top@gmail.com -# 07 Jul 2017 -# report bugs at https://github.com/non7top/acme.sh - -# Values to export: -# export PDD_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Sometimes cloudflare / google doesn't pick new dns records fast enough. -# You can add --dnssleep XX to params as workaround. +# shellcheck disable=SC2034 +dns_yandex_info='Yandex Domains +Site: tech.Yandex.com/domain/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_yandex +Options: + PDD_Token API Token +Issues: github.com/non7top/acme.sh/issues +Author: +' ######## Public functions ##################### diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index ec3bbc87..e81b6fd2 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -1,11 +1,18 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_yc_info='Yandex Cloud DNS +Site: Cloud.Yandex.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yc +Options: + YC_Zone_ID DNS Zone ID + YC_Folder_ID YC Folder ID + YC_SA_ID Service Account ID + YC_SA_Key_ID Service Account IAM Key ID + YC_SA_Key_File_Path Private key file path. Optional. + YC_SA_Key_File_PEM_b64 Base64 content of private key file. Use instead of Path to private key file. Optional. +Issues: github.com/acmesh-official/acme.sh/issues/4210 +' -#YC_Zone_ID="" # DNS Zone ID -#YC_Folder_ID="" # YC Folder ID -#YC_SA_ID="" # Service Account ID -#YC_SA_Key_ID="" # Service Account IAM Key ID -#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of YC_SA_Key_File_PEM_b64 -#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of YC_SA_Key_File_Path YC_Api="https://dns.api.cloud.yandex.net/dns/v1" ######## Public functions ##################### diff --git a/dnsapi/dns_zilore.sh b/dnsapi/dns_zilore.sh index 42111025..369ce152 100644 --- a/dnsapi/dns_zilore.sh +++ b/dnsapi/dns_zilore.sh @@ -1,7 +1,13 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_zilore_info='Zilore.com +Site: Zilore.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zilore +Options: + Zilore_Key API Key +' Zilore_API="https://api.zilore.com/dns/v1" -# Zilore_Key="YOUR-ZILORE-API-KEY" ######## Public functions ##################### diff --git a/dnsapi/dns_zone.sh b/dnsapi/dns_zone.sh index 176fc494..e4685707 100755 --- a/dnsapi/dns_zone.sh +++ b/dnsapi/dns_zone.sh @@ -1,8 +1,16 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_zone_info='Zone.eu +Site: Zone.eu +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zone +Options: + ZONE_Username Username + ZONE_Key API Key +Issues: github.com/acmesh-official/acme.sh/issues/2146 +' # Zone.ee dns API # https://help.zone.eu/kb/zoneid-api-v2/ -# required ZONE_Username and ZONE_Key ZONE_Api="https://api.zone.eu/v2" ######## Public functions ##################### diff --git a/dnsapi/dns_zonomi.sh b/dnsapi/dns_zonomi.sh index 52a889ea..ee817381 100644 --- a/dnsapi/dns_zonomi.sh +++ b/dnsapi/dns_zonomi.sh @@ -1,9 +1,11 @@ #!/usr/bin/env sh - -# -#ZM_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# -#https://zonomi.com dns api +# shellcheck disable=SC2034 +dns_zonomi_info='zonomi.com +Site: zonomi.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_zonomi +Options: + ZM_Key API Key +' ZM_Api="https://zonomi.com/app/dns/dyndns.jsp" diff --git a/notify/ntfy.sh b/notify/ntfy.sh new file mode 100644 index 00000000..650d1c74 --- /dev/null +++ b/notify/ntfy.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +# support ntfy + +#NTFY_URL="https://ntfy.sh" +#NTFY_TOPIC="xxxxxxxxxxxxx" + +ntfy_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + NTFY_URL="${NTFY_URL:-$(_readaccountconf_mutable NTFY_URL)}" + if [ "$NTFY_URL" ]; then + _saveaccountconf_mutable NTFY_URL "$NTFY_URL" + fi + + NTFY_TOPIC="${NTFY_TOPIC:-$(_readaccountconf_mutable NTFY_TOPIC)}" + if [ "$NTFY_TOPIC" ]; then + _saveaccountconf_mutable NTFY_TOPIC "$NTFY_TOPIC" + fi + + _data="${_subject}. $_content" + response="$(_post "$_data" "$NTFY_URL/$NTFY_TOPIC" "" "POST" "")" + + if [ "$?" = "0" ] && _contains "$response" "expires"; then + _info "ntfy event fired success." + return 0 + fi + + _err "ntfy event fired error." + _err "$response" + return 1 +} From 3fc39aad3320321ce0e18029159b0a3acbefb292 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Mon, 19 Aug 2024 13:30:11 +0000 Subject: [PATCH 426/687] Add ACCOUNT_THUMBPRINT to update account Ref: #590 --- acme.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acme.sh b/acme.sh index c3564e68..ed45ff16 100755 --- a/acme.sh +++ b/acme.sh @@ -3881,6 +3881,9 @@ updateaccount() { if [ "$code" = '200' ]; then echo "$response" >"$ACCOUNT_JSON_PATH" _info "Account update success for $_accUri." + + ACCOUNT_THUMBPRINT="$(__calc_account_thumbprint)" + _info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT" else _info "An error occurred and the account was not updated." return 1 From 5f68ad4e19c2bb283b6b266bfa47a1e368920123 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 19 Aug 2024 22:15:39 +0800 Subject: [PATCH 427/687] fix --- .github/workflows/PebbleStrict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml index 3f8fdb62..b0326332 100644 --- a/.github/workflows/PebbleStrict.yml +++ b/.github/workflows/PebbleStrict.yml @@ -37,7 +37,7 @@ jobs: - name: Install tools run: sudo apt-get install -y socat - name: Run Pebble - run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d + run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker compose up -d - name: Set up Pebble run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 - name: Clone acmetest From 435bb3f1d30408ec8838d0ee0661e22b2984a4b6 Mon Sep 17 00:00:00 2001 From: Roland Giesler Date: Wed, 21 Aug 2024 12:13:04 +0200 Subject: [PATCH 428/687] Update dns_miab.sh The MIAB API requires that the txtvlaue to a TXT record includes the "value=" and "ttl=" components as part of the TXT record when adding a new record. --- dnsapi/dns_miab.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index ec9867db..79e751bf 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -19,7 +19,8 @@ dns_miab_add() { txtvalue=$2 _info "Using miab challange add" _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" + # Added to accomodate the new TXT record format used by the API + _debug txtvalue "value="+="$txtvalue"+"&ttl=300" #retrieve MIAB environemt vars if ! _retrieve_miab_env; then From 0122eabd44a8d82b033a51292457161e18381aee Mon Sep 17 00:00:00 2001 From: Roland Giesler Date: Wed, 21 Aug 2024 15:10:37 +0200 Subject: [PATCH 429/687] Update dns_miab.sh Corrected typo --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 79e751bf..837234c4 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -20,7 +20,7 @@ dns_miab_add() { _info "Using miab challange add" _debug fulldomain "$fulldomain" # Added to accomodate the new TXT record format used by the API - _debug txtvalue "value="+="$txtvalue"+"&ttl=300" + _debug txtvalue "value="+="$txtvalue"+="&ttl=300" #retrieve MIAB environemt vars if ! _retrieve_miab_env; then From 42e78f9a3ee031a0332b6a5241800aa8fee2ee94 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Wed, 21 Aug 2024 15:42:49 +0200 Subject: [PATCH 430/687] changes not yet tested --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 837234c4..6b1555d0 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -19,7 +19,7 @@ dns_miab_add() { txtvalue=$2 _info "Using miab challange add" _debug fulldomain "$fulldomain" - # Added to accomodate the new TXT record format used by the API + # Added to accomodate the new TXT record format used by the API to include value= and ttl= _debug txtvalue "value="+="$txtvalue"+="&ttl=300" #retrieve MIAB environemt vars From 10cfc6838dacc56f2415ce179816549fb9d2b31e Mon Sep 17 00:00:00 2001 From: Nikolay Pronchev Date: Thu, 22 Aug 2024 09:12:21 +0300 Subject: [PATCH 431/687] add Timeweb Cloud DNS API --- dnsapi/dns_timeweb.sh | 405 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 dnsapi/dns_timeweb.sh diff --git a/dnsapi/dns_timeweb.sh b/dnsapi/dns_timeweb.sh new file mode 100644 index 00000000..2edca180 --- /dev/null +++ b/dnsapi/dns_timeweb.sh @@ -0,0 +1,405 @@ +#!/usr/bin/env sh + +# acme.sh DNS API for Timeweb Cloud provider (https://timeweb.cloud). +# +# Author: https://github.com/nikolaypronchev. +# +# Prerequisites: +# Timeweb Cloud API JWT token. Obtain one from the Timeweb Cloud control panel +# ("API and Terraform" section: https://timeweb.cloud/my/api-keys). The JWT token +# must be provided to this script in one of two ways: +# 1. As the "TW_Token" variable, for example: "export TW_Token=eyJhbG...zUxMiIs"; +# 2. As a "TW_Token" config entry in acme.sh account config file +# (usually located at ~/.acme.sh/account.conf by default). + +TW_Api="https://api.timeweb.cloud/api/v1" + +################ Public functions ################ + +# Adds an ACME DNS-01 challenge DNS TXT record via the Timeweb Cloud API. +# +# Param1: The ACME DNS-01 challenge FQDN. +# Param2: The value of the ACME DNS-01 challenge TXT record. +# +# Example: dns_timeweb_add "_acme-challenge.sub.domain.com" "D-52Wm...4uYM" +dns_timeweb_add() { + _debug "$(__green "Timeweb DNS API"): \"dns_timeweb_add\" started." + + _timeweb_set_acme_fqdn "$1" || return 1 + _timeweb_set_acme_txt "$2" || return 1 + _timeweb_check_token || return 1 + _timeweb_split_acme_fqdn || return 1 + _timeweb_dns_txt_add || return 1 + + _debug "$(__green "Timeweb DNS API"): \"dns_timeweb_add\" finished." +} + +# Removes a DNS TXT record via the Timeweb Cloud API. +# +# Param1: The ACME DNS-01 challenge FQDN. +# Param2: The value of the ACME DNS-01 challenge TXT record. +# +# Example: dns_timeweb_rm "_acme-challenge.sub.domain.com" "D-52Wm...4uYM" +dns_timeweb_rm() { + _debug "$(__green "Timeweb DNS API"): \"dns_timeweb_rm\" started." + + _timeweb_set_acme_fqdn "$1" || return 1 + _timeweb_set_acme_txt "$2" || return 1 + _timeweb_check_token || return 1 + _timeweb_split_acme_fqdn || return 1 + _timeweb_get_dns_txt || return 1 + _timeweb_dns_txt_remove || return 1 + + _debug "$(__green "Timeweb DNS API"): \"dns_timeweb_rm\" finished." +} + +################ Private functions ################ + +# Checks and sets the ACME DNS-01 challenge FQDN. +# +# Param1: The ACME DNS-01 challenge FQDN. +# +# Example: _timeweb_set_acme_fqdn "_acme-challenge.sub.domain.com" +# +# Sets the "Acme_Fqdn" variable (_acme-challenge.sub.domain.com) +_timeweb_set_acme_fqdn() { + Acme_Fqdn=$1 + _debug "Setting ACME DNS-01 challenge FQDN \"$Acme_Fqdn\"." + [ -z "$Acme_Fqdn" ] && { + _err "ACME DNS-01 challenge FQDN is empty." + return 1 + } + return 0 +} + +# Checks and sets the value of the ACME DNS-01 challenge TXT record. +# +# Param1: Value of the ACME DNS-01 challenge TXT record. +# +# Example: _timeweb_set_acme_txt "D-52Wm...4uYM" +# +# Sets the "Acme_Txt" variable to the provided value (D-52Wm...4uYM) +_timeweb_set_acme_txt() { + Acme_Txt=$1 + _debug "Setting the value of the ACME DNS-01 challenge TXT record to \"$Acme_Txt\"." + [ -z "$Acme_Txt" ] && { + _err "ACME DNS-01 challenge TXT record value is empty." + return 1 + } + return 0 +} + +# Checks if the Timeweb Cloud API JWT token is present (refer to the script description). +# Adds or updates the token in the acme.sh account configuration. +_timeweb_check_token() { + _debug "Checking for the presence of the Timeweb Cloud API JWT token." + + TW_Token="${TW_Token:-$(_readaccountconf_mutable TW_Token)}" + + [ -z "$TW_Token" ] && { + _err "Timeweb Cloud API JWT token was not found." + return 1 + } + + _saveaccountconf_mutable TW_Token "$TW_Token" +} + +# Divides the ACME DNS-01 challenge FQDN into its main domain and subdomain components. +_timeweb_split_acme_fqdn() { + _debug "Trying to divide \"$Acme_Fqdn\" into its main domain and subdomain components." + + TW_Page_Limit=100 + TW_Page_Offset=0 + + while [ -z "$TW_Domains_Total" ] || + [ "$((TW_Domains_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do + + _timeweb_list_domains "$TW_Page_Limit" "$TW_Page_Offset" || return 1 + + # Remove the 'subdomains' subarray to prevent confusion with FQDNs. + + TW_Domains=$( + echo "$TW_Domains" | + sed 's/"subdomains":\[[^]]*]//g' + ) + + [ -z "$TW_Domains" ] && { + _err "Failed to parse the list of domains." + return 1 + } + + while + TW_Domain=$( + echo "$TW_Domains" | + sed -n 's/.*{[^{]*"fqdn":"\([^"]*\)"[^}]*}.*/\1/p' + ) + + [ -n "$TW_Domain" ] && { + _timeweb_is_main_domain "$TW_Domain" && return 0 + + TW_Domains=$( + echo "$TW_Domains" | + sed 's/{\([^{]*"fqdn":"'"$TW_Domain"'"[^}]*\)}//' + ) + continue + } + do :; done + + TW_Page_Offset=$(_math "$TW_Page_Offset" + "$TW_Page_Limit") + done + + _err "Failed to divide \"$Acme_Fqdn\" into its main domain and subdomain components." + return 1 +} + +# Searches for a previously added DNS TXT record. +# +# Sets the "TW_Dns_Txt_Id" variable. +_timeweb_get_dns_txt() { + _debug "Trying to locate a DNS TXT record with the value \"$Acme_Txt\"." + + TW_Page_Limit=100 + TW_Page_Offset=0 + + while [ -z "$TW_Dns_Records_Total" ] || + [ "$((TW_Dns_Records_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do + _timeweb_list_dns_records "$TW_Page_Limit" "$TW_Page_Offset" || return 1 + + while + Dns_Record=$( + echo "$TW_Dns_Records" | + sed -n 's/.*{\([^{]*{[^{]*'"$Acme_Txt"'[^}]*}[^}]*\)}.*/\1/p' + ) + + [ -n "$Dns_Record" ] && { + _timeweb_is_added_txt "$Dns_Record" && return 0 + + TW_Dns_Records=$( + echo "$TW_Dns_Records" | + sed 's/{\([^{]*{[^{]*'"$Acme_Txt"'[^}]*}[^}]*\)}//' + ) + continue + } + do :; done + + TW_Page_Offset=$(_math "$TW_Page_Offset" + "$TW_Page_Limit") + done + + _err "DNS TXT record was not found." + return 1 +} + +# Lists domains via the Timeweb Cloud API. +# +# Param 1: Limit for listed domains. +# Param 2: Offset for domains list. +# +# Sets the "TW_Domains" variable. +# Sets the "TW_Domains_Total" variable. +_timeweb_list_domains() { + _debug "Listing domains via Timeweb Cloud API. Limit: $1, offset: $2." + + export _H1="Authorization: Bearer $TW_Token" + + if ! TW_Domains=$(_get "$TW_Api/domains?limit=$1&offset=$2"); then + _err "The request to the Timeweb Cloud API failed." + return 1 + fi + + [ -z "$TW_Domains" ] && { + _err "Empty response from the Timeweb Cloud API." + return 1 + } + + TW_Domains_Total=$( + echo "$TW_Domains" | + sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' + ) + + [ -z "$TW_Domains_Total" ] && { + _err "Failed to extract the total count of domains." + return 1 + } + + [ "$TW_Domains_Total" -eq "0" ] && { + _err "Domains are missing." + return 1 + } + + _debug "Total count of domains in the Timeweb Cloud account: $TW_Domains_Total." +} + +# Lists domain DNS records via the Timeweb Cloud API. +# +# Param 1: Limit for listed DNS records. +# Param 2: Offset for DNS records list. +# +# Sets the "TW_Dns_Records" variable. +# Sets the "TW_Dns_Records_Total" variable. +_timeweb_list_dns_records() { + _debug "Listing domain DNS records via the Timeweb Cloud API. Limit: $1, offset: $2." + + export _H1="Authorization: Bearer $TW_Token" + + if ! TW_Dns_Records=$(_get "$TW_Api/domains/$TW_Main_Domain/dns-records?limit=$1&offset=$2"); then + _err "The request to the Timeweb Cloud API failed." + return 1 + fi + + [ -z "$TW_Dns_Records" ] && { + _err "Empty response from the Timeweb Cloud API." + return 1 + } + + TW_Dns_Records_Total=$( + echo "$TW_Dns_Records" | + sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' + ) + + [ -z "$TW_Dns_Records_Total" ] && { + _err "Failed to extract the total count of DNS records." + return 1 + } + + [ "$TW_Dns_Records_Total" -eq "0" ] && { + _err "DNS records are missing." + return 1 + } + + _debug "Total count of DNS records: $TW_Dns_Records_Total." +} + +# Verifies whether the domain is the primary domain for the ACME DNS-01 challenge FQDN. +# The requirement is that the provided domain is the top-level domain +# for the ACME DNS-01 challenge FQDN. +# +# Param 1: Domain object returned by Timeweb Cloud API. +# +# Sets the "TW_Main_Domain" variable (e.g. "_acme-challenge.s1.domain.co.uk" → "domain.co.uk"). +# Sets the "TW_Subdomains" variable (e.g. "_acme-challenge.s1.domain.co.uk" → "_acme-challenge.s1"). +_timeweb_is_main_domain() { + _debug "Checking if \"$1\" is the main domain of the ACME DNS-01 challenge FQDN." + + [ -z "$1" ] && { + _debug "Failed to extract FQDN. Skipping domain." + return 1 + } + + ! echo ".$Acme_Fqdn" | grep -qi "\.$1$" && { + _debug "Domain does not match the ACME DNS-01 challenge FQDN. Skipping domain." + return 1 + } + + TW_Main_Domain=$1 + TW_Subdomains=$( + echo "$Acme_Fqdn" | + sed "s/\.*.\{${#1}\}$//" + ) + + _debug "Matched domain. ACME DNS-01 challenge FQDN split as [$TW_Subdomains].[$TW_Main_Domain]." + return 0 +} + +# Verifies whether a DNS record was previously added based on the following criteria: +# - The value matches the ACME DNS-01 challenge TXT record value; +# - The record type is TXT; +# - The subdomain matches the ACME DNS-01 challenge FQDN. +# +# Param 1: DNS record object returned by Timeweb Cloud API. +# +# Sets the "TW_Dns_Txt_Id" variable. +_timeweb_is_added_txt() { + _debug "Checking if \"$1\" is a previously added DNS TXT record." + + echo "$1" | grep -qv '"type":"TXT"' && { + _debug "Not a TXT record. Skipping the record." + return 1 + } + + if [ -n "$TW_Subdomains" ]; then + echo "$1" | grep -qvi "\"subdomain\":\"$TW_Subdomains\"" && { + _debug "Subdomains do not match. Skipping the record." + return 1 + } + else + echo "$1" | grep -q '"subdomain\":"..*"' && { + _debug "Subdomains do not match. Skipping the record." + return 1 + } + fi + + TW_Dns_Txt_Id=$( + echo "$1" | + sed 's/.*"id":\([0-9]*\)[^0-9].*/\1/' + ) + + [ -z "$TW_Dns_Txt_Id" ] && { + _debug "Failed to extract the DNS record ID. Skipping the record." + return 1 + } + + _debug "Matching DNS TXT record ID is \"$TW_Dns_Txt_Id\"." + return 0 +} + +# Adds a DNS TXT record via the Timeweb Cloud API. +_timeweb_dns_txt_add() { + _debug "Adding a new DNS TXT record via the Timeweb Cloud API." + + export _H1="Authorization: Bearer $TW_Token" + export _H2="Content-Type: application/json" + + if ! TW_Response=$( + _post "{ + \"subdomain\":\"$TW_Subdomains\", + \"type\":\"TXT\", + \"value\":\"$Acme_Txt\" + }" \ + "$TW_Api/domains/$TW_Main_Domain/dns-records" + ); then + _err "The request to the Timeweb Cloud API failed." + return 1 + fi + + [ -z "$TW_Response" ] && { + _err "An unexpected empty response was received from the Timeweb Cloud API." + return 1 + } + + TW_Dns_Txt_Id=$( + echo "$TW_Response" | + sed 's/.*"id":\([0-9]*\)[^0-9].*/\1/' + ) + + [ -z "$TW_Dns_Txt_Id" ] && { + _err "Failed to extract the DNS TXT Record ID." + return 1 + } + + _debug "DNS TXT record has been added. ID: \"$TW_Dns_Txt_Id\"." +} + +# Removes a DNS record via the Timeweb Cloud API. +_timeweb_dns_txt_remove() { + _debug "Removing DNS record via the Timeweb Cloud API." + + export _H1="Authorization: Bearer $TW_Token" + + if ! TW_Response=$( + _post \ + "" \ + "$TW_Api/domains/$TW_Main_Domain/dns-records/$TW_Dns_Txt_Id" \ + "" \ + "DELETE" + ); then + _err "The request to the Timeweb Cloud API failed." + return 1 + fi + + [ -n "$TW_Response" ] && { + _err "Received an unexpected response body from the Timeweb Cloud API." + return 1 + } + + _debug "DNS TXT record with ID \"$TW_Dns_Txt_Id\" has been removed." +} From fa3591f4f2393640bad4e153c0e91e5964d8498c Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Thu, 22 Aug 2024 14:39:09 +0200 Subject: [PATCH 432/687] TXT record ADD test successfully --- dnsapi/dns_miab.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 6b1555d0..6177903e 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -16,11 +16,11 @@ Author: Darven Dissek, William Gertz #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 - txtvalue=$2 - _info "Using miab challange add" - _debug fulldomain "$fulldomain" + txtvalue="value="$2"&ttl=300" # Added to accomodate the new TXT record format used by the API to include value= and ttl= - _debug txtvalue "value="+="$txtvalue"+="&ttl=300" + _info "Using miab challenge add" + _debug fulldomain "$fulldomain" + _debug txtvalue $txtvalue #retrieve MIAB environemt vars if ! _retrieve_miab_env; then @@ -56,7 +56,7 @@ dns_miab_rm() { fulldomain=$1 txtvalue=$2 - _info "Using miab challage delete" + _info "Using miab challenge delete" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" From 00bbe68f78e72661d1df71b64cda8764fcc97abc Mon Sep 17 00:00:00 2001 From: "i18n.site" Date: Fri, 23 Aug 2024 16:00:08 +0800 Subject: [PATCH 433/687] Update dns_huaweicloud.sh fix https://github.com/acmesh-official/acme.sh/issues/5261 --- dnsapi/dns_huaweicloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index f3df41f4..ee2d2b8e 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -210,7 +210,7 @@ _get_recordset_id() { _zoneid=$3 export _H1="X-Auth-Token: ${_token}" - response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") + response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}&status=ACTIVE") if _contains "${response}" '"id"'; then _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")" printf "%s" "${_id}" @@ -227,7 +227,7 @@ _add_record() { # Get Existing Records export _H1="X-Auth-Token: ${_token}" - response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") + response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}&status=ACTIVE") _debug2 "${response}" _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') From fab292d2dea84d41e3237324978e395f630753ce Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Tue, 27 Aug 2024 17:06:36 +0200 Subject: [PATCH 434/687] correct a typo --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 6177903e..c126b666 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -27,7 +27,7 @@ dns_miab_add() { return 1 fi - #check domain and seperate into doamin and host + #check domain and seperate into domain and host if ! _get_root "$fulldomain"; then _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}" return 1 From cefa7d940a310af21dedcad1d03676fbe6c7064c Mon Sep 17 00:00:00 2001 From: "i18n.site" Date: Wed, 28 Aug 2024 11:31:29 +0800 Subject: [PATCH 435/687] Update DNS.yml DNS.yml can be triggered manually --- .github/workflows/DNS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index 727ba315..c1406d91 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -1,5 +1,6 @@ name: DNS on: + workflow_dispatch: push: paths: - 'dnsapi/*.sh' From 65c3dc21f42484173fa4a94c7905df7dd531b0ab Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 11:50:33 +0200 Subject: [PATCH 436/687] Added comments --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index c126b666..aeeab03c 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -16,8 +16,8 @@ Author: Darven Dissek, William Gertz #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 + # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB API txtvalue="value="$2"&ttl=300" - # Added to accomodate the new TXT record format used by the API to include value= and ttl= _info "Using miab challenge add" _debug fulldomain "$fulldomain" _debug txtvalue $txtvalue From 9cec2688edc0978d2a138ffe38e19e2392342854 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 11:58:27 +0200 Subject: [PATCH 437/687] Syntax corrections suggested by testing script --- dnsapi/dns_miab.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index aeeab03c..5e7b3c3a 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -17,10 +17,10 @@ Author: Darven Dissek, William Gertz dns_miab_add() { fulldomain=$1 # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB API - txtvalue="value="$2"&ttl=300" + txtvalue="value=" "$2" "&ttl=300" _info "Using miab challenge add" _debug fulldomain "$fulldomain" - _debug txtvalue $txtvalue + _debug txtvalue "$txtvalue" #retrieve MIAB environemt vars if ! _retrieve_miab_env; then From 3006c90fb84aed0d8372ac87fe942ea28aed95a7 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 12:04:56 +0200 Subject: [PATCH 438/687] Syntax corrections suggested by testing script --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 5e7b3c3a..c42b25e8 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -16,7 +16,7 @@ Author: Darven Dissek, William Gertz #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 - # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB API + # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB / PMIAB API txtvalue="value=" "$2" "&ttl=300" _info "Using miab challenge add" _debug fulldomain "$fulldomain" From 031d53b04f27e5cf7e74ad66b989b8e042e443c5 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 12:14:22 +0200 Subject: [PATCH 439/687] Syntax corrections suggested by testing script --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index c42b25e8..a24ed9a6 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -16,7 +16,7 @@ Author: Darven Dissek, William Gertz #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 - # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB / PMIAB API + # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB/PMIAB API txtvalue="value=" "$2" "&ttl=300" _info "Using miab challenge add" _debug fulldomain "$fulldomain" From dc6ea97877764c51c836ed87cdaaebd48fbf3130 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 14:54:22 +0200 Subject: [PATCH 440/687] Syntax corrections, previous change broke script --- dnsapi/dns_miab.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index a24ed9a6..c16c856b 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -17,10 +17,10 @@ Author: Darven Dissek, William Gertz dns_miab_add() { fulldomain=$1 # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB/PMIAB API - txtvalue="value=" "$2" "&ttl=300" + txtvalue="value=$2&ttl=300" _info "Using miab challenge add" _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" + _debug txtvalue $txtvalue #retrieve MIAB environemt vars if ! _retrieve_miab_env; then From 02fb40c5074cd0b069e0be408b6c740491858552 Mon Sep 17 00:00:00 2001 From: Lifeboy Date: Mon, 2 Sep 2024 14:56:00 +0200 Subject: [PATCH 441/687] Syntax corrections, previous change broke script --- dnsapi/dns_miab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index c16c856b..9416c8ce 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -20,7 +20,7 @@ dns_miab_add() { txtvalue="value=$2&ttl=300" _info "Using miab challenge add" _debug fulldomain "$fulldomain" - _debug txtvalue $txtvalue + _debug txtvalue "$txtvalue" #retrieve MIAB environemt vars if ! _retrieve_miab_env; then From fcffe8beb9da574818ee6f53772fcd3bbe737d72 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 15:40:45 +0200 Subject: [PATCH 442/687] feat: add bearer token support --- dnsapi/dns_azure.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 00ccd798..c482ed03 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -9,6 +9,7 @@ Options: AZUREDNS_APPID App ID. App ID of the service principal AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false" + AZUREDNS_BEARERTOKEN Optional Bearer Token. Used instead of service principal credentials or managed identity ' ######## Public functions ##################### @@ -83,7 +84,11 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" fi - accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") + else + accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then _err "invalid domain" From 92a47aaac54309fd8a3ebc82044724acccc55751 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 15:41:55 +0200 Subject: [PATCH 443/687] logic --- dnsapi/dns_azure.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index c482ed03..9db028a1 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -84,10 +84,10 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" fi - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then - accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") - else + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + else + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then From 1eaa2cc6198632bd03bd329fb2b6390190ccd100 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 15:53:33 +0200 Subject: [PATCH 444/687] debug --- dnsapi/dns_azure.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 9db028a1..b0db0f76 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -126,6 +126,7 @@ dns_azure_add() { # Add the txtvalue TXT Record body="{\"properties\":{\"metadata\":{\"acmetscheck\":\"$timestamp\"},\"TTL\":10, \"TXTRecords\":[$values]}}" _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken" + _debug "$acmeRecordURI $body $accesstoken" if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then _info "validation value added" return 0 From c7fb15573300d9428c73ed3248d877b389bf40d9 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 15:56:12 +0200 Subject: [PATCH 445/687] debug --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index b0db0f76..c1e48d23 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -101,6 +101,7 @@ dns_azure_add() { acmeRecordURI="https://management.azure.com$(printf '%s' "$_domain_id" | sed 's/\\//g')/TXT/$_sub_domain?api-version=2017-09-01" _debug "$acmeRecordURI" # Get existing TXT record + _debug "$acmeRecordURI $accesstoken" _azure_rest GET "$acmeRecordURI" "" "$accesstoken" values="{\"value\":[\"$txtvalue\"]}" timestamp="$(_time)" @@ -126,7 +127,6 @@ dns_azure_add() { # Add the txtvalue TXT Record body="{\"properties\":{\"metadata\":{\"acmetscheck\":\"$timestamp\"},\"TTL\":10, \"TXTRecords\":[$values]}}" _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken" - _debug "$acmeRecordURI $body $accesstoken" if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then _info "validation value added" return 0 From dd634382d7c4a038e5c60d20625c89a3eacbfdef Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 15:57:48 +0200 Subject: [PATCH 446/687] debug --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index c1e48d23..6edb19cc 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -101,7 +101,6 @@ dns_azure_add() { acmeRecordURI="https://management.azure.com$(printf '%s' "$_domain_id" | sed 's/\\//g')/TXT/$_sub_domain?api-version=2017-09-01" _debug "$acmeRecordURI" # Get existing TXT record - _debug "$acmeRecordURI $accesstoken" _azure_rest GET "$acmeRecordURI" "" "$accesstoken" values="{\"value\":[\"$txtvalue\"]}" timestamp="$(_time)" @@ -361,6 +360,7 @@ _get_root() { ## (ZoneListResult with continuation token for the next page of results) ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways ## + _debug "$accesstoken $subscriptionId" _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" # Find matching domain name in Json response while true; do From 0b2edd28dfad12d7061ea00277d87e27e4c5192a Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 16:02:36 +0200 Subject: [PATCH 447/687] bearer check --- dnsapi/dns_azure.sh | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 6edb19cc..95cadd07 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -45,36 +45,39 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_APPID "" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "" else - _info "You didn't ask to use Azure managed identity, checking service principal credentials" + _info "You didn't ask to use Azure managed identity, checking service principal credentials or provided bearer token" AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + _info "Using provided bearer token" + else + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Tenant ID " + return 1 + fi - if [ -z "$AZUREDNS_TENANTID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Tenant ID " - return 1 - fi - - if [ -z "$AZUREDNS_APPID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure App ID" - return 1 - fi + if [ -z "$AZUREDNS_APPID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure App ID" + return 1 + fi - if [ -z "$AZUREDNS_CLIENTSECRET" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Client Secret" - return 1 + if [ -z "$AZUREDNS_CLIENTSECRET" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Client Secret" + return 1 + fi fi #save account details to account conf file, don't opt in for azure manages identity check. @@ -360,7 +363,6 @@ _get_root() { ## (ZoneListResult with continuation token for the next page of results) ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways ## - _debug "$accesstoken $subscriptionId" _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" # Find matching domain name in Json response while true; do From b27767e8f4ecc3ded21ed25ab9f84e4547b82cb7 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Mon, 2 Sep 2024 16:04:34 +0200 Subject: [PATCH 448/687] logic --- dnsapi/dns_azure.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 95cadd07..f67dac29 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -50,8 +50,6 @@ dns_azure_add() { AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then - _info "Using provided bearer token" - else if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -78,6 +76,8 @@ dns_azure_add() { _err "You didn't specify the Azure Client Secret" return 1 fi + else + _info "Using provided bearer token" fi #save account details to account conf file, don't opt in for azure manages identity check. From 0fa20da990243d619e87f623601e5fdf60b1010c Mon Sep 17 00:00:00 2001 From: WhiteAls Date: Tue, 3 Sep 2024 17:11:43 +0000 Subject: [PATCH 449/687] Little optimisations and fixes. - Removed or moved `_normalizeJson` processing to occur only when needed. - Corrected usage of `_red` to `__red`. - Simplified JSON parsing by using more concise `cut` commands. - Simplify token refresh logic. --- dnsapi/dns_yandex360.sh | 70 +++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/dnsapi/dns_yandex360.sh b/dnsapi/dns_yandex360.sh index 05563f90..c6b6053d 100644 --- a/dnsapi/dns_yandex360.sh +++ b/dnsapi/dns_yandex360.sh @@ -39,7 +39,6 @@ dns_yandex360_add() { data='{"name":"'"$sub_domain"'","type":"TXT","ttl":60,"text":"'"$txtvalue"'"}' response="$(_post "$data" "$dns_api_url" '' 'POST' 'application/json')" - response="$(echo "$response" | _normalizeJson)" if _contains "$response" 'recordId'; then return 0 @@ -65,7 +64,6 @@ dns_yandex360_rm() { _debug 'Retrieving 100 records from Yandex 360 DNS' dns_api_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${root_domain}/dns?perPage=100" response="$(_get "$dns_api_url" '' '')" - response="$(echo "$response" | _normalizeJson)" if ! _contains "$response" "$txtvalue"; then _info 'DNS record not found. Nothing to remove.' @@ -73,6 +71,8 @@ dns_yandex360_rm() { return 1 fi + response="$(echo "$response" | _normalizeJson)" + record_id=$( echo "$response" | _egrep_o '\{[^}]*'"${txtvalue}"'[^}]*\}' | @@ -89,7 +89,6 @@ dns_yandex360_rm() { delete_url="${YANDEX360_API_BASE}/org/${YANDEX360_ORG_ID}/domains/${root_domain}/dns/${record_id}" response="$(_post '' "$delete_url" '' 'DELETE')" - response="$(echo "$response" | _normalizeJson)" if _contains "$response" '{}'; then return 0 @@ -138,27 +137,20 @@ _check_variables() { if [ -n "$YANDEX360_REFRESH_TOKEN" ]; then _debug 'Refresh token found. Attempting to refresh access token.' - if ! _refresh_token; then - if ! _get_token; then - return 1 - fi - fi - else - if ! _get_token; then - return 1 - fi fi + + _refresh_token || _get_token || return 1 fi if [ -z "$YANDEX360_ORG_ID" ]; then org_response="$(_get "${YANDEX360_API_BASE}/org" '' '')" - org_response="$(echo "$org_response" | _normalizeJson)" - if _contains "$org_response" '"organizations":'; then + if _contains "$org_response" '"organizations"'; then + org_response="$(echo "$org_response" | _normalizeJson)" YANDEX360_ORG_ID=$( echo "$org_response" | _egrep_o '"id":[[:space:]]*[0-9]+' | - cut -d: -f2 + cut -d':' -f2 ) _debug 'Automatically retrieved YANDEX360_ORG_ID' "$YANDEX360_ORG_ID" else @@ -177,13 +169,13 @@ _check_variables() { } _get_token() { - _info "$(_red '=========================================')" - _info "$(_red ' NOTICE')" - _info "$(_red '=========================================')" - _info "$(_red 'Before using the Yandex 360 API, you need to complete an authorization procedure.')" - _info "$(_red 'The initial access token is obtained interactively and is a one-time operation.')" - _info "$(_red 'Subsequent API requests will be handled automatically.')" - _info "$(_red '=========================================')" + _info "$(__red '=========================================')" + _info "$(__red ' NOTICE')" + _info "$(__red '=========================================')" + _info "$(__red 'Before using the Yandex 360 API, you need to complete an authorization procedure.')" + _info "$(__red 'The initial access token is obtained interactively and is a one-time operation.')" + _info "$(__red 'Subsequent API requests will be handled automatically.')" + _info "$(__red '=========================================')" _info 'Initiating device authorization flow' device_code_url="${YANDEX360_OAUTH_BASE}/device/code" @@ -192,7 +184,6 @@ _get_token() { data="client_id=$YANDEX360_CLIENT_ID&device_id=acme.sh ${hostname}&device_name=acme.sh ${hostname}" response="$(_post "$data" "$device_code_url" '' 'POST')" - response="$(echo "$response" | _normalizeJson)" if ! _contains "$response" 'device_code'; then _err 'Failed to get device code' @@ -200,34 +191,33 @@ _get_token() { return 1 fi + response="$(echo "$response" | _normalizeJson)" + device_code=$( echo "$response" | _egrep_o '"device_code":"[^"]*"' | - cut -d: -f2 | - tr -d '"' + cut -d'"' -f4 ) _debug 'Device code' "$device_code" user_code=$( echo "$response" | _egrep_o '"user_code":"[^"]*"' | - cut -d: -f2 | - tr -d '"' + cut -d'"' -f4 ) _debug 'User code' "$user_code" verification_url=$( echo "$response" | _egrep_o '"verification_url":"[^"]*"' | - cut -d: -f2- | - tr -d '"' + cut -d'"' -f4 ) _debug 'Verification URL' "$verification_url" interval=$( echo "$response" | _egrep_o '"interval":[[:space:]]*[0-9]+' | - cut -d: -f2 + cut -d':' -f2 ) _debug 'Polling interval' "$interval" @@ -242,20 +232,18 @@ _get_token() { data="grant_type=device_code&code=$device_code&client_id=$YANDEX360_CLIENT_ID&client_secret=$YANDEX360_CLIENT_SECRET" response="$(_post "$data" "$token_url" '' 'POST')" - response="$(echo "$response" | _normalizeJson)" if _contains "$response" 'access_token'; then + response="$(echo "$response" | _normalizeJson)" YANDEX360_ACCESS_TOKEN=$( echo "$response" | _egrep_o '"access_token":"[^"]*"' | - cut -d: -f2- | - tr -d '"' + cut -d'"' -f4 ) YANDEX360_REFRESH_TOKEN=$( echo "$response" | _egrep_o '"refresh_token":"[^"]*"' | - cut -d: -f2- | - tr -d '"' + cut -d'"' -f4 ) _secure_debug 'Obtained access token' "$YANDEX360_ACCESS_TOKEN" @@ -285,20 +273,18 @@ _refresh_token() { data="grant_type=refresh_token&refresh_token=$YANDEX360_REFRESH_TOKEN&client_id=$YANDEX360_CLIENT_ID&client_secret=$YANDEX360_CLIENT_SECRET" response="$(_post "$data" "$token_url" '' 'POST')" - response="$(echo "$response" | _normalizeJson)" if _contains "$response" 'access_token'; then + response="$(echo "$response" | _normalizeJson)" YANDEX360_ACCESS_TOKEN=$( echo "$response" | _egrep_o '"access_token":"[^"]*"' | - cut -d: -f2 | - tr -d '"' + cut -d'"' -f4 ) YANDEX360_REFRESH_TOKEN=$( echo "$response" | _egrep_o '"refresh_token":"[^"]*"' | - cut -d: -f2- | - tr -d '"' + cut -d'"' -f4 ) _secure_debug 'Received access token' "$YANDEX360_ACCESS_TOKEN" @@ -325,14 +311,14 @@ _get_root() { domains_api_url="${YANDEX360_API_BASE}/org/${org_id}/domains" domains_response="$(_get "$domains_api_url" '' '')" - domains_response="$(echo "$domains_response" | _normalizeJson)" - if ! _contains "$domains_response" '"domains":'; then + if ! _contains "$domains_response" '"domains"'; then _debug 'No domains found for organization' "$org_id" _debug 'Response' "$domains_response" continue fi + domains_response="$(echo "$domains_response" | _normalizeJson)" domain_names=$( echo "$domains_response" | _egrep_o '"name":"[^"]*"' | From f0d486d1ff6d96554c0545c8276155b8d0d4368f Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Tue, 3 Sep 2024 20:59:17 +0200 Subject: [PATCH 450/687] add bearer token to removal --- dnsapi/dns_azure.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index f67dac29..875520cb 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -194,8 +194,12 @@ dns_azure_rm() { fi fi - accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") - + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") + else + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") + fi + if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then _err "invalid domain" return 1 From 8860915fb9fafde9c23456f5d7be6d3877ffd26e Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Tue, 3 Sep 2024 21:36:54 +0200 Subject: [PATCH 451/687] remove dns --- dnsapi/dns_azure.sh | 55 ++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 875520cb..31bc42ca 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -161,36 +161,39 @@ dns_azure_rm() { if [ "$AZUREDNS_MANAGEDIDENTITY" = true ]; then _info "Using Azure managed identity" else - _info "You didn't ask to use Azure managed identity, checking service principal credentials" + _info "You didn't ask to use Azure managed identity, checking service principal credentials or provided bearer token" AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Tenant ID " + return 1 + fi - if [ -z "$AZUREDNS_TENANTID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Tenant ID " - return 1 - fi - - if [ -z "$AZUREDNS_APPID" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure App ID" - return 1 - fi + if [ -z "$AZUREDNS_APPID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure App ID" + return 1 + fi - if [ -z "$AZUREDNS_CLIENTSECRET" ]; then - AZUREDNS_SUBSCRIPTIONID="" - AZUREDNS_TENANTID="" - AZUREDNS_APPID="" - AZUREDNS_CLIENTSECRET="" - _err "You didn't specify the Azure Client Secret" - return 1 + if [ -z "$AZUREDNS_CLIENTSECRET" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + _err "You didn't specify the Azure Client Secret" + return 1 + fi + else + _info "Using provided bearer token" fi fi @@ -199,7 +202,7 @@ dns_azure_rm() { else accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") fi - + if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then _err "invalid domain" return 1 From 2d282597cab255aa925864e61670fc205a1f94e2 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 15 Sep 2024 14:30:12 +0200 Subject: [PATCH 452/687] fix format --- deploy/synology_dsm.sh | 6 +++--- dnsapi/dns_inwx.sh | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh index 3ddb8de1..0d01e199 100644 --- a/deploy/synology_dsm.sh +++ b/deploy/synology_dsm.sh @@ -113,9 +113,9 @@ synology_dsm_deploy() { # Default values for scheme, hostname and port # Defaulting to localhost and http, because it's localhost… - [ -n "$SYNO_SCHEME" ] || SYNO_SCHEME="http" - [ -n "$SYNO_HOSTNAME" ] || SYNO_HOSTNAME="localhost" - [ -n "$SYNO_PORT" ] || SYNO_PORT="5000" + [ -n "$SYNO_SCHEME" ] || SYNO_SCHEME=http + [ -n "$SYNO_HOSTNAME" ] || SYNO_HOSTNAME=localhost + [ -n "$SYNO_PORT" ] || SYNO_PORT=5000 _savedeployconf SYNO_SCHEME "$SYNO_SCHEME" _savedeployconf SYNO_HOSTNAME "$SYNO_HOSTNAME" _savedeployconf SYNO_PORT "$SYNO_PORT" diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index ffd6bf9d..8060a3ee 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -164,12 +164,12 @@ _inwx_check_cookie() { } _htmlEscape() { - local s - s=${1//&/&} - s=${s///>} - s=${s//'"'/"} - printf -- %s "$s" + _s="$1" + _s=$(echo "$_s" | sed "s/&/&/g") + _s=$(echo "$_s" | sed "s//\>/g") + _s=$(echo "$_s" | sed 's/"/\"/g') + printf -- %s "$_s" } _inwx_login() { From f86ee84457620cfe3e38d3d7667a9c42950677f1 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 15 Sep 2024 14:31:15 +0200 Subject: [PATCH 453/687] fix format --- dnsapi/dns_inwx.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 8060a3ee..b2d42451 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -165,10 +165,10 @@ _inwx_check_cookie() { _htmlEscape() { _s="$1" - _s=$(echo "$_s" | sed "s/&/&/g") - _s=$(echo "$_s" | sed "s//\>/g") - _s=$(echo "$_s" | sed 's/"/\"/g') + _s=$(echo "$_s" | sed "s/&/&/g") + _s=$(echo "$_s" | sed "s//\>/g") + _s=$(echo "$_s" | sed 's/"/\"/g') printf -- %s "$_s" } From 522c95386013a5ce6cae4d4b5512fd299d29d1a4 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Sun, 15 Sep 2024 17:08:09 +0200 Subject: [PATCH 454/687] Update dockerhub.yml --- .github/workflows/dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index e8e496f1..ea446d84 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -51,7 +51,7 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE=${{ secrets.DOCKER_USERNAME }}/acme.sh + DOCKER_IMAGE=neilpang/acme.sh if [[ $GITHUB_REF == refs/tags/* ]]; then DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} From 22d260f4e67960ceea6104a0d58547c5bb66586d Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Mon, 16 Sep 2024 16:49:28 +0200 Subject: [PATCH 455/687] fix dns_nsupdate when NSUPDATE_OPT is empty, refs #5224 --- dnsapi/dns_nsupdate.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 2bc3d382..7e78f9a5 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -39,13 +39,13 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then - nsupdate -k "${NSUPDATE_KEY}" $nsdebug "${NSUPDATE_OPT}" < Date: Tue, 17 Sep 2024 14:08:22 +0200 Subject: [PATCH 456/687] resolve shellcheck offenses With nsupdate the rule seems to be: filenames need to be wrapped in double quotes, while all other options must not use double quotes. Hence there is no way to resolve the shellcheck offense, because the key requires quotes, but the other options must not use quotes. --- dnsapi/dns_nsupdate.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 7e78f9a5..d5dbbcbc 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -39,12 +39,14 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then + #shellcheck disable=SC2086 nsupdate -k "${NSUPDATE_KEY}" $nsdebug $NSUPDATE_OPT < Date: Wed, 18 Sep 2024 08:57:32 +0200 Subject: [PATCH 457/687] update version --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d1565039..f6f34b6d 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.8 +VER=3.0.9 PROJECT_NAME="acme.sh" From fca6e9b9329c41678cb1c74405d8f6281852b65f Mon Sep 17 00:00:00 2001 From: PMExtra Date: Thu, 19 Sep 2024 15:49:42 +0800 Subject: [PATCH 458/687] refactor: Alibaba Cloud API --- acme.sh | 5 ++ deploy/ali_cdn.sh | 111 ++++++++-------------------------------- dnsapi/dns_ali.sh | 127 ++++++++++++++++++++++++---------------------- 3 files changed, 92 insertions(+), 151 deletions(-) diff --git a/acme.sh b/acme.sh index f6f34b6d..64a1f73e 100755 --- a/acme.sh +++ b/acme.sh @@ -672,8 +672,10 @@ _hex_dump() { #0 1 2 3 4 5 6 7 8 9 - _ . ~ #30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e +#_url_encode [upper-hex] the encoded hex will be upper-case if the argument upper-hex is followed #stdin stdout _url_encode() { + _upper_hex=$1 _hex_str=$(_hex_dump) _debug3 "_url_encode" _debug3 "_hex_str" "$_hex_str" @@ -883,6 +885,9 @@ _url_encode() { ;; #other hex *) + if [ "$_upper_hex" = "upper-hex" ]; then + _hex_code=$(printf "%s" "$_hex_code" | _upper_case) + fi printf '%%%s' "$_hex_code" ;; esac diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 6bbb3b43..29ac4b98 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -2,15 +2,28 @@ # Script to create certificate to Alibaba Cloud CDN # +# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-alibaba-cloud-cdn-aliyun +# # This deployment required following variables # export Ali_Key="ALIACCESSKEY" # export Ali_Secret="ALISECRETKEY" +# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi +# +# To specify the CDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates # export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com" -# If you have more than one domain, just +# If you have multiple CDN domains using the same certificate, just # export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com" -# -# The credentials are shared with all domains, also shared with dns_ali api +# Load dnsapi/dns_ali.sh to reduce the duplicated codes +# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 +dnsapi_ali="$(_findHook "" "$_SUB_FOLDER_DNSAPI" dns_ali)" +# shellcheck source=/dev/null +if ! . "$dnsapi_ali"; then + _err "Error loading file $dnsapi_ali. Please check your API file and try again." + return 1 +fi + +# shellcheck disable=SC2034 Ali_API="https://cdn.aliyuncs.com/" ali_cdn_deploy() { @@ -26,18 +39,7 @@ ali_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" - Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" - if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then - Ali_Key="" - Ali_Secret="" - _err "You don't specify aliyun api key and secret yet." - return 1 - fi - - #save the api key and secret to the account conf file. - _saveaccountconf_mutable Ali_Key "$Ali_Key" - _saveaccountconf_mutable Ali_Secret "$Ali_Secret" + _prepare_ali_credentials _getdeployconf DEPLOY_ALI_CDN_DOMAIN if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then @@ -47,8 +49,8 @@ ali_cdn_deploy() { fi # read cert and key files and urlencode both - _cert=$(_url_encode_upper <"$_cfullchain") - _key=$(_url_encode_upper <"$_ckey") + _cert=$(_url_encode upper-hex <"$_cfullchain") + _key=$(_url_encode upper-hex <"$_ckey") _debug2 _cert "$_cert" _debug2 _key "$_key" @@ -64,80 +66,7 @@ ali_cdn_deploy() { return 0 } -#################### Private functions below ################################## - -# act ign mtd -_ali_rest() { - act="$1" - ign="$2" - mtd="$3" - - signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) - signature=$(_ali_urlencode "$signature") - url="$Ali_API?$query&Signature=$signature" - - if [ "$mtd" = "GET" ]; then - response="$(_get "$url")" - else - # post payload is not supported yet because of signature - response="$(_post "" "$url")" - fi - - _ret="$?" - _debug2 response "$response" - if [ "$_ret" != "0" ]; then - _err "Error <$act>" - return 1 - fi - - if [ -z "$ign" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_ali_urlencode() { - _str="$1" - _str_len=${#_str} - _u_i=1 - while [ "$_u_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" - case $_str_c in [a-zA-Z0-9.~_-]) - printf "%s" "$_str_c" - ;; - *) - printf "%%%02X" "'$_str_c" - ;; - esac - _u_i="$(_math "$_u_i" + 1)" - done -} - -_ali_nonce() { - #_head_n 1 " + return 1 + fi + + if [ -z "$ign" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then + _err "$message" + return 1 + fi + fi +} + +_ali_nonce() { + #_head_n 1 " - return 1 - fi - - _debug2 response "$response" - if [ -z "$2" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_ali_urlencode() { - _str="$1" - _str_len=${#_str} - _u_i=1 - while [ "$_u_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" - case $_str_c in [a-zA-Z0-9.~_-]) - printf "%s" "$_str_c" - ;; - *) - printf "%%%02X" "'$_str_c" - ;; - esac - _u_i="$(_math "$_u_i" + 1)" - done -} - -_ali_nonce() { - #_head_n 1 Date: Thu, 19 Sep 2024 16:30:04 +0800 Subject: [PATCH 459/687] refactor(ali): set API endpoint for each action --- deploy/ali_cdn.sh | 6 +++--- dnsapi/dns_ali.sh | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 29ac4b98..786bcc7e 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -1,4 +1,5 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034,SC2154 # Script to create certificate to Alibaba Cloud CDN # @@ -23,8 +24,7 @@ if ! . "$dnsapi_ali"; then return 1 fi -# shellcheck disable=SC2034 -Ali_API="https://cdn.aliyuncs.com/" +Ali_CDN_API="https://cdn.aliyuncs.com/" ali_cdn_deploy() { _cdomain="$1" @@ -66,9 +66,9 @@ ali_cdn_deploy() { return 0 } -# shellcheck disable=SC2154 # domain pub pri _set_cdn_domain_ssl_certificate_query() { + endpoint=$Ali_CDN_API query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=SetCdnDomainSSLCertificate' diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 76a8d314..be632bec 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -14,7 +14,7 @@ Options: # https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 # Be careful when modifying this file, especially when making breaking changes for common functions -Ali_API="https://alidns.aliyuncs.com/" +Ali_DNS_API="https://alidns.aliyuncs.com/" #Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_ali_add() { @@ -71,7 +71,7 @@ _ali_rest() { signature=$(printf "%s" "$mtd&%2F&$(printf "%s" "$query" | _url_encode upper-hex)" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) signature=$(printf "%s" "$signature" | _url_encode upper-hex) - url="$Ali_API?Signature=$signature" + url="$endpoint?Signature=$signature" if [ "$mtd" = "GET" ]; then url="$url&$query" @@ -140,6 +140,7 @@ _get_root() { _check_exist_query() { _qdomain="$1" _qsubdomain="$2" + endpoint=$Ali_DNS_API query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=DescribeDomainRecords' @@ -155,6 +156,7 @@ _check_exist_query() { } _add_record_query() { + endpoint=$Ali_DNS_API query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=AddDomainRecord' @@ -171,6 +173,7 @@ _add_record_query() { } _delete_record_query() { + endpoint=$Ali_DNS_API query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=DeleteDomainRecord' @@ -184,6 +187,7 @@ _delete_record_query() { } _describe_records_query() { + endpoint=$Ali_DNS_API query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=DescribeDomainRecords' From ea2330b49f0d4a1d533445a9288dcb4c3a1746c8 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 20 Sep 2024 14:54:07 +0800 Subject: [PATCH 460/687] refactor(ali): move the loading script into ali_cdn_deploy --- deploy/ali_cdn.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 786bcc7e..541781b9 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -15,15 +15,6 @@ # If you have multiple CDN domains using the same certificate, just # export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com" -# Load dnsapi/dns_ali.sh to reduce the duplicated codes -# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 -dnsapi_ali="$(_findHook "" "$_SUB_FOLDER_DNSAPI" dns_ali)" -# shellcheck source=/dev/null -if ! . "$dnsapi_ali"; then - _err "Error loading file $dnsapi_ali. Please check your API file and try again." - return 1 -fi - Ali_CDN_API="https://cdn.aliyuncs.com/" ali_cdn_deploy() { @@ -39,6 +30,15 @@ ali_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" + # Load dnsapi/dns_ali.sh to reduce the duplicated codes + # https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 + dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)" + # shellcheck source=/dev/null + if ! . "$dnsapi_ali"; then + _err "Error loading file $dnsapi_ali. Please check your API file and try again." + return 1 + fi + _prepare_ali_credentials _getdeployconf DEPLOY_ALI_CDN_DOMAIN From 2ea37e6a0da09d0390cb5ed1b654190b4fcbafa9 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 20 Sep 2024 14:55:33 +0800 Subject: [PATCH 461/687] refactor(ali): check the result of prepare_ali_credentials --- deploy/ali_cdn.sh | 2 +- dnsapi/dns_ali.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 541781b9..6eb6659a 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -39,7 +39,7 @@ ali_cdn_deploy() { return 1 fi - _prepare_ali_credentials + _prepare_ali_credentials || return 1 _getdeployconf DEPLOY_ALI_CDN_DOMAIN if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index be632bec..0f1626f5 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -21,7 +21,7 @@ dns_ali_add() { fulldomain=$1 txtvalue=$2 - _prepare_ali_credentials + _prepare_ali_credentials || return 1 _debug "First detect the root zone" if ! _get_root "$fulldomain"; then From 1029dd3504b28ae686a0e5a32d7ebbb97eaeb7c2 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Fri, 20 Sep 2024 15:44:50 +0200 Subject: [PATCH 462/687] fix format --- dnsapi/dns_azure.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 31bc42ca..c39fc846 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,7 +49,7 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -87,7 +87,7 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" fi - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") @@ -197,7 +197,7 @@ dns_azure_rm() { fi fi - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") From df6aa99ec21ff5222cd64612022d81f887102192 Mon Sep 17 00:00:00 2001 From: Nikolay Pronchev Date: Fri, 20 Sep 2024 14:00:44 +0000 Subject: [PATCH 463/687] fix Timeweb Cloud DNS API pagination --- dnsapi/dns_timeweb.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_timeweb.sh b/dnsapi/dns_timeweb.sh index 2edca180..5cdd0986 100644 --- a/dnsapi/dns_timeweb.sh +++ b/dnsapi/dns_timeweb.sh @@ -111,8 +111,7 @@ _timeweb_split_acme_fqdn() { TW_Page_Limit=100 TW_Page_Offset=0 - while [ -z "$TW_Domains_Total" ] || - [ "$((TW_Domains_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do + while [ -z "$TW_Domains_Returned" ] || [ "$TW_Domains_Returned" -ge "$TW_Page_Limit" ]; do _timeweb_list_domains "$TW_Page_Limit" "$TW_Page_Offset" || return 1 @@ -161,8 +160,8 @@ _timeweb_get_dns_txt() { TW_Page_Limit=100 TW_Page_Offset=0 - while [ -z "$TW_Dns_Records_Total" ] || - [ "$((TW_Dns_Records_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do + while [ -z "$TW_Dns_Records_Returned" ] || [ "$TW_Dns_Records_Returned" -ge "$TW_Page_Limit" ]; do + _timeweb_list_dns_records "$TW_Page_Limit" "$TW_Page_Offset" || return 1 while @@ -195,7 +194,7 @@ _timeweb_get_dns_txt() { # Param 2: Offset for domains list. # # Sets the "TW_Domains" variable. -# Sets the "TW_Domains_Total" variable. +# Sets the "TW_Domains_Returned" variable. _timeweb_list_domains() { _debug "Listing domains via Timeweb Cloud API. Limit: $1, offset: $2." @@ -211,22 +210,22 @@ _timeweb_list_domains() { return 1 } - TW_Domains_Total=$( + TW_Domains_Returned=$( echo "$TW_Domains" | sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' ) - [ -z "$TW_Domains_Total" ] && { + [ -z "$TW_Domains_Returned" ] && { _err "Failed to extract the total count of domains." return 1 } - [ "$TW_Domains_Total" -eq "0" ] && { + [ "$TW_Domains_Returned" -eq "0" ] && { _err "Domains are missing." return 1 } - _debug "Total count of domains in the Timeweb Cloud account: $TW_Domains_Total." + _debug "Domains returned by Timeweb Cloud API: $TW_Domains_Returned." } # Lists domain DNS records via the Timeweb Cloud API. @@ -235,7 +234,7 @@ _timeweb_list_domains() { # Param 2: Offset for DNS records list. # # Sets the "TW_Dns_Records" variable. -# Sets the "TW_Dns_Records_Total" variable. +# Sets the "TW_Dns_Records_Returned" variable. _timeweb_list_dns_records() { _debug "Listing domain DNS records via the Timeweb Cloud API. Limit: $1, offset: $2." @@ -251,22 +250,22 @@ _timeweb_list_dns_records() { return 1 } - TW_Dns_Records_Total=$( + TW_Dns_Records_Returned=$( echo "$TW_Dns_Records" | sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' ) - [ -z "$TW_Dns_Records_Total" ] && { + [ -z "$TW_Dns_Records_Returned" ] && { _err "Failed to extract the total count of DNS records." return 1 } - [ "$TW_Dns_Records_Total" -eq "0" ] && { + [ "$TW_Dns_Records_Returned" -eq "0" ] && { _err "DNS records are missing." return 1 } - _debug "Total count of DNS records: $TW_Dns_Records_Total." + _debug "DNS records returned by Timeweb Cloud API: $TW_Dns_Records_Returned." } # Verifies whether the domain is the primary domain for the ACME DNS-01 challenge FQDN. From 45ea2f82ba98cc837f067f43947c3cad23606b9b Mon Sep 17 00:00:00 2001 From: Nikolay Pronchev Date: Fri, 20 Sep 2024 15:14:30 +0000 Subject: [PATCH 464/687] explicitly reset *_return variables --- dnsapi/dns_timeweb.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_timeweb.sh b/dnsapi/dns_timeweb.sh index 5cdd0986..9860872c 100644 --- a/dnsapi/dns_timeweb.sh +++ b/dnsapi/dns_timeweb.sh @@ -110,6 +110,7 @@ _timeweb_split_acme_fqdn() { TW_Page_Limit=100 TW_Page_Offset=0 + TW_Domains_Returned="" while [ -z "$TW_Domains_Returned" ] || [ "$TW_Domains_Returned" -ge "$TW_Page_Limit" ]; do @@ -159,6 +160,7 @@ _timeweb_get_dns_txt() { TW_Page_Limit=100 TW_Page_Offset=0 + TW_Dns_Records_Returned="" while [ -z "$TW_Dns_Records_Returned" ] || [ "$TW_Dns_Records_Returned" -ge "$TW_Page_Limit" ]; do From 997bd3392f9952b62ecb4817b463bce116d15017 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 21 Sep 2024 13:21:26 +0200 Subject: [PATCH 465/687] fix https://github.com/acmesh-official/acme.sh/issues/5293 --- acme.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/acme.sh b/acme.sh index 64a1f73e..708c40e9 100755 --- a/acme.sh +++ b/acme.sh @@ -5116,6 +5116,19 @@ $_authorizations_map" _on_issue_err "$_post_hook" "$vlist" return 1 fi + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _sleep_overload_retry_sec=$_retryafter + if [ "$_sleep_overload_retry_sec" ]; then + if [ $_sleep_overload_retry_sec -le 600 ]; then + _sleep $_sleep_overload_retry_sec + else + _info "The retryafter=$_retryafter value is too large (> 600), will not retry anymore." + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 + fi + fi done done From 8cb684e6bde7a4ec935573842534d6504b2403fc Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 21 Sep 2024 17:11:17 +0200 Subject: [PATCH 466/687] fix https://github.com/acmesh-official/acme.sh/issues/5067 --- dnsapi/dns_gcore.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh index ac2e614c..bd8a1e56 100755 --- a/dnsapi/dns_gcore.sh +++ b/dnsapi/dns_gcore.sh @@ -28,7 +28,7 @@ dns_gcore_add() { fi #save the api key to the account conf file. - _saveaccountconf_mutable GCORE_Key "$GCORE_Key" + _saveaccountconf_mutable GCORE_Key "$GCORE_Key" "base64" _debug "First detect the zone name" if ! _get_root "$fulldomain"; then From 89342bcb75d3203b9d5334a4599d9e758674b6d2 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Mon, 23 Sep 2024 15:11:04 +0800 Subject: [PATCH 467/687] add ali_dcdn deploy hook --- deploy/ali_cdn.sh | 4 ++- deploy/ali_dcdn.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 deploy/ali_dcdn.sh diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 6eb6659a..70a2e532 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -3,7 +3,7 @@ # Script to create certificate to Alibaba Cloud CDN # -# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-alibaba-cloud-cdn-aliyun +# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-cdn-or-dcdn-of-alibaba-cloud-aliyun # # This deployment required following variables # export Ali_Key="ALIACCESSKEY" @@ -14,6 +14,8 @@ # export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com" # If you have multiple CDN domains using the same certificate, just # export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com" +# +# For DCDN, see ali_dcdn deploy hook Ali_CDN_API="https://cdn.aliyuncs.com/" diff --git a/deploy/ali_dcdn.sh b/deploy/ali_dcdn.sh new file mode 100644 index 00000000..dad004b8 --- /dev/null +++ b/deploy/ali_dcdn.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034,SC2154 + +# Script to create certificate to Alibaba Cloud DCDN +# +# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-cdn-or-dcdn-of-alibaba-cloud-aliyun +# +# This deployment required following variables +# export Ali_Key="ALIACCESSKEY" +# export Ali_Secret="ALISECRETKEY" +# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi +# +# To specify the DCDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates +# export DEPLOY_ALI_DCDN_DOMAIN="dcdn.example.com" +# If you have multiple CDN domains using the same certificate, just +# export DEPLOY_ALI_DCDN_DOMAIN="dcdn1.example.com dcdn2.example.com" +# +# For regular CDN, see ali_cdn deploy hook + +Ali_DCDN_API="https://dcdn.aliyuncs.com/" + +ali_dcdn_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + # Load dnsapi/dns_ali.sh to reduce the duplicated codes + # https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 + dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)" + # shellcheck source=/dev/null + if ! . "$dnsapi_ali"; then + _err "Error loading file $dnsapi_ali. Please check your API file and try again." + return 1 + fi + + _prepare_ali_credentials || return 1 + + _getdeployconf DEPLOY_ALI_DCDN_DOMAIN + if [ "$DEPLOY_ALI_DCDN_DOMAIN" ]; then + _savedeployconf DEPLOY_ALI_DCDN_DOMAIN "$DEPLOY_ALI_DCDN_DOMAIN" + else + DEPLOY_ALI_DCDN_DOMAIN="$_cdomain" + fi + + # read cert and key files and urlencode both + _cert=$(_url_encode upper-hex <"$_cfullchain") + _key=$(_url_encode upper-hex <"$_ckey") + + _debug2 _cert "$_cert" + _debug2 _key "$_key" + + ## update domain ssl config + for domain in $DEPLOY_ALI_DCDN_DOMAIN; do + _set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key" + if _ali_rest "Set DCDN domain SSL certificate for $domain" "" POST; then + _info "Domain $domain certificate has been deployed successfully" + fi + done + + return 0 +} + +# domain pub pri +_set_dcdn_domain_ssl_certificate_query() { + endpoint=$Ali_DCDN_API + query='' + query=$query'AccessKeyId='$Ali_Key + query=$query'&Action=SetDcdnDomainSSLCertificate' + query=$query'&CertType=upload' + query=$query'&DomainName='$1 + query=$query'&Format=json' + query=$query'&SSLPri='$3 + query=$query'&SSLProtocol=on' + query=$query'&SSLPub='$2 + query=$query'&SignatureMethod=HMAC-SHA1' + query=$query"&SignatureNonce=$(_ali_nonce)" + query=$query'&SignatureVersion=1.0' + query=$query'&Timestamp='$(_timestamp) + query=$query'&Version=2018-01-05' +} From c20b0169a95a76d1a26ab4de5bb1a99505513a1c Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 23 Sep 2024 18:15:10 +0200 Subject: [PATCH 468/687] upgrade version --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 708c40e9..e39a146b 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.9 +VER=3.1.0 PROJECT_NAME="acme.sh" From e6b3e42d613c018897427d3e154fc00d0a12caa9 Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Mon, 23 Sep 2024 22:21:37 -0500 Subject: [PATCH 469/687] Adding omg.lol DNS API --- dnsapi/dns_omglol.sh | 363 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 dnsapi/dns_omglol.sh diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh new file mode 100644 index 00000000..7f62b2d8 --- /dev/null +++ b/dnsapi/dns_omglol.sh @@ -0,0 +1,363 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_myapi_info='omg.lol + Based on the omg.lol API, defined at https://api.omg.lol/ +Domains: omg.lol +Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + omglolapikey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account + omgloladdress This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard +Issues: github.com/acmesh-official/acme.sh +Author: @Kholin +' + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_omglol_add() { + fulldomain=$1 + txtvalue=$2 + omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}" + omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}" + + # As omg.lol includes a leading @ for their addresses, pre-strip this before save + omglol_address="$(echo "$omglol_address" | tr -d '@')" + + _saveaccountconf_mutable omglol_apikey "$omglol_apikey" + _saveaccountconf_mutable omglol_address "$omglol_address" + + _info "Using omg.lol." + _debug "Function" "dns_omglol_add()" + _debug "Full Domain Name" "$fulldomain" + _debug "txt Record Value" "$txtvalue" + _secure_debug "omg.lol API key" "$omglol_apikey" + _debug "omg.lol Address" "$omglol_address" + + omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + + dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") + authHeader="$(_createAuthHeader "$omglol_apikey")" + + _debug2 " dns_omglol_add(): Address" "$dnsName" + + omglol_add "$omglol_address" "$authHeader" "$dnsName" "$txtvalue" + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_omglol_rm() { + fulldomain=$1 + txtvalue=$2 + omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}" + omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}" + + # As omg.lol includes a leading @ for their addresses, strip this in case provided + omglol_address="$(echo "$omglol_address" | tr -d '@')" + + _info "Using omg.lol" + _debug fulldomain "$fulldomain" + _secure_debug ApiKey "$omglol_apikey" + _debug address "$omglol_address" + + omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + + dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") + authHeader="$(_createAuthHeader "$omglol_apikey")" + + omglol_delete "$omglol_address" "$authHeader" "$dnsName" "$txtvalue" +} + +#################### Private functions below ################################## +# Check that the minimum requirements are present. Close ungracefully if not +omglol_validate() { + omglol_apikey=$1 + omglol_address=$2 + fulldomain=$3 + + if [ "" = "$omglol_address" ]; then + _err "omg.lol base address not provided. Exiting" + exit 1 + fi + + if [ "" = "$omglol_apikey" ]; then + _err "omg.lol API key not provided. Exiting" + exit 1 + fi + + _endswith "$fulldomain" "omg.lol" + if [ ! $? ]; then + _err "Domain name requested is not under omg.lol" + exit 1 + fi + + _endswith "$fulldomain" "$omglol_address.omg.lol" + if [ ! $? ]; then + _err "Domain name is not a subdomain of provided omg.lol address $omglol_address" + exit 1 + fi + + _debug "omglol_validate(): Required environment parameters are all present" +} + +# Add (or modify) an entry for a new ACME query +omglol_add() { + address=$1 + authHeader=$2 + dnsName=$3 + txtvalue=$4 + + _info " Creating DNS entry for $dnsName" + _debug2 " omglol_add()" + _debug2 " omg.lol Address: " "$address" + _secure_debug2 " omg.lol authorization header: " "$authHeader" + _debug2 " Full Domain name:" "$dnsName.$address.omg.lol" + _debug2 " TXT value to set:" "$txtvalue" + + export _H1="$authHeader" + + endpoint="https://api.omg.lol/address/$address/dns" + _debug2 " Endpoint" "$endpoint" + + payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}' + _debug2 " Payload" "$payload" + + response=$(_post "$payload" "$endpoint" "" "POST" "application/json") + + omglol_validate_add "$response" "$dnsName.$address" "$txtvalue" +} + +omglol_validate_add() { + response=$1 + name=$2 + content=$3 + + _info " Validating DNS record addition" + _debug2 " omglol_validate_add()" + _debug2 " Response" "$response" + _debug2 " DNS Name" "$name" + _debug2 " DNS value" "$content" + + _jsonResponseCheck "$response" "success" "true" + if [ "1" = "$?" ]; then + _err "Response did not report success" + return 1 + fi + + _jsonResponseCheck "$response" "message" "Your DNS record was created successfully." + if [ "1" = "$?" ]; then + _err "Response message did not indicate DNS record was successfully created" + return 1 + fi + + _jsonResponseCheck "$response" "name" "$name" + if [ "1" = "$?" ]; then + _err "Response DNS Name did not match the response received" + return 1 + fi + + _jsonResponseCheck "$response" "content" "$content" + if [ "1" = "$?" ]; then + _err "Response DNS Name did not match the response received" + return 1 + fi + + _debug " Record Created successfully" + return 0 +} + +omglol_getRecords() { + address=$1 + authHeader=$2 + dnsName=$3 + txtValue=$4 + + _debug2 " omglol_getRecords()" + _debug2 " omg.lol Address: " "$address" + _secure_debug2 " omg.lol Auth Header: " "$authHeader" + _debug2 " omg.lol DNS name:" "$dnsName" + _debug2 " txt Value" "$txtValue" + + export _H1="$authHeader" + + endpoint="https://api.omg.lol/address/$address/dns" + _debug2 " Endpoint" "$endpoint" + + payload=$(_get "$endpoint") + + _debug2 " Received Payload:" "$payload" + + # Reformat the JSON to be more parseable + recordID=$(echo "$payload" | _stripWhitespace) + recordID=$(echo "$recordID" | _exposeJsonArray) + + # Now find the one with the right value, and caputre its ID + recordID=$(echo "$recordID" | grep -- "$txtValue" | grep -i -- "$dnsName.$address") + _getJsonElement "$recordID" "id" +} + +omglol_delete() { + address=$1 + authHeader=$2 + dnsName=$3 + txtValue=$4 + + _info " Deleting DNS entry for $dnsName with value $txtValue" + _debug2 " omglol_delete()" + _debug2 " omg.lol Address: " "$address" + _secure_debug2 " omg.lol Auth Header: " "$authHeader" + _debug2 " Full Domain name:" "$dnsName.$address.omg.lol" + _debug2 " txt Value" "$txtValue" + + record=$(omglol_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue") + + endpoint="https://api.omg.lol/address/$address/dns/$record" + _debug2 " Endpoint" "$endpoint" + + export _H1="$authHeader" + output=$(_post "" "$endpoint" "" "DELETE") + + _debug2 " Response" "$output" + + omglol_validate_delete "$output" +} + +# Validate the response on request to delete. Confirm stastus is success and +# Message indicates deletion was successful +# Input: Response - HTTP response received from delete request +omglol_validate_delete() { + response=$1 + + _info " Validating DNS record deletion" + _debug2 " omglol_validate_delete()" + _debug " Response" "$response" + + _jsonResponseCheck "$output" "success" "true" + if [ "1" = "$?" ]; then + _err "Response did not report success" + return 1 + fi + + _jsonResponseCheck "$output" "message" "OK, your DNS record has been deleted." + if [ "1" = "$?" ]; then + _err "Response message did not indicate DNS record was successfully deleted" + return 1 + fi + + _info " Record deleted successfully" + return 0 +} + +########## Utility Functions ##################################### +# All utility functions only log at debug3 +_jsonResponseCheck() { + response=$1 + field=$2 + correct=$3 + + correct=$(echo "$correct" | _lower_case) + + _debug3 " jsonResponseCheck()" + _debug3 " Response to parse" "$response" + _debug3 " Field to get response from" "$field" + _debug3 " What is the correct response" "$correct" + + responseValue=$(_jsonGetLastResponse "$response" "$field") + + if [ "$responseValue" != "$correct" ]; then + _debug3 " Expected: $correct" + _debug3 " Actual: $responseValue" + return 1 + else + _debug3 " Matched: $responseValue" + fi + return 0 +} + +_jsonGetLastResponse() { + response=$1 + field=$2 + + _debug3 " jsonGetLastResponse()" + _debug3 " Response provided" "$response" + _debug3 " Field to get responses for" "$field" + responseValue=$(echo "$response" | grep -- "\"$field\"" | cut -f2 -d":") + + _debug3 " Response lines found:" "$responseValue" + + responseValue=$(echo "$responseValue" | sed 's/^ //g' | sed 's/^"//g' | sed 's/\\"//g') + responseValue=$(echo "$responseValue" | sed 's/,$//g' | sed 's/"$//g') + responseValue=$(echo "$responseValue" | _lower_case) + + _debug3 " Responses found" "$responseValue" + _debug3 " Response Selected" "$(echo "$responseValue" | tail -1)" + + echo "$responseValue" | tail -1 +} + +_stripWhitespace() { + tr -d '\n' | tr -d '\r' | tr -d '\t' | sed -r 's/ +/ /g' | sed 's/\\"//g' +} + +_exposeJsonArray() { + sed -r 's/.*\[//g' | tr '}' '|' | tr '{' '|' | sed 's/|, |/|/g' | tr '|' '\n' +} + +_getJsonElement() { + content=$1 + field=$2 + + # With a single JSON entry to parse, convert commas to newlines puts each element on + # its own line - which then allows us to just grep teh name, remove the key, and + # isolate the value + output=$(echo "$content" | tr ',' '\n' | grep -- "\"$field\":" | sed 's/.*: //g') + + _debug3 " String before unquoting: $output" + + _unquoteString "$output" +} + +_createAuthHeader() { + apikey=$1 + + authheader="Authorization: Bearer $apikey" + _secure_debug2 " Authorization Header" "$authheader" + echo "$authheader" +} + +_getDnsRecordName() { + fqdn=$1 + address=$2 + + echo "$fqdn" | sed 's/\.omg\.lol//g' | sed 's/\.'"$address"'$//g' +} + +_unquoteString() { + output=$1 + quotes=0 + + _startswith "$output" "\"" + if [ $? ]; then + quotes=$((quotes + 1)) + fi + + _endswith "$output" "\"" + if [ $? ]; then + quotes=$((quotes + 1)) + fi + + _debug3 " Original String: $output" + _debug3 " Quotes found: $quotes" + + if [ $((quotes)) -gt 1 ]; then + output=$(echo "$output" | sed 's/^"//g' | sed 's/"$//g') + _debug3 " Quotes removed: $output" + fi + + echo "$output" +} From cb113437f6aaafac06c456faacbd4c936181696c Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Tue, 24 Sep 2024 07:23:39 -0500 Subject: [PATCH 470/687] Updating per comment re: Exit vs Return on initial validation --- dnsapi/dns_omglol.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index 7f62b2d8..a77ddd15 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -39,6 +39,9 @@ dns_omglol_add() { _debug "omg.lol Address" "$omglol_address" omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + if [ ! $? ]; then + return 1 + fi dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") authHeader="$(_createAuthHeader "$omglol_apikey")" @@ -66,6 +69,9 @@ dns_omglol_rm() { _debug address "$omglol_address" omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + if [ ! $? ]; then + return 1 + fi dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") authHeader="$(_createAuthHeader "$omglol_apikey")" @@ -82,24 +88,24 @@ omglol_validate() { if [ "" = "$omglol_address" ]; then _err "omg.lol base address not provided. Exiting" - exit 1 + return 1 fi if [ "" = "$omglol_apikey" ]; then _err "omg.lol API key not provided. Exiting" - exit 1 + return 1 fi _endswith "$fulldomain" "omg.lol" if [ ! $? ]; then _err "Domain name requested is not under omg.lol" - exit 1 + return 1 fi _endswith "$fulldomain" "$omglol_address.omg.lol" if [ ! $? ]; then _err "Domain name is not a subdomain of provided omg.lol address $omglol_address" - exit 1 + return 1 fi _debug "omglol_validate(): Required environment parameters are all present" From 76719d1bf5931e4f6b2db2cde810ce06b6c3eb99 Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Wed, 25 Sep 2024 00:27:04 +0800 Subject: [PATCH 471/687] fix: fix ali_dcdn function naming typo --- deploy/ali_dcdn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ali_dcdn.sh b/deploy/ali_dcdn.sh index dad004b8..14ac500a 100644 --- a/deploy/ali_dcdn.sh +++ b/deploy/ali_dcdn.sh @@ -59,7 +59,7 @@ ali_dcdn_deploy() { ## update domain ssl config for domain in $DEPLOY_ALI_DCDN_DOMAIN; do - _set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key" + _set_dcdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key" if _ali_rest "Set DCDN domain SSL certificate for $domain" "" POST; then _info "Domain $domain certificate has been deployed successfully" fi @@ -84,5 +84,5 @@ _set_dcdn_domain_ssl_certificate_query() { query=$query"&SignatureNonce=$(_ali_nonce)" query=$query'&SignatureVersion=1.0' query=$query'&Timestamp='$(_timestamp) - query=$query'&Version=2018-01-05' + query=$query'&Version=2018-01-15' } From 25703296a61a7e253052917d4391171c625e88f6 Mon Sep 17 00:00:00 2001 From: Maximilian Irro Date: Wed, 25 Sep 2024 08:14:31 +0200 Subject: [PATCH 472/687] Add OpenContainer Image Format Annotations as Labels to Docker Image --- .github/workflows/dockerhub.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index ea446d84..435fd6b5 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -15,6 +15,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + DOCKER_IMAGE: neilpang/acme.sh jobs: CheckToken: @@ -44,6 +46,11 @@ jobs: uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5.5.1 + with: + images: ${DOCKER_IMAGE} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: login to docker hub @@ -51,8 +58,6 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE=neilpang/acme.sh - if [[ $GITHUB_REF == refs/tags/* ]]; then DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} fi @@ -66,8 +71,14 @@ jobs: fi fi + DOCKER_LABELS=() + while read -r label; do + DOCKER_LABELS+=(--label "${label}") + done <<<"${DOCKER_METADATA_OUTPUT_LABELS}" + docker buildx build \ --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ + "${DOCKER_LABELS[@]}" \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x . From 1c58c4c4099fbab3a9cbf7b694861aead913a0b8 Mon Sep 17 00:00:00 2001 From: Jan Schaumann Date: Sat, 28 Sep 2024 14:18:22 -0400 Subject: [PATCH 473/687] on OpenBSD, add libiconv acme.sh dnsapi/dns_edgedns.sh invokes iconv(1) which is not provided by OpenBSD in the base system. Adding the libiconv package provides this tool. This should also help address acmesh-official/acme.sh#4350, albeit indirectly: it looks like that PR cannot be merged because the OpenBSD test fails despite the PR not actually changing anything having to do with iconv. That is, I suspect that the test for OpenBSD failed (or would have failed, had it been run?) prior to that PR being issued. (This was previously submitted as https://github.com/acmesh-official/acmetest/pull/28 ) --- .github/workflows/DNS.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml index c1406d91..be9d3aae 100644 --- a/.github/workflows/DNS.yml +++ b/.github/workflows/DNS.yml @@ -281,7 +281,7 @@ jobs: - uses: vmactions/openbsd-vm@v1 with: envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' - prepare: pkg_add socat curl + prepare: pkg_add socat curl libiconv usesh: true copyback: false run: | From 432f6ac4d7f627bb378e767e27370d3faa939784 Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Sun, 29 Sep 2024 13:34:34 -0500 Subject: [PATCH 474/687] Updated input parameters per feedback from @Neilpang. Also updated debugging statements to be consistently applied. --- dnsapi/dns_omglol.sh | 210 ++++++++++++++++++++++++------------------- 1 file changed, 118 insertions(+), 92 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index a77ddd15..bb898455 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -6,10 +6,10 @@ Domains: omg.lol Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns Options: - omglolapikey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account - omgloladdress This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard + omg_apikey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account + omg_address This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard Issues: github.com/acmesh-official/acme.sh -Author: @Kholin +Author: @Kholin ' #returns 0 means success, otherwise error. @@ -22,33 +22,33 @@ Author: @Kholin dns_omglol_add() { fulldomain=$1 txtvalue=$2 - omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}" - omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}" + omg_apikey="${omg_apikey:-$(_readaccountconf_mutable omg_apikey)}" + omg_address="${omg_address:-$(_readaccountconf_mutable omg_address)}" # As omg.lol includes a leading @ for their addresses, pre-strip this before save - omglol_address="$(echo "$omglol_address" | tr -d '@')" + omg_address="$(echo "$omg_address" | tr -d '@')" - _saveaccountconf_mutable omglol_apikey "$omglol_apikey" - _saveaccountconf_mutable omglol_address "$omglol_address" + _saveaccountconf_mutable omg_apikey "$omg_apikey" + _saveaccountconf_mutable omg_address "$omg_address" _info "Using omg.lol." _debug "Function" "dns_omglol_add()" _debug "Full Domain Name" "$fulldomain" _debug "txt Record Value" "$txtvalue" - _secure_debug "omg.lol API key" "$omglol_apikey" - _debug "omg.lol Address" "$omglol_address" + _secure_debug "omg.lol API key" "$omg_apikey" + _debug "omg.lol Address" "$omg_address" - omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + omg_validate "$omg_apikey" "$omg_address" "$fulldomain" if [ ! $? ]; then return 1 fi - dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") - authHeader="$(_createAuthHeader "$omglol_apikey")" + dnsName=$(_getDnsRecordName "$fulldomain" "$omg_address") + authHeader="$(_createAuthHeader "$omg_apikey")" - _debug2 " dns_omglol_add(): Address" "$dnsName" + _debug2 "dns_omglol_add(): Address" "$dnsName" - omglol_add "$omglol_address" "$authHeader" "$dnsName" "$txtvalue" + omg_add "$omg_address" "$authHeader" "$dnsName" "$txtvalue" } @@ -57,41 +57,48 @@ dns_omglol_add() { dns_omglol_rm() { fulldomain=$1 txtvalue=$2 - omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}" - omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}" + omg_apikey="${omg_apikey:-$(_readaccountconf_mutable omg_apikey)}" + omg_address="${omg_address:-$(_readaccountconf_mutable omg_address)}" # As omg.lol includes a leading @ for their addresses, strip this in case provided - omglol_address="$(echo "$omglol_address" | tr -d '@')" + omg_address="$(echo "$omg_address" | tr -d '@')" _info "Using omg.lol" - _debug fulldomain "$fulldomain" - _secure_debug ApiKey "$omglol_apikey" - _debug address "$omglol_address" + _debug "Function" "dns_omglol_rm()" + _debug "Full Domain Name" "$fulldomain" + _debug "txt Record Value" "$txtvalue" + _secure_debug "omg.lol API key" "$omg_apikey" + _debug "omg.lol Address" "$omg_address" - omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain" + omg_validate "$omg_apikey" "$omg_address" "$fulldomain" if [ ! $? ]; then return 1 fi - dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address") - authHeader="$(_createAuthHeader "$omglol_apikey")" + dnsName=$(_getDnsRecordName "$fulldomain" "$omg_address") + authHeader="$(_createAuthHeader "$omg_apikey")" - omglol_delete "$omglol_address" "$authHeader" "$dnsName" "$txtvalue" + omg_delete "$omg_address" "$authHeader" "$dnsName" "$txtvalue" } #################### Private functions below ################################## # Check that the minimum requirements are present. Close ungracefully if not -omglol_validate() { - omglol_apikey=$1 - omglol_address=$2 +omg_validate() { + omg_apikey=$1 + omg_address=$2 fulldomain=$3 - if [ "" = "$omglol_address" ]; then + _debug2 "Function" "dns_validate()" + _secure_debug2 "omg.lol API key" "$omg_apikey" + _debug2 "omg.lol Address" "$omg_address" + _debug2 "Full Domain Name" "$fulldomain" + + if [ "" = "$omg_address" ]; then _err "omg.lol base address not provided. Exiting" return 1 fi - if [ "" = "$omglol_apikey" ]; then + if [ "" = "$omg_apikey" ]; then _err "omg.lol API key not provided. Exiting" return 1 fi @@ -102,52 +109,52 @@ omglol_validate() { return 1 fi - _endswith "$fulldomain" "$omglol_address.omg.lol" + _endswith "$fulldomain" "$omg_address.omg.lol" if [ ! $? ]; then - _err "Domain name is not a subdomain of provided omg.lol address $omglol_address" + _err "Domain name is not a subdomain of provided omg.lol address $omg_address" return 1 fi - _debug "omglol_validate(): Required environment parameters are all present" + _debug "Required environment parameters are all present" } # Add (or modify) an entry for a new ACME query -omglol_add() { +omg_add() { address=$1 authHeader=$2 dnsName=$3 txtvalue=$4 - _info " Creating DNS entry for $dnsName" - _debug2 " omglol_add()" - _debug2 " omg.lol Address: " "$address" - _secure_debug2 " omg.lol authorization header: " "$authHeader" - _debug2 " Full Domain name:" "$dnsName.$address.omg.lol" - _debug2 " TXT value to set:" "$txtvalue" + _info "Creating DNS entry for $dnsName" + _debug2 "omg_add()" + _debug2 "omg.lol Address: " "$address" + _secure_debug2 "omg.lol authorization header: " "$authHeader" + _debug2 "Full Domain name:" "$dnsName.$address.omg.lol" + _debug2 "TXT value to set:" "$txtvalue" export _H1="$authHeader" endpoint="https://api.omg.lol/address/$address/dns" - _debug2 " Endpoint" "$endpoint" + _debug3 "Endpoint" "$endpoint" payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}' - _debug2 " Payload" "$payload" + _debug3 "Payload" "$payload" response=$(_post "$payload" "$endpoint" "" "POST" "application/json") - omglol_validate_add "$response" "$dnsName.$address" "$txtvalue" + omg_validate_add "$response" "$dnsName.$address" "$txtvalue" } -omglol_validate_add() { +omg_validate_add() { response=$1 name=$2 content=$3 - _info " Validating DNS record addition" - _debug2 " omglol_validate_add()" - _debug2 " Response" "$response" - _debug2 " DNS Name" "$name" - _debug2 " DNS value" "$content" + _debug "Validating DNS record addition" + _debug2 "omg_validate_add()" + _debug3 "Response" "$response" + _debug3 "DNS Name" "$name" + _debug3 "DNS value" "$content" _jsonResponseCheck "$response" "success" "true" if [ "1" = "$?" ]; then @@ -173,30 +180,30 @@ omglol_validate_add() { return 1 fi - _debug " Record Created successfully" + _info "Record Created successfully" return 0 } -omglol_getRecords() { +omg_getRecords() { address=$1 authHeader=$2 dnsName=$3 txtValue=$4 - _debug2 " omglol_getRecords()" - _debug2 " omg.lol Address: " "$address" - _secure_debug2 " omg.lol Auth Header: " "$authHeader" - _debug2 " omg.lol DNS name:" "$dnsName" - _debug2 " txt Value" "$txtValue" + _debug2 "omg_getRecords()" + _debug3 "omg.lol Address: " "$address" + _secure_debug3 "omg.lol Auth Header: " "$authHeader" + _debug3 "omg.lol DNS name:" "$dnsName" + _debug3 "txt Value" "$txtValue" export _H1="$authHeader" endpoint="https://api.omg.lol/address/$address/dns" - _debug2 " Endpoint" "$endpoint" + _debug3 "Endpoint" "$endpoint" payload=$(_get "$endpoint") - _debug2 " Received Payload:" "$payload" + _debug3 "Received Payload:" "$payload" # Reformat the JSON to be more parseable recordID=$(echo "$payload" | _stripWhitespace) @@ -207,41 +214,45 @@ omglol_getRecords() { _getJsonElement "$recordID" "id" } -omglol_delete() { +omg_delete() { address=$1 authHeader=$2 dnsName=$3 txtValue=$4 - _info " Deleting DNS entry for $dnsName with value $txtValue" - _debug2 " omglol_delete()" - _debug2 " omg.lol Address: " "$address" - _secure_debug2 " omg.lol Auth Header: " "$authHeader" - _debug2 " Full Domain name:" "$dnsName.$address.omg.lol" - _debug2 " txt Value" "$txtValue" + _info "Deleting DNS entry for $dnsName with value $txtValue" + _debug3 "omg_delete()" + _debug3 "omg.lol Address: " "$address" + _secure_debug3 "omg.lol Auth Header: " "$authHeader" + _debug3 "Full Domain name:" "$dnsName.$address.omg.lol" + _debug3 "txt Value" "$txtValue" - record=$(omglol_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue") + record=$(omg_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue") + if [ "" = "$record" ]; then + _err "DNS record $address not found!" + return 1 + fi endpoint="https://api.omg.lol/address/$address/dns/$record" - _debug2 " Endpoint" "$endpoint" + _debug3 "Endpoint" "$endpoint" export _H1="$authHeader" output=$(_post "" "$endpoint" "" "DELETE") - _debug2 " Response" "$output" + _debug3 "Response" "$output" - omglol_validate_delete "$output" + omg_validate_delete "$output" } # Validate the response on request to delete. Confirm stastus is success and # Message indicates deletion was successful # Input: Response - HTTP response received from delete request -omglol_validate_delete() { +omg_validate_delete() { response=$1 - _info " Validating DNS record deletion" - _debug2 " omglol_validate_delete()" - _debug " Response" "$response" + _info "Validating DNS record deletion" + _debug3 "omg_validate_delete()" + _debug3 "Response" "$response" _jsonResponseCheck "$output" "success" "true" if [ "1" = "$?" ]; then @@ -255,7 +266,7 @@ omglol_validate_delete() { return 1 fi - _info " Record deleted successfully" + _info "Record deleted successfully" return 0 } @@ -268,19 +279,19 @@ _jsonResponseCheck() { correct=$(echo "$correct" | _lower_case) - _debug3 " jsonResponseCheck()" - _debug3 " Response to parse" "$response" - _debug3 " Field to get response from" "$field" - _debug3 " What is the correct response" "$correct" + _debug3 "jsonResponseCheck()" + _debug3 "Response to parse" "$response" + _debug3 "Field to get response from" "$field" + _debug3 "What is the correct response" "$correct" responseValue=$(_jsonGetLastResponse "$response" "$field") if [ "$responseValue" != "$correct" ]; then - _debug3 " Expected: $correct" - _debug3 " Actual: $responseValue" + _debug3 "Expected: $correct" + _debug3 "Actual: $responseValue" return 1 else - _debug3 " Matched: $responseValue" + _debug3 "Matched: $responseValue" fi return 0 } @@ -289,19 +300,20 @@ _jsonGetLastResponse() { response=$1 field=$2 - _debug3 " jsonGetLastResponse()" - _debug3 " Response provided" "$response" - _debug3 " Field to get responses for" "$field" + _debug3 "jsonGetLastResponse()" + _debug3 "Response provided" "$response" + _debug3 "Field to get responses for" "$field" + responseValue=$(echo "$response" | grep -- "\"$field\"" | cut -f2 -d":") - _debug3 " Response lines found:" "$responseValue" + _debug3 "Response lines found:" "$responseValue" responseValue=$(echo "$responseValue" | sed 's/^ //g' | sed 's/^"//g' | sed 's/\\"//g') responseValue=$(echo "$responseValue" | sed 's/,$//g' | sed 's/"$//g') responseValue=$(echo "$responseValue" | _lower_case) - _debug3 " Responses found" "$responseValue" - _debug3 " Response Selected" "$(echo "$responseValue" | tail -1)" + _debug3 "Responses found" "$responseValue" + _debug3 "Response Selected" "$(echo "$responseValue" | tail -1)" echo "$responseValue" | tail -1 } @@ -318,12 +330,16 @@ _getJsonElement() { content=$1 field=$2 + _debug3 "_getJsonElement()" + _debug3 "Input JSON element" "$content" + _debug3 "JSON element to isolate" "$field" + # With a single JSON entry to parse, convert commas to newlines puts each element on # its own line - which then allows us to just grep teh name, remove the key, and # isolate the value output=$(echo "$content" | tr ',' '\n' | grep -- "\"$field\":" | sed 's/.*: //g') - _debug3 " String before unquoting: $output" + _debug3 "String before unquoting: $output" _unquoteString "$output" } @@ -331,8 +347,11 @@ _getJsonElement() { _createAuthHeader() { apikey=$1 + _debug3 "_createAuthHeader()" + _secure_debug3 "Provided API Key" "$apikey" + authheader="Authorization: Bearer $apikey" - _secure_debug2 " Authorization Header" "$authheader" + _secure_debug3 "Authorization Header" "$authheader" echo "$authheader" } @@ -340,6 +359,10 @@ _getDnsRecordName() { fqdn=$1 address=$2 + _debug3 "_getDnsRecordName()" + _debug3 "FQDN" "$fqdn" + _debug3 "omg.lol Address" "$address" + echo "$fqdn" | sed 's/\.omg\.lol//g' | sed 's/\.'"$address"'$//g' } @@ -347,6 +370,9 @@ _unquoteString() { output=$1 quotes=0 + _debug3 "_unquoteString()" + _debug3 "Possibly quoted string" "$output" + _startswith "$output" "\"" if [ $? ]; then quotes=$((quotes + 1)) @@ -357,12 +383,12 @@ _unquoteString() { quotes=$((quotes + 1)) fi - _debug3 " Original String: $output" - _debug3 " Quotes found: $quotes" + _debug3 "Original String: $output" + _debug3 "Quotes found: $quotes" if [ $((quotes)) -gt 1 ]; then output=$(echo "$output" | sed 's/^"//g' | sed 's/"$//g') - _debug3 " Quotes removed: $output" + _debug3 "Quotes removed: $output" fi echo "$output" From dbe9dd47ce83f8e620c533f2924a1096d4624978 Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Sun, 29 Sep 2024 23:08:39 -0500 Subject: [PATCH 475/687] Correcting over-correct on debugging levels --- dnsapi/dns_omglol.sh | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index bb898455..28fecfb9 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -135,10 +135,10 @@ omg_add() { export _H1="$authHeader" endpoint="https://api.omg.lol/address/$address/dns" - _debug3 "Endpoint" "$endpoint" + _debug2 "Endpoint" "$endpoint" payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}' - _debug3 "Payload" "$payload" + _debug2 "Payload" "$payload" response=$(_post "$payload" "$endpoint" "" "POST" "application/json") @@ -152,9 +152,9 @@ omg_validate_add() { _debug "Validating DNS record addition" _debug2 "omg_validate_add()" - _debug3 "Response" "$response" - _debug3 "DNS Name" "$name" - _debug3 "DNS value" "$content" + _debug2 "Response" "$response" + _debug2 "DNS Name" "$name" + _debug2 "DNS value" "$content" _jsonResponseCheck "$response" "success" "true" if [ "1" = "$?" ]; then @@ -191,19 +191,19 @@ omg_getRecords() { txtValue=$4 _debug2 "omg_getRecords()" - _debug3 "omg.lol Address: " "$address" - _secure_debug3 "omg.lol Auth Header: " "$authHeader" - _debug3 "omg.lol DNS name:" "$dnsName" - _debug3 "txt Value" "$txtValue" + _debug2 "omg.lol Address: " "$address" + _secure_debug2 "omg.lol Auth Header: " "$authHeader" + _debug2 "omg.lol DNS name:" "$dnsName" + _debug2 "txt Value" "$txtValue" export _H1="$authHeader" endpoint="https://api.omg.lol/address/$address/dns" - _debug3 "Endpoint" "$endpoint" + _debug2 "Endpoint" "$endpoint" payload=$(_get "$endpoint") - _debug3 "Received Payload:" "$payload" + _debug2 "Received Payload:" "$payload" # Reformat the JSON to be more parseable recordID=$(echo "$payload" | _stripWhitespace) @@ -221,11 +221,11 @@ omg_delete() { txtValue=$4 _info "Deleting DNS entry for $dnsName with value $txtValue" - _debug3 "omg_delete()" - _debug3 "omg.lol Address: " "$address" - _secure_debug3 "omg.lol Auth Header: " "$authHeader" - _debug3 "Full Domain name:" "$dnsName.$address.omg.lol" - _debug3 "txt Value" "$txtValue" + _debug2 "omg_delete()" + _debug2 "omg.lol Address: " "$address" + _secure_debug2 "omg.lol Auth Header: " "$authHeader" + _debug2 "Full Domain name:" "$dnsName.$address.omg.lol" + _debug2 "txt Value" "$txtValue" record=$(omg_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue") if [ "" = "$record" ]; then @@ -234,12 +234,12 @@ omg_delete() { fi endpoint="https://api.omg.lol/address/$address/dns/$record" - _debug3 "Endpoint" "$endpoint" + _debug2 "Endpoint" "$endpoint" export _H1="$authHeader" output=$(_post "" "$endpoint" "" "DELETE") - _debug3 "Response" "$output" + _debug2 "Response" "$output" omg_validate_delete "$output" } @@ -251,8 +251,8 @@ omg_validate_delete() { response=$1 _info "Validating DNS record deletion" - _debug3 "omg_validate_delete()" - _debug3 "Response" "$response" + _debug2 "omg_validate_delete()" + _debug2 "Response" "$response" _jsonResponseCheck "$output" "success" "true" if [ "1" = "$?" ]; then From 254eb8f304518cd851523bb859a220f5d0da7f1f Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Mon, 30 Sep 2024 06:47:26 -0500 Subject: [PATCH 476/687] Updated variable names per @NeilPang --- dnsapi/dns_omglol.sh | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index 28fecfb9..8d9b9fb5 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -6,10 +6,10 @@ Domains: omg.lol Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns Options: - omg_apikey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account - omg_address This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard + OMG_ApiKey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account + OMG_Address This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard Issues: github.com/acmesh-official/acme.sh -Author: @Kholin +Author: @Kholin ' #returns 0 means success, otherwise error. @@ -22,33 +22,33 @@ Author: @Kholin dns_omglol_add() { fulldomain=$1 txtvalue=$2 - omg_apikey="${omg_apikey:-$(_readaccountconf_mutable omg_apikey)}" - omg_address="${omg_address:-$(_readaccountconf_mutable omg_address)}" + OMG_ApiKey="${OMG_ApiKey:-$(_readaccountconf_mutable OMG_ApiKey)}" + OMG_Address="${OMG_Address:-$(_readaccountconf_mutable OMG_Address)}" # As omg.lol includes a leading @ for their addresses, pre-strip this before save - omg_address="$(echo "$omg_address" | tr -d '@')" + OMG_Address="$(echo "$OMG_Address" | tr -d '@')" - _saveaccountconf_mutable omg_apikey "$omg_apikey" - _saveaccountconf_mutable omg_address "$omg_address" + _saveaccountconf_mutable omg_apikey "$OMG_ApiKey" + _saveaccountconf_mutable omg_address "$OMG_Address" _info "Using omg.lol." _debug "Function" "dns_omglol_add()" _debug "Full Domain Name" "$fulldomain" _debug "txt Record Value" "$txtvalue" - _secure_debug "omg.lol API key" "$omg_apikey" - _debug "omg.lol Address" "$omg_address" + _secure_debug "omg.lol API key" "$OMG_ApiKey" + _debug "omg.lol Address" "$OMG_Address" - omg_validate "$omg_apikey" "$omg_address" "$fulldomain" + omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain" if [ ! $? ]; then return 1 fi - dnsName=$(_getDnsRecordName "$fulldomain" "$omg_address") - authHeader="$(_createAuthHeader "$omg_apikey")" + dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address") + authHeader="$(_createAuthHeader "$OMG_ApiKey")" _debug2 "dns_omglol_add(): Address" "$dnsName" - omg_add "$omg_address" "$authHeader" "$dnsName" "$txtvalue" + omg_add "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue" } @@ -57,28 +57,28 @@ dns_omglol_add() { dns_omglol_rm() { fulldomain=$1 txtvalue=$2 - omg_apikey="${omg_apikey:-$(_readaccountconf_mutable omg_apikey)}" - omg_address="${omg_address:-$(_readaccountconf_mutable omg_address)}" + OMG_ApiKey="${OMG_ApiKey:-$(_readaccountconf_mutable OMG_ApiKey)}" + OMG_Address="${OMG_Address:-$(_readaccountconf_mutable OMG_Address)}" # As omg.lol includes a leading @ for their addresses, strip this in case provided - omg_address="$(echo "$omg_address" | tr -d '@')" + OMG_Address="$(echo "$OMG_Address" | tr -d '@')" _info "Using omg.lol" _debug "Function" "dns_omglol_rm()" _debug "Full Domain Name" "$fulldomain" _debug "txt Record Value" "$txtvalue" - _secure_debug "omg.lol API key" "$omg_apikey" - _debug "omg.lol Address" "$omg_address" + _secure_debug "omg.lol API key" "$OMG_ApiKey" + _debug "omg.lol Address" "$OMG_Address" - omg_validate "$omg_apikey" "$omg_address" "$fulldomain" + omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain" if [ ! $? ]; then return 1 fi - dnsName=$(_getDnsRecordName "$fulldomain" "$omg_address") - authHeader="$(_createAuthHeader "$omg_apikey")" + dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address") + authHeader="$(_createAuthHeader "$OMG_ApiKey")" - omg_delete "$omg_address" "$authHeader" "$dnsName" "$txtvalue" + omg_delete "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue" } #################### Private functions below ################################## From fe971680ead3d5d7528a0538d4f3a580755d7b57 Mon Sep 17 00:00:00 2001 From: Gary McGregor Date: Mon, 30 Sep 2024 07:42:09 -0500 Subject: [PATCH 477/687] With variable name updates, correct missed update for the name for saved variables --- dnsapi/dns_omglol.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index 8d9b9fb5..b6c06aee 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -28,8 +28,8 @@ dns_omglol_add() { # As omg.lol includes a leading @ for their addresses, pre-strip this before save OMG_Address="$(echo "$OMG_Address" | tr -d '@')" - _saveaccountconf_mutable omg_apikey "$OMG_ApiKey" - _saveaccountconf_mutable omg_address "$OMG_Address" + _saveaccountconf_mutable OMG_ApiKey "$OMG_ApiKey" + _saveaccountconf_mutable OMG_Address "$OMG_Address" _info "Using omg.lol." _debug "Function" "dns_omglol_add()" From a0b8be5941ebf42ff4710617f8312511f178da40 Mon Sep 17 00:00:00 2001 From: Adam Bulgatz Date: Thu, 3 Oct 2024 01:24:07 -0500 Subject: [PATCH 478/687] Updated MS links, added wiki link, updated error messages, updated API limit comment Updated all Microsoft links from old `docs` subdomain to new `learn` subdomain, and fixed a couple that weren't working. Added missing $wiki variable to print the wiki link in error messages. Updated spelling and formatting in error messages Updated a comment and added a TODO as Microsoft has increased the number of allowed Public DNS zones per subscription from 100 to 250, while the function in this script can only handle the old limit of 100. --- dnsapi/dns_azure.sh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 00ccd798..89620172 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -11,12 +11,14 @@ Options: AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false" ' +wiki=https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS + ######## Public functions ##################### # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Used to add txt record # -# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/createorupdate +# Ref: https://learn.microsoft.com/en-us/rest/api/dns/record-sets/create-or-update?view=rest-dns-2018-05-01&tabs=HTTP # dns_azure_add() { @@ -133,7 +135,7 @@ dns_azure_add() { # Usage: fulldomain txtvalue # Used to remove the txt record after validation # -# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/delete +# Ref: https://learn.microsoft.com/en-us/rest/api/dns/record-sets/delete?view=rest-dns-2018-05-01&tabs=HTTP # dns_azure_rm() { fulldomain=$1 @@ -265,10 +267,10 @@ _azure_rest() { if [ "$_code" = "401" ]; then # we have an invalid access token set to expired _saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "0" - _err "access denied make sure your Azure settings are correct. See $WIKI" + _err "Access denied. Invalid access token. Make sure your Azure settings are correct. See: $wiki" return 1 fi - # See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes + # See https://learn.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then _request_retry_times="$(_math "$_request_retry_times" + 1)" _info "REST call error $_code retrying $ep in $_request_retry_times s" @@ -286,7 +288,7 @@ _azure_rest() { return 0 } -## Ref: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#request-an-access-token +## Ref: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#request-an-access-token _azure_getaccess_token() { managedIdentity=$1 tenantID=$2 @@ -310,7 +312,7 @@ _azure_getaccess_token() { _debug "getting new bearer token" if [ "$managedIdentity" = true ]; then - # https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http + # https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http export _H1="Metadata: true" response="$(_get http://169.254.169.254/metadata/identity/oauth2/token\?api-version=2018-02-01\&resource=https://management.azure.com/)" response="$(echo "$response" | _normalizeJson)" @@ -330,7 +332,7 @@ _azure_getaccess_token() { fi if [ -z "$accesstoken" ]; then - _err "no acccess token received. Check your Azure settings see $WIKI" + _err "No acccess token received. Check your Azure settings. See: $wiki" return 1 fi if [ "$_ret" != "0" ]; then @@ -350,10 +352,13 @@ _get_root() { i=1 p=1 - ## Ref: https://docs.microsoft.com/en-us/rest/api/dns/zones/list - ## returns up to 100 zones in one response therefore handling more results is not not implemented - ## (ZoneListResult with continuation token for the next page of results) - ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways + ## Ref: https://learn.microsoft.com/en-us/rest/api/dns/zones/list?view=rest-dns-2018-05-01&tabs=HTTP + ## returns up to 100 zones in one response. Handling more results is not implemented + ## (ZoneListResult with continuation token for the next page of results) + ## + ## TODO: handle more than 100 results, as per: + ## https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-dns-limits + ## The new limit is 250 Public DNS zones per subscription, while the old limit was only 100 ## _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" # Find matching domain name in Json response From c390f1bfee3072c5adb83c1e3c7031289ce1440d Mon Sep 17 00:00:00 2001 From: fazelukario Date: Mon, 7 Oct 2024 03:34:49 +0300 Subject: [PATCH 479/687] Escape markdown for subject --- notify/telegram.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/notify/telegram.sh b/notify/telegram.sh index 454b4146..676e7494 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,6 +27,7 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" + _subject="$(printf "%s" "$_subject" | sed -e 's/\*/\*\\\\*\*/g')" _content="$(printf "%s" "$_content" | sed -e 's/\([_*`\[]\)/\\\\\1/g')" _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"text\": \"$_content\", " From fef74c3bca3d849356aaceab199d6a9cc128529e Mon Sep 17 00:00:00 2001 From: fazelukario Date: Mon, 7 Oct 2024 03:46:35 +0300 Subject: [PATCH 480/687] feat Cross-Platform Compatibility Guide --- notify/telegram.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index 676e7494..fb203879 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,8 +27,8 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" - _subject="$(printf "%s" "$_subject" | sed -e 's/\*/\*\\\\*\*/g')" - _content="$(printf "%s" "$_content" | sed -e 's/\([_*`\[]\)/\\\\\1/g')" + _subject="$(printf "%s" "$_subject" | sed 's/\*/\*\\\\*\*/g')" + _content="$(printf "%s" "$_content" | sed 's/\([_*`\[]\)/\\\\\1/g')" _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"text\": \"$_content\", " _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", " From 26c2fc21c8a062c22438351492df89f752da8909 Mon Sep 17 00:00:00 2001 From: fazelukario Date: Mon, 7 Oct 2024 05:16:11 +0300 Subject: [PATCH 481/687] Moving to MarkdownV2 as the old Markdown is obsolete - Implemented MarkdownV2 with escape of all necessary characters. - Ref: https://core.telegram.org/bots/api#markdownv2-style --- notify/telegram.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notify/telegram.sh b/notify/telegram.sh index fb203879..cca8ee25 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,12 +27,12 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" - _subject="$(printf "%s" "$_subject" | sed 's/\*/\*\\\\*\*/g')" - _content="$(printf "%s" "$_content" | sed 's/\([_*`\[]\)/\\\\\1/g')" + _subject="$(printf "%s" "$_subject" | sed 's/\\/\\\\\\\\/g' | sed 's/\]/\\\\\]/g' | sed 's/\([_*[()~`>#+--=|{}.!]\)/\\\\\1/g')" + _content="$(printf "%s" "$_content" | sed 's/\\/\\\\\\\\/g' | sed 's/\]/\\\\\]/g' | sed 's/\([_*[()~`>#+--=|{}.!]\)/\\\\\1/g')" _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)" _data="{\"text\": \"$_content\", " _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", " - _data="$_data\"parse_mode\": \"markdown\", " + _data="$_data\"parse_mode\": \"MarkdownV2\", " _data="$_data\"disable_web_page_preview\": \"1\"}" _debug "$_data" From 28afe6f29f1bd6700fbfa7c87a705fd212c635da Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 10:30:54 +0200 Subject: [PATCH 482/687] comment --- dnsapi/dns_azure.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index c39fc846..d2372cca 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -87,6 +87,7 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" fi + # Use provided bearer token if available and prefix it with Bearer if not already done if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else From ba7764aeaf59c4bed00e8ac7867e329dbc3e82ef Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 10:59:29 +0200 Subject: [PATCH 483/687] saveaccountconf --- dnsapi/dns_azure.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index d2372cca..703203a1 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -85,6 +85,7 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" + _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN" fi # Use provided bearer token if available and prefix it with Bearer if not already done From 8887a0a6d39bd08e7ae7d5c0f6adeddf78568c17 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:09:25 +0200 Subject: [PATCH 484/687] new name --- dnsapi/dns_azure.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 703203a1..7f838a6c 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,7 +49,7 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -85,14 +85,14 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" - _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN" + _saveaccountconf_mutable AZUREDNS_BEARERTOKEN2 "$AZUREDNS_BEARERTOKEN2" fi # Use provided bearer token if available and prefix it with Bearer if not already done - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else - accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN2" | sed "s/Bearer //g") fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then @@ -167,7 +167,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -199,10 +199,10 @@ dns_azure_rm() { fi fi - if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else - accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN2" | sed "s/Bearer //g") fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then From fc87fc7cab30a888fab1fd4aff4423bd34192744 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:18:03 +0200 Subject: [PATCH 485/687] debug --- dnsapi/dns_azure.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 7f838a6c..d3248436 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,7 +49,8 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + _debug "Contents of bearertoken: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -85,14 +86,13 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" - _saveaccountconf_mutable AZUREDNS_BEARERTOKEN2 "$AZUREDNS_BEARERTOKEN2" + _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN" fi - # Use provided bearer token if available and prefix it with Bearer if not already done - if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else - accesstoken=$(echo "$AZUREDNS_BEARERTOKEN2" | sed "s/Bearer //g") + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then @@ -167,7 +167,8 @@ dns_azure_rm() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + _debug "Contents of bearertoken second time: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -199,10 +200,10 @@ dns_azure_rm() { fi fi - if [ -z "$AZUREDNS_BEARERTOKEN2" ]; then + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET") else - accesstoken=$(echo "$AZUREDNS_BEARERTOKEN2" | sed "s/Bearer //g") + accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g") fi if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then From 5fc41a3ea2c57e896c8de9d456cbda24007b7a2e Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:24:24 +0200 Subject: [PATCH 486/687] read account conf --- dnsapi/dns_azure.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index d3248436..caeeb76a 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,6 +49,7 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then _debug "Contents of bearertoken: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then @@ -167,6 +168,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then _debug "Contents of bearertoken second time: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then From 1305b0d8dd8fd0b0d680bf7451ec4a274537776b Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:29:34 +0200 Subject: [PATCH 487/687] revert --- dnsapi/dns_azure.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index caeeb76a..56b755cf 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -51,7 +51,6 @@ dns_azure_add() { AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then - _debug "Contents of bearertoken: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -170,7 +169,6 @@ dns_azure_rm() { AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then - _debug "Contents of bearertoken second time: $AZUREDNS_BEARERTOKEN" if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" AZUREDNS_TENANTID="" @@ -404,4 +402,4 @@ _get_root() { i=$(_math "$i" + 1) done return 1 -} +} \ No newline at end of file From ffd3b3e6b540bd65feda1ab8c149dc1dab868b17 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:36:37 +0200 Subject: [PATCH 488/687] revert --- dnsapi/dns_azure.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 56b755cf..95087616 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,7 +49,6 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" @@ -86,7 +85,6 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" - _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN" fi if [ -z "$AZUREDNS_BEARERTOKEN" ]; then @@ -167,7 +165,6 @@ dns_azure_rm() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" - AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" From 0dff1dce8fa925ddaa79585ed258027a074af94d Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:50:57 +0200 Subject: [PATCH 489/687] accoutn conf --- dnsapi/dns_azure.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 95087616..351af80e 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -49,6 +49,7 @@ dns_azure_add() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" @@ -85,6 +86,7 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID" _saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET" + _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN" fi if [ -z "$AZUREDNS_BEARERTOKEN" ]; then @@ -165,6 +167,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}" AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" if [ -z "$AZUREDNS_BEARERTOKEN" ]; then if [ -z "$AZUREDNS_TENANTID" ]; then AZUREDNS_SUBSCRIPTIONID="" @@ -308,7 +311,7 @@ _azure_getaccess_token() { clientID=$3 clientSecret=$4 - accesstoken="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" + accesstoken="${AZUREDNS_ACCESSTOKEN:-$(_readaccountconf_mutable AZUREDNS_ACCESSTOKEN)}" expires_on="${AZUREDNS_TOKENVALIDTO:-$(_readaccountconf_mutable AZUREDNS_TOKENVALIDTO)}" # can we reuse the bearer token? @@ -352,7 +355,7 @@ _azure_getaccess_token() { _err "error $response" return 1 fi - _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$accesstoken" + _saveaccountconf_mutable AZUREDNS_ACCESSTOKEN "$accesstoken" _saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "$expires_on" printf "%s" "$accesstoken" return 0 From 40df6e87db78e5f3ff83ce4b16e1155f97aaded5 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 11:54:42 +0200 Subject: [PATCH 490/687] newline --- dnsapi/dns_azure.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 351af80e..ee2dc9d4 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -402,4 +402,4 @@ _get_root() { i=$(_math "$i" + 1) done return 1 -} \ No newline at end of file +} From a30c81dadcf9d7237c4528d9686c569b0b040e25 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 12:00:11 +0200 Subject: [PATCH 491/687] bearetoken --- dnsapi/dns_azure.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index ee2dc9d4..8ca1b359 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -30,6 +30,7 @@ dns_azure_add() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Subscription ID" return 1 fi @@ -44,6 +45,7 @@ dns_azure_add() { _saveaccountconf_mutable AZUREDNS_TENANTID "" _saveaccountconf_mutable AZUREDNS_APPID "" _saveaccountconf_mutable AZUREDNS_CLIENTSECRET "" + _saveaccountconf_mutable AZUREDNS_BEARERTOKEN "" else _info "You didn't ask to use Azure managed identity, checking service principal credentials or provided bearer token" AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}" @@ -56,6 +58,7 @@ dns_azure_add() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Tenant ID " return 1 fi @@ -65,6 +68,7 @@ dns_azure_add() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure App ID" return 1 fi @@ -74,6 +78,7 @@ dns_azure_add() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Client Secret" return 1 fi @@ -155,6 +160,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Subscription ID " return 1 fi @@ -174,6 +180,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Tenant ID " return 1 fi @@ -183,6 +190,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure App ID" return 1 fi @@ -192,6 +200,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Client Secret" return 1 fi From b0418cb39404c68a37c00666c0c542922017f4c6 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 12:23:07 +0200 Subject: [PATCH 492/687] trigger --- dnsapi/dns_azure.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 8ca1b359..14546899 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -412,3 +412,4 @@ _get_root() { done return 1 } + From 0c10bd7dd7bba1775e03074e83256c8249697b85 Mon Sep 17 00:00:00 2001 From: stbeldarborge Date: Thu, 10 Oct 2024 12:35:05 +0200 Subject: [PATCH 493/687] shfmt --- dnsapi/dns_azure.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 14546899..8ca1b359 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -412,4 +412,3 @@ _get_root() { done return 1 } - From ad4780a1ac5dabe86e8d54694c7e89922f8bf5b5 Mon Sep 17 00:00:00 2001 From: allddd <117767298+allddd@users.noreply.github.com> Date: Sat, 12 Oct 2024 01:07:35 +0200 Subject: [PATCH 494/687] update api url --- dnsapi/dns_porkbun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index 0a443855..d156b014 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -9,7 +9,7 @@ Options: Issues: github.com/acmesh-official/acme.sh/issues/3450 ' -PORKBUN_Api="https://porkbun.com/api/json/v3" +PORKBUN_Api="https://api.porkbun.com/api/json/v3" ######## Public functions ##################### From 87beb0a5f2bdd52a33d5d3336afb453d20038d05 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:26:14 +0200 Subject: [PATCH 495/687] fix name --- .github/workflows/pr_notify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml index 3b0e3e4b..b6b03c67 100644 --- a/.github/workflows/pr_notify.yml +++ b/.github/workflows/pr_notify.yml @@ -1,4 +1,4 @@ -name: Check dns api +name: Check notify api on: pull_request_target: From 7362e8de4d2d81995f417079e3d4d2cc9bb6d9de Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:41:22 +0200 Subject: [PATCH 496/687] fix format --- deploy/exim4.sh | 1 - deploy/vsftpd.sh | 2 +- dnsapi/dns_active24.sh | 6 +++--- dnsapi/dns_ad.sh | 4 ++-- dnsapi/dns_ali.sh | 6 +++--- dnsapi/dns_anx.sh | 4 ++-- dnsapi/dns_arvan.sh | 4 ++-- dnsapi/dns_aurora.sh | 4 ++-- dnsapi/dns_autodns.sh | 4 ++-- dnsapi/dns_aws.sh | 4 ++-- dnsapi/dns_azion.sh | 4 ++-- dnsapi/dns_azure.sh | 4 ++-- dnsapi/dns_cf.sh | 4 ++-- dnsapi/dns_cloudns.sh | 2 +- dnsapi/dns_cn.sh | 4 ++-- dnsapi/dns_conoha.sh | 4 ++-- dnsapi/dns_constellix.sh | 4 ++-- dnsapi/dns_curanet.sh | 2 +- dnsapi/dns_da.sh | 4 ++-- dnsapi/dns_desec.sh | 4 ++-- dnsapi/dns_dnsexit.sh | 2 +- dnsapi/dns_dnsimple.sh | 4 ++-- dnsapi/dns_domeneshop.sh | 4 ++-- dnsapi/dns_dp.sh | 4 ++-- dnsapi/dns_dpi.sh | 4 ++-- dnsapi/dns_durabledns.sh | 4 ++-- dnsapi/dns_dynu.sh | 4 ++-- dnsapi/dns_easydns.sh | 4 ++-- dnsapi/dns_euserv.sh | 4 ++-- dnsapi/dns_exoscale.sh | 4 ++-- dnsapi/dns_fornex.sh | 2 +- dnsapi/dns_gandi_livedns.sh | 4 ++-- dnsapi/dns_gcore.sh | 4 ++-- dnsapi/dns_gd.sh | 4 ++-- dnsapi/dns_googledomains.sh | 2 +- dnsapi/dns_hetzner.sh | 4 ++-- dnsapi/dns_hexonet.sh | 4 ++-- dnsapi/dns_inwx.sh | 4 ++-- dnsapi/dns_ionos.sh | 4 ++-- dnsapi/dns_jd.sh | 4 ++-- dnsapi/dns_joker.sh | 2 +- dnsapi/dns_kappernet.sh | 4 ++-- dnsapi/dns_la.sh | 4 ++-- dnsapi/dns_limacity.sh | 4 ++-- dnsapi/dns_linode.sh | 4 ++-- dnsapi/dns_linode_v4.sh | 4 ++-- dnsapi/dns_loopia.sh | 4 ++-- dnsapi/dns_lua.sh | 4 ++-- dnsapi/dns_me.sh | 4 ++-- dnsapi/dns_misaka.sh | 4 ++-- dnsapi/dns_mydnsjp.sh | 4 ++-- dnsapi/dns_mythic_beasts.sh | 4 ++-- dnsapi/dns_namecheap.sh | 10 +++++----- dnsapi/dns_namecom.sh | 4 ++-- dnsapi/dns_namesilo.sh | 4 ++-- dnsapi/dns_nederhost.sh | 4 ++-- dnsapi/dns_neodigit.sh | 4 ++-- dnsapi/dns_netlify.sh | 4 ++-- dnsapi/dns_nic.sh | 2 +- dnsapi/dns_njalla.sh | 4 ++-- dnsapi/dns_nsone.sh | 4 ++-- dnsapi/dns_nw.sh | 2 +- dnsapi/dns_oci.sh | 4 ++-- dnsapi/dns_one.sh | 4 ++-- dnsapi/dns_online.sh | 4 ++-- dnsapi/dns_openprovider.sh | 2 +- dnsapi/dns_opnsense.sh | 4 ++-- dnsapi/dns_ovh.sh | 4 ++-- dnsapi/dns_pdns.sh | 2 +- dnsapi/dns_pointhq.sh | 4 ++-- dnsapi/dns_porkbun.sh | 2 +- dnsapi/dns_rackcorp.sh | 4 ++-- dnsapi/dns_rackspace.sh | 4 ++-- dnsapi/dns_rcode0.sh | 2 +- dnsapi/dns_scaleway.sh | 4 ++-- dnsapi/dns_schlundtech.sh | 4 ++-- dnsapi/dns_selectel.sh | 4 ++-- dnsapi/dns_servercow.sh | 4 ++-- dnsapi/dns_simply.sh | 4 ++-- dnsapi/dns_transip.sh | 4 ++-- dnsapi/dns_udr.sh | 2 +- dnsapi/dns_ultra.sh | 4 ++-- dnsapi/dns_unoeuro.sh | 4 ++-- dnsapi/dns_variomedia.sh | 4 ++-- dnsapi/dns_veesp.sh | 4 ++-- dnsapi/dns_vercel.sh | 4 ++-- dnsapi/dns_vscale.sh | 4 ++-- dnsapi/dns_vultr.sh | 2 +- dnsapi/dns_websupport.sh | 4 ++-- dnsapi/dns_yc.sh | 4 ++-- dnsapi/dns_zilore.sh | 4 ++-- dnsapi/dns_zone.sh | 4 ++-- 92 files changed, 172 insertions(+), 173 deletions(-) diff --git a/deploy/exim4.sh b/deploy/exim4.sh index 260b8798..cf664d79 100644 --- a/deploy/exim4.sh +++ b/deploy/exim4.sh @@ -109,6 +109,5 @@ exim4_deploy() { fi return 1 fi - return 0 } diff --git a/deploy/vsftpd.sh b/deploy/vsftpd.sh index 8cf24e4f..570495cc 100644 --- a/deploy/vsftpd.sh +++ b/deploy/vsftpd.sh @@ -106,5 +106,5 @@ vsftpd_deploy() { fi return 1 fi - return 0 + } diff --git a/dnsapi/dns_active24.sh b/dnsapi/dns_active24.sh index 1a6f97f0..c56dd363 100755 --- a/dnsapi/dns_active24.sh +++ b/dnsapi/dns_active24.sh @@ -83,10 +83,10 @@ _get_root() { return 1 fi - i=2 + i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug "h" "$h" if [ -z "$h" ]; then #not valid @@ -94,7 +94,7 @@ _get_root() { fi if _contains "$response" "\"$h\"" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index ccd8226f..850af5b4 100755 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -95,7 +95,7 @@ _get_root() { if _ad_rest GET "domain/"; then response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -106,7 +106,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 0f1626f5..53a82f91 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -110,10 +110,10 @@ _timestamp() { _get_root() { domain=$1 - i=2 + i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -125,7 +125,7 @@ _get_root() { fi if _contains "$response" "PageNumber"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _debug _sub_domain "$_sub_domain" _domain="$h" _debug _domain "$_domain" diff --git a/dnsapi/dns_anx.sh b/dnsapi/dns_anx.sh index 9b283476..d45d9736 100644 --- a/dnsapi/dns_anx.sh +++ b/dnsapi/dns_anx.sh @@ -131,7 +131,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -140,7 +140,7 @@ _get_root() { _anx_rest GET "zone.json/${h}" if _contains "$response" "\"name\":\"$h\""; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index ed3b1314..cbe6dc1f 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -107,7 +107,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -120,7 +120,7 @@ _get_root() { if _contains "$response" "\"domain\":\"$h\""; then _domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_aurora.sh b/dnsapi/dns_aurora.sh index 746fce54..110ef0fa 100644 --- a/dnsapi/dns_aurora.sh +++ b/dnsapi/dns_aurora.sh @@ -117,7 +117,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -132,7 +132,7 @@ _get_root() { _domain_id=$(echo "$response" | _normalizeJson | tr -d "{}" | tr "," "\n" | grep "\"id\": *\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_autodns.sh b/dnsapi/dns_autodns.sh index 309e5f27..ce566978 100644 --- a/dnsapi/dns_autodns.sh +++ b/dnsapi/dns_autodns.sh @@ -110,7 +110,7 @@ _get_autodns_zone() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then @@ -128,7 +128,7 @@ _get_autodns_zone() { if _contains "$autodns_response" "1" >/dev/null; then _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") return 0 fi diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index c599b4e0..c88c9d9c 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -158,7 +158,7 @@ _get_root() { # iterate over names (a.b.c.d -> b.c.d -> c.d -> d) while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100 | sed 's/\./\\./g') + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100 | sed 's/\./\\./g') _debug "Checking domain: $h" if [ -z "$h" ]; then _error "invalid domain" @@ -174,7 +174,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_azion.sh b/dnsapi/dns_azion.sh index 2371833e..1375e32f 100644 --- a/dnsapi/dns_azion.sh +++ b/dnsapi/dns_azion.sh @@ -100,7 +100,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then # not valid @@ -111,7 +111,7 @@ _get_root() { _domain_id=$(echo "$response" | tr '{' "\n" | grep "\"domain\":\"$h\"" | _egrep_o "\"id\":[0-9]*" | _head_n 1 | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_azure.sh b/dnsapi/dns_azure.sh index 89620172..7d818cc2 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -363,7 +363,7 @@ _get_root() { _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken" # Find matching domain name in Json response while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug2 "Checking domain: $h" if [ -z "$h" ]; then #not valid @@ -378,7 +378,7 @@ _get_root() { #create the record at the domain apex (@) if only the domain name was provided as --domain-alias _sub_domain="@" else - _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) + _sub_domain=$(echo "$domain" | cut -d . -f 1-"$p") fi _domain=$h return 0 diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index da63e771..736742f3 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -186,7 +186,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -206,7 +206,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_cloudns.sh b/dnsapi/dns_cloudns.sh index 145a85be..8bb0e00d 100755 --- a/dnsapi/dns_cloudns.sh +++ b/dnsapi/dns_cloudns.sh @@ -164,7 +164,7 @@ _dns_cloudns_get_zone_info() { _dns_cloudns_get_zone_name() { i=2 while true; do - zoneForCheck=$(printf "%s" "$1" | cut -d . -f $i-100) + zoneForCheck=$(printf "%s" "$1" | cut -d . -f "$i"-100) if [ -z "$zoneForCheck" ]; then return 1 diff --git a/dnsapi/dns_cn.sh b/dnsapi/dns_cn.sh index 797f788e..79698e88 100644 --- a/dnsapi/dns_cn.sh +++ b/dnsapi/dns_cn.sh @@ -131,7 +131,7 @@ _cn_get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" _debug _H1 "${_H1}" @@ -149,7 +149,7 @@ _cn_get_root() { fi if _contains "$_cn_zonelist" "\"name\":\"$h\"" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 else diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index 6ceca829..ecd56fc8 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -237,7 +237,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100). + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100). _debug h "$h" if [ -z "$h" ]; then #not valid @@ -251,7 +251,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\"" >/dev/null; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_constellix.sh b/dnsapi/dns_constellix.sh index 0376dda1..6a50e199 100644 --- a/dnsapi/dns_constellix.sh +++ b/dnsapi/dns_constellix.sh @@ -122,7 +122,7 @@ _get_root() { p=1 _debug "Detecting root zone" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then return 1 fi @@ -134,7 +134,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-"$p") _domain="$h" _debug _domain_id "$_domain_id" diff --git a/dnsapi/dns_curanet.sh b/dnsapi/dns_curanet.sh index a530d304..f57afa1f 100644 --- a/dnsapi/dns_curanet.sh +++ b/dnsapi/dns_curanet.sh @@ -142,7 +142,7 @@ _get_root() { i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid diff --git a/dnsapi/dns_da.sh b/dnsapi/dns_da.sh index b2789a6f..36251b05 100755 --- a/dnsapi/dns_da.sh +++ b/dnsapi/dns_da.sh @@ -61,7 +61,7 @@ _get_root() { # response will contain "list[]=example.com&list[]=example.org" _da_api CMD_API_SHOW_DOMAINS "" "${domain}" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then # not valid @@ -69,7 +69,7 @@ _get_root() { return 1 fi if _contains "$response" "$h" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 0d6a6c2f..d6b9c355 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -176,7 +176,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -188,7 +188,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_dnsexit.sh b/dnsapi/dns_dnsexit.sh index 9f2871b4..ec3b07a4 100644 --- a/dnsapi/dns_dnsexit.sh +++ b/dnsapi/dns_dnsexit.sh @@ -84,7 +84,7 @@ _get_root() { domain=$1 i=1 while true; do - _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) + _domain=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$_domain" if [ -z "$_domain" ]; then return 1 diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index e080ecf0..9b72bf44 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -92,7 +92,7 @@ _get_root() { i=2 previous=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then # not valid return 1 @@ -105,7 +105,7 @@ _get_root() { if _contains "$response" 'not found'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$previous) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p"revious) _domain="$h" _debug _domain "$_domain" diff --git a/dnsapi/dns_domeneshop.sh b/dnsapi/dns_domeneshop.sh index 16d3dbe5..925ca335 100644 --- a/dnsapi/dns_domeneshop.sh +++ b/dnsapi/dns_domeneshop.sh @@ -93,7 +93,7 @@ _get_domainid() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug "h" "$h" if [ -z "$h" ]; then #not valid @@ -102,7 +102,7 @@ _get_domainid() { if _contains "$response" "\"$h\"" >/dev/null; then # We have found the domain name. - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _domainid=$(printf "%s" "$response" | _egrep_o "[^{]*\"domain\":\"$_domain\"[^}]*" | _egrep_o "\"id\":[0-9]+" | cut -d : -f 2) return 0 diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 29d32c27..7bc331e2 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -109,7 +109,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -123,7 +123,7 @@ _get_root() { _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _debug _sub_domain "$_sub_domain" _domain="$h" _debug _domain "$_domain" diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh index 521f2d69..e8b9b5a5 100755 --- a/dnsapi/dns_dpi.sh +++ b/dnsapi/dns_dpi.sh @@ -109,7 +109,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -123,7 +123,7 @@ _get_root() { _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _debug _sub_domain "$_sub_domain" _domain="$h" _debug _domain "$_domain" diff --git a/dnsapi/dns_durabledns.sh b/dnsapi/dns_durabledns.sh index cd4bd2eb..d71f0ccb 100644 --- a/dnsapi/dns_durabledns.sh +++ b/dnsapi/dns_durabledns.sh @@ -110,7 +110,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -118,7 +118,7 @@ _get_root() { fi if _contains "$response" ">$h."; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_dynu.sh b/dnsapi/dns_dynu.sh index 0dbeda24..1d1fc311 100644 --- a/dnsapi/dns_dynu.sh +++ b/dnsapi/dns_dynu.sh @@ -126,7 +126,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -140,7 +140,7 @@ _get_root() { if _contains "$response" "\"domainName\":\"$h\"" >/dev/null; then dnsId=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 2 | cut -d : -f 2) _domain_name=$h - _node=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _node=$(printf "%s" "$domain" | cut -d . -f 1-"$p") return 0 fi p=$i diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index d168054a..1c96ac8f 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -121,7 +121,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -133,7 +133,7 @@ _get_root() { fi if _contains "$response" "\"status\":200"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_euserv.sh b/dnsapi/dns_euserv.sh index 2da00c3d..744f6ca6 100644 --- a/dnsapi/dns_euserv.sh +++ b/dnsapi/dns_euserv.sh @@ -151,7 +151,7 @@ _get_root() { response="$_euserv_domain_orders" while true; do - h=$(echo "$domain" | cut -d . -f $i-100) + h=$(echo "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -159,7 +159,7 @@ _get_root() { fi if _contains "$response" "$h"; then - _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) + _sub_domain=$(echo "$domain" | cut -d . -f 1-"$p") _domain="$h" if ! _euserv_get_domain_id "$_domain"; then _err "invalid domain" diff --git a/dnsapi/dns_exoscale.sh b/dnsapi/dns_exoscale.sh index 4cc5a513..6898ce38 100755 --- a/dnsapi/dns_exoscale.sh +++ b/dnsapi/dns_exoscale.sh @@ -119,7 +119,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -130,7 +130,7 @@ _get_root() { _domain_id=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \") _domain_token=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_token" ] && [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index 38cdf5e6..cede0cd0 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -90,7 +90,7 @@ _get_root() { i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh index 141ddccf..0516fee9 100644 --- a/dnsapi/dns_gandi_livedns.sh +++ b/dnsapi/dns_gandi_livedns.sh @@ -95,7 +95,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -112,7 +112,7 @@ _get_root() { elif _contains "$response" '"code": 404'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_gcore.sh b/dnsapi/dns_gcore.sh index bd8a1e56..fbdba7ee 100755 --- a/dnsapi/dns_gcore.sh +++ b/dnsapi/dns_gcore.sh @@ -138,7 +138,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -152,7 +152,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _zone_name=$h if [ "$_zone_name" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 08afa8f5..ee66ee19 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -148,7 +148,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -161,7 +161,7 @@ _get_root() { if _contains "$response" '"code":"NOT_FOUND"'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_googledomains.sh b/dnsapi/dns_googledomains.sh index 7d241ab6..07a37e07 100755 --- a/dnsapi/dns_googledomains.sh +++ b/dnsapi/dns_googledomains.sh @@ -132,7 +132,7 @@ _dns_googledomains_get_zone() { i=2 while true; do - curr=$(printf "%s" "$domain" | cut -d . -f $i-100) + curr=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug curr "$curr" if [ -z "$curr" ]; then diff --git a/dnsapi/dns_hetzner.sh b/dnsapi/dns_hetzner.sh index a60bd55d..5a9cf2d9 100644 --- a/dnsapi/dns_hetzner.sh +++ b/dnsapi/dns_hetzner.sh @@ -181,7 +181,7 @@ _get_root() { _debug "Trying to get zone id by domain name for '$domain_without_acme'." while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -193,7 +193,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_entries":1'; then _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h HETZNER_Zone_ID=$_domain_id _savedomainconf "$domain_param_name" "$HETZNER_Zone_ID" diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index 6c86e6a4..017641fd 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -123,7 +123,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -135,7 +135,7 @@ _get_root() { fi if _contains "$response" "CODE=200"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index b2d42451..808fc3a9 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -293,7 +293,7 @@ _get_root() { response="$(_post "$xml_content" "$INWX_Api" "" "POST")" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -301,7 +301,7 @@ _get_root() { fi if _contains "$response" "$h"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_ionos.sh b/dnsapi/dns_ionos.sh index e4d28e11..9a464253 100755 --- a/dnsapi/dns_ionos.sh +++ b/dnsapi/dns_ionos.sh @@ -87,7 +87,7 @@ _get_root() { _response="$(echo "$_response" | tr -d "\n")" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then return 1 fi @@ -96,7 +96,7 @@ _get_root() { if [ "$_zone" ]; then _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') if [ "$_zone_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index a45aa2ca..4b9067f2 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -135,7 +135,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug2 "Checking domain: $h" if ! jd_rest GET "domain"; then _err "error get domain list" @@ -153,7 +153,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_joker.sh b/dnsapi/dns_joker.sh index 49c544b9..1fe33c67 100644 --- a/dnsapi/dns_joker.sh +++ b/dnsapi/dns_joker.sh @@ -80,7 +80,7 @@ _get_root() { fulldomain=$1 i=1 while true; do - h=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + h=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then return 1 diff --git a/dnsapi/dns_kappernet.sh b/dnsapi/dns_kappernet.sh index 7b6fb8a6..762ba8b3 100644 --- a/dnsapi/dns_kappernet.sh +++ b/dnsapi/dns_kappernet.sh @@ -102,7 +102,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -113,7 +113,7 @@ _get_root() { if _contains "$response" '"OK":false'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh index 7a1c0a1c..f19333c4 100644 --- a/dnsapi/dns_la.sh +++ b/dnsapi/dns_la.sh @@ -113,7 +113,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -126,7 +126,7 @@ _get_root() { if _contains "$response" '"domainid":'; then _domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n') if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_limacity.sh b/dnsapi/dns_limacity.sh index 649550ae..fb12f8c6 100644 --- a/dnsapi/dns_limacity.sh +++ b/dnsapi/dns_limacity.sh @@ -69,7 +69,7 @@ _lima_get_domain_id() { if [ "$(echo "$domains" | _egrep_o "\{.*""domains""")" ]; then response="$(echo "$domains" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -80,7 +80,7 @@ _lima_get_domain_id() { if [ "$hostedzone" ]; then LIMACITY_DOMAINID=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$LIMACITY_DOMAINID" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index 5e4c694b..d74d1fc8 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -136,7 +136,7 @@ _get_root() { if _rest GET "domain.list"; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -147,7 +147,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index e562f80f..f6a61a99 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -138,7 +138,7 @@ _get_root() { if _rest GET; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -149,7 +149,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_loopia.sh b/dnsapi/dns_loopia.sh index 1f943e51..98a4f3ab 100644 --- a/dnsapi/dns_loopia.sh +++ b/dnsapi/dns_loopia.sh @@ -180,14 +180,14 @@ _get_root() { response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")" while true; do - h=$(echo "$domain" | cut -d . -f $i-100) + h=$(echo "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 fi if _contains "$response" "$h"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index b037e90f..34cce6a1 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -110,7 +110,7 @@ _get_root() { return 1 fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -121,7 +121,7 @@ _get_root() { _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1) _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 66545c46..43c903cd 100644 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -107,7 +107,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -120,7 +120,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _domain_id=$(printf "%s\n" "$response" | sed 's/^{//; s/}$//; s/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/') if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_misaka.sh b/dnsapi/dns_misaka.sh index c6c0f5f3..50ed4360 100755 --- a/dnsapi/dns_misaka.sh +++ b/dnsapi/dns_misaka.sh @@ -116,7 +116,7 @@ _get_root() { return 1 fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -124,7 +124,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh index 4fa646e8..336c4889 100755 --- a/dnsapi/dns_mydnsjp.sh +++ b/dnsapi/dns_mydnsjp.sh @@ -126,7 +126,7 @@ _get_root() { fi while true; do - _domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-100) if [ -z "$_domain" ]; then # not valid @@ -134,7 +134,7 @@ _get_root() { fi if [ "$_domain" = "$_root_domain" ]; then - _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$p") return 0 fi diff --git a/dnsapi/dns_mythic_beasts.sh b/dnsapi/dns_mythic_beasts.sh index b85401f4..1529e1e7 100755 --- a/dnsapi/dns_mythic_beasts.sh +++ b/dnsapi/dns_mythic_beasts.sh @@ -107,7 +107,7 @@ _get_root() { _debug "Detect the root zone" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then _err "Domain exhausted" return 1 @@ -118,7 +118,7 @@ _get_root() { _mb_rest GET "$h/records" ret="$?" if [ "$ret" -eq 0 ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index abe64d09..ed378838 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -109,7 +109,7 @@ _get_root_by_getList() { while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -123,7 +123,7 @@ _get_root_by_getList() { if ! _contains "$response" "$h"; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi @@ -139,12 +139,12 @@ _get_root_by_getHosts() { while [ $p -ne 0 ]; do - h=$(printf "%s" "$1" | cut -d . -f $i-100) + h=$(printf "%s" "$1" | cut -d . -f "$i"-100) if [ -n "$h" ]; then if _contains "$h" "\\."; then _debug h "$h" if _namecheap_set_tld_sld "$h"; then - _sub_domain=$(printf "%s" "$1" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$1" | cut -d . -f 1-"$p") _domain="$h" return 0 else @@ -378,7 +378,7 @@ _namecheap_set_tld_sld() { while true; do - _tld=$(printf "%s" "$domain" | cut -d . -f $i-100) + _tld=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug tld "$_tld" if [ -z "$_tld" ]; then diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index 2d146974..b1c37876 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -160,14 +160,14 @@ _namecom_get_root() { # Need to exclude the last field (tld) numfields=$(echo "$domain" | _egrep_o "\." | wc -l) while [ $i -le "$numfields" ]; do - host=$(printf "%s" "$domain" | cut -d . -f $i-100) + host=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug host "$host" if [ -z "$host" ]; then return 1 fi if _contains "$response" "$host"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$host" return 0 fi diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index 2995e7dc..5840d60c 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -110,14 +110,14 @@ _get_root() { # Need to exclude the last field (tld) numfields=$(echo "$domain" | _egrep_o "\." | wc -l) while [ $i -le "$numfields" ]; do - host=$(printf "%s" "$domain" | cut -d . -f $i-100) + host=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug host "$host" if [ -z "$host" ]; then return 1 fi if _contains "$response" ">$host"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$host" return 0 fi diff --git a/dnsapi/dns_nederhost.sh b/dnsapi/dns_nederhost.sh index d0b97d3c..b16c36ec 100755 --- a/dnsapi/dns_nederhost.sh +++ b/dnsapi/dns_nederhost.sh @@ -88,8 +88,8 @@ _get_root() { i=2 p=1 while true; do - _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _debug _domain "$_domain" if [ -z "$_domain" ]; then #not valid diff --git a/dnsapi/dns_neodigit.sh b/dnsapi/dns_neodigit.sh index 1119f916..a31f8c9b 100644 --- a/dnsapi/dns_neodigit.sh +++ b/dnsapi/dns_neodigit.sh @@ -126,7 +126,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -142,7 +142,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\"" >/dev/null; then _domain_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index bb5f5809..7f5eb046 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -111,7 +111,7 @@ _get_root() { _netlify_rest GET "dns_zones" "" "$accesstoken" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug2 "Checking domain: $h" if [ -z "$h" ]; then #not valid @@ -126,7 +126,7 @@ _get_root() { #create the record at the domain apex (@) if only the domain name was provided as --domain-alias _sub_domain="@" else - _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) + _sub_domain=$(echo "$domain" | cut -d . -f 1-"$p") fi _domain=$h return 0 diff --git a/dnsapi/dns_nic.sh b/dnsapi/dns_nic.sh index 42f35cb0..5f3e7d5d 100644 --- a/dnsapi/dns_nic.sh +++ b/dnsapi/dns_nic.sh @@ -169,7 +169,7 @@ _get_root() { fi if _contains "$_all_domains" "^$h$"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _service=$(printf "%s" "$response" | grep -m 1 "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/") return 0 diff --git a/dnsapi/dns_njalla.sh b/dnsapi/dns_njalla.sh index 5d241ebf..c410447d 100644 --- a/dnsapi/dns_njalla.sh +++ b/dnsapi/dns_njalla.sh @@ -126,7 +126,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -140,7 +140,7 @@ _get_root() { if _contains "$response" "\"$h\""; then _domain_returned=$(echo "$response" | _egrep_o "\{\"name\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") if [ "$_domain_returned" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_nsone.sh b/dnsapi/dns_nsone.sh index 2a073950..e1bfa531 100644 --- a/dnsapi/dns_nsone.sh +++ b/dnsapi/dns_nsone.sh @@ -119,7 +119,7 @@ _get_root() { return 1 fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -127,7 +127,7 @@ _get_root() { fi if _contains "$response" "\"zone\":\"$h\""; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_nw.sh b/dnsapi/dns_nw.sh index 8c68ead8..0a21c452 100644 --- a/dnsapi/dns_nw.sh +++ b/dnsapi/dns_nw.sh @@ -154,7 +154,7 @@ _get_root() { _debug response "${response}" while true; do - h=$(printf "%s" "${domain}" | cut -d . -f $i-100) + h=$(printf "%s" "${domain}" | cut -d . -f "$i"-100) _debug h "${h}" if [ -z "${h}" ]; then #not valid diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh index f1138efa..c76a4565 100644 --- a/dnsapi/dns_oci.sh +++ b/dnsapi/dns_oci.sh @@ -190,7 +190,7 @@ _get_zone() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then # not valid @@ -199,7 +199,7 @@ _get_zone() { _domain_id=$(_signed_request "GET" "/20180115/zones/$h" "" "id") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug _domain_id "$_domain_id" diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index b2adf253..d258ecc1 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -94,7 +94,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid @@ -104,7 +104,7 @@ _get_root() { response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")" if ! _contains "$response" "CRMRST_000302"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_online.sh b/dnsapi/dns_online.sh index c83cd458..7ec27d71 100755 --- a/dnsapi/dns_online.sh +++ b/dnsapi/dns_online.sh @@ -124,7 +124,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -133,7 +133,7 @@ _get_root() { _online_rest GET "domain/$h/version/active" if ! _contains "$response" "Domain not found" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" _real_dns_version=$(echo "$response" | _egrep_o '"uuid_ref":.*' | cut -d ':' -f 2 | cut -d '"' -f 2) return 0 diff --git a/dnsapi/dns_openprovider.sh b/dnsapi/dns_openprovider.sh index 4d115dcf..b584fad2 100755 --- a/dnsapi/dns_openprovider.sh +++ b/dnsapi/dns_openprovider.sh @@ -186,7 +186,7 @@ _get_root() { results_retrieved=0 while true; do - h=$(echo "$domain" | cut -d . -f $i-100) + h=$(echo "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index 6d3d3eec..cedf277f 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -144,7 +144,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -153,7 +153,7 @@ _get_root() { id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"primary\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" - _host=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _host=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="${h}" _domainid="${id}" return 0 diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 7f62c05e..22a719f8 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -260,7 +260,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -273,7 +273,7 @@ _get_root() { if ! _contains "$response" "This service does not exist" >/dev/null && ! _contains "$response" "This call has not been granted" >/dev/null && ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index cde3b1a6..d29fde33 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -181,7 +181,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if _contains "$_zones_response" "\"name\":\"$h.\""; then _domain="$h." diff --git a/dnsapi/dns_pointhq.sh b/dnsapi/dns_pointhq.sh index fe95cd52..0abc087b 100644 --- a/dnsapi/dns_pointhq.sh +++ b/dnsapi/dns_pointhq.sh @@ -118,7 +118,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -130,7 +130,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_porkbun.sh b/dnsapi/dns_porkbun.sh index d156b014..1681ca9a 100644 --- a/dnsapi/dns_porkbun.sh +++ b/dnsapi/dns_porkbun.sh @@ -107,7 +107,7 @@ _get_root() { domain=$1 i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then return 1 diff --git a/dnsapi/dns_rackcorp.sh b/dnsapi/dns_rackcorp.sh index e1e4f27d..b8fc73ab 100644 --- a/dnsapi/dns_rackcorp.sh +++ b/dnsapi/dns_rackcorp.sh @@ -83,7 +83,7 @@ _get_root() { return 1 fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug searchhost "$h" if [ -z "$h" ]; then _err "Could not find domain for record $domain in RackCorp using the provided credentials" @@ -95,7 +95,7 @@ _get_root() { if _contains "$response" "\"matches\":1"; then if _contains "$response" "\"name\":\"$h\""; then - _lookup=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _lookup=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_rackspace.sh b/dnsapi/dns_rackspace.sh index 03edce0d..05ec14a6 100644 --- a/dnsapi/dns_rackspace.sh +++ b/dnsapi/dns_rackspace.sh @@ -72,7 +72,7 @@ _get_root_zone() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -88,7 +88,7 @@ _get_root_zone() { _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p") _debug2 domain_id "$_domain_id" if [ -n "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_rcode0.sh b/dnsapi/dns_rcode0.sh index 131a22b1..c3e6582b 100755 --- a/dnsapi/dns_rcode0.sh +++ b/dnsapi/dns_rcode0.sh @@ -171,7 +171,7 @@ _get_root() { i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug "try to find: $h" if _rcode0_rest "GET" "/api/v1/acme/zones/$h"; then diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index 64bfcc38..53857eae 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -104,7 +104,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -113,7 +113,7 @@ _get_root() { _scaleway_rest GET "dns-zones/$h/records" if ! _contains "$response" "subdomain not found" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_schlundtech.sh b/dnsapi/dns_schlundtech.sh index 02146494..6d2930a2 100644 --- a/dnsapi/dns_schlundtech.sh +++ b/dnsapi/dns_schlundtech.sh @@ -106,7 +106,7 @@ _get_autodns_zone() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then @@ -124,7 +124,7 @@ _get_autodns_zone() { if _contains "$autodns_response" "1" >/dev/null; then _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") return 0 fi diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 32b0737f..8b52b24e 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -117,7 +117,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -125,7 +125,7 @@ _get_root() { fi if _contains "$response" "\"name\" *: *\"$h\","; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" if ! _sl_rest GET "/$h"; then diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 37c2a97b..462ba0af 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -137,7 +137,7 @@ _get_root() { p=1 while true; do - _domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100) + _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-100) _debug _domain "$_domain" if [ -z "$_domain" ]; then @@ -150,7 +150,7 @@ _get_root() { fi if ! _contains "$response" '"error":"no such domain in user context"' >/dev/null; then - _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$p") if [ -z "$_sub_domain" ]; then # not valid return 1 diff --git a/dnsapi/dns_simply.sh b/dnsapi/dns_simply.sh index 9fac3ef7..e0ad16e2 100644 --- a/dnsapi/dns_simply.sh +++ b/dnsapi/dns_simply.sh @@ -166,7 +166,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -179,7 +179,7 @@ _get_root() { if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh index 6171678e..2abbe34d 100644 --- a/dnsapi/dns_transip.sh +++ b/dnsapi/dns_transip.sh @@ -55,14 +55,14 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 fi - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" if _transip_rest GET "domains/$h/dns" && _contains "$response" "dnsEntries"; then diff --git a/dnsapi/dns_udr.sh b/dnsapi/dns_udr.sh index 24a843b9..f9772e10 100644 --- a/dnsapi/dns_udr.sh +++ b/dnsapi/dns_udr.sh @@ -115,7 +115,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then diff --git a/dnsapi/dns_ultra.sh b/dnsapi/dns_ultra.sh index 8b8c9122..e8da431c 100644 --- a/dnsapi/dns_ultra.sh +++ b/dnsapi/dns_ultra.sh @@ -115,7 +115,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" _debug response "$response" if [ -z "$h" ]; then @@ -128,7 +128,7 @@ _get_root() { if _contains "${response}" "${h}." >/dev/null; then _domain_id=$(echo "$response" | _egrep_o "${h}" | head -1) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="${h}" _debug sub_domain "${_sub_domain}" _debug domain "${_domain}" diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index a1263abe..ff70c8b6 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -133,7 +133,7 @@ _get_root() { i=2 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -147,7 +147,7 @@ _get_root() { if _contains "$response" "\"status\": 200"; then _domain_id=$h if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_variomedia.sh b/dnsapi/dns_variomedia.sh index 23ec29bf..fa38bbb6 100644 --- a/dnsapi/dns_variomedia.sh +++ b/dnsapi/dns_variomedia.sh @@ -102,7 +102,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then return 1 fi @@ -112,7 +112,7 @@ _get_root() { fi if _contains "$response" "\"id\":\"$h\""; then - _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_veesp.sh b/dnsapi/dns_veesp.sh index 5ea6e718..1afeeb30 100644 --- a/dnsapi/dns_veesp.sh +++ b/dnsapi/dns_veesp.sh @@ -112,7 +112,7 @@ _get_root() { return 1 fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -125,7 +125,7 @@ _get_root() { _service_id=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$h\",\"service_id\":[^}]*" | cut -d : -f 3 | cut -d '"' -f 2) _debug _service_id "$_service_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain="$h" return 0 fi diff --git a/dnsapi/dns_vercel.sh b/dnsapi/dns_vercel.sh index 46a4cb7e..469f7670 100644 --- a/dnsapi/dns_vercel.sh +++ b/dnsapi/dns_vercel.sh @@ -94,7 +94,7 @@ _get_root() { i=1 p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) if [ -z "$h" ]; then #not valid return 1 @@ -105,7 +105,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\"" >/dev/null; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_vscale.sh b/dnsapi/dns_vscale.sh index 54abb439..c3915c69 100755 --- a/dnsapi/dns_vscale.sh +++ b/dnsapi/dns_vscale.sh @@ -97,7 +97,7 @@ _get_root() { if _vscale_rest GET "domains/"; then response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -108,7 +108,7 @@ _get_root() { if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh index 94d14f02..61ec3f60 100644 --- a/dnsapi/dns_vultr.sh +++ b/dnsapi/dns_vultr.sh @@ -112,7 +112,7 @@ _get_root() { domain=$1 i=1 while true; do - _domain=$(printf "%s" "$domain" | cut -d . -f $i-100) + _domain=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$_domain" if [ -z "$_domain" ]; then return 1 diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh index 3df8d81c..bfc4b23a 100644 --- a/dnsapi/dns_websupport.sh +++ b/dnsapi/dns_websupport.sh @@ -121,7 +121,7 @@ _get_root() { p=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -135,7 +135,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *[^,]*" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_yc.sh b/dnsapi/dns_yc.sh index e81b6fd2..36c49ce4 100644 --- a/dnsapi/dns_yc.sh +++ b/dnsapi/dns_yc.sh @@ -179,7 +179,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -197,7 +197,7 @@ _get_root() { _domain_id=$(echo "$response" | _normalizeJson | _egrep_o "[^{]*\"zone\":\"$h\"[^}]*" | _egrep_o "\"id\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"') _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h return 0 fi diff --git a/dnsapi/dns_zilore.sh b/dnsapi/dns_zilore.sh index 369ce152..a4bacac5 100644 --- a/dnsapi/dns_zilore.sh +++ b/dnsapi/dns_zilore.sh @@ -98,9 +98,9 @@ dns_zilore_rm() { _get_root() { domain=$1 - i=2 + i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then #not valid diff --git a/dnsapi/dns_zone.sh b/dnsapi/dns_zone.sh index e4685707..cf82e5f4 100755 --- a/dnsapi/dns_zone.sh +++ b/dnsapi/dns_zone.sh @@ -137,9 +137,9 @@ _zone_rest() { _get_root() { domain=$1 - i=2 + i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then return 1 From 9b2eae24d21331a42f576d2940503941fdbe6ddf Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:49:29 +0200 Subject: [PATCH 497/687] fix format --- dnsapi/dns_bunny.sh | 6 +++--- dnsapi/dns_dgon.sh | 6 +++--- dnsapi/dns_dnsimple.sh | 2 +- dnsapi/dns_dynv6.sh | 3 +-- dnsapi/dns_geoscaling.sh | 2 +- dnsapi/dns_he.sh | 2 +- dnsapi/dns_internetbs.sh | 4 ++-- dnsapi/dns_maradns.sh | 2 +- dnsapi/dns_opnsense.sh | 2 +- dnsapi/dns_pdns.sh | 2 +- dnsapi/dns_rcode0.sh | 2 +- 11 files changed, 16 insertions(+), 17 deletions(-) diff --git a/dnsapi/dns_bunny.sh b/dnsapi/dns_bunny.sh index 681f748a..ac589e54 100644 --- a/dnsapi/dns_bunny.sh +++ b/dnsapi/dns_bunny.sh @@ -196,7 +196,7 @@ _get_base_domain() { _debug2 domain_list "$domain_list" i=1 - while [ $i -gt 0 ]; do + while [ "$i" -gt 0 ]; do ## get next longest domain _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM") ## check we got something back from our cut (or are we at the end) @@ -208,7 +208,7 @@ _get_base_domain() { ## check if it exists if [ -n "$found" ]; then ## exists - exit loop returning the parts - sub_point=$(_math $i - 1) + sub_point=$(_math "$i" - 1) _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") _domain_id="$(echo "$found" | _egrep_o "Id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")" _debug _domain_id "$_domain_id" @@ -218,7 +218,7 @@ _get_base_domain() { return 0 fi ## increment cut point $i - i=$(_math $i + 1) + i=$(_math "$i" + 1) done if [ -z "$found" ]; then diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh index 9aaa9606..cb887cfa 100755 --- a/dnsapi/dns_dgon.sh +++ b/dnsapi/dns_dgon.sh @@ -203,7 +203,7 @@ _get_base_domain() { _debug2 domain_list "$domain_list" i=1 - while [ $i -gt 0 ]; do + while [ "$i" -gt 0 ]; do ## get next longest domain _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM") ## check we got something back from our cut (or are we at the end) @@ -215,14 +215,14 @@ _get_base_domain() { ## check if it exists if [ -n "$found" ]; then ## exists - exit loop returning the parts - sub_point=$(_math $i - 1) + sub_point=$(_math "$i" - 1) _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point") _debug _domain "$_domain" _debug _sub_domain "$_sub_domain" return 0 fi ## increment cut point $i - i=$(_math $i + 1) + i=$(_math "$i" + 1) done if [ -z "$found" ]; then diff --git a/dnsapi/dns_dnsimple.sh b/dnsapi/dns_dnsimple.sh index 9b72bf44..10a3821d 100644 --- a/dnsapi/dns_dnsimple.sh +++ b/dnsapi/dns_dnsimple.sh @@ -105,7 +105,7 @@ _get_root() { if _contains "$response" 'not found'; then _debug "$h not found" else - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p"revious) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$previous") _domain="$h" _debug _domain "$_domain" diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh index 6fbb23ca..76af17f5 100644 --- a/dnsapi/dns_dynv6.sh +++ b/dnsapi/dns_dynv6.sh @@ -43,9 +43,8 @@ dns_dynv6_add() { _err "Something went wrong! it does not seem like the record was added successfully" return 1 fi - return 1 fi - return 1 + } #Usage: fulldomain txtvalue #Remove the txt record after validation. diff --git a/dnsapi/dns_geoscaling.sh b/dnsapi/dns_geoscaling.sh index 96b3e218..05887c7e 100755 --- a/dnsapi/dns_geoscaling.sh +++ b/dnsapi/dns_geoscaling.sh @@ -202,7 +202,7 @@ find_zone() { # Walk through all possible zone names strip_counter=1 while true; do - attempted_zone=$(echo "${domain}" | cut -d . -f ${strip_counter}-) + attempted_zone=$(echo "${domain}" | cut -d . -f "${strip_counter}"-) # All possible zone names have been tried if [ -z "${attempted_zone}" ]; then diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index cfb6efb8..a768f352 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -143,7 +143,7 @@ _find_zone() { # Walk through all possible zone names _strip_counter=1 while true; do - _attempted_zone=$(echo "$_domain" | cut -d . -f ${_strip_counter}-) + _attempted_zone=$(echo "$_domain" | cut -d . -f "${_strip_counter}"-) # All possible zone names have been tried if [ -z "$_attempted_zone" ]; then diff --git a/dnsapi/dns_internetbs.sh b/dnsapi/dns_internetbs.sh index 84dfd70f..4238bfe4 100755 --- a/dnsapi/dns_internetbs.sh +++ b/dnsapi/dns_internetbs.sh @@ -133,7 +133,7 @@ _get_root() { fi while true; do - h=$(printf "%s" "$domain" | cut -d . -f ${i}-100) + h=$(printf "%s" "$domain" | cut -d . -f "${i}"-100) _debug h "$h" if [ -z "$h" ]; then #not valid @@ -141,7 +141,7 @@ _get_root() { fi if _contains "$response" "\"$h\""; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-${p}) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"${p}") _domain=${h} return 0 fi diff --git a/dnsapi/dns_maradns.sh b/dnsapi/dns_maradns.sh index 09d7248e..9eefb175 100755 --- a/dnsapi/dns_maradns.sh +++ b/dnsapi/dns_maradns.sh @@ -72,7 +72,7 @@ _reload_maradns() { pidpath="$1" kill -s HUP -- "$(cat "$pidpath")" if [ $? -ne 0 ]; then - _err "Unable to reload MaraDNS, kill returned $?" + _err "Unable to reload MaraDNS, kill returned" return 1 fi } diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index cedf277f..d1e9c0ac 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -159,7 +159,7 @@ _get_root() { return 0 fi p=$i - i=$(_math $i + 1) + i=$(_math "$i" + 1) done _debug "$domain not found" diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index d29fde33..6cce54da 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -194,7 +194,7 @@ _get_root() { if [ -z "$h" ]; then return 1 fi - i=$(_math $i + 1) + i=$(_math "$i" + 1) done _debug "$domain not found" diff --git a/dnsapi/dns_rcode0.sh b/dnsapi/dns_rcode0.sh index c3e6582b..4ffdf572 100755 --- a/dnsapi/dns_rcode0.sh +++ b/dnsapi/dns_rcode0.sh @@ -189,7 +189,7 @@ _get_root() { if [ -z "$h" ]; then return 1 fi - i=$(_math $i + 1) + i=$(_math "$i" + 1) done _debug "no matching domain for $domain found" From e0381dd75702a9d95bbf608e69fefce5ba2ca8c7 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:55:22 +0200 Subject: [PATCH 498/687] fix format --- dnsapi/dns_bunny.sh | 2 +- dnsapi/dns_miab.sh | 4 ++-- dnsapi/dns_namecheap.sh | 2 +- dnsapi/dns_namecom.sh | 2 +- dnsapi/dns_namesilo.sh | 2 +- dnsapi/dns_netlify.sh | 2 -- dnsapi/dns_ovh.sh | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dnsapi/dns_bunny.sh b/dnsapi/dns_bunny.sh index ac589e54..780198e1 100644 --- a/dnsapi/dns_bunny.sh +++ b/dnsapi/dns_bunny.sh @@ -222,7 +222,7 @@ _get_base_domain() { done if [ -z "$found" ]; then - page=$(_math $page + 1) + page=$(_math "$page" + 1) nextpage="https://api.bunny.net/dnszone?page=$page" ## Find the next page if we don't have a match. hasnextpage="$(echo "$domain_list" | _egrep_o "\"HasMoreItems\"\s*:\s*true")" diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index 9416c8ce..c2aa9789 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -113,7 +113,7 @@ _get_root() { #cycle through the passed domain seperating out a test domain discarding # the subdomain by marching thorugh the dots while true; do - _test_domain=$(printf "%s" "$_passed_domain" | cut -d . -f ${_i}-100) + _test_domain=$(printf "%s" "$_passed_domain" | cut -d . -f "${_i}"-100) _debug _test_domain "$_test_domain" if [ -z "$_test_domain" ]; then @@ -123,7 +123,7 @@ _get_root() { #report found if the test domain is in the json response and # report the subdomain if _contains "$response" "\"$_test_domain\""; then - _sub_domain=$(printf "%s" "$_passed_domain" | cut -d . -f 1-${_p}) + _sub_domain=$(printf "%s" "$_passed_domain" | cut -d . -f 1-"${_p}") _domain=${_test_domain} return 0 fi diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index ed378838..5527b357 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -137,7 +137,7 @@ _get_root_by_getHosts() { i=100 p=99 - while [ $p -ne 0 ]; do + while [ "$p" -ne 0 ]; do h=$(printf "%s" "$1" | cut -d . -f "$i"-100) if [ -n "$h" ]; then diff --git a/dnsapi/dns_namecom.sh b/dnsapi/dns_namecom.sh index b1c37876..44549c9e 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -159,7 +159,7 @@ _namecom_get_root() { # Need to exclude the last field (tld) numfields=$(echo "$domain" | _egrep_o "\." | wc -l) - while [ $i -le "$numfields" ]; do + while [ "$i" -le "$numfields" ]; do host=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug host "$host" if [ -z "$host" ]; then diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index 5840d60c..b31e32a1 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -109,7 +109,7 @@ _get_root() { # Need to exclude the last field (tld) numfields=$(echo "$domain" | _egrep_o "\." | wc -l) - while [ $i -le "$numfields" ]; do + while [ "$i" -le "$numfields" ]; do host=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug host "$host" if [ -z "$host" ]; then diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 7f5eb046..11e0902b 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -55,8 +55,6 @@ dns_netlify_add() { return 1 fi - _err "Not fully implemented!" - return 1 } #Usage: dns_myapi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 22a719f8..24ad0904 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -113,7 +113,7 @@ _initAuth() { _saveaccountconf_mutable OVH_END_POINT "$OVH_END_POINT" fi - OVH_API="$(_ovh_get_api $OVH_END_POINT)" + OVH_API="$(_ovh_get_api "$OVH_END_POINT")" _debug OVH_API "$OVH_API" OVH_CK="${OVH_CK:-$(_readaccountconf_mutable OVH_CK)}" From 7031df494868c4e0e9f67ca313dbd62ed150bbe7 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:58:19 +0200 Subject: [PATCH 499/687] fix format --- dnsapi/dns_netlify.sh | 1 - dnsapi/dns_nw.sh | 2 +- dnsapi/dns_scaleway.sh | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh index 11e0902b..322f10ad 100644 --- a/dnsapi/dns_netlify.sh +++ b/dnsapi/dns_netlify.sh @@ -93,7 +93,6 @@ dns_netlify_rm() { _err "error removing validation value ($_code)" return 1 fi - return 0 fi return 1 } diff --git a/dnsapi/dns_nw.sh b/dnsapi/dns_nw.sh index 0a21c452..0735f5de 100644 --- a/dnsapi/dns_nw.sh +++ b/dnsapi/dns_nw.sh @@ -165,7 +165,7 @@ _get_root() { if [ "${hostedzone}" ]; then _zone_id=$(printf "%s\n" "${hostedzone}" | _egrep_o "\"zone_id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "${_zone_id}" ]; then - _sub_domain=$(printf "%s" "${domain}" | cut -d . -f 1-${p}) + _sub_domain=$(printf "%s" "${domain}" | cut -d . -f 1-"${p}") _domain="${h}" return 0 fi diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index 53857eae..4cbf68d2 100755 --- a/dnsapi/dns_scaleway.sh +++ b/dnsapi/dns_scaleway.sh @@ -41,9 +41,7 @@ dns_scaleway_add() { _err error "$response" return 1 fi - _info "Record added." - return 0 } dns_scaleway_rm() { @@ -71,9 +69,7 @@ dns_scaleway_rm() { _err error "$response" return 1 fi - _info "Record deleted." - return 0 } #################### Private functions below ################################## From 2ebecf1aa03ca5fbc7bbf2afa22526b42566f216 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 13 Oct 2024 17:59:25 +0200 Subject: [PATCH 500/687] fix format --- dnsapi/dns_servercow.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh index 462ba0af..d6994681 100755 --- a/dnsapi/dns_servercow.sh +++ b/dnsapi/dns_servercow.sh @@ -81,7 +81,6 @@ dns_servercow_add() { return 1 fi - return 1 } # Usage fulldomain txtvalue From 1aabb7d6dec01bd49d5d507e5c99826988c3cf8f Mon Sep 17 00:00:00 2001 From: sahsanu Date: Mon, 14 Oct 2024 15:59:54 +0200 Subject: [PATCH 501/687] Fix dns_pdns.sh to use saved account conf --- dnsapi/dns_pdns.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 6cce54da..12e0e83d 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/bash # shellcheck disable=SC2034 dns_pdns_info='PowerDNS Server API Site: PowerDNS.com @@ -10,6 +10,7 @@ Options: PDNS_Ttl=60 Domain TTL. Default: "60". ' + DEFAULT_PDNS_TTL=60 ######## Public functions ##################### @@ -20,6 +21,11 @@ dns_pdns_add() { fulldomain=$1 txtvalue=$2 + PDNS_Url="${PDNS_Url:-$(_readaccountconf_mutable PDNS_Url)}" + PDNS_ServerId="${PDNS_ServerId:-$(_readaccountconf_mutable PDNS_ServerId)}" + PDNS_Token="${PDNS_Token:-$(_readaccountconf_mutable PDNS_Token)}" + PDNS_Ttl="${PDNS_Ttl:-$(_readaccountconf_mutable PDNS_Ttl)}" + if [ -z "$PDNS_Url" ]; then PDNS_Url="" _err "You don't specify PowerDNS address." @@ -73,6 +79,11 @@ dns_pdns_rm() { fulldomain=$1 txtvalue=$2 + PDNS_Url="${PDNS_Url:-$(_readaccountconf_mutable PDNS_Url)}" + PDNS_ServerId="${PDNS_ServerId:-$(_readaccountconf_mutable PDNS_ServerId)}" + PDNS_Token="${PDNS_Token:-$(_readaccountconf_mutable PDNS_Token)}" + PDNS_Ttl="${PDNS_Ttl:-$(_readaccountconf_mutable PDNS_Ttl)}" + if [ -z "$PDNS_Ttl" ]; then PDNS_Ttl="$DEFAULT_PDNS_TTL" fi From 1782eeb785372a618cd64fd6a31e1b22510678bf Mon Sep 17 00:00:00 2001 From: sahsanu Date: Mon, 14 Oct 2024 16:18:44 +0200 Subject: [PATCH 502/687] Fix dns_pdns.sh to use saved account conf --- dnsapi/dns_pdns.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 12e0e83d..3130a02b 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env sh # shellcheck disable=SC2034 dns_pdns_info='PowerDNS Server API Site: PowerDNS.com @@ -10,7 +10,6 @@ Options: PDNS_Ttl=60 Domain TTL. Default: "60". ' - DEFAULT_PDNS_TTL=60 ######## Public functions ##################### From 6a9304dd1caf145ec01e11d8b40472d2734335d6 Mon Sep 17 00:00:00 2001 From: sahsanu Date: Wed, 16 Oct 2024 09:03:18 +0200 Subject: [PATCH 503/687] Change _saveaccountconf to _saveaccountconf_mutable --- dnsapi/dns_pdns.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 3130a02b..2478e19f 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -51,12 +51,12 @@ dns_pdns_add() { fi #save the api addr and key to the account conf file. - _saveaccountconf PDNS_Url "$PDNS_Url" - _saveaccountconf PDNS_ServerId "$PDNS_ServerId" - _saveaccountconf PDNS_Token "$PDNS_Token" + _saveaccountconf_mutable PDNS_Url "$PDNS_Url" + _saveaccountconf_mutable PDNS_ServerId "$PDNS_ServerId" + _saveaccountconf_mutable PDNS_Token "$PDNS_Token" if [ "$PDNS_Ttl" != "$DEFAULT_PDNS_TTL" ]; then - _saveaccountconf PDNS_Ttl "$PDNS_Ttl" + _saveaccountconf_mutable PDNS_Ttl "$PDNS_Ttl" fi _debug "Detect root zone" From 30ed4af38d7ee9a3fb01ee719658e7efc65d579c Mon Sep 17 00:00:00 2001 From: Roland Giesler Date: Wed, 16 Oct 2024 11:49:29 +0200 Subject: [PATCH 504/687] Revert TXT add update The change was needed for Power-Mailinabox and broke Mail-in-a-box, so a new API for Power-Mailinabox has been added --- dnsapi/dns_miab.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh index c2aa9789..0824a4e7 100644 --- a/dnsapi/dns_miab.sh +++ b/dnsapi/dns_miab.sh @@ -16,8 +16,7 @@ Author: Darven Dissek, William Gertz #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_miab_add() { fulldomain=$1 - # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB/PMIAB API - txtvalue="value=$2&ttl=300" + txtvalue=$2 _info "Using miab challenge add" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" From 838a20ea9510860533973aa26d6741c26dcdf0f7 Mon Sep 17 00:00:00 2001 From: Ryo ONODERA Date: Thu, 24 Oct 2024 22:47:30 +0900 Subject: [PATCH 505/687] Fix POSIX shell portability POSIX standard says test command has '=" as for checking identical. '==' is bash dialect. Replace '==' with '='. See: https://pubs.opengroup.org/onlinepubs/009604399/utilities/test.html --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index e39a146b..03d4c552 100755 --- a/acme.sh +++ b/acme.sh @@ -1442,7 +1442,7 @@ _toPkcs() { else ${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca" fi - if [ "$?" == "0" ]; then + if [ "$?" = "0" ]; then _savedomainconf "Le_PFXPassword" "$pfxPassword" fi From 10833dcf395d50d177b78988aa19359c919a063e Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Mon, 28 Oct 2024 11:50:28 -0300 Subject: [PATCH 506/687] trigger github action --- dnsapi/dns_linode_v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 12682dbf..6af076cc 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -1,5 +1,6 @@ #!/usr/bin/env sh + #Original Author: Philipp Grosswiler #v4 Update Author: Aaron W. Swenson From 03906cc055e533f444bd6731c8bab37de2dc701c Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Mon, 28 Oct 2024 12:07:33 -0300 Subject: [PATCH 507/687] trigger github action --- dnsapi/dns_linode_v4.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 6af076cc..12682dbf 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -1,6 +1,5 @@ #!/usr/bin/env sh - #Original Author: Philipp Grosswiler #v4 Update Author: Aaron W. Swenson From a4e7806d2103c03cfd3a1287fd5f5fee73311e32 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 3 Nov 2024 13:09:44 +0100 Subject: [PATCH 508/687] fix https://github.com/acmesh-official/acme.sh/issues/5208 --- acme.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/acme.sh b/acme.sh index 03d4c552..2eea666a 100755 --- a/acme.sh +++ b/acme.sh @@ -2193,7 +2193,6 @@ _send_signed_request() { _debug2 _headers "$_headers" _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" fi - _debug2 _CACHED_NONCE "$_CACHED_NONCE" if [ "$?" != "0" ]; then _err "Cannot connect to $nonceurl to get nonce." return 1 From a3032ab9456c83ff91150c3f42fc1a65f08cf7d0 Mon Sep 17 00:00:00 2001 From: vmmello Date: Tue, 5 Nov 2024 11:10:55 -0300 Subject: [PATCH 509/687] dns_linode_v4.sh: remove uneeeded extra space (shfmt error) --- dnsapi/dns_linode_v4.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index e79ec309..1c7c0db9 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -145,7 +145,6 @@ _get_root() { return 1 fi - _debug "Querying Linode APIv4 for hosted zone: $h" if _H4="X-Filter: {\"domain\":\"$h\"}" _rest GET; then _debug "Got response from API: $response" From 43ed998ed682a2c49f48d338374158c38792e672 Mon Sep 17 00:00:00 2001 From: vmmello Date: Tue, 5 Nov 2024 11:26:37 -0300 Subject: [PATCH 510/687] dns_linode_v4.sh: trigger action execution (dummy change) --- dnsapi/dns_linode_v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 1c7c0db9..e2f06420 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -4,7 +4,7 @@ dns_linode_v4_info='Linode.com Site: Linode.com Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 Options: - LINODE_V4_API_KEY API Key + LINODE_V4_API_KEY API Key Author: Philipp Grosswiler , Aaron W. Swenson ' From 2663f500cff18b0a954f4774336ab62257c147b9 Mon Sep 17 00:00:00 2001 From: vmmello Date: Tue, 5 Nov 2024 11:43:04 -0300 Subject: [PATCH 511/687] dns_linode_v4.sh: trigger action --- dnsapi/dns_linode_v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index e2f06420..c9511f8b 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -4,7 +4,7 @@ dns_linode_v4_info='Linode.com Site: Linode.com Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 Options: - LINODE_V4_API_KEY API Key + LINODE_V4_API_KEY API Key Author: Philipp Grosswiler , Aaron W. Swenson ' From 1ff326c89c120c0775e3522cd9ac938544a656ae Mon Sep 17 00:00:00 2001 From: vmmello Date: Tue, 5 Nov 2024 14:57:28 -0300 Subject: [PATCH 512/687] dns_linode_v4.sh: trigger action --- dnsapi/dns_linode_v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index c9511f8b..e2f06420 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -4,7 +4,7 @@ dns_linode_v4_info='Linode.com Site: Linode.com Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 Options: - LINODE_V4_API_KEY API Key + LINODE_V4_API_KEY API Key Author: Philipp Grosswiler , Aaron W. Swenson ' From 724f3aa301da65a0a8ce472b78d88e8e99ca30d0 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Wed, 6 Nov 2024 16:18:21 -0300 Subject: [PATCH 513/687] rename variable, undo accidental revert from dev --- dnsapi/dns_linode_v4.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index e2f06420..a4cec0b3 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -4,7 +4,7 @@ dns_linode_v4_info='Linode.com Site: Linode.com Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_linode_v4 Options: - LINODE_V4_API_KEY API Key + LINODE_V4_API_KEY API Key Author: Philipp Grosswiler , Aaron W. Swenson ' @@ -138,24 +138,25 @@ _get_root() { while true; do # loop through the received string (e.g. _acme-challenge.sub3.sub2.sub1.domain.tld), # starting from the lowest subdomain, and check if it's a hosted domain - h=$(printf "%s" "$full_host_str" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then + tst_hosted_domain=$(printf "%s" "$full_host_str" | cut -d . -f "$i"-100) + _debug tst_hosted_domain "$tst_hosted_domain" + if [ -z "$tst_hosted_domain" ]; then #not valid + _err "Couldn't get domain from string '$full_host_str'." return 1 fi - _debug "Querying Linode APIv4 for hosted zone: $h" - if _H4="X-Filter: {\"domain\":\"$h\"}" _rest GET; then + _debug "Querying Linode APIv4 for hosted zone: $tst_hosted_domain" + if _H4="X-Filter: {\"domain\":\"$tst_hosted_domain\"}" _rest GET; then _debug "Got response from API: $response" response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" - hostedzone="$(echo "$response" | _egrep_o "\{.*\"domain\": *\"$h\".*}")" + hostedzone="$(echo "$response" | _egrep_o "\{.*\"domain\": *\"$tst_hosted_domain\".*}")" if [ "$hostedzone" ]; then _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) - _debug "Found domain hosted on Linode DNS. Zone: $h, id: $_domain_id" + _debug "Found domain hosted on Linode DNS. Zone: $tst_hosted_domain, id: $_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$full_host_str" | cut -d . -f 1-$p) - _domain=$h + _sub_domain=$(printf "%s" "$full_host_str" | cut -d . -f 1-"$p") + _domain=$tst_hosted_domain return 0 fi return 1 From 7b63ebfcaa8e59d6099953de14b0c20e0be722e2 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Thu, 7 Nov 2024 12:33:56 -0300 Subject: [PATCH 514/687] fix random failures due to unnecessary headers on requests was unintendedly replaying the save _H4 header on all requests, what was causing random failures on responses from the API. --- dnsapi/dns_linode_v4.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index a4cec0b3..fc59c342 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -192,6 +192,10 @@ _rest() { response="$(_get "$LINODE_V4_API_URL$ep$data")" fi + # unset _H4, for it not to be used on every request unnecessarily, because it + # causes random failures inside Linode API when using unnecessary _H4 parameters (e.g. X-Filter) + unset _H4 + if [ "$?" != "0" ]; then _err "error $ep" return 1 From 4f96a2a6679a7093ef36b8746431d32dcd5e2253 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Thu, 7 Nov 2024 17:36:25 -0300 Subject: [PATCH 515/687] remove unnecessary variable 'export' on variable _H4 --- dnsapi/dns_linode_v4.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index fc59c342..20c32ad1 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -182,7 +182,6 @@ _rest() { export _H1="Accept: application/json" export _H2="Content-Type: application/json" export _H3="Authorization: Bearer $LINODE_V4_API_KEY" - export _H4 # used to query for the root domain on _get_root() if [ "$mtd" != "GET" ]; then # both POST and DELETE. @@ -192,10 +191,6 @@ _rest() { response="$(_get "$LINODE_V4_API_URL$ep$data")" fi - # unset _H4, for it not to be used on every request unnecessarily, because it - # causes random failures inside Linode API when using unnecessary _H4 parameters (e.g. X-Filter) - unset _H4 - if [ "$?" != "0" ]; then _err "error $ep" return 1 From d3cf3f7a5c672a78f7b82b024f176a5deb25c1b2 Mon Sep 17 00:00:00 2001 From: Vinicius Mello Date: Fri, 8 Nov 2024 00:59:21 -0300 Subject: [PATCH 516/687] fix pagination bug for domains with a big zone file the same pagination bug that happens for accounts with a large number of domains also happens for DNS zones with a large number of records. The previous code assumes that all records are returned in a single page. Changed the code to do an exact match search so that it returns only the few required records and never paginates replies. --- dnsapi/dns_linode_v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode_v4.sh b/dnsapi/dns_linode_v4.sh index 20c32ad1..3c6997a0 100755 --- a/dnsapi/dns_linode_v4.sh +++ b/dnsapi/dns_linode_v4.sh @@ -76,7 +76,7 @@ dns_linode_v4_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then + if _H4="X-Filter: { \"type\": \"TXT\", \"name\": \"$_sub_domain\" }" _rest GET "/$_domain_id/records" && [ -n "$response" ]; then response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")" resource="$(echo "$response" | _egrep_o "\{.*\"name\": *\"$_sub_domain\".*}")" From 1a43c81840fc9ca8a386fa3677ea530a3f5f80a3 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sat, 9 Nov 2024 17:24:22 +0200 Subject: [PATCH 517/687] dnsapi omg.lol: fix info Description "Based on the omg.lol API" is useless for users so removed. The link to api moved to comment bellow. Domains: omg.lol is unnecessary because the DNS provider name is anyway omg.lol. Site: changed to point to the https://omg.lol site. Issues: put a link to the support issue. Remove the useless "Please Read this guide first" comment. Fix typos. Signed-off-by: Sergey Ponomarev --- dnsapi/dns_omglol.sh | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_omglol.sh b/dnsapi/dns_omglol.sh index b6c06aee..5c137c3f 100644 --- a/dnsapi/dns_omglol.sh +++ b/dnsapi/dns_omglol.sh @@ -1,23 +1,19 @@ #!/usr/bin/env sh # shellcheck disable=SC2034 -dns_myapi_info='omg.lol - Based on the omg.lol API, defined at https://api.omg.lol/ -Domains: omg.lol -Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide -Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +dns_omglol_info='omg.lol +Site: omg.lol +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_omglol Options: - OMG_ApiKey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account + OMG_ApiKey API Key from omg.lol. This is accessible from the bottom of the account page at https://home.omg.lol/account OMG_Address This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard -Issues: github.com/acmesh-official/acme.sh +Issues: github.com/acmesh-official/acme.sh/issues/5299 Author: @Kholin ' -#returns 0 means success, otherwise error. +# See API Docs https://api.omg.lol/ ######## Public functions ##################### -# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide - #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_omglol_add() { fulldomain=$1 @@ -244,8 +240,8 @@ omg_delete() { omg_validate_delete "$output" } -# Validate the response on request to delete. Confirm stastus is success and -# Message indicates deletion was successful +# Validate the response on request to delete. +# Confirm status is success and message indicates deletion was successful. # Input: Response - HTTP response received from delete request omg_validate_delete() { response=$1 From 4f17bc0d864180467a74917a11f88292bea3a60f Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sat, 9 Nov 2024 18:05:28 +0200 Subject: [PATCH 518/687] dnsapi timeweb: Use structured info Signed-off-by: Sergey Ponomarev --- dnsapi/dns_timeweb.sh | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_timeweb.sh b/dnsapi/dns_timeweb.sh index 9860872c..544564ea 100644 --- a/dnsapi/dns_timeweb.sh +++ b/dnsapi/dns_timeweb.sh @@ -1,16 +1,13 @@ #!/usr/bin/env sh - -# acme.sh DNS API for Timeweb Cloud provider (https://timeweb.cloud). -# -# Author: https://github.com/nikolaypronchev. -# -# Prerequisites: -# Timeweb Cloud API JWT token. Obtain one from the Timeweb Cloud control panel -# ("API and Terraform" section: https://timeweb.cloud/my/api-keys). The JWT token -# must be provided to this script in one of two ways: -# 1. As the "TW_Token" variable, for example: "export TW_Token=eyJhbG...zUxMiIs"; -# 2. As a "TW_Token" config entry in acme.sh account config file -# (usually located at ~/.acme.sh/account.conf by default). +# shellcheck disable=SC2034 +dns_timeweb_info='Timeweb.Cloud +Site: Timeweb.Cloud +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_timeweb +Options: + TW_Token API JWT token. Get it from the control panel at https://timeweb.cloud/my/api-keys +Issues: github.com/acmesh-official/acme.sh/issues/5140 +Author: Nikolay Pronchev +' TW_Api="https://api.timeweb.cloud/api/v1" From fe8ad3548bd64a0c17887b2f45f37dc085c978ef Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sat, 9 Nov 2024 18:22:01 +0200 Subject: [PATCH 519/687] dnsapi alviy: Use structured info Signed-off-by: Sergey Ponomarev --- dnsapi/dns_alviy.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_alviy.sh b/dnsapi/dns_alviy.sh index 2217b0df..8aa7da34 100644 --- a/dnsapi/dns_alviy.sh +++ b/dnsapi/dns_alviy.sh @@ -1,11 +1,12 @@ #!/usr/bin/env sh -# Alviy domain api -# -# Get API key and secret from https://cloud.alviy.com/token -# -# Alviy_token="some-secret-key" -# -# Ex.: acme.sh --issue --staging --dns dns_alviy -d "*.s.example.com" -d "s.example.com" +# shellcheck disable=SC2034 +dns_alviy_info='Alviy.com +Site: Alviy.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_alviy +Options: + Alviy_token API token. Get it from the https://cloud.alviy.com/token +Issues: github.com/acmesh-official/acme.sh/issues/5115 +' Alviy_Api="https://cloud.alviy.com/api/v1" From 8bf9482bc094baa6d1bf52d4cf5aa6dad9852755 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sat, 9 Nov 2024 18:31:52 +0200 Subject: [PATCH 520/687] dnsapi ionos_cloud: Use structured info Signed-off-by: Sergey Ponomarev --- dnsapi/dns_ionos_cloud.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_ionos_cloud.sh b/dnsapi/dns_ionos_cloud.sh index fa229e03..f255092f 100644 --- a/dnsapi/dns_ionos_cloud.sh +++ b/dnsapi/dns_ionos_cloud.sh @@ -1,12 +1,14 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_ionos_cloud_info='IONOS Cloud DNS +Site: ionos.com +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ionos_cloud +Options: + IONOS_TOKEN API Token. +Issues: github.com/acmesh-official/acme.sh/issues/5243 +' # Supports IONOS Cloud DNS API v1.15.4 -# -# Usage: -# Export IONOS_TOKEN before calling acme.sh: -# $ export IONOS_TOKEN="..." -# -# $ acme.sh --issue --dns dns_ionos_cloud ... IONOS_CLOUD_API="https://dns.de-fra.ionos.com" IONOS_CLOUD_ROUTE_ZONES="/zones" From 2c67934191a9a382b1c8f6397551042dcc0f033c Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sat, 9 Nov 2024 23:29:52 +0100 Subject: [PATCH 521/687] fix(truenas): builtin service deprecation --- deploy/truenas.sh | 140 +++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index c79e6dac..7f6a8ec8 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -9,7 +9,7 @@ # # Following environment variables must be set: # -# export DEPLOY_TRUENAS_APIKEY=" Date: Sun, 10 Nov 2024 00:13:53 +0100 Subject: [PATCH 522/687] fix: verify truenas os version --- deploy/truenas.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 7f6a8ec8..c98b51ab 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -66,8 +66,17 @@ truenas_deploy() { _info "Getting TrueNAS version" _response=$(_get "$_api_url/system/version") - _info "TrueNAS system version: $_response" - _truenas_version=$(echo "$_response" | cut -d '-' -f 3) + + if [[ "$_response" == *"SCALE"* ]]; then + _truenas_os=$(echo "$_response" | cut -d '-' -f 2) + _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"') + else + _truenas_os="unknown" + _truenas_version="unknown" + fi + + _info "Detected TrueNAS system os: $_truenas_os" + _info "Detected TrueNAS system version: $_truenas_version" if [ -z "$_response" ]; then _err "Unable to authenticate to $_api_url." @@ -123,7 +132,7 @@ truenas_deploy() { _truenas_version_23_10="23.10.0.0" _truenas_version_24_10="24.10.0.0" - if [ "$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_23_10" ]; then + if [[ "$_truenas_os" != "SCALE" || "$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_23_10" ]]; then _info "Checking if WebDAV certificate is the same as the TrueNAS web UI" _webdav_list=$(_get "$_api_url/webdav") _webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,') @@ -171,7 +180,7 @@ truenas_deploy() { fi fi - if [ "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]; then + if [[ "$_truenas_os" != "SCALE" || "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]]; then _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then _info "Query all chart release" From 34c8b882c63edbf40251f1705c7edc34c371c560 Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sun, 10 Nov 2024 00:34:26 +0100 Subject: [PATCH 523/687] fix: helm chart seems available only on truenas scale Signed-off-by: Ludovic Ortega --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index c98b51ab..5cc108b3 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -180,7 +180,7 @@ truenas_deploy() { fi fi - if [[ "$_truenas_os" != "SCALE" || "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]]; then + if [[ "$_truenas_os" == "SCALE" || "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]]; then _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then _info "Query all chart release" From 64a1e889824f40fcef29503c6d8f0b44f9cdbf0c Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sun, 10 Nov 2024 02:41:38 +0100 Subject: [PATCH 524/687] feat: add support for docker apps Signed-off-by: Ludovic Ortega --- deploy/truenas.sh | 64 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 5cc108b3..75cece6d 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -180,26 +180,52 @@ truenas_deploy() { fi fi - if [[ "$_truenas_os" == "SCALE" || "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]]; then - _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" - if _exists jq; then - _info "Query all chart release" - _release_list=$(_get "$_api_url/chart/release") - _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") - _release_length=$(printf "%s" "$_related_name_list" | jq -r "length") - _info "Found $_release_length related chart release in list: $_related_name_list" - for i in $(seq 0 $((_release_length - 1))); do - _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") - _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" - #Read the chart release configuration - _chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")") - #Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress - _updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ") - _update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")" - _debug3 _update_chart_result "$_update_chart_result" - done + if [ "$_truenas_os" == "SCALE" ]; then + if [ "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]; then + _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" + if _exists jq; then + _info "Query all chart release" + _release_list=$(_get "$_api_url/chart/release") + _related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique") + _release_length=$(printf "%s" "$_related_name_list" | jq -r "length") + _info "Found $_release_length related chart release in list: $_related_name_list" + for i in $(seq 0 $((_release_length - 1))); do + _release_name=$(echo "$_related_name_list" | jq -r ".[$i]") + _info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name" + #Read the chart release configuration + _chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")") + #Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress + _updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ") + _update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")" + _debug3 _update_chart_result "$_update_chart_result" + done + else + _info "Tool 'jq' does not exists, skip chart release checking" + fi else - _info "Tool 'jq' does not exists, skip chart release checking" + _info "Checking if any app is using the same certificate as TrueNAS web UI. Tool 'jq' is required" + if _exists jq; then + _info "Query all apps" + _app_list=$(_get "$_api_url/app") + _app_id_list=$(printf "%s" "$_app_list" | jq -r '.[].name') + _app_length=$(echo "$_app_id_list" | wc -l) + _info "Found $_app_length apps" + _info "Checking for each app if an update is needed" + for i in $(seq 1 $_app_length); do + _app_id=$(echo "$_app_id_list" | sed -n "${i}p") + _app_config="$(_post "\"$_app_id\"" "$_api_url/app/config" "" "POST" "application/json")" + # Check if the app use the same certificate TrueNAS web UI + _app_active_cert_config=$(echo "$_app_config" | _json_decode | jq -r ".ix_certificates[\"$_active_cert_id\"]") + if [[ "$_app_active_cert_config" != "null" ]]; then + _info "Updating certificate from $_active_cert_id to $_cert_id for app: $_app_id" + #Replace the old certificate id with the new one in path + _update_app_result="$(_post "{\"values\" : { \"network\": { \"certificate_id\": $_cert_id } } }" "$_api_url/app/id/$_app_id" "" "PUT" "application/json")" + _debug3 _update_app_result "$_update_app_result" + fi + done + else + _info "Tool 'jq' does not exists, skip chart release checking" + fi fi fi From 21b966c8e6a4fd08079aff7fa52d677e78b6381b Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sun, 10 Nov 2024 02:56:40 +0100 Subject: [PATCH 525/687] fix: don't check for subversion that can lead to error Signed-off-by: Ludovic Ortega --- deploy/truenas.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 75cece6d..944ba240 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -69,7 +69,7 @@ truenas_deploy() { if [[ "$_response" == *"SCALE"* ]]; then _truenas_os=$(echo "$_response" | cut -d '-' -f 2) - _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"') + _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"' | cut -d '.' -f 1,2) else _truenas_os="unknown" _truenas_version="unknown" @@ -129,8 +129,8 @@ truenas_deploy() { _debug3 _activate_result "$_activate_result" - _truenas_version_23_10="23.10.0.0" - _truenas_version_24_10="24.10.0.0" + _truenas_version_23_10="23.10" + _truenas_version_24_10="24.10" if [[ "$_truenas_os" != "SCALE" || "$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_23_10" ]]; then _info "Checking if WebDAV certificate is the same as the TrueNAS web UI" From b6a77e0231923ab13a31c00c73e2727ec2adb070 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:12:38 +1300 Subject: [PATCH 526/687] Ruckus - use _get() and _post() --- deploy/ruckus.sh | 134 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 35 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index d16f40e4..cbd5e353 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -1,9 +1,8 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh -# Here is a script to deploy cert to Ruckus Zone Director/Unleashed. -# -# Adapted from: -# https://ms264556.net/pages/PfSenseLetsEncryptToRuckus +# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed. +# +# Public domain, 2024, Tony Rielly # # ```sh # acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus @@ -13,11 +12,11 @@ # deploy script to work. # # ```sh -# export RUCKUS_HOST=ruckus.example.com +# export RUCKUS_HOST=myruckus.example.com # export RUCKUS_USER=myruckususername # export RUCKUS_PASS=myruckuspassword # -# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus +# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus # ``` # # returns 0 means success, otherwise error. @@ -66,45 +65,110 @@ ruckus_deploy() { _debug RUCKUS_USER "$RUCKUS_USER" _debug RUCKUS_PASS "$RUCKUS_PASS" - COOKIE_JAR=$(mktemp) - cleanup() { - rm $COOKIE_JAR - } - trap cleanup EXIT - - LOGIN_URL=$(curl https://$RUCKUS_HOST -ksSLo /dev/null -w '%{url_effective}') - _debug LOGIN_URL "$LOGIN_URL" - - XSS=$(curl -ksSic $COOKIE_JAR $LOGIN_URL -d username=$RUCKUS_USER -d password="$RUCKUS_PASS" -d ok='Log In' | awk '/^HTTP_X_CSRF_TOKEN:/ { print $2 }' | tr -d '\040\011\012\015') - _debug XSS "$XSS" + export HTTPS_INSECURE=1 + export ACME_HTTP_NO_REDIRECTS=1 + + _info Discovering the login URL + _get "https://$RUCKUS_HOST" >/dev/null + _login_url="$(_response_header 'Location')" + if [ -n "$_login_url" ]; then + _login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||') + if [ -z "$_login_path" ]; then + # redirect was to a different host + _get "$_login_url" >/dev/null + _login_url="$(_response_header 'Location')" + fi + fi - if [ -n "$XSS" ]; then - _info "Authentication successful" - else - _err "Authentication failed" + if [ -z "${_login_url}" ]; then + _err "Connection failed: couldn't find login page." return 1 fi + + _base_url=$(dirname "$_login_url") + _login_page=$(basename "$_login_url") - BASE_URL=$(dirname $LOGIN_URL) - CONF_ARGS="-ksSo /dev/null -b $COOKIE_JAR -c $COOKIE_JAR" - UPLOAD="$CONF_ARGS $BASE_URL/_upload.jsp?request_type=xhr" - CMD="$CONF_ARGS $BASE_URL/_cmdstat.jsp" + if [ "$_login_page" = "index.html" ]; then + _err "Connection temporarily unavailable: Unleashed Rebuilding." + return 1 + fi - REPLACE_CERT_AJAX='' - CERT_REBOOT_AJAX='' + if [ "$_login_page" = "wizard.jsp" ]; then + _err "Connection failed: Setup Wizard not complete." + return 1 + fi + + _info Login + _username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)" + _password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)" + _login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")" + _post "$_login_query" "$_login_url" >/dev/null + + _login_code="$(_response_code)" + if [ "$_login_code" = "200" ]; then + _err "Login failed: incorrect credentials." + return 1 + fi + + _info Collect Session Cookie + _H1="Cookie: $(_response_cookie)" + export _H1 + _info Collect CSRF Token + _H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')" + export _H2 _info "Uploading certificate" - curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ccert" -F action=uploadcert -F callback=uploader_uploadcert || return 1 - + _post_upload "uploadcert" "$_cfullchain" + _info "Uploading private key" - curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ckey" -F action=uploadprivatekey -F callback=uploader_uploadprivatekey || return 1 + _post_upload "uploadprivatekey" "$_ckey" _info "Replacing certificate" - curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$REPLACE_CERT_AJAX" || return 1 + _replace_cert_ajax='' + _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null + + info "Rebooting" + _cert_reboot_ajax='' + _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null + + return 0 +} + +_response_code() { + < "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" +} - _info "Rebooting" - curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$CERT_REBOOT_AJAX" || return 1 +_response_header() { + < "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " +} - return 0 +_response_cookie() { + _response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//' } +_post_upload() { + _post_action="$1" + _post_file="$2" + _post_url="$3" + + _post_boundary="----FormBoundary$(date "+%s%N")" + + _post_data="$({ + printf -- "--%s\r\n" "$_post_boundary" + printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action" + printf -- "Content-Type: application/octet-stream\r\n\r\n" + printf -- "%s\r\n" "$(cat "$_post_file")" + + printf -- "--%s\r\n" "$_post_boundary" + printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n" + printf -- "%s\r\n" "$_post_action" + + printf -- "--%s\r\n" "$_post_boundary" + printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n" + printf -- "%s\r\n" "uploader_$_post_action" + + printf -- "--%s--\r\n\r\n" "$_post_boundary" + })" + + _post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null +} From 717802611afb4d3e36c2aa2796b013355a0643f7 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:43:57 +1300 Subject: [PATCH 527/687] remove dead code --- deploy/ruckus.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index cbd5e353..def8197d 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -149,8 +149,7 @@ _response_cookie() { _post_upload() { _post_action="$1" _post_file="$2" - _post_url="$3" - + _post_boundary="----FormBoundary$(date "+%s%N")" _post_data="$({ From e8a453c567be8c5f77f8cdee69fadf1901425761 Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sun, 10 Nov 2024 13:21:09 +0100 Subject: [PATCH 528/687] fix: lint Signed-off-by: Ludovic Ortega --- deploy/truenas.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 944ba240..d53a5514 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -67,14 +67,14 @@ truenas_deploy() { _info "Getting TrueNAS version" _response=$(_get "$_api_url/system/version") - if [[ "$_response" == *"SCALE"* ]]; then - _truenas_os=$(echo "$_response" | cut -d '-' -f 2) - _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"' | cut -d '.' -f 1,2) + if [[ "$_response" = *"SCALE"* ]]; then + _truenas_os=$(echo "$_response" | cut -d '-' -f 2) + _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"' | cut -d '.' -f 1,2) else _truenas_os="unknown" _truenas_version="unknown" fi - + _info "Detected TrueNAS system os: $_truenas_os" _info "Detected TrueNAS system version: $_truenas_version" @@ -132,7 +132,8 @@ truenas_deploy() { _truenas_version_23_10="23.10" _truenas_version_24_10="24.10" - if [[ "$_truenas_os" != "SCALE" || "$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_23_10" ]]; then + _check_version=$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1) + if [ "$_truenas_os" != "SCALE" ] || [ "$_check_version" != "$_truenas_version_23_10" ]; then _info "Checking if WebDAV certificate is the same as the TrueNAS web UI" _webdav_list=$(_get "$_api_url/webdav") _webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,') @@ -180,8 +181,9 @@ truenas_deploy() { fi fi - if [ "$_truenas_os" == "SCALE" ]; then - if [ "$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1)" != "$_truenas_version_24_10" ]; then + if [ "$_truenas_os" = "SCALE" ]; then + _check_version=$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1) + if [ "$_check_version" != "$_truenas_version_24_10" ]; then _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then _info "Query all chart release" @@ -211,12 +213,12 @@ truenas_deploy() { _app_length=$(echo "$_app_id_list" | wc -l) _info "Found $_app_length apps" _info "Checking for each app if an update is needed" - for i in $(seq 1 $_app_length); do + for i in $(seq 1 "$_app_length"); do _app_id=$(echo "$_app_id_list" | sed -n "${i}p") _app_config="$(_post "\"$_app_id\"" "$_api_url/app/config" "" "POST" "application/json")" # Check if the app use the same certificate TrueNAS web UI _app_active_cert_config=$(echo "$_app_config" | _json_decode | jq -r ".ix_certificates[\"$_active_cert_id\"]") - if [[ "$_app_active_cert_config" != "null" ]]; then + if [ "$_app_active_cert_config" != "null" ]; then _info "Updating certificate from $_active_cert_id to $_cert_id for app: $_app_id" #Replace the old certificate id with the new one in path _update_app_result="$(_post "{\"values\" : { \"network\": { \"certificate_id\": $_cert_id } } }" "$_api_url/app/id/$_app_id" "" "PUT" "application/json")" From 08807b498ed7b382b503741de0c04aa38fea3176 Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Sun, 10 Nov 2024 13:30:18 +0100 Subject: [PATCH 529/687] fix: bad copy/paste Signed-off-by: Ludovic Ortega --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index d53a5514..4b0f17f4 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -226,7 +226,7 @@ truenas_deploy() { fi done else - _info "Tool 'jq' does not exists, skip chart release checking" + _info "Tool 'jq' does not exists, skip app checking" fi fi fi From 1bfd4672e1ca68670a362cfe78a8df78d2f3b52c Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Tue, 12 Nov 2024 22:10:34 +0100 Subject: [PATCH 530/687] fix: remove double square brackets --- deploy/truenas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index 4b0f17f4..a425cff2 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -67,7 +67,7 @@ truenas_deploy() { _info "Getting TrueNAS version" _response=$(_get "$_api_url/system/version") - if [[ "$_response" = *"SCALE"* ]]; then + if echo "$_response" | grep -q "SCALE"; then _truenas_os=$(echo "$_response" | cut -d '-' -f 2) _truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"' | cut -d '.' -f 1,2) else From 2229bcc98b9a00b938f612951b8ba1d3199f128e Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Tue, 12 Nov 2024 22:15:44 +0100 Subject: [PATCH 531/687] fix: echo flag --- deploy/truenas.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/truenas.sh b/deploy/truenas.sh index a425cff2..407395a3 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -132,7 +132,7 @@ truenas_deploy() { _truenas_version_23_10="23.10" _truenas_version_24_10="24.10" - _check_version=$(echo -e "$_truenas_version_23_10\n$_truenas_version" | sort -V | head -n 1) + _check_version=$(printf "%s\n%s" "$_truenas_version_23_10" "$_truenas_version" | sort -V | head -n 1) if [ "$_truenas_os" != "SCALE" ] || [ "$_check_version" != "$_truenas_version_23_10" ]; then _info "Checking if WebDAV certificate is the same as the TrueNAS web UI" _webdav_list=$(_get "$_api_url/webdav") @@ -182,7 +182,7 @@ truenas_deploy() { fi if [ "$_truenas_os" = "SCALE" ]; then - _check_version=$(echo -e "$_truenas_version_24_10\n$_truenas_version" | sort -V | head -n 1) + _check_version=$(printf "%s\n%s" "$_truenas_version_24_10" "$_truenas_version" | sort -V | head -n 1) if [ "$_check_version" != "$_truenas_version_24_10" ]; then _info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required" if _exists jq; then From 0cc74b7cfe910d6961cd225e70dfaba884a418b4 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:50:51 +1300 Subject: [PATCH 532/687] fix insecure password debug and _info typo --- deploy/ruckus.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index def8197d..d83675bb 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -63,7 +63,7 @@ ruckus_deploy() { _debug RUCKUS_HOST "$RUCKUS_HOST" _debug RUCKUS_USER "$RUCKUS_USER" - _debug RUCKUS_PASS "$RUCKUS_PASS" + _secure_debug RUCKUS_PASS "$RUCKUS_PASS" export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 @@ -127,7 +127,7 @@ ruckus_deploy() { _replace_cert_ajax='' _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - info "Rebooting" + _info "Rebooting" _cert_reboot_ajax='' _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null From 9c25365b1222ad944f585d043f888f6dbd7f0b0d Mon Sep 17 00:00:00 2001 From: Sergey Parfenov Date: Tue, 12 Nov 2024 01:20:39 +0300 Subject: [PATCH 533/687] Add swanctl support --- deploy/strongswan.sh | 111 ++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 34 deletions(-) diff --git a/deploy/strongswan.sh b/deploy/strongswan.sh index 3d5f1b34..14567d17 100644 --- a/deploy/strongswan.sh +++ b/deploy/strongswan.sh @@ -10,46 +10,89 @@ #domain keyfile certfile cafile fullchain strongswan_deploy() { - _cdomain="$1" - _ckey="$2" - _ccert="$3" - _cca="$4" - _cfullchain="$5" - + _cdomain="${1}" + _ckey="${2}" + _ccert="${3}" + _cca="${4}" + _cfullchain="${5}" _info "Using strongswan" - - if [ -x /usr/sbin/ipsec ]; then - _ipsec=/usr/sbin/ipsec - elif [ -x /usr/sbin/strongswan ]; then - _ipsec=/usr/sbin/strongswan - elif [ -x /usr/local/sbin/ipsec ]; then - _ipsec=/usr/local/sbin/ipsec - else + if _exists ipsec; then + _ipsec=ipsec + elif _exists strongswan; then + _ipsec=strongswan + fi + if _exists swanctl; then + _swanctl=swanctl + fi + # For legacy stroke mode + if [ -n "${_ipsec}" ]; then + _info "${_ipsec} command detected" + _confdir=$(${_ipsec} --confdir) + if [ -z "${_confdir}" ]; then + _err "no strongswan --confdir is detected" + return 1 + fi + _info _confdir "${_confdir}" + __deploy_cert "$@" "stroke" "${_confdir}" + ${_ipsec} reload + fi + # For modern vici mode + if [ -n "${_swanctl}" ]; then + _info "${_swanctl} command detected" + for _dir in /usr/local/etc/swanctl /etc/swanctl /etc/strongswan/swanctl; do + if [ -d ${_dir} ]; then + _confdir=${_dir} + _info _confdir "${_confdir}" + break + fi + done + if [ -z "${_confdir}" ]; then + _err "no swanctl config dir is found" + return 1 + fi + __deploy_cert "$@" "vici" "${_confdir}" + ${_swanctl} --load-creds + fi + if [ -z "${_swanctl}" ] && [ -z "${_ipsec}" ]; then _err "no strongswan or ipsec command is detected" + _err "no swanctl is detected" return 1 fi +} - _info _ipsec "$_ipsec" +#################### Private functions below ################################## - _confdir=$($_ipsec --confdir) - if [ $? -ne 0 ] || [ -z "$_confdir" ]; then - _err "no strongswan --confdir is detected" +__deploy_cert() { + _cdomain="${1}" + _ckey="${2}" + _ccert="${3}" + _cca="${4}" + _cfullchain="${5}" + _swan_mode="${6}" + _confdir="${7}" + _debug _cdomain "${_cdomain}" + _debug _ckey "${_ckey}" + _debug _ccert "${_ccert}" + _debug _cca "${_cca}" + _debug _cfullchain "${_cfullchain}" + _debug _swan_mode "${_swan_mode}" + _debug _confdir "${_confdir}" + if [ "${_swan_mode}" = "vici" ]; then + _dir_private="private" + _dir_cert="x509" + _dir_ca="x509ca" + elif [ "${_swan_mode}" = "stroke" ]; then + _dir_private="ipsec.d/private" + _dir_cert="ipsec.d/certs" + _dir_ca="ipsec.d/cacerts" + else + _err "unknown StrongSwan mode ${_swan_mode}" return 1 fi - - _info _confdir "$_confdir" - - _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" - _debug _ccert "$_ccert" - _debug _cca "$_cca" - _debug _cfullchain "$_cfullchain" - - cat "$_ckey" >"${_confdir}/ipsec.d/private/$(basename "$_ckey")" - cat "$_ccert" >"${_confdir}/ipsec.d/certs/$(basename "$_ccert")" - cat "$_cca" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cca")" - cat "$_cfullchain" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cfullchain")" - - $_ipsec reload - + cat "${_ckey}" >"${_confdir}/${_dir_private}/$(basename "${_ckey}")" + cat "${_ccert}" >"${_confdir}/${_dir_cert}/$(basename "${_ccert}")" + cat "${_cca}" >"${_confdir}/${_dir_ca}/$(basename "${_cca}")" + if [ "${_swan_mode}" = "stroke" ]; then + cat "${_cfullchain}" >"${_confdir}/${_dir_ca}/$(basename "${_cfullchain}")" + fi } From e98e7a232ffa70d37bc4af6260e754a5a5060b98 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:27:36 +1300 Subject: [PATCH 534/687] Fix info logging --- deploy/ruckus.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index d83675bb..3b147c25 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -68,7 +68,7 @@ ruckus_deploy() { export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 - _info Discovering the login URL + _info "Discovering the login URL" _get "https://$RUCKUS_HOST" >/dev/null _login_url="$(_response_header 'Location')" if [ -n "$_login_url" ]; then @@ -98,7 +98,7 @@ ruckus_deploy() { return 1 fi - _info Login + _info "Login" _username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)" _password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)" _login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")" @@ -110,10 +110,10 @@ ruckus_deploy() { return 1 fi - _info Collect Session Cookie + _info "Collect Session Cookie" _H1="Cookie: $(_response_cookie)" export _H1 - _info Collect CSRF Token + _info "Collect CSRF Token" _H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')" export _H2 From 38c41b72d6acc0edfe6d7a1fa072fe16a1505ff5 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:16:38 +1300 Subject: [PATCH 535/687] fix acme.sh PR shfmt failure --- deploy/ruckus.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index 3b147c25..b4249472 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh # Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed. -# +# # Public domain, 2024, Tony Rielly # # ```sh @@ -84,20 +84,20 @@ ruckus_deploy() { _err "Connection failed: couldn't find login page." return 1 fi - + _base_url=$(dirname "$_login_url") _login_page=$(basename "$_login_url") - if [ "$_login_page" = "index.html" ]; then + if [ "$_login_page" = "index.html" ]; then _err "Connection temporarily unavailable: Unleashed Rebuilding." return 1 fi - if [ "$_login_page" = "wizard.jsp" ]; then + if [ "$_login_page" = "wizard.jsp" ]; then _err "Connection failed: Setup Wizard not complete." return 1 fi - + _info "Login" _username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)" _password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)" @@ -109,7 +109,7 @@ ruckus_deploy() { _err "Login failed: incorrect credentials." return 1 fi - + _info "Collect Session Cookie" _H1="Cookie: $(_response_cookie)" export _H1 @@ -119,27 +119,27 @@ ruckus_deploy() { _info "Uploading certificate" _post_upload "uploadcert" "$_cfullchain" - + _info "Uploading private key" _post_upload "uploadprivatekey" "$_ckey" _info "Replacing certificate" _replace_cert_ajax='' _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - + _info "Rebooting" _cert_reboot_ajax='' _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - + return 0 } _response_code() { - < "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" + _egrep_o <"$HTTP_HEADER" "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" } _response_header() { - < "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " + grep <"$HTTP_HEADER" -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " } _response_cookie() { @@ -149,9 +149,9 @@ _response_cookie() { _post_upload() { _post_action="$1" _post_file="$2" - + _post_boundary="----FormBoundary$(date "+%s%N")" - + _post_data="$({ printf -- "--%s\r\n" "$_post_boundary" printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action" From 2bb5fbdee549f6f1baacd2e7cc3cd8f1a4c4fc48 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:21:19 +1300 Subject: [PATCH 536/687] Remove HTTPS_INSECURE --- deploy/ruckus.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index b4249472..1bfa6bd6 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -65,7 +65,6 @@ ruckus_deploy() { _debug RUCKUS_USER "$RUCKUS_USER" _secure_debug RUCKUS_PASS "$RUCKUS_PASS" - export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 _info "Discovering the login URL" From 0c2d7b9c06a648e31a5bd7c93436088ab8a0ca83 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 14 Nov 2024 20:03:22 +0100 Subject: [PATCH 537/687] fix for latest omnios-r151052 --- acme.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 2eea666a..a55ee41c 100755 --- a/acme.sh +++ b/acme.sh @@ -1811,7 +1811,11 @@ _date2time() { return fi #Omnios - if da="$(echo "$1" | tr -d "Z" | tr "T" ' ')" perl -MTime::Piece -e 'print Time::Piece->strptime($ENV{da}, "%Y-%m-%d %H:%M:%S")->epoch, "\n";' 2>/dev/null; then + if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%d %H:%M:%S\").timestamp()))" 2>/dev/null; then + return + fi + #Omnios + if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%dT%H:%M:%SZ\").timestamp()))" 2>/dev/null; then return fi _err "Cannot parse _date2time $1" From 709f1e76d3ea77f3415e8bdca5d13ae4532c0e7e Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 14 Nov 2024 20:17:03 +0100 Subject: [PATCH 538/687] fix for omnios-r151052 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index a55ee41c..2791325d 100755 --- a/acme.sh +++ b/acme.sh @@ -1811,11 +1811,11 @@ _date2time() { return fi #Omnios - if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%d %H:%M:%S\").timestamp()))" 2>/dev/null; then + if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%d %H:%M:%S\").replace(tzinfo=datetime.timezone.utc).timestamp()))" 2>/dev/null; then return fi #Omnios - if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%dT%H:%M:%SZ\").timestamp()))" 2>/dev/null; then + if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%dT%H:%M:%SZ\").replace(tzinfo=datetime.timezone.utc).timestamp()))" 2>/dev/null; then return fi _err "Cannot parse _date2time $1" From 4e0686f73cf89d29d19cd24d46386b770d194bbb Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 14 Nov 2024 20:35:15 +0100 Subject: [PATCH 539/687] fix for omnios-r151052 --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index 2791325d..9842e3f1 100755 --- a/acme.sh +++ b/acme.sh @@ -1628,6 +1628,11 @@ _time2str() { return fi + #Omnios + if date -u -r "$1" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null; then + return + fi + #Solaris if printf "%(%Y-%m-%dT%H:%M:%SZ)T\n" $1 2>/dev/null; then return From 4232923641479da186a21009cd1aae9617801da4 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:39:41 +1300 Subject: [PATCH 540/687] Remove awk usage and refuse redirect to new host --- deploy/ruckus.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index 1bfa6bd6..f62e2fc0 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -74,8 +74,8 @@ ruckus_deploy() { _login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||') if [ -z "$_login_path" ]; then # redirect was to a different host - _get "$_login_url" >/dev/null - _login_url="$(_response_header 'Location')" + _err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface." + return 1 fi fi @@ -142,7 +142,7 @@ _response_header() { } _response_cookie() { - _response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//' + _response_header 'Set-Cookie' | sed 's/;.*//' } _post_upload() { From 413a91646c03b0cd4ab6dace1bdabe78d702a710 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Sat, 16 Nov 2024 19:15:39 +0100 Subject: [PATCH 541/687] Create truenas_ws.sh --- deploy/truenas_ws.sh | 317 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 deploy/truenas_ws.sh diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh new file mode 100644 index 00000000..b5ba51ab --- /dev/null +++ b/deploy/truenas_ws.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash + +# TrueNAS deploy script for SCALE/CORE using websocket +# It is recommend to use a wildcard certificate +# +# Websocket Documentation: https://www.truenas.com/docs/api/scale_websocket_api.html +# +# Tested with TrueNAS Scale - Electric Eel 24.10 +# Changes certificate in the following services: +# - Web UI +# - FTP +# - iX Apps +# +# The following environment variables must be set: +# ------------------------------------------------ +# +# # API KEY +# # Use the folowing URL to create a new API token: /ui/apikeys +# export DEPLOY_TRUENAS_APIKEY=" Date: Sun, 17 Nov 2024 20:58:06 +0100 Subject: [PATCH 542/687] Fix syntax for OpenBSD sh --- dnsapi/dns_netcup.sh | 6 +++--- notify/aws_ses.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 687b99bc..8609adf6 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -19,7 +19,7 @@ client="" dns_netcup_add() { _debug NC_Apikey "$NC_Apikey" - login + _login if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then _err "No Credentials given" return 1 @@ -61,7 +61,7 @@ dns_netcup_add() { } dns_netcup_rm() { - login + _login fulldomain=$1 txtvalue=$2 @@ -125,7 +125,7 @@ dns_netcup_rm() { logout } -login() { +_login() { tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) _debug "$tmp" diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 30db45ad..07e0c48c 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -89,7 +89,7 @@ _use_metadata() { _normalizeJson | tr '{,}' '\n' | while read -r _line; do - _key="$(echo "${_line%%:*}" | tr -d '"')" + _key="$(echo "${_line%%:*}" | tr -d \")" _value="${_line#*:}" _debug3 "_key" "$_key" _secure_debug3 "_value" "$_value" From 276e089419592eabe1f188fdb53d161ab835cf70 Mon Sep 17 00:00:00 2001 From: mikhailkhr Date: Wed, 20 Nov 2024 12:38:06 +0300 Subject: [PATCH 543/687] fix: new version of fornex dns based on api version 2.3.1 --- dnsapi/dns_fornex.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index cede0cd0..a352547b 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -9,7 +9,7 @@ Issues: github.com/acmesh-official/acme.sh/issues/3998 Author: Timur Umarov ' -FORNEX_API_URL="https://fornex.com/api/dns/v0.1" +FORNEX_API_URL="https://fornex.com/api" ######## Public functions ##################### @@ -30,12 +30,10 @@ dns_fornex_add() { fi _info "Adding record" - if _rest POST "$_domain/entry_set/add/" "host=$fulldomain&type=TXT&value=$txtvalue&apikey=$FORNEX_API_KEY"; then + if _rest POST "dns/domain/$_domain/entry_set/" "{\"host\" : \"${fulldomain}\" , \"type\" : \"TXT\" , \"value\" : \"${txtvalue}\" , \"ttl\" : null}"; then _debug _response "$response" - if _contains "$response" '"ok": true' || _contains "$response" 'Такая запись уже существует.'; then - _info "Added, OK" - return 0 - fi + _info "Added, OK" + return 0 fi _err "Add txt record error." return 1 @@ -58,21 +56,21 @@ dns_fornex_rm() { fi _debug "Getting txt records" - _rest GET "$_domain/entry_set.json?apikey=$FORNEX_API_KEY" + _rest GET "dns/domain/$_domain/entry_set?type=TXT&q=$fulldomain" if ! _contains "$response" "$txtvalue"; then _err "Txt record not found" return 1 fi - _record_id="$(echo "$response" | _egrep_o "{[^{]*\"value\"*:*\"$txtvalue\"[^}]*}" | sed -n -e 's#.*"id": \([0-9]*\).*#\1#p')" + _record_id="$(echo "$response" | _egrep_o "\{[^\{]*\"value\"*:*\"$txtvalue\"[^\}]*\}" | sed -n -e 's#.*"id":\([0-9]*\).*#\1#p')" _debug "_record_id" "$_record_id" if [ -z "$_record_id" ]; then - _err "can not find _record_id" + _err "can not find _record_id return 1 fi - if ! _rest POST "$_domain/entry_set/$_record_id/delete/" "apikey=$FORNEX_API_KEY"; then + if ! _rest DELETE "dns/domain/$_domain/entry_set/$_record_id/"; then _err "Delete record error." return 1 fi @@ -90,18 +88,18 @@ _get_root() { i=1 while true; do - h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" if [ -z "$h" ]; then #not valid return 1 fi - if ! _rest GET "domain_list.json?q=$h&apikey=$FORNEX_API_KEY"; then + if ! _rest GET "dns/domain/"; then return 1 fi - if _contains "$response" "\"$h\"" >/dev/null; then + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then _domain=$h return 0 else @@ -134,7 +132,9 @@ _rest() { data="$3" _debug "$ep" - export _H1="Accept: application/json" + export _H1="Authorization: Api-Key $FORNEX_API_KEY" + export _H2="Content-Type: application/json" + export _H3="Accept: application/json" if [ "$m" != "GET" ]; then _debug data "$data" From 54ac0048c4bdb9c57c26e8204d1996c61fd54456 Mon Sep 17 00:00:00 2001 From: mikhailkhr Date: Wed, 20 Nov 2024 12:43:58 +0300 Subject: [PATCH 544/687] fix: missing quotes --- dnsapi/dns_fornex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_fornex.sh b/dnsapi/dns_fornex.sh index a352547b..d1a10af8 100644 --- a/dnsapi/dns_fornex.sh +++ b/dnsapi/dns_fornex.sh @@ -66,7 +66,7 @@ dns_fornex_rm() { _record_id="$(echo "$response" | _egrep_o "\{[^\{]*\"value\"*:*\"$txtvalue\"[^\}]*\}" | sed -n -e 's#.*"id":\([0-9]*\).*#\1#p')" _debug "_record_id" "$_record_id" if [ -z "$_record_id" ]; then - _err "can not find _record_id + _err "can not find _record_id" return 1 fi From d7855e8fe58d7fcbd01cbd195e23f315bb5086e4 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Sun, 24 Nov 2024 14:59:51 +0100 Subject: [PATCH 545/687] Update truenas_ws.sh (shfmt and shellcheck) --- deploy/truenas_ws.sh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index b5ba51ab..4b3a5c72 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -51,7 +51,7 @@ _ws_call() { _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1") fi _debug "_ws_response" "$_ws_response" - printf "%s" $_ws_response + printf "%s" "$_ws_response" return 0 } @@ -99,7 +99,7 @@ _ws_get_job_result() { then _ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')" _debug "_ws_result" "$_ws_result" - printf "%s" $_ws_result + printf "%s" "$_ws_result" _ws_error="$(printf "%s" "$_ws_response" | jq '.[]."error"')" if [ "$_ws_error" != "null" ] then @@ -175,7 +175,7 @@ truenas_ws_deploy() { then _err "Error calling system.ready:" _err "$_ws_response" - exit $_ws_re + exit $_ws_ret fi if [ "$_ws_response" != "TRUE" ] @@ -196,7 +196,7 @@ truenas_ws_deploy() { _truenas_version=$(printf "%s" "$_ws_response" | jq -r '."version"' | cut -d '-' -f 3) _info "TrueNAS system: $_truenas_system" _info "TrueNAS version: $_truenas_version" - if [ "$_truenas_system" != "SCALE" ] && ["$_truenas_system" != "CORE" ] + if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." exit 10 @@ -210,7 +210,6 @@ truenas_ws_deploy() { _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') _info "Current WebUI certificate ID: $_ui_certificate_id" _info "Current WebUI certificate name: $_ui_certificate_name" - _info "WebUI redirect to https: $_ui_http_redirect" ########## Upload new certificate @@ -225,9 +224,10 @@ truenas_ws_deploy() { exit 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") - if [ $? -gt 0 ] + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') @@ -251,11 +251,11 @@ truenas_ws_deploy() { then _info "Replace app certificates..." _ws_response=$(_ws_call "app.query") - for _app_name in $(printf "%s" $_ws_response | jq -r '.[]."name"') + for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"') do _info "Checking app $_app_name..." _ws_response=$(_ws_call "app.config" "$_app_name") - if [ "$(printf "%s" $_ws_response | jq -r '."network" | has("certificate_id")')" = "true" ] + if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ] then _info "App has certificate option, setup new certificate..." _info "App will be redeployed after updating the certificate." @@ -267,9 +267,10 @@ truenas_ws_deploy() { exit 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") - if [ $? -gt 0 ] + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." @@ -305,10 +306,11 @@ truenas_ws_deploy() { _err "No JobID returned from websocket method." exit 3 fi - _ws_result=$(_ws_get_job_result $_ws_jobid) - if [ $? -gt 0 ] + _ws_result=$(_ws_get_job_result "$_ws_jobid") + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi From f2a311bb8194cff518978545da619c439b2f1621 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:44:52 +0100 Subject: [PATCH 546/687] Update truenas_ws.sh (added return instead exit) --- deploy/truenas_ws.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 4b3a5c72..952cfc42 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -161,7 +161,7 @@ truenas_ws_deploy() { if [ -z "$DEPLOY_TRUENAS_APIKEY" ] then _err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable." - exit 1 + return 1 fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "Environment variables: OK" @@ -175,7 +175,7 @@ truenas_ws_deploy() { then _err "Error calling system.ready:" _err "$_ws_response" - exit $_ws_ret + return $_ws_ret fi if [ "$_ws_response" != "TRUE" ] @@ -183,7 +183,7 @@ truenas_ws_deploy() { _err "TrueNAS is not ready." _err "Please check environment variables DEPLOY_TRUENAS_APIKEY, DEPLOY_TRUENAS_HOSTNAME and DEPLOY_TRUENAS_PROTOCOL." _err "Verify API key." - exit 2 + return 2 fi _savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "TrueNAS health: OK" @@ -199,7 +199,7 @@ truenas_ws_deploy() { if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." - exit 10 + return 10 fi ########## Gather current certificate @@ -221,13 +221,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') @@ -242,7 +242,7 @@ truenas_ws_deploy() { then _err "Cannot set FTP certificate." _debug "_ws_response" "$_ws_response" - exit 4 + return 4 fi ########## ix Apps (SCALE only) @@ -264,13 +264,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." @@ -288,7 +288,7 @@ truenas_ws_deploy() { if [ "$_changed_certid" != "$_new_certid" ] then _err "WebUI certificate change error.." - exit 5 + return 5 else _info "WebUI certificate replaced." fi @@ -304,13 +304,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi From cd924099e43a1eb4ac1895b8004557945499a450 Mon Sep 17 00:00:00 2001 From: Henning Reich Date: Mon, 25 Nov 2024 17:46:59 +0000 Subject: [PATCH 547/687] add template --- dnsapi/dns_technitum.sh | 44 +++++++++++++++++++++++++++++++++++++++++ test.technitum.sh | 3 +++ 2 files changed, 47 insertions(+) create mode 100755 dnsapi/dns_technitum.sh create mode 100755 test.technitum.sh diff --git a/dnsapi/dns_technitum.sh b/dnsapi/dns_technitum.sh new file mode 100755 index 00000000..c9f5eb9f --- /dev/null +++ b/dnsapi/dns_technitum.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_myapi_info='Custom API Example + A sample custom DNS API script. +Domains: example.com +Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + MYAPI_Token API Token. Get API Token from https://example.com/api/. Optional. +Issues: github.com/acmesh-official/acme.sh +Author: Neil Pang +' + +#This file name is "dns_myapi.sh" +#So, here must be a method dns_myapi_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_myapi_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _err "Not implemented!" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_myapi_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" +} + +#################### Private functions below ################################## diff --git a/test.technitum.sh b/test.technitum.sh new file mode 100755 index 00000000..438d2f4d --- /dev/null +++ b/test.technitum.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./acme.sh --issue --staging --debug 2 -d test.07q.de --dns dns_technitum From c3557bbe3f07052ac29b5ca95ff2405a557af817 Mon Sep 17 00:00:00 2001 From: qupfer Date: Mon, 25 Nov 2024 20:26:23 +0100 Subject: [PATCH 548/687] 1 --- dnsapi/dns_technitum.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_technitum.sh b/dnsapi/dns_technitum.sh index c9f5eb9f..8eb2e4b8 100755 --- a/dnsapi/dns_technitum.sh +++ b/dnsapi/dns_technitum.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh # shellcheck disable=SC2034 -dns_myapi_info='Custom API Example - A sample custom DNS API script. +dns_technitum_info='Technitum DNS Server + Domains: example.com Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns @@ -21,10 +21,10 @@ Author: Neil Pang # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_myapi_add() { +dns_technitum_add() { fulldomain=$1 txtvalue=$2 - _info "Using myapi" + _info "Using technitum" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _err "Not implemented!" @@ -33,12 +33,17 @@ dns_myapi_add() { #Usage: fulldomain txtvalue #Remove the txt record after validation. -dns_myapi_rm() { +dns_technitum_rm() { fulldomain=$1 txtvalue=$2 - _info "Using myapi" + _info "Using technitum" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" + _err "Not implemented!" + return 1 } #################### Private functions below ################################## + + +dns_technitum_add "_acme-challenge.test.07q.de" "abcd" \ No newline at end of file From 91103751736161e43e1806bc485e591661f4591a Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:50:40 +0100 Subject: [PATCH 549/687] Update truenas_ws.sh (fixed shfmt) --- deploy/truenas_ws.sh | 98 ++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 62 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 952cfc42..3ee983a3 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -38,16 +38,13 @@ _ws_call() { _debug "_ws_call arg1" "$1" _debug "_ws_call arg2" "$2" _debug "_ws_call arg3" "$3" - if [ $# -eq 3 ] - then + if [ $# -eq 3 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2" "$3") fi - if [ $# -eq 2 ] - then + if [ $# -eq 2 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2") fi - if [ $# -eq 1 ] - then + if [ $# -eq 1 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1") fi _debug "_ws_response" "$_ws_response" @@ -69,14 +66,13 @@ _ws_call() { # 1: false _ws_check_jobid() { case "$1" in - [0-9]*) - return 0 - ;; + [0-9]*) + return 0 + ;; esac return 1 } - # Wait for job to finish and return result as JSON # Usage: # _ws_result=$(_ws_get_job_result "$_ws_jobid") @@ -91,18 +87,15 @@ _ws_check_jobid() { # Returns: # n/a _ws_get_job_result() { - while true - do + while true; do sleep 2 _ws_response=$(_ws_call "core.get_jobs" "[[\"id\", \"=\", $1]]") - if [ "$(printf "%s" "$_ws_response" | jq -r '.[]."state"')" != "RUNNING" ] - then + if [ "$(printf "%s" "$_ws_response" | jq -r '.[]."state"')" != "RUNNING" ]; then _ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')" _debug "_ws_result" "$_ws_result" printf "%s" "$_ws_result" _ws_error="$(printf "%s" "$_ws_response" | jq '.[]."error"')" - if [ "$_ws_error" != "null" ] - then + if [ "$_ws_error" != "null" ]; then _err "Job $1 failed:" _err "$_ws_error" return 7 @@ -113,9 +106,6 @@ _ws_get_job_result() { return 0 } - - - ######################## ### Public functions ### ######################## @@ -153,33 +143,30 @@ truenas_ws_deploy() { _debug _file_ca "$_file_ca" _debug _file_fullchain "$_file_fullchain" -########## Environment check + ########## Environment check _info "Checking environment variables..." _getdeployconf DEPLOY_TRUENAS_APIKEY # Check API Key - if [ -z "$DEPLOY_TRUENAS_APIKEY" ] - then + if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then _err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable." return 1 fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "Environment variables: OK" -########## Health check + ########## Health check _info "Checking TrueNAS health..." _ws_response=$(_ws_call "system.ready" | tr '[:lower:]' '[:upper:]') _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then _err "Error calling system.ready:" _err "$_ws_response" return $_ws_ret fi - if [ "$_ws_response" != "TRUE" ] - then + if [ "$_ws_response" != "TRUE" ]; then _err "TrueNAS is not ready." _err "Please check environment variables DEPLOY_TRUENAS_APIKEY, DEPLOY_TRUENAS_HOSTNAME and DEPLOY_TRUENAS_PROTOCOL." _err "Verify API key." @@ -188,7 +175,7 @@ truenas_ws_deploy() { _savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "TrueNAS health: OK" -########## System info + ########## System info _info "Gather system info..." _ws_response=$(_ws_call "system.info") @@ -196,82 +183,73 @@ truenas_ws_deploy() { _truenas_version=$(printf "%s" "$_ws_response" | jq -r '."version"' | cut -d '-' -f 3) _info "TrueNAS system: $_truenas_system" _info "TrueNAS version: $_truenas_version" - if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] - then + if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ]; then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." return 10 fi -########## Gather current certificate + ########## Gather current certificate _info "Gather current WebUI certificate..." _ws_response="$(_ws_call "system.general.config")" _ui_certificate_id=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"') - _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') + _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') _info "Current WebUI certificate ID: $_ui_certificate_id" _info "Current WebUI certificate name: $_ui_certificate_name" -########## Upload new certificate + ########## Upload new certificate _info "Upload new certificate..." _certname="acme_$(_utc_date | tr -d '\-\:' | tr ' ' '_')" _debug _certname "$_certname" _ws_jobid=$(_ws_call "certificate.create" "{\"name\": \"${_certname}\", \"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"certificate\": \"$(_json_encode <"$_file_fullchain")\", \"privatekey\": \"$(_json_encode <"$_file_key")\", \"passphrase\": \"\"}") _debug "_ws_jobid" "$_ws_jobid" - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then return $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') _info "New certificate ID: $_new_certid" -########## FTP + ########## FTP _info "Replace FTP certificate..." _ws_response=$(_ws_call "ftp.update" "{\"ssltls_certificate\": $_new_certid}") _ftp_certid=$(printf "%s" "$_ws_response" | jq -r '."ssltls_certificate"') - if [ "$_ftp_certid" != "$_new_certid" ] - then + if [ "$_ftp_certid" != "$_new_certid" ]; then _err "Cannot set FTP certificate." _debug "_ws_response" "$_ws_response" return 4 fi -########## ix Apps (SCALE only) + ########## ix Apps (SCALE only) - if [ "$_truenas_system" = "SCALE" ] - then + if [ "$_truenas_system" = "SCALE" ]; then _info "Replace app certificates..." _ws_response=$(_ws_call "app.query") - for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"') - do + for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"'); do _info "Checking app $_app_name..." _ws_response=$(_ws_call "app.config" "$_app_name") - if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ] - then + if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ]; then _info "App has certificate option, setup new certificate..." _info "App will be redeployed after updating the certificate." _ws_jobid=$(_ws_call "app.update" "$_app_name" "{\"values\": {\"network\": {\"certificate_id\": $_new_certid}}}") _debug "_ws_jobid" "$_ws_jobid" - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then - return $_ws_ret - fi + if [ $_ws_ret -gt 0 ]; then + return $_ws_ret + fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." else @@ -280,13 +258,12 @@ truenas_ws_deploy() { done fi -########## WebUI + ########## WebUI _info "Replace WebUI certificate..." _ws_response=$(_ws_call "system.general.update" "{\"ui_certificate\": $_new_certid}") _changed_certid=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"') - if [ "$_changed_certid" != "$_new_certid" ] - then + if [ "$_changed_certid" != "$_new_certid" ]; then _err "WebUI certificate change error.." return 5 else @@ -297,23 +274,20 @@ truenas_ws_deploy() { _info "Waiting for UI restart..." sleep 6 -########## Certificates + ########## Certificates _info "Deleting old certificate..." _ws_jobid=$(_ws_call "certificate.delete" "$_ui_certificate_id") - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then return $_ws_ret fi - _info "Have a nice day...bye!" } From 44240339d9856568d418d41f89556495cb651be2 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:13:43 +0100 Subject: [PATCH 550/687] Update truenas_ws.sh (Interpreter changed from bash to sh) --- deploy/truenas_ws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 3ee983a3..7292987b 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # TrueNAS deploy script for SCALE/CORE using websocket # It is recommend to use a wildcard certificate From ebaf4c9c01bd590003bc91dec4ca05e88c091cb7 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:23:59 +0100 Subject: [PATCH 551/687] Update truenas_ws.sh (Output new certificate name) --- deploy/truenas_ws.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 7292987b..940cde2e 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -201,6 +201,7 @@ truenas_ws_deploy() { _info "Upload new certificate..." _certname="acme_$(_utc_date | tr -d '\-\:' | tr ' ' '_')" + _info "New WebUI certificate name: $_certname" _debug _certname "$_certname" _ws_jobid=$(_ws_call "certificate.create" "{\"name\": \"${_certname}\", \"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"certificate\": \"$(_json_encode <"$_file_fullchain")\", \"privatekey\": \"$(_json_encode <"$_file_key")\", \"passphrase\": \"\"}") _debug "_ws_jobid" "$_ws_jobid" From 9cd1d1a9dcbabcc2a316f1d655e2f5f2db8682cb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 26 Nov 2024 09:20:18 +0100 Subject: [PATCH 552/687] dns_world4you: Adapt to change in world4you.com DeleteDnsRecordForm --- dnsapi/dns_world4you.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index be6ef5c8..2e8efe82 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -115,7 +115,7 @@ dns_world4you_rm() { _resethttp export ACME_HTTP_NO_REDIRECTS=1 - body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token" + body="DeleteDnsRecordForm[id]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token" _info "Removing record..." ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded') _resethttp @@ -203,6 +203,7 @@ _get_paketnr() { form="$2" domains=$(echo "$form" | grep '