diff --git a/dnsapi/dns_hostingukraine.sh b/dnsapi/dns_hostingukraine.sh new file mode 100644 index 00000000..4ef4793d --- /dev/null +++ b/dnsapi/dns_hostingukraine.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env sh + +# Author: Qvinti (Aleksandr Zaitsev) +# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2683 or https://www.ukraine.com.ua/forum/domennie-imena/acmesh-dnsapi-dlya-hosting-Ukra.html +# Will be called by acme.sh to add the txt record to https://www.ukraine.com.ua/ DNS api. +# Hosting Ukraine API documentation: https://api.adm.tools/osnovnie-polozheniya/dostup-k-api/ +# Usage: ./acme.sh --issue -d yourdomain.com [-d '*.yourdomain.com'] --dns dns_hostingukraine +# API endpoint: +HostingUkraine_Api="https://adm.tools/api.php" +# Your login (uncomment the line below and change xxxx to your login): +#HostingUkraine_Login="xxxx" +# Your api token (uncomment the line below and change xxxx to your token): +#HostingUkraine_Token="xxxx" + +######## Public functions ##################### +# Used to add txt record +#fulldomain=_acme-challenge.yourDomain.com +#txtvalue=txt_data_value +dns_hostingukraine_add() { + fulldomain=$1 + txtvalue=$2 + + _hostingukraine_init + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid root domain for: ($fulldomain)" + return 1 + fi + + _info "Adding txt record. ($fulldomain)" + _hostingukraine_api_request POST "dns_record" "create" "\"domain\":\"$_domain\",\"subdomain\":\"$_sub_domain\",\"type\":\"TXT\",\"data\":\"$txtvalue\"" + if _contains "$response" "\"status\":\"error\""; then + _err "Add txt record, Failure! ($fulldomain)" + return 1 + fi + _info "Add txt record, OK! ($fulldomain)" + return 0 +} + +# Used to remove the txt record after validation +#fulldomain=_acme-challenge.yourDomain.com +#txtvalue=txt_data_value +dns_hostingukraine_rm() { + fulldomain=$1 + txtvalue=$2 + + _hostingukraine_init + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid root domain for: ($fulldomain)" + return 1 + fi + + _debug "Getting txt records" + _hostingukraine_api_request POST "dns_record" "info" "\"domain\":\"$_domain\"" + if _contains "$response" "\"status\":\"error\""; then + _err "Get domain records, Failure! ($_domain)" + return 1 + fi + + ids=$(echo "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o "id\":[^\,]+" | cut -c5-) + _debug ids "$ids" + if [ -z "$ids" ]; then + _err "Empty TXT records! ($fulldomain: $txtvalue)" + return 1 + fi + + for id in $ids; do + stack="${stack:+${stack},}${id}" + done + + _hostingukraine_api_request POST "dns_record" "delete" "\"domain\":\"$_domain\",\"stack\":[$stack]" + if _contains "$response" "\"status\":\"error\""; then + _err "Remove txt record, Failure! ($fulldomain: $id)" + return 1 + fi + _info "Remove txt record, OK! ($fulldomain: $id)" + return 0 +} + +#################### Private functions below ################################## +# Check root zone +#domain=_acme-challenge.yourDomain.com +#returns +# _sub_domain=_acme-challenge +# _domain=yourDomain.com +_get_root() { + domain=$1 + i=1 + p=1 + + _hostingukraine_api_request POST "dns_domain" "info" "\"search\":\"\"" + + while true; do + host=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug host "$host" + if [ -z "$host" ]; then + _err "Get root, Failure! ($domain)" + return 1 + fi + + if _contains "$response" "\"name\":\"$host\""; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$host + _debug fulldomain "$domain" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _info "Get root, OK! ($host)" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + _err "Get root, Error! ($domain)" + return 1 +} + +# Check credentials and root zone +_hostingukraine_init() { + HostingUkraine_Login="${HostingUkraine_Login:-$(_readaccountconf_mutable HostingUkraine_Login)}" + HostingUkraine_Token="${HostingUkraine_Token:-$(_readaccountconf_mutable HostingUkraine_Token)}" + if [ -z "$HostingUkraine_Login" ] || [ -z "$HostingUkraine_Token" ]; then + HostingUkraine_Login="" + HostingUkraine_Token="" + _err "You didn't specify a Hosting Ukraine account or token yet." + _err "Please create the account and token and try again. Info: https://api.adm.tools/osnovnie-polozheniya/dostup-k-api/" + return 1 + fi + + _saveaccountconf_mutable HostingUkraine_Login "$HostingUkraine_Login" + _saveaccountconf_mutable HostingUkraine_Token "$HostingUkraine_Token" +} + +# Send request to API endpoint +#request_method=POST +#class=dns_domain|dns_record +#method=info|create|delete +#data=part_of_json_data +_hostingukraine_api_request() { + request_method=$1 + class=$2 + method=$3 + data=$4 + + response="$(_post "{\"auth_login\":\"$HostingUkraine_Login\",\"auth_token\":\"$HostingUkraine_Token\",\"class\":\"$class\",\"method\":\"$method\",$data}" "$HostingUkraine_Api" "" "$request_method" "application/json")" + + if [ "$?" != "0" ]; then + _err "error $response" + return 1 + fi + _debug2 response "$response" + return 0 +}