|
|
@ -33,30 +33,30 @@
|
|
|
|
########
|
|
|
|
########
|
|
|
|
|
|
|
|
|
|
|
|
dns_cyon_add() {
|
|
|
|
dns_cyon_add() {
|
|
|
|
_load_credentials \
|
|
|
|
_cyon_load_credentials \
|
|
|
|
&& _load_parameters "$@" \
|
|
|
|
&& _cyon_load_parameters "$@" \
|
|
|
|
&& _info_header "add" \
|
|
|
|
&& _cyon_print_header "add" \
|
|
|
|
&& _login \
|
|
|
|
&& _cyon_login \
|
|
|
|
&& _domain_env \
|
|
|
|
&& _cyon_change_domain_env \
|
|
|
|
&& _add_txt \
|
|
|
|
&& _cyon_add_txt \
|
|
|
|
&& _logout
|
|
|
|
&& _cyon_logout
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dns_cyon_rm() {
|
|
|
|
dns_cyon_rm() {
|
|
|
|
_load_credentials \
|
|
|
|
_cyon_load_credentials \
|
|
|
|
&& _load_parameters "$@" \
|
|
|
|
&& _cyon_load_parameters "$@" \
|
|
|
|
&& _info_header "delete" \
|
|
|
|
&& _cyon_print_header "delete" \
|
|
|
|
&& _login \
|
|
|
|
&& _cyon_login \
|
|
|
|
&& _domain_env \
|
|
|
|
&& _cyon_change_domain_env \
|
|
|
|
&& _delete_txt \
|
|
|
|
&& _cyon_delete_txt \
|
|
|
|
&& _logout
|
|
|
|
&& _cyon_logout
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#########################
|
|
|
|
#########################
|
|
|
|
### PRIVATE FUNCTIONS ###
|
|
|
|
### PRIVATE FUNCTIONS ###
|
|
|
|
#########################
|
|
|
|
#########################
|
|
|
|
|
|
|
|
|
|
|
|
_load_credentials() {
|
|
|
|
_cyon_load_credentials() {
|
|
|
|
# Convert loaded password to/from base64 as needed.
|
|
|
|
# Convert loaded password to/from base64 as needed.
|
|
|
|
if [ "${cyon_password_b64}" ]; then
|
|
|
|
if [ "${cyon_password_b64}" ]; then
|
|
|
|
cyon_password="$(printf "%s" "${cyon_password_b64}" | _dbase64 "multiline")"
|
|
|
|
cyon_password="$(printf "%s" "${cyon_password_b64}" | _dbase64 "multiline")"
|
|
|
@ -88,25 +88,25 @@ _load_credentials() {
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_is_idn_cyon() {
|
|
|
|
_cyon_is_idn() {
|
|
|
|
_idn_temp="$(printf "%s" "${1}" | tr -d "[0-9a-zA-Z.,-_]")"
|
|
|
|
_idn_temp="$(printf "%s" "${1}" | tr -d "[0-9a-zA-Z.,-_]")"
|
|
|
|
_idn_temp2="$(printf "%s" "${1}" | grep -o "xn--")"
|
|
|
|
_idn_temp2="$(printf "%s" "${1}" | grep -o "xn--")"
|
|
|
|
[ "$_idn_temp" ] || [ "$_idn_temp2" ]
|
|
|
|
[ "$_idn_temp" ] || [ "$_idn_temp2" ]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# comment on https://stackoverflow.com/a/10797966
|
|
|
|
# comment on https://stackoverflow.com/a/10797966
|
|
|
|
_urlencode_cyon() {
|
|
|
|
_cyon_urlencode() {
|
|
|
|
curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
|
|
|
|
curl -Gso /dev/null -w "%{url_effective}" --data-urlencode @- "" | cut -c 3-
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_load_parameters() {
|
|
|
|
_cyon_load_parameters() {
|
|
|
|
# Read the required parameters to add the TXT entry.
|
|
|
|
# Read the required parameters to add the TXT entry.
|
|
|
|
fulldomain="$(printf "%s" "${1}" | tr '[:upper:]' '[:lower:]')"
|
|
|
|
fulldomain="$(printf "%s" "${1}" | tr '[:upper:]' '[:lower:]')"
|
|
|
|
fulldomain_idn="${fulldomain}"
|
|
|
|
fulldomain_idn="${fulldomain}"
|
|
|
|
|
|
|
|
|
|
|
|
# Special case for IDNs, as cyon needs a domain environment change,
|
|
|
|
# Special case for IDNs, as cyon needs a domain environment change,
|
|
|
|
# which uses the "pretty" instead of the punycode version.
|
|
|
|
# which uses the "pretty" instead of the punycode version.
|
|
|
|
if _is_idn_cyon "${fulldomain}"; then
|
|
|
|
if _cyon_is_idn "${fulldomain}"; then
|
|
|
|
if ! _exists idn; then
|
|
|
|
if ! _exists idn; then
|
|
|
|
_err "Please install idn to process IDN names."
|
|
|
|
_err "Please install idn to process IDN names."
|
|
|
|
_err ""
|
|
|
|
_err ""
|
|
|
@ -127,7 +127,7 @@ _load_parameters() {
|
|
|
|
_H1="X-Requested-With: XMLHttpRequest"
|
|
|
|
_H1="X-Requested-With: XMLHttpRequest"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_info_header() {
|
|
|
|
_cyon_print_header() {
|
|
|
|
if [ "${1}" = "add" ]; then
|
|
|
|
if [ "${1}" = "add" ]; then
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
_info "+---------------------------------------------+"
|
|
|
|
_info "+---------------------------------------------+"
|
|
|
@ -148,15 +148,15 @@ _info_header() {
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_get_cookie_header() {
|
|
|
|
_cyon_get_cookie_header() {
|
|
|
|
printf "%s" "$(sed -n 's/Set-\(Cookie:.*cyon=[^;]*\).*/\1/p' "$HTTP_HEADER" | _tail_n 1)"
|
|
|
|
printf "%s" "$(sed -n 's/Set-\(Cookie:.*cyon=[^;]*\).*/\1/p' "$HTTP_HEADER" | _tail_n 1)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_login() {
|
|
|
|
_cyon_login() {
|
|
|
|
_info " - Logging in..."
|
|
|
|
_info " - Logging in..."
|
|
|
|
|
|
|
|
|
|
|
|
username_encoded="$(printf "%s" "${cyon_username}" | _urlencode_cyon)"
|
|
|
|
username_encoded="$(printf "%s" "${cyon_username}" | _cyon_urlencode)"
|
|
|
|
password_encoded="$(printf "%s" "${cyon_password}" | _urlencode_cyon)"
|
|
|
|
password_encoded="$(printf "%s" "${cyon_password}" | _cyon_urlencode)"
|
|
|
|
|
|
|
|
|
|
|
|
login_url="https://my.cyon.ch/auth/index/dologin-async"
|
|
|
|
login_url="https://my.cyon.ch/auth/index/dologin-async"
|
|
|
|
login_data="$(printf "%s" "username=${username_encoded}&password=${password_encoded}&pathname=%2F")"
|
|
|
|
login_data="$(printf "%s" "username=${username_encoded}&password=${password_encoded}&pathname=%2F")"
|
|
|
@ -165,8 +165,8 @@ _login() {
|
|
|
|
_debug login_response "${login_response}"
|
|
|
|
_debug login_response "${login_response}"
|
|
|
|
|
|
|
|
|
|
|
|
# Bail if login fails.
|
|
|
|
# Bail if login fails.
|
|
|
|
if [ "$(printf "%s" "${login_response}" | _get_response_success)" != "success" ]; then
|
|
|
|
if [ "$(printf "%s" "${login_response}" | _cyon_get_response_success)" != "success" ]; then
|
|
|
|
_err " $(printf "%s" "${login_response}" | _get_response_message)"
|
|
|
|
_err " $(printf "%s" "${login_response}" | _cyon_get_response_message)"
|
|
|
|
_err ""
|
|
|
|
_err ""
|
|
|
|
return 1
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
@ -174,8 +174,8 @@ _login() {
|
|
|
|
_info " success"
|
|
|
|
_info " success"
|
|
|
|
|
|
|
|
|
|
|
|
# NECESSARY!! Load the main page after login, to get the new cookie.
|
|
|
|
# NECESSARY!! Load the main page after login, to get the new cookie.
|
|
|
|
_H2="$(_get_cookie_header)"
|
|
|
|
_H2="$(_cyon_get_cookie_header)"
|
|
|
|
_get "https://my.cyon.ch/" > /dev/null
|
|
|
|
_get "https://my.cyon.ch/" >/dev/null
|
|
|
|
|
|
|
|
|
|
|
|
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
|
|
|
|
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
|
|
|
|
|
|
|
|
|
|
|
@ -199,8 +199,8 @@ _login() {
|
|
|
|
_debug login_otp_response "${login_otp_response}"
|
|
|
|
_debug login_otp_response "${login_otp_response}"
|
|
|
|
|
|
|
|
|
|
|
|
# Bail if OTP authentication fails.
|
|
|
|
# Bail if OTP authentication fails.
|
|
|
|
if [ "$(printf "%s" "${login_otp_response}" | _get_response_success)" != "success" ]; then
|
|
|
|
if [ "$(printf "%s" "${login_otp_response}" | _cyon_get_response_success)" != "success" ]; then
|
|
|
|
_err " $(printf "%s" "${login_otp_response}" | _get_response_message)"
|
|
|
|
_err " $(printf "%s" "${login_otp_response}" | _cyon_get_response_message)"
|
|
|
|
_err ""
|
|
|
|
_err ""
|
|
|
|
return 1
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
@ -211,16 +211,16 @@ _login() {
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_logout() {
|
|
|
|
_cyon_logout() {
|
|
|
|
_info " - Logging out..."
|
|
|
|
_info " - Logging out..."
|
|
|
|
|
|
|
|
|
|
|
|
_get "https://my.cyon.ch/auth/index/dologout" > /dev/null
|
|
|
|
_get "https://my.cyon.ch/auth/index/dologout" >/dev/null
|
|
|
|
|
|
|
|
|
|
|
|
_info " success"
|
|
|
|
_info " success"
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_domain_env() {
|
|
|
|
_cyon_change_domain_env() {
|
|
|
|
_info " - Changing domain environment..."
|
|
|
|
_info " - Changing domain environment..."
|
|
|
|
|
|
|
|
|
|
|
|
# Get the "example.com" part of the full domain name.
|
|
|
|
# Get the "example.com" part of the full domain name.
|
|
|
@ -232,13 +232,13 @@ _domain_env() {
|
|
|
|
domain_env_response="$(_get "${domain_env_url}")"
|
|
|
|
domain_env_response="$(_get "${domain_env_url}")"
|
|
|
|
_debug domain_env_response "${domain_env_response}"
|
|
|
|
_debug domain_env_response "${domain_env_response}"
|
|
|
|
|
|
|
|
|
|
|
|
if ! _check_if_2fa_missed "${domain_env_response}"; then return 1; fi
|
|
|
|
if ! _cyon_check_if_2fa_missed "${domain_env_response}"; then return 1; fi
|
|
|
|
|
|
|
|
|
|
|
|
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
|
|
|
|
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
|
|
|
|
|
|
|
|
|
|
|
|
# Bail if domain environment change fails.
|
|
|
|
# Bail if domain environment change fails.
|
|
|
|
if [ "${domain_env_success}" != "true" ]; then
|
|
|
|
if [ "${domain_env_success}" != "true" ]; then
|
|
|
|
_err " $(printf "%s" "${domain_env_response}" | _get_response_message)"
|
|
|
|
_err " $(printf "%s" "${domain_env_response}" | _cyon_get_response_message)"
|
|
|
|
_err ""
|
|
|
|
_err ""
|
|
|
|
return 1
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
@ -247,7 +247,7 @@ _domain_env() {
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_add_txt() {
|
|
|
|
_cyon_add_txt() {
|
|
|
|
_info " - Adding DNS TXT entry..."
|
|
|
|
_info " - Adding DNS TXT entry..."
|
|
|
|
|
|
|
|
|
|
|
|
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
|
|
|
|
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
|
|
|
@ -256,10 +256,10 @@ _add_txt() {
|
|
|
|
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
|
|
|
|
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
|
|
|
|
_debug add_txt_response "${add_txt_response}"
|
|
|
|
_debug add_txt_response "${add_txt_response}"
|
|
|
|
|
|
|
|
|
|
|
|
if ! _check_if_2fa_missed "${add_txt_response}"; then return 1; fi
|
|
|
|
if ! _cyon_check_if_2fa_missed "${add_txt_response}"; then return 1; fi
|
|
|
|
|
|
|
|
|
|
|
|
add_txt_message="$(printf "%s" "${add_txt_response}" | _get_response_message)"
|
|
|
|
add_txt_message="$(printf "%s" "${add_txt_response}" | _cyon_get_response_message)"
|
|
|
|
add_txt_status="$(printf "%s" "${add_txt_response}" | _get_response_status)"
|
|
|
|
add_txt_status="$(printf "%s" "${add_txt_response}" | _cyon_get_response_status)"
|
|
|
|
|
|
|
|
|
|
|
|
# Bail if adding TXT entry fails.
|
|
|
|
# Bail if adding TXT entry fails.
|
|
|
|
if [ "${add_txt_status}" != "true" ]; then
|
|
|
|
if [ "${add_txt_status}" != "true" ]; then
|
|
|
@ -272,7 +272,7 @@ _add_txt() {
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_delete_txt() {
|
|
|
|
_cyon_delete_txt() {
|
|
|
|
_info " - Deleting DNS TXT entry..."
|
|
|
|
_info " - Deleting DNS TXT entry..."
|
|
|
|
|
|
|
|
|
|
|
|
list_txt_url="https://my.cyon.ch/domain/dnseditor/list-async"
|
|
|
|
list_txt_url="https://my.cyon.ch/domain/dnseditor/list-async"
|
|
|
@ -280,7 +280,7 @@ _delete_txt() {
|
|
|
|
list_txt_response="$(_get "${list_txt_url}" | sed -e 's/data-hash/\\ndata-hash/g')"
|
|
|
|
list_txt_response="$(_get "${list_txt_url}" | sed -e 's/data-hash/\\ndata-hash/g')"
|
|
|
|
_debug list_txt_response "${list_txt_response}"
|
|
|
|
_debug list_txt_response "${list_txt_response}"
|
|
|
|
|
|
|
|
|
|
|
|
if ! _check_if_2fa_missed "${list_txt_response}"; then return 1; fi
|
|
|
|
if ! _cyon_check_if_2fa_missed "${list_txt_response}"; then return 1; fi
|
|
|
|
|
|
|
|
|
|
|
|
# Find and delete all acme challenge entries for the $fulldomain.
|
|
|
|
# Find and delete all acme challenge entries for the $fulldomain.
|
|
|
|
_dns_entries="$(printf "%b\n" "${list_txt_response}" | sed -n 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p')"
|
|
|
|
_dns_entries="$(printf "%b\n" "${list_txt_response}" | sed -n 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p')"
|
|
|
@ -293,8 +293,8 @@ _delete_txt() {
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
hash_encoded="$(printf "%s" "${_hash}" | _urlencode_cyon)"
|
|
|
|
hash_encoded="$(printf "%s" "${_hash}" | _cyon_urlencode)"
|
|
|
|
identifier_encoded="$(printf "%s" "${_identifier}" | _urlencode_cyon)"
|
|
|
|
identifier_encoded="$(printf "%s" "${_identifier}" | _cyon_urlencode)"
|
|
|
|
|
|
|
|
|
|
|
|
delete_txt_url="https://my.cyon.ch/domain/dnseditor/delete-record-async"
|
|
|
|
delete_txt_url="https://my.cyon.ch/domain/dnseditor/delete-record-async"
|
|
|
|
delete_txt_data="$(printf "%s" "hash=${hash_encoded}&identifier=${identifier_encoded}")"
|
|
|
|
delete_txt_data="$(printf "%s" "hash=${hash_encoded}&identifier=${identifier_encoded}")"
|
|
|
@ -302,10 +302,10 @@ _delete_txt() {
|
|
|
|
delete_txt_response="$(_post "$delete_txt_data" "$delete_txt_url")"
|
|
|
|
delete_txt_response="$(_post "$delete_txt_data" "$delete_txt_url")"
|
|
|
|
_debug delete_txt_response "${delete_txt_response}"
|
|
|
|
_debug delete_txt_response "${delete_txt_response}"
|
|
|
|
|
|
|
|
|
|
|
|
if ! _check_if_2fa_missed "${delete_txt_response}"; then return 1; fi
|
|
|
|
if ! _cyon_check_if_2fa_missed "${delete_txt_response}"; then return 1; fi
|
|
|
|
|
|
|
|
|
|
|
|
delete_txt_message="$(printf "%s" "${delete_txt_response}" | _get_response_message)"
|
|
|
|
delete_txt_message="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_message)"
|
|
|
|
delete_txt_status="$(printf "%s" "${delete_txt_response}" | _get_response_status)"
|
|
|
|
delete_txt_status="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_status)"
|
|
|
|
|
|
|
|
|
|
|
|
# Skip if deleting TXT entry fails.
|
|
|
|
# Skip if deleting TXT entry fails.
|
|
|
|
if [ "${delete_txt_status}" != "true" ]; then
|
|
|
|
if [ "${delete_txt_status}" != "true" ]; then
|
|
|
@ -319,19 +319,19 @@ _delete_txt() {
|
|
|
|
_info ""
|
|
|
|
_info ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_get_response_message() {
|
|
|
|
_cyon_get_response_message() {
|
|
|
|
_egrep_o '"message":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
|
|
|
_egrep_o '"message":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_get_response_status() {
|
|
|
|
_cyon_get_response_status() {
|
|
|
|
_egrep_o '"status":\w*' | cut -d : -f 2
|
|
|
|
_egrep_o '"status":\w*' | cut -d : -f 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_get_response_success() {
|
|
|
|
_cyon_get_response_success() {
|
|
|
|
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
|
|
|
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_check_if_2fa_missed() {
|
|
|
|
_cyon_check_if_2fa_missed() {
|
|
|
|
# Did we miss the 2FA?
|
|
|
|
# Did we miss the 2FA?
|
|
|
|
if test "${1#*multi_factor_form}" != "${1}"; then
|
|
|
|
if test "${1#*multi_factor_form}" != "${1}"; then
|
|
|
|
_err " Missed OTP authentication!"
|
|
|
|
_err " Missed OTP authentication!"
|
|
|
|