diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml
index 615e5d8b..507755c9 100644
--- a/.github/workflows/DNS.yml
+++ b/.github/workflows/DNS.yml
@@ -384,7 +384,7 @@ jobs:
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 install -y curl socat
+ pkg install -y curl socat libnghttp2
usesh: true
copyback: false
run: |
diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml
index 6daa9be4..5a0d81ba 100644
--- a/.github/workflows/DragonFlyBSD.yml
+++ b/.github/workflows/DragonFlyBSD.yml
@@ -62,7 +62,7 @@ jobs:
nat: |
"8080": "80"
prepare: |
- pkg install -y curl socat
+ pkg install -y curl socat libnghttp2
usesh: true
run: |
cd ../acmetest \
diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml
index 7746645a..745a9408 100644
--- a/.github/workflows/OpenBSD.yml
+++ b/.github/workflows/OpenBSD.yml
@@ -66,7 +66,7 @@ jobs:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
- prepare: pkg_add socat curl wget
+ prepare: pkg_add socat curl wget libnghttp2
usesh: true
copyback: false
run: |
diff --git a/README.md b/README.md
index 73ff3321..717ecf5f 100644
--- a/README.md
+++ b/README.md
@@ -506,10 +506,6 @@ Support this project with your organization. Your logo will show up here with a
-#### Sponsors
-
-[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
-
# 19. License & Others
diff --git a/acme.sh b/acme.sh
index 7a9468fd..54dfa9a5 100755
--- a/acme.sh
+++ b/acme.sh
@@ -102,12 +102,12 @@ ECC_SUFFIX="${ECC_SEP}ecc"
LOG_LEVEL_1=1
LOG_LEVEL_2=2
LOG_LEVEL_3=3
-DEFAULT_LOG_LEVEL="$LOG_LEVEL_1"
+DEFAULT_LOG_LEVEL="$LOG_LEVEL_2"
DEBUG_LEVEL_1=1
DEBUG_LEVEL_2=2
DEBUG_LEVEL_3=3
-DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1
+DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_2
DEBUG_LEVEL_NONE=0
DOH_CLOUDFLARE=1
@@ -923,8 +923,16 @@ _sed_i() {
fi
}
+if [ "$(echo abc | egrep -o b 2>/dev/null)" = "b" ]; then
+ __USE_EGREP=1
+else
+ __USE_EGREP=""
+fi
+
_egrep_o() {
- if ! egrep -o "$1" 2>/dev/null; then
+ if [ "$__USE_EGREP" ]; then
+ egrep -o -- "$1"
+ else
sed -n 's/.*\('"$1"'\).*/\1/p'
fi
}
@@ -1553,7 +1561,7 @@ createDomainKey() {
createCSR() {
_info "Creating csr"
if [ -z "$1" ]; then
- _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...]"
+ _usage "Usage: $PROJECT_ENTRY --create-csr --domain [--domain ...] [--ecc]"
return
fi
@@ -2101,9 +2109,20 @@ _head_n() {
}
_tail_n() {
- if ! tail -n "$1" 2>/dev/null; then
+ if _is_solaris; then
#fix for solaris
tail -"$1"
+ else
+ tail -n "$1"
+ fi
+}
+
+_tail_c() {
+ if _is_solaris; then
+ #fix for solaris
+ tail -"$1"c
+ else
+ tail -c "$1"
fi
}
@@ -2278,7 +2297,7 @@ _setopt() {
if [ ! -f "$__conf" ]; then
touch "$__conf"
fi
- if [ -n "$(tail -c1 <"$__conf")" ]; then
+ if [ -n "$(_tail_c 1 <"$__conf")" ]; then
echo >>"$__conf"
fi
@@ -3111,7 +3130,7 @@ _setNginx() {
_err "nginx command is not found."
return 1
fi
- NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "--conf-path=[^ ]* " | tr -d " ")"
+ NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "\-\-conf-path=[^ ]* " | tr -d " ")"
_debug NGINX_CONF "$NGINX_CONF"
NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)"
_debug NGINX_CONF "$NGINX_CONF"
@@ -4996,9 +5015,9 @@ $_authorizations_map"
errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)"
_debug2 errordetail "$errordetail"
if [ "$errordetail" ]; then
- _err "$d:Verify error:$errordetail"
+ _err "Invalid status, $d:Verify error detail:$errordetail"
else
- _err "$d:Verify error:$error"
+ _err "Invalid status, $d:Verify error:$error"
fi
if [ "$DEBUG" ]; then
if [ "$vtype" = "$VTYPE_HTTP" ]; then
@@ -5025,7 +5044,7 @@ $_authorizations_map"
elif _contains "$status" "processing"; then
_info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)"
else
- _err "$d:Verify error:$response"
+ _err "Unknown status: $status, $d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
_clearup
_on_issue_err "$_post_hook" "$vlist"
@@ -5038,7 +5057,7 @@ $_authorizations_map"
_send_signed_request "$_authz_url"
if [ "$?" != "0" ]; then
- _err "$d:Verify error:$response"
+ _err "Invalid code, $d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
_clearup
_on_issue_err "$_post_hook" "$vlist"
@@ -6880,7 +6899,7 @@ Parameters:
-f, --force Force install, force cert renewal or override sudo restrictions.
--staging, --test Use staging server, for testing.
- --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
+ --debug [0|1|2|3] Output debug info. Defaults to $DEBUG_LEVEL_DEFAULT if argument is omitted.
--output-insecure Output all the sensitive messages.
By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
-w, --webroot Specifies the web root folder for web root mode.
@@ -6898,7 +6917,7 @@ Parameters:
-k, --keylength Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
-ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096
--log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
- --log-level <1|2> Specifies the log level, default is 1.
+ --log-level <1|2> Specifies the log level, default is $DEFAULT_LOG_LEVEL.
--syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
--eab-kid Key Identifier for External Account Binding.
--eab-hmac-key HMAC key for External Account Binding.
@@ -6906,7 +6925,7 @@ Parameters:
These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert:
- --cert-file Path to copy the cert file to after issue/renew..
+ --cert-file Path to copy the cert file to after issue/renew.
--key-file Path to copy the key file to after issue/renew.
--ca-file Path to copy the intermediate cert file to after issue/renew.
--fullchain-file Path to copy the fullchain cert file to after issue/renew.
@@ -6936,7 +6955,8 @@ Parameters:
--no-profile Only valid for '--install' command, which means: do not install aliases to user profile.
--no-color Do not output color text.
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
- --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr'
+ --ecc Specifies use of the ECC cert. Only valid for '--install-cert', '--renew', '--remove ', '--revoke',
+ '--deploy', '--to-pkcs8', '--to-pkcs12' and '--create-csr'.
--csr Specifies the input csr.
--pre-hook Command to be run before obtaining any certificates.
--post-hook Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed.
diff --git a/deploy/panos.sh b/deploy/panos.sh
index ef622ded..89458e5f 100644
--- a/deploy/panos.sh
+++ b/deploy/panos.sh
@@ -7,11 +7,15 @@
#
# Firewall admin with superuser and IP address is required.
#
-# export PANOS_USER="" # required
-# export PANOS_PASS="" # required
-# export PANOS_HOST="" # required
+# REQURED:
+# export PANOS_HOST=""
+# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
+# export PANOS_PASS=""
+#
+# The script will automatically generate a new API key if
+# no key is found, or if a saved key has expired or is invalid.
-# This function is to parse the XML
+# This function is to parse the XML response from the firewall
parse_response() {
type=$2
if [ "$type" = 'keygen' ]; then
@@ -23,25 +27,46 @@ parse_response() {
message="PAN-OS Key could not be set."
fi
else
- status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g')
- message=$(echo "$1" | sed 's/^.*\(.*\)<\/result.*/\1/g')
+ status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g')
+ message=$(echo "$1" | tr -d '\n' | sed 's/.*\(\|\|\)\([^<]*\).*/\2/g')
+ _debug "Firewall message: $message"
+ if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then
+ _debug "**** API Key has EXPIRED or is INVALID ****"
+ unset _panos_key
+ fi
fi
return 0
}
+#This function is used to deploy to the firewall
deployer() {
content=""
- type=$1 # Types are keygen, cert, key, commit
- _debug "**** Deploying $type *****"
+ type=$1 # Types are keytest, keygen, cert, key, commit
panos_url="https://$_panos_host/api/"
+
+ #Test API Key by performing a lookup
+ if [ "$type" = 'keytest' ]; then
+ _debug "**** Testing saved API Key ****"
+ _H1="Content-Type: application/x-www-form-urlencoded"
+ # Get Version Info to test key
+ content="type=version&key=$_panos_key"
+ ## Exclude all scopes for the empty commit
+ #_exclude_scope="excludeexcludeexclude"
+ #content="type=commit&action=partial&key=$_panos_key&cmd=$_exclude_scopeacmekeytest"
+ fi
+
+ # Generate API Key
if [ "$type" = 'keygen' ]; then
+ _debug "**** Generating new API Key ****"
_H1="Content-Type: application/x-www-form-urlencoded"
content="type=keygen&user=$_panos_user&password=$_panos_pass"
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
fi
+ # Deploy Cert or Key
if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then
- #Generate DEIM
+ _debug "**** Deploying $type ****"
+ #Generate DELIM
delim="-----MultipartDelimiter$(date "+%s%N")"
nl="\015\012"
#Set Header
@@ -61,7 +86,7 @@ deployer() {
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
- content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
+ content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
fi
#Close multipart
content="$content${nl}--$delim--${nl}${nl}"
@@ -69,16 +94,25 @@ deployer() {
content=$(printf %b "$content")
fi
+ # Commit changes
if [ "$type" = 'commit' ]; then
+ _debug "**** Committing changes ****"
export _H1="Content-Type: application/x-www-form-urlencoded"
- cmd=$(printf "%s" "<$_panos_user>$_panos_user>" | _url_encode)
- content="type=commit&key=$_panos_key&cmd=$cmd"
+ #Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
+ if [ "$FORCE" ]; then
+ _debug "Force switch detected. Committing ALL changes to the firewall."
+ cmd=$(printf "%s" "$_panos_user" | _url_encode)
+ else
+ _exclude_scope="excludeexclude"
+ cmd=$(printf "%s" "$_exclude_scope$_panos_user" | _url_encode)
+ fi
+ content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
fi
+
response=$(_post "$content" "$panos_url" "" "POST")
parse_response "$response" "$type"
# Saving response to variables
response_status=$status
- #DEBUG
_debug response_status "$response_status"
if [ "$response_status" = "success" ]; then
_debug "Successfully deployed $type"
@@ -92,43 +126,85 @@ deployer() {
# This is the main function that will call the other functions to deploy everything.
panos_deploy() {
- _cdomain="$1"
+ _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename
_ckey="$2"
_cfullchain="$5"
- # PANOS ENV VAR check
- if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then
- _debug "No ENV variables found lets check for saved variables"
- _getdeployconf PANOS_USER
- _getdeployconf PANOS_PASS
- _getdeployconf PANOS_HOST
- _panos_user=$PANOS_USER
- _panos_pass=$PANOS_PASS
- _panos_host=$PANOS_HOST
- if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then
- _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs."
- return 1
- else
- _debug "Using saved env variables."
- fi
+
+ # VALID FILE CHECK
+ if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then
+ _err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying."
+ return 1
+ fi
+
+ # PANOS_HOST
+ if [ "$PANOS_HOST" ]; then
+ _debug "Detected ENV variable PANOS_HOST. Saving to file."
+ _savedeployconf PANOS_HOST "$PANOS_HOST" 1
else
- _debug "Detected ENV variables to be saved to the deploy conf."
- # Encrypt and save user
+ _debug "Attempting to load variable PANOS_HOST from file."
+ _getdeployconf PANOS_HOST
+ fi
+
+ # PANOS USER
+ if [ "$PANOS_USER" ]; then
+ _debug "Detected ENV variable PANOS_USER. Saving to file."
_savedeployconf PANOS_USER "$PANOS_USER" 1
+ else
+ _debug "Attempting to load variable PANOS_USER from file."
+ _getdeployconf PANOS_USER
+ fi
+
+ # PANOS_PASS
+ if [ "$PANOS_PASS" ]; then
+ _debug "Detected ENV variable PANOS_PASS. Saving to file."
_savedeployconf PANOS_PASS "$PANOS_PASS" 1
- _savedeployconf PANOS_HOST "$PANOS_HOST" 1
- _panos_user="$PANOS_USER"
- _panos_pass="$PANOS_PASS"
- _panos_host="$PANOS_HOST"
+ else
+ _debug "Attempting to load variable PANOS_PASS from file."
+ _getdeployconf PANOS_PASS
fi
- _debug "Let's use username and pass to generate token."
- if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then
- _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
+
+ # PANOS_KEY
+ _getdeployconf PANOS_KEY
+ if [ "$PANOS_KEY" ]; then
+ _debug "Detected saved key."
+ _panos_key=$PANOS_KEY
+ else
+ _debug "No key detected"
+ unset _panos_key
+ fi
+
+ #Store variables
+ _panos_host=$PANOS_HOST
+ _panos_user=$PANOS_USER
+ _panos_pass=$PANOS_PASS
+
+ #Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
+ if [ "$_panos_host" ] && [ "$_panos_key" ]; then
+ _debug "**** Testing API KEY ****"
+ deployer keytest
+ fi
+
+ # Check for valid variables
+ if [ -z "$_panos_host" ]; then
+ _err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs."
+ return 1
+ elif [ -z "$_panos_user" ]; then
+ _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs."
+ return 1
+ elif [ -z "$_panos_pass" ]; then
+ _err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
else
- _debug "Getting PANOS KEY"
- deployer keygen
+ # Generate a new API key if no valid API key is found
+ if [ -z "$_panos_key" ]; then
+ _debug "**** Generating new PANOS API KEY ****"
+ deployer keygen
+ _savedeployconf PANOS_KEY "$_panos_key" 1
+ fi
+
+ # Confirm that a valid key was generated
if [ -z "$_panos_key" ]; then
- _err "Missing apikey."
+ _err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the PANOS_USER and PANOS_PASS credentials and try again"
return 1
else
deployer cert
diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh
index 8dc99a85..15f961e2 100644
--- a/deploy/synology_dsm.sh
+++ b/deploy/synology_dsm.sh
@@ -15,11 +15,12 @@
# 1. export SYNO_Username="adminUser"
# 2. export SYNO_Password="adminPassword"
# Optional exports (shown values are the defaults):
-# - export SYNO_Certificate="" to replace a specific certificate via description
+# - export SYNO_Certificate="" - to replace a specific certificate via description
# - export SYNO_Scheme="http"
# - export SYNO_Hostname="localhost"
# - export SYNO_Port="5000"
-# - export SYNO_Device_Name="CertRenewal" - required for skipping 2FA-OTP
+# - export SYNO_Create=1 to allow creating the certificate if it doesn't exist
+# - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled
# - export SYNO_Device_ID="" - required for skipping 2FA-OTP
# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com
################################################################################
@@ -110,8 +111,10 @@ synology_dsm_deploy() {
_debug "Getting API version"
response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth")
+ api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([0-9]*\)".*/\1/p')
api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p')
_debug3 response "$response"
+ _debug3 api_path "$api_path"
_debug3 api_version "$api_version"
# Login, get the session ID & SynoToken from JSON
@@ -151,21 +154,26 @@ synology_dsm_deploy() {
response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes")
_debug3 response "$response"
# Get device ID if still empty first, otherwise log in right away
+ # If SYNO_Device_Name is set, we treat that account enabled two-factor authorization, consider SYNO_Device_ID is not set, so it won't be able to login without requiring the OTP code.
elif [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then
printf "Enter OTP code for user '%s': " "$SYNO_Username"
read -r otp_code
- response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name")
- _debug3 response "$response"
- SYNO_Device_ID=$(echo "$response" | grep "device_id" | sed -n 's/.*"device_id" *: *"\([^"]*\).*/\1/p')
+ response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&otp_code=$otp_code&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name")
+ _secure_debug3 response "$response"
+
+ id_property='device_id'
+ [ "${api_version}" -gt '6' ] || id_property='did'
+ SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p')
_secure_debug2 SYNO_Device_ID "$SYNO_Device_ID"
+ # Otherwise, if SYNO_Device_ID is set, we can just use it to login.
else
if [ -z "${SYNO_Device_Name:-}" ]; then
printf "Enter device name or leave empty for default (CertRenewal): "
read -r SYNO_Device_Name
[ -n "${SYNO_Device_Name}" ] || SYNO_Device_Name="CertRenewal"
fi
- response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID")
- _debug3 response "$response"
+ response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_Device_Name&device_id=$SYNO_Device_ID")
+ _secure_debug3 response "$response"
fi
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
@@ -183,7 +191,7 @@ synology_dsm_deploy() {
_H1="X-SYNO-TOKEN: $token"
export _H1
- _debug2 H1 "${_H1}"
+ _debug2 H1 "${_H1}"
# Now that we know the username & password are good, save them
_savedeployconf SYNO_Username "$SYNO_Username"
diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh
index c2105672..c69839dc 100755
--- a/dnsapi/dns_ali.sh
+++ b/dnsapi/dns_ali.sh
@@ -117,7 +117,7 @@ _ali_urlencode() {
_ali_nonce() {
#_head_n 1 <
# Also used to test credentials and URI.
# No params.
+pleskxml_tplt_get_additional_domains=""
+# Get a list of additional domains that PLESK can manage, so we can check root domain + host for acme.sh
+# No params.
+
pleskxml_tplt_get_dns_records="%s"
# Get all DNS records for a Plesk domain ID.
# PARAM = Plesk domain id to query
@@ -375,16 +379,44 @@ _pleskxml_get_root_domain() {
return 1
fi
- # Generate a crude list of domains known to this Plesk account.
+ # Generate a crude list of domains known to this Plesk account based on subscriptions.
# We convert tags to so it'll flag on a hit with either or fields,
# for non-Western character sets.
# Output will be one line per known domain, containing 2 tages and a single tag
# We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned.
output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')"
+ debug_output="$(printf "%s" "$output" | sed -n 's:.*\(.*\).*:\1:p')"
+
+ _debug 'Domains managed by Plesk server are:'
+ _debug "$debug_output"
+
+ _debug "Querying Plesk server for list of additional managed domains..."
+
+ _call_api "$pleskxml_tplt_get_additional_domains"
+ if [ "$pleskxml_retcode" -ne 0 ]; then
+ return 1
+ fi
+
+ # Generate a crude list of additional domains known to this Plesk account based on sites.
+ # We convert tags to so it'll flag on a hit with either or fields,
+ # for non-Western character sets.
+ # Output will be one line per known domain, containing 2 tages and a single tag
+ # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned.
+
+ output_additional="$(_api_response_split "$pleskxml_prettyprint_result" 'result' 'ok' | sed 's///g;s/<\/ascii-name>/<\/name>/g' | grep '' | grep '')"
+ debug_additional="$(printf "%s" "$output_additional" | sed -n 's:.*\(.*\).*:\1:p')"
+
+ _debug 'Additional domains managed by Plesk server are:'
+ _debug "$debug_additional"
+
+ # Concate the two outputs together.
+
+ output="$(printf "%s" "$output $NEWLINE $output_additional")"
+ debug_output="$(printf "%s" "$output" | sed -n 's:.*\(.*\).*:\1:p')"
- _debug 'Domains managed by Plesk server are (ignore the hacked output):'
- _debug "$output"
+ _debug 'Domains (including additional) managed by Plesk server are:'
+ _debug "$debug_output"
# loop and test if domain, or any parent domain, is managed by Plesk
# Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain