diff --git a/dnsapi/dns_pmiab.sh b/dnsapi/dns_pmiab.sh new file mode 100644 index 0000000000..704b2af6f2 --- /dev/null +++ b/dnsapi/dns_pmiab.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_pmiab_info='Power-Mail-in-a-Box +Site: github.com/ddavness/power-mailinabox +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_pmiab +Options: + PMIAB_Username Admin username + PMIAB_Password Admin password + PMIAB_Server Server hostname. FQDN of your_PMIAB Server +Issues: github.com/acmesh-official/acme.sh/issues/2550 +Author: Roland Giesler (lifeboy) +Cloned from dns_miab by Darven Dissek, William Gertz +' + +######## Public functions ##################### + +#Usage: dns_pmiab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pmiab_add() { + fulldomain=$1 + txtvalue="$2" + _info "Using pmiab challenge add" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + #retrieve pmiab environemt vars + if ! _retrieve_pmiab_env; then + return 1 + fi + + #check domain and seperate into domain and host + if ! _get_root "$fulldomain"; then + _err "Cannot find any part of ${fulldomain} is hosted on ${PMIAB_Server}" + return 1 + fi + + _debug2 _sub_domain "$_sub_domain" + _debug2 _domain "$_domain" + + #add the challenge record + _api_path="custom/${fulldomain}/txt" + # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the PMIAB API + _pmiab_rest "value=$txtvalue&ttl=300" "$_api_path" "POST" + + #check if result was good + if _contains "$response" "updated DNS"; then + _info "Successfully created the txt record" + return 0 + else + _err "Error encountered during record add" + _err "$response" + return 1 + fi +} + +#Usage: dns_pmiab_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_pmiab_rm() { + fulldomain=$1 + txtvalue=$2 + + _info "Using pmiab challenge delete" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + #retrieve PMIAB environemt vars + if ! _retrieve_pmiab_env; then + return 1 + fi + + #check domain and seperate into doamin and host + if ! _get_root "$fulldomain"; then + _err "Cannot find any part of ${fulldomain} is hosted on ${PMIAB_Server}" + return 1 + fi + + _debug2 _sub_domain "$_sub_domain" + _debug2 _domain "$_domain" + + #Remove the challenge record + _api_path="custom/${fulldomain}/txt" + _pmiab_rest "$txtvalue" "$_api_path" "DELETE" + + #check if result was good + if _contains "$response" "updated DNS"; then + _info "Successfully removed the txt record" + return 0 + else + _err "Error encountered during record remove" + _err "$response" + return 1 + fi +} + +#################### Private functions below ################################## +# +#Usage: _get_root _acme-challenge.www.domain.com +#Returns: +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + _passed_domain=$1 + _debug _passed_domain "$_passed_domain" + _i=2 + _p=1 + + #get the zones hosed on PMIAB server, must be a json stream + _pmiab_rest "" "zones" "GET" + + if ! _is_json "$response"; then + _err "ERROR fetching domain list" + _err "$response" + return 1 + fi + + #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) + _debug _test_domain "$_test_domain" + + if [ -z "$_test_domain" ]; then + return 1 + fi + + #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}") + _domain=${_test_domain} + return 0 + fi + + #cycle to the next dot in the passed domain + _p=${_i} + _i=$(_math "$_i" + 1) + done + + return 1 +} + +#Usage: _retrieve_pmiab_env +#Returns (from store or environment variables): +# PMIAB_Username +# PMIAB_Password +# PMIAB_Server +#retrieve PMIAB environment variables, report errors and quit if problems +_retrieve_pmiab_env() { + PMIAB_Username="${PMIAB_Username:-$(_readaccountconf_mutable PMIAB_Username)}" + PMIAB_Password="${PMIAB_Password:-$(_readaccountconf_mutable PMIAB_Password)}" + PMIAB_Server="${PMIAB_Server:-$(_readaccountconf_mutable PMIAB_Server)}" + + #debug log the environmental variables + _debug PMIAB_Username "$PMIAB_Username" + _debug PMIAB_Password "$PMIAB_Password" + _debug PMIAB_Server "$PMIAB_Server" + + #check if PMIAB environemt vars set and quit if not + if [ -z "$PMIAB_Username" ] || [ -z "$PMIAB_Password" ] || [ -z "$PMIAB_Server" ]; then + _err "You didn't specify one or more of PMIAB_Username, PMIAB_Password or PMIAB_Server." + _err "Please check these environment variables and try again." + return 1 + fi + + #save the credentials to the account conf file. + _saveaccountconf_mutable PMIAB_Username "$PMIAB_Username" + _saveaccountconf_mutable PMIAB_Password "$PMIAB_Password" + _saveaccountconf_mutable PMIAB_Server "$PMIAB_Server" + return 0 +} + +#Useage: _pmiab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST" +#Returns: "updated DNS: domain.com" +#rest interface PMIAB dns +_pmiab_rest() { + _data="$1" + _api_path="$2" + _httpmethod="$3" + + #encode username and password for basic authentication + _credentials="$(printf "%s" "$PMIAB_Username:$PMIAB_Password" | _base64)" + export _H1="Authorization: Basic $_credentials" + _url="https://${PMIAB_Server}/admin/dns/${_api_path}" + + _debug2 _data "$_data" + _debug _api_path "$_api_path" + _debug2 _url "$_url" + _debug2 _credentails "$_credentials" + _debug _httpmethod "$_httpmethod" + + if [ "$_httpmethod" = "GET" ]; then + response="$(_get "$_url")" + else + response="$(_post "$_data" "$_url" "" "$_httpmethod")" + fi + + _retcode="$?" + + if [ "$_retcode" != "0" ]; then + _err "PMIAB REST authentication failed on $_httpmethod" + return 1 + fi + + _debug response "$response" + return 0 +} + +#Usage: _is_json "\[\n "mydomain.com"\n]" +#Reurns "\[\n "mydomain.com"\n]" +#returns the string if it begins and ends with square braces +_is_json() { + _str="$(echo "$1" | _normalizeJson)" + echo "$_str" | grep '^\[.*\]$' >/dev/null 2>&1 +}