Merge branch 'dev' into add-mijn-host
commit
ae0aa6a412
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034,SC2154
|
||||
|
||||
# Script to create certificate to Alibaba Cloud CDN
|
||||
#
|
||||
# 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 CDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates
|
||||
# export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com"
|
||||
# If you have 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/"
|
||||
|
||||
ali_cdn_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
_debug _cca "$_cca"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
# 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_CDN_DOMAIN
|
||||
if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then
|
||||
_savedeployconf DEPLOY_ALI_CDN_DOMAIN "$DEPLOY_ALI_CDN_DOMAIN"
|
||||
else
|
||||
DEPLOY_ALI_CDN_DOMAIN="$_cdomain"
|
||||
fi
|
||||
|
||||
# read cert and key files and urlencode both
|
||||
_cert=$(_url_encode upper-hex <"$_cfullchain")
|
||||
_key=$(_url_encode upper-hex <"$_ckey")
|
||||
|
||||
_debug2 _cert "$_cert"
|
||||
_debug2 _key "$_key"
|
||||
|
||||
## update domain ssl config
|
||||
for domain in $DEPLOY_ALI_CDN_DOMAIN; do
|
||||
_set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key"
|
||||
if _ali_rest "Set CDN domain SSL certificate for $domain" "" POST; then
|
||||
_info "Domain $domain certificate has been deployed successfully"
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# domain pub pri
|
||||
_set_cdn_domain_ssl_certificate_query() {
|
||||
endpoint=$Ali_CDN_API
|
||||
query=''
|
||||
query=$query'AccessKeyId='$Ali_Key
|
||||
query=$query'&Action=SetCdnDomainSSLCertificate'
|
||||
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-05-10'
|
||||
}
|
@ -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'
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed.
|
||||
#
|
||||
# Public domain, 2024, Tony Rielly <https://github.com/ms264556>
|
||||
#
|
||||
# ```sh
|
||||
# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus
|
||||
# ```
|
||||
#
|
||||
# Then you need to set the environment variables for the
|
||||
# deploy script to work.
|
||||
#
|
||||
# ```sh
|
||||
# export RUCKUS_HOST=myruckus.example.com
|
||||
# export RUCKUS_USER=myruckususername
|
||||
# export RUCKUS_PASS=myruckuspassword
|
||||
#
|
||||
# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus
|
||||
# ```
|
||||
#
|
||||
# returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
ruckus_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
_err_code=0
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
_debug _cca "$_cca"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
_getdeployconf RUCKUS_HOST
|
||||
_getdeployconf RUCKUS_USER
|
||||
_getdeployconf RUCKUS_PASS
|
||||
|
||||
if [ -z "$RUCKUS_HOST" ]; then
|
||||
_debug "Using _cdomain as RUCKUS_HOST, please set if not correct."
|
||||
RUCKUS_HOST="$_cdomain"
|
||||
fi
|
||||
|
||||
if [ -z "$RUCKUS_USER" ]; then
|
||||
_err "Need to set the env variable RUCKUS_USER"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$RUCKUS_PASS" ]; then
|
||||
_err "Need to set the env variable RUCKUS_PASS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_savedeployconf RUCKUS_HOST "$RUCKUS_HOST"
|
||||
_savedeployconf RUCKUS_USER "$RUCKUS_USER"
|
||||
_savedeployconf RUCKUS_PASS "$RUCKUS_PASS"
|
||||
|
||||
_debug RUCKUS_HOST "$RUCKUS_HOST"
|
||||
_debug RUCKUS_USER "$RUCKUS_USER"
|
||||
_secure_debug RUCKUS_PASS "$RUCKUS_PASS"
|
||||
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
|
||||
_info "Discovering the login URL"
|
||||
_get "https://$RUCKUS_HOST" >/dev/null
|
||||
_login_url="$(_response_header 'Location')"
|
||||
if [ -n "$_login_url" ]; then
|
||||
_login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||')
|
||||
if [ -z "$_login_path" ]; then
|
||||
# redirect was to a different host
|
||||
_err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${_login_url}" ]; then
|
||||
_err "Connection failed: couldn't find login page."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_base_url=$(dirname "$_login_url")
|
||||
_login_page=$(basename "$_login_url")
|
||||
|
||||
if [ "$_login_page" = "index.html" ]; then
|
||||
_err "Connection temporarily unavailable: Unleashed Rebuilding."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_login_page" = "wizard.jsp" ]; then
|
||||
_err "Connection failed: Setup Wizard not complete."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Login"
|
||||
_username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)"
|
||||
_password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)"
|
||||
_login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")"
|
||||
_post "$_login_query" "$_login_url" >/dev/null
|
||||
|
||||
_login_code="$(_response_code)"
|
||||
if [ "$_login_code" = "200" ]; then
|
||||
_err "Login failed: incorrect credentials."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Collect Session Cookie"
|
||||
_H1="Cookie: $(_response_cookie)"
|
||||
export _H1
|
||||
_info "Collect CSRF Token"
|
||||
_H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')"
|
||||
export _H2
|
||||
|
||||
_info "Uploading certificate"
|
||||
_post_upload "uploadcert" "$_cfullchain"
|
||||
|
||||
_info "Uploading private key"
|
||||
_post_upload "uploadprivatekey" "$_ckey"
|
||||
|
||||
_info "Replacing certificate"
|
||||
_replace_cert_ajax='<ajax-request action="docmd" comp="system" updater="rid.0.5" xcmd="replace-cert" checkAbility="6" timeout="-1"><xcmd cmd="replace-cert" cn="'$RUCKUS_HOST'"/></ajax-request>'
|
||||
_post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
|
||||
|
||||
_info "Rebooting"
|
||||
_cert_reboot_ajax='<ajax-request action="docmd" comp="worker" updater="rid.0.5" xcmd="cert-reboot" checkAbility="6"><xcmd cmd="cert-reboot" action="undefined"/></ajax-request>'
|
||||
_post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_response_code() {
|
||||
_egrep_o <"$HTTP_HEADER" "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*"
|
||||
}
|
||||
|
||||
_response_header() {
|
||||
grep <"$HTTP_HEADER" -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t "
|
||||
}
|
||||
|
||||
_response_cookie() {
|
||||
_response_header 'Set-Cookie' | sed 's/;.*//'
|
||||
}
|
||||
|
||||
_post_upload() {
|
||||
_post_action="$1"
|
||||
_post_file="$2"
|
||||
|
||||
_post_boundary="----FormBoundary$(date "+%s%N")"
|
||||
|
||||
_post_data="$({
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action"
|
||||
printf -- "Content-Type: application/octet-stream\r\n\r\n"
|
||||
printf -- "%s\r\n" "$(cat "$_post_file")"
|
||||
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
|
||||
printf -- "%s\r\n" "$_post_action"
|
||||
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n"
|
||||
printf -- "%s\r\n" "uploader_$_post_action"
|
||||
|
||||
printf -- "--%s--\r\n\r\n" "$_post_boundary"
|
||||
})"
|
||||
|
||||
_post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
# 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"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_alviy_add _acme-challenge.www.domain.com "content"
|
||||
dns_alviy_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
|
||||
if [ -z "$Alviy_token" ]; then
|
||||
Alviy_token=""
|
||||
_err "Please specify Alviy token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable Alviy_token "$Alviy_token"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting existing records"
|
||||
if _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
|
||||
_info "This record already exists, skipping"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_add_data="{\"content\":\"$txtvalue\",\"type\":\"TXT\"}"
|
||||
_debug2 _add_data "$_add_data"
|
||||
_info "Adding record"
|
||||
if _alviy_rest POST "zone/$_domain/domain/$fulldomain/" "$_add_data"; then
|
||||
_debug "Checking updated records of '${fulldomain}'"
|
||||
|
||||
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
|
||||
_err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
else
|
||||
_err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_sleep 10
|
||||
_info "Added TXT record '${txtvalue}' for '${fulldomain}'."
|
||||
return 0
|
||||
}
|
||||
|
||||
#fulldomain
|
||||
dns_alviy_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
|
||||
_info "The record does not exist, skip"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_add_data=""
|
||||
uuid=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | tr "," "\n" | grep uuid | cut -d \" -f4)
|
||||
# delete record
|
||||
_debug "Delete TXT record for '${fulldomain}'"
|
||||
if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then
|
||||
_err "Cannot delete empty TXT record for '$fulldomain'"
|
||||
return 1
|
||||
fi
|
||||
_info "The record '$fulldomain'='$txtvalue' deleted"
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=3
|
||||
a="init"
|
||||
while [ -n "$a" ]; do
|
||||
a=$(printf "%s" "$domain" | cut -d . -f $i-)
|
||||
i=$((i + 1))
|
||||
done
|
||||
n=$((i - 3))
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $n-)
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
_alviy_rest GET "zone/$domain/"
|
||||
_debug "can't get host from $domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _alviy_rest GET "zone/$h/"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" '"code":"NOT_FOUND"'; then
|
||||
_debug "$h not found"
|
||||
else
|
||||
s=$((n - 1))
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_alviy_txt_exists() {
|
||||
zone=$1
|
||||
domain=$2
|
||||
content_data=$3
|
||||
_debug "Getting existing records"
|
||||
|
||||
if ! _alviy_rest GET "zone/$zone/domain/$domain/TXT/"; then
|
||||
_info "The record does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "$3"; then
|
||||
_info "The record has other value"
|
||||
return 1
|
||||
fi
|
||||
# GOOD code return - TRUE function
|
||||
return 0
|
||||
}
|
||||
|
||||
_alviy_rest() {
|
||||
method=$1
|
||||
path="$2"
|
||||
content_data="$3"
|
||||
_debug "$path"
|
||||
|
||||
export _H1="Authorization: Bearer $Alviy_token"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$content_data" ] || [ "$method" = "DELETE" ]; then
|
||||
_debug "data ($method): " "$content_data"
|
||||
response="$(_post "$content_data" "$Alviy_Api/$path" "" "$method")"
|
||||
else
|
||||
response="$(_get "$Alviy_Api/$path")"
|
||||
fi
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||
if [ "$_code" = "401" ]; then
|
||||
_err "It seems that your api key or secret is not correct."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_code" != "200" ]; then
|
||||
_err "API call error ($method): $path Response code $_code"
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error on rest call ($method): $path. Response:"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
@ -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 <kholin+acme.omglolapi@omg.lol>
|
||||
'
|
||||
|
||||
# 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"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue