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: | 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: diff --git a/acme.sh b/acme.sh index e39a146b..9842e3f1 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 @@ -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 @@ -1811,7 +1816,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\").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\").replace(tzinfo=datetime.timezone.utc).timestamp()))" 2>/dev/null; then return fi _err "Cannot parse _date2time $1" @@ -2193,7 +2202,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 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..14ac500a --- /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_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 + 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-15' +} 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/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 } diff --git a/deploy/truenas.sh b/deploy/truenas.sh index c79e6dac..407395a3 100644 --- a/deploy/truenas.sh +++ b/deploy/truenas.sh @@ -9,7 +9,7 @@ # # Following environment variables must be set: # -# export DEPLOY_TRUENAS_APIKEY="/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_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" 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 00ccd798..3f0dfa3d 100644 --- a/dnsapi/dns_azure.sh +++ b/dnsapi/dns_azure.sh @@ -9,14 +9,17 @@ 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 ' +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() { @@ -29,6 +32,7 @@ dns_azure_add() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Subscription ID" return 1 fi @@ -43,37 +47,45 @@ 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" + _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)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" + _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="" + AZUREDNS_BEARERTOKEN="" + _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="" + AZUREDNS_BEARERTOKEN="" + _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. @@ -81,9 +93,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" 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" @@ -133,7 +150,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 @@ -145,6 +162,7 @@ dns_azure_rm() { AZUREDNS_TENANTID="" AZUREDNS_APPID="" AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" _err "You didn't specify the Azure Subscription ID " return 1 fi @@ -153,40 +171,51 @@ 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)}" + AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}" + if [ -z "$AZUREDNS_BEARERTOKEN" ]; then + if [ -z "$AZUREDNS_TENANTID" ]; then + AZUREDNS_SUBSCRIPTIONID="" + AZUREDNS_TENANTID="" + AZUREDNS_APPID="" + AZUREDNS_CLIENTSECRET="" + AZUREDNS_BEARERTOKEN="" + _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="" + AZUREDNS_BEARERTOKEN="" + _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="" + AZUREDNS_BEARERTOKEN="" + _err "You didn't specify the Azure Client Secret" + return 1 + fi + else + _info "Using provided bearer token" 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" @@ -265,10 +294,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,14 +315,14 @@ _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 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? @@ -310,7 +339,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,14 +359,14 @@ _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 _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 @@ -350,15 +379,18 @@ _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 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 @@ -373,7 +405,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_bunny.sh b/dnsapi/dns_bunny.sh index 681f748a..780198e1 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,11 +218,11 @@ _get_base_domain() { return 0 fi ## increment cut point $i - i=$(_math $i + 1) + i=$(_math "$i" + 1) 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_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_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_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..10a3821d 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-"$previous") _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_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_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..d1a10af8 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" 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 @@ -97,11 +95,11 @@ _get_root() { 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" 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_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_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_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_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_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_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_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" 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..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\".*}")" @@ -131,34 +131,42 @@ _Linode_API() { # _domain=domain.com # _domain_id=12345 _get_root() { - domain=$1 + 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 + 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 - 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 - - hostedzone="$(echo "$response" | _egrep_o "\{.*\"domain\": *\"$h\".*}")" + _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\": *\"$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: $tst_hosted_domain, id: $_domain_id" if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | 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 fi + p=$i i=$(_math "$i" + 1) - done - fi + fi + done + return 1 } 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_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_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_miab.sh b/dnsapi/dns_miab.sh index 9416c8ce..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" @@ -113,7 +112,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 +122,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_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..5527b357 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 @@ -137,14 +137,14 @@ _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) + 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..44549c9e 100755 --- a/dnsapi/dns_namecom.sh +++ b/dnsapi/dns_namecom.sh @@ -159,15 +159,15 @@ _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) + while [ "$i" -le "$numfields" ]; do + 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..b31e32a1 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -109,15 +109,15 @@ _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) + while [ "$i" -le "$numfields" ]; do + 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..322f10ad 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" @@ -95,7 +93,6 @@ dns_netlify_rm() { _err "error removing validation value ($_code)" return 1 fi - return 0 fi return 1 } @@ -111,7 +108,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 +123,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..0735f5de 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 @@ -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_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_omglol.sh b/dnsapi/dns_omglol.sh new file mode 100644 index 00000000..5c137c3f --- /dev/null +++ b/dnsapi/dns_omglol.sh @@ -0,0 +1,391 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +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 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/5299 +Author: @Kholin +' + +# See API Docs https://api.omg.lol/ + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_omglol_add() { + fulldomain=$1 + txtvalue=$2 + 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 '@')" + + _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" + + omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain" + if [ ! $? ]; then + return 1 + fi + + dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address") + authHeader="$(_createAuthHeader "$OMG_ApiKey")" + + _debug2 "dns_omglol_add(): Address" "$dnsName" + + omg_add "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue" + +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_omglol_rm() { + fulldomain=$1 + txtvalue=$2 + 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 '@')" + + _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" + + omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain" + if [ ! $? ]; then + return 1 + fi + + dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address") + authHeader="$(_createAuthHeader "$OMG_ApiKey")" + + omg_delete "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue" +} + +#################### Private functions below ################################## +# Check that the minimum requirements are present. Close ungracefully if not +omg_validate() { + omg_apikey=$1 + omg_address=$2 + fulldomain=$3 + + _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 [ "" = "$omg_apikey" ]; then + _err "omg.lol API key not provided. Exiting" + return 1 + fi + + _endswith "$fulldomain" "omg.lol" + if [ ! $? ]; then + _err "Domain name requested is not under omg.lol" + return 1 + fi + + _endswith "$fulldomain" "$omg_address.omg.lol" + if [ ! $? ]; then + _err "Domain name is not a subdomain of provided omg.lol address $omg_address" + return 1 + fi + + _debug "Required environment parameters are all present" +} + +# Add (or modify) an entry for a new ACME query +omg_add() { + address=$1 + authHeader=$2 + dnsName=$3 + txtvalue=$4 + + _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" + + payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}' + _debug2 "Payload" "$payload" + + response=$(_post "$payload" "$endpoint" "" "POST" "application/json") + + omg_validate_add "$response" "$dnsName.$address" "$txtvalue" +} + +omg_validate_add() { + response=$1 + name=$2 + content=$3 + + _debug "Validating DNS record addition" + _debug2 "omg_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 + + _info "Record Created successfully" + return 0 +} + +omg_getRecords() { + address=$1 + authHeader=$2 + dnsName=$3 + txtValue=$4 + + _debug2 "omg_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" +} + +omg_delete() { + address=$1 + authHeader=$2 + dnsName=$3 + txtValue=$4 + + _info "Deleting DNS entry for $dnsName with 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 + _err "DNS record $address not found!" + return 1 + fi + + endpoint="https://api.omg.lol/address/$address/dns/$record" + _debug2 "Endpoint" "$endpoint" + + export _H1="$authHeader" + output=$(_post "" "$endpoint" "" "DELETE") + + _debug2 "Response" "$output" + + omg_validate_delete "$output" +} + +# 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 + + _info "Validating DNS record deletion" + _debug2 "omg_validate_delete()" + _debug2 "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 + + _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" + + _unquoteString "$output" +} + +_createAuthHeader() { + apikey=$1 + + _debug3 "_createAuthHeader()" + _secure_debug3 "Provided API Key" "$apikey" + + authheader="Authorization: Bearer $apikey" + _secure_debug3 "Authorization Header" "$authheader" + echo "$authheader" +} + +_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' +} + +_unquoteString() { + output=$1 + quotes=0 + + _debug3 "_unquoteString()" + _debug3 "Possibly quoted string" "$output" + + _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" +} 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..d1e9c0ac 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,13 +153,13 @@ _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 fi p=$i - i=$(_math $i + 1) + i=$(_math "$i" + 1) done _debug "$domain not found" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 7f62c05e..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)}" @@ -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..2478e19f 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -20,6 +20,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." @@ -46,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" @@ -73,6 +78,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 @@ -181,7 +191,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." @@ -194,7 +204,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_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 0a443855..1681ca9a 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 ##################### @@ -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..4ffdf572 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 @@ -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" diff --git a/dnsapi/dns_scaleway.sh b/dnsapi/dns_scaleway.sh index 64bfcc38..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 ################################## @@ -104,7 +100,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 +109,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..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 @@ -137,7 +136,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 +149,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_technitium.sh b/dnsapi/dns_technitium.sh new file mode 100755 index 00000000..a50db97c --- /dev/null +++ b/dnsapi/dns_technitium.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_Technitium_info='Technitium DNS Server + +Site: https://technitium.com/dns/ +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_technitium +Options: + Technitium_Server Server Address + Technitium_Token API Token +Issues:https://github.com/acmesh-official/acme.sh/issues/6116 +Author: Henning Reich +' + +dns_technitium_add() { + _info "add txt Record using Technitium" + _Technitium_account + fulldomain=$1 + txtvalue=$2 + response="$(_get "$Technitium_Server/api/zones/records/add?token=$Technitium_Token&domain=$fulldomain&type=TXT&text=${txtvalue}")" + if _contains "$response" '"status":"ok"'; then + return 0 + fi + _err "Could not add txt record." + return 1 +} + +dns_technitium_rm() { + _info "remove txt record using Technitium" + _Technitium_account + fulldomain=$1 + txtvalue=$2 + response="$(_get "$Technitium_Server/api/zones/records/delete?token=$Technitium_Token&domain=$fulldomain&type=TXT&text=${txtvalue}")" + if _contains "$response" '"status":"ok"'; then + return 0 + fi + _err "Could not remove txt record" + return 1 +} + +#################### Private functions below ################################## + +_Technitium_account() { + Technitium_Server="${Technitium_Server:-$(_readaccountconf_mutable Technitium_Server)}" + Technitium_Token="${Technitium_Token:-$(_readaccountconf_mutable Technitium_Token)}" + if [ -z "$Technitium_Server" ] || [ -z "$Technitium_Token" ]; then + Technitium_Server="" + Technitium_Token="" + _err "You don't specify Technitium Server and Token yet." + _err "Please create your Token and add server address and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable Technitium_Server "$Technitium_Server" + _saveaccountconf_mutable Technitium_Token "$Technitium_Token" +} 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" 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 diff --git a/notify/telegram.sh b/notify/telegram.sh index 454b4146..cca8ee25 100644 --- a/notify/telegram.sh +++ b/notify/telegram.sh @@ -27,11 +27,12 @@ telegram_send() { fi _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID" - _content="$(printf "%s" "$_content" | sed -e '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"