mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-08-13 12:33:30 +02:00
Merge branch 'dev' into master
This commit is contained in:
commit
24501ac0ca
13 changed files with 805 additions and 67 deletions
116
acme.sh
116
acme.sh
|
|
@ -1995,6 +1995,26 @@ _calc_next_renew_time() {
|
||||||
printf "%s" "$_cnrt_next"
|
printf "%s" "$_cnrt_next"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Usage: _calc_validto_renew_time notaftertime renewaldays now
|
||||||
|
#Prints the next renew time for a cert issued with a relative --valid-to.
|
||||||
|
#A negative renewaldays is anchored to the expiry: notaftertime +
|
||||||
|
#renewaldays*86400. Otherwise the cert renews one day before the expiry,
|
||||||
|
#or one hour before for certs whose lifetime is 24 hours or less.
|
||||||
|
_calc_validto_renew_time() {
|
||||||
|
_cvrt_end="$1"
|
||||||
|
_cvrt_days="$2"
|
||||||
|
_cvrt_now="$3"
|
||||||
|
if [ "$_cvrt_days" ] && [ "$_cvrt_days" -lt 0 ]; then
|
||||||
|
_math "$_cvrt_end" + "$_cvrt_days" \* 24 \* 60 \* 60
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [ "$(_math "$_cvrt_end" - "$_cvrt_now")" -gt 86400 ]; then
|
||||||
|
_math "$_cvrt_end" - 86400
|
||||||
|
else
|
||||||
|
_math "$_cvrt_end" - 3600
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
_mktemp() {
|
_mktemp() {
|
||||||
if _exists mktemp; then
|
if _exists mktemp; then
|
||||||
if mktemp 2>/dev/null; then
|
if mktemp 2>/dev/null; then
|
||||||
|
|
@ -4125,7 +4145,7 @@ _regAccount() {
|
||||||
fi
|
fi
|
||||||
_savecaconf "ACCOUNT_URL" "$_accUri"
|
_savecaconf "ACCOUNT_URL" "$_accUri"
|
||||||
else
|
else
|
||||||
ACCOUNT_URL="$(_readcaconf ACCOUNT_URL)"
|
_accUri="$(_readcaconf ACCOUNT_URL)"
|
||||||
fi
|
fi
|
||||||
export ACCOUNT_URL="$_accUri"
|
export ACCOUNT_URL="$_accUri"
|
||||||
|
|
||||||
|
|
@ -4179,6 +4199,12 @@ updateaccount() {
|
||||||
if [ "$code" = '200' ]; then
|
if [ "$code" = '200' ]; then
|
||||||
echo "$response" >"$ACCOUNT_JSON_PATH"
|
echo "$response" >"$ACCOUNT_JSON_PATH"
|
||||||
_info "Account update success for $_accUri."
|
_info "Account update success for $_accUri."
|
||||||
|
# persist the effective mailbox like _regAccount does; otherwise
|
||||||
|
# "--update-account -m new@..." updates the CA but the local conf
|
||||||
|
# keeps showing the old address (issue 4673)
|
||||||
|
if [ "$_email" ]; then
|
||||||
|
_savecaconf "CA_EMAIL" "$_email"
|
||||||
|
fi
|
||||||
|
|
||||||
ACCOUNT_THUMBPRINT="$(__calc_account_thumbprint)"
|
ACCOUNT_THUMBPRINT="$(__calc_account_thumbprint)"
|
||||||
_info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT"
|
_info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT"
|
||||||
|
|
@ -5298,7 +5324,7 @@ $_authorizations_map"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018
|
# Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018
|
||||||
entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
|
entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^{]*"type":"'$vtype'"[^}]*')"
|
||||||
_debug entry "$entry"
|
_debug entry "$entry"
|
||||||
|
|
||||||
if [ -z "$keyauthorization" -a -z "$entry" ]; then
|
if [ -z "$keyauthorization" -a -z "$entry" ]; then
|
||||||
|
|
@ -5630,7 +5656,7 @@ $_authorizations_map"
|
||||||
status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
|
status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
|
||||||
_debug2 status "$status"
|
_debug2 status "$status"
|
||||||
if _contains "$status" "invalid"; then
|
if _contains "$status" "invalid"; then
|
||||||
error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')"
|
error="$(echo "$response" | _egrep_o '"error":[{][^}]*')"
|
||||||
_debug2 error "$error"
|
_debug2 error "$error"
|
||||||
errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)"
|
errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)"
|
||||||
_debug2 errordetail "$errordetail"
|
_debug2 errordetail "$errordetail"
|
||||||
|
|
@ -5812,7 +5838,7 @@ $_authorizations_map"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$response" >"$CERT_PATH"
|
echo "$response" | _strip_blank_lines >"$CERT_PATH"
|
||||||
_split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH"
|
_split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH"
|
||||||
if [ -z "$_preferred_chain" ]; then
|
if [ -z "$_preferred_chain" ]; then
|
||||||
_preferred_chain=$(_readcaconf DEFAULT_PREFERRED_CHAIN)
|
_preferred_chain=$(_readcaconf DEFAULT_PREFERRED_CHAIN)
|
||||||
|
|
@ -5839,7 +5865,7 @@ $_authorizations_map"
|
||||||
_relcert="$CERT_PATH.alt"
|
_relcert="$CERT_PATH.alt"
|
||||||
_relfullchain="$CERT_FULLCHAIN_PATH.alt"
|
_relfullchain="$CERT_FULLCHAIN_PATH.alt"
|
||||||
_relca="$CA_CERT_PATH.alt"
|
_relca="$CA_CERT_PATH.alt"
|
||||||
echo "$response" >"$_relcert"
|
echo "$response" | _strip_blank_lines >"$_relcert"
|
||||||
_split_cert_chain "$_relcert" "$_relfullchain" "$_relca"
|
_split_cert_chain "$_relcert" "$_relfullchain" "$_relca"
|
||||||
if [ "$DEBUG" ]; then
|
if [ "$DEBUG" ]; then
|
||||||
_debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")"
|
_debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")"
|
||||||
|
|
@ -5944,19 +5970,8 @@ $_authorizations_map"
|
||||||
_info "It cannot be renewed automatically"
|
_info "It cannot be renewed automatically"
|
||||||
_info "See: $_VALIDITY_WIKI"
|
_info "See: $_VALIDITY_WIKI"
|
||||||
else
|
else
|
||||||
_now=$(_time)
|
Le_NextRenewTime=$(_calc_validto_renew_time "$Le_NextRenewTime" "$Le_RenewalDays" "$(_time)")
|
||||||
_debug2 "_now" "$_now"
|
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
||||||
_lifetime=$(_math $Le_NextRenewTime - $_now)
|
|
||||||
_debug2 "_lifetime" "$_lifetime"
|
|
||||||
if [ $_lifetime -gt 86400 ]; then
|
|
||||||
#if lifetime is logner than one day, it will renew one day before
|
|
||||||
Le_NextRenewTime=$(_math $Le_NextRenewTime - 86400)
|
|
||||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
|
||||||
else
|
|
||||||
#if lifetime is less than 24 hours, it will renew one hour before
|
|
||||||
Le_NextRenewTime=$(_math $Le_NextRenewTime - 3600)
|
|
||||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
elif [ "$Le_RenewalDays" -lt "0" ]; then
|
elif [ "$Le_RenewalDays" -lt "0" ]; then
|
||||||
_enddate_value=$(_enddate "$CERT_PATH")
|
_enddate_value=$(_enddate "$CERT_PATH")
|
||||||
|
|
@ -6057,6 +6072,15 @@ $_authorizations_map"
|
||||||
}
|
}
|
||||||
|
|
||||||
#in_out_cert out_fullchain out_ca
|
#in_out_cert out_fullchain out_ca
|
||||||
|
#Reads a PEM chain from stdin, prints it without the blank lines.
|
||||||
|
#Some CAs (Let's Encrypt) separate the certificates of a chain with a blank
|
||||||
|
#line, others (ZeroSSL) don't. The blank lines are valid PEM (RFC 7468), but
|
||||||
|
#some devices and APIs reject them, so the certs are stored back to back.
|
||||||
|
#https://github.com/acmesh-official/acme.sh/issues/1940
|
||||||
|
_strip_blank_lines() {
|
||||||
|
sed '/^[[:space:]]*$/d'
|
||||||
|
}
|
||||||
|
|
||||||
_split_cert_chain() {
|
_split_cert_chain() {
|
||||||
_certf="$1"
|
_certf="$1"
|
||||||
_fullchainf="$2"
|
_fullchainf="$2"
|
||||||
|
|
@ -6575,7 +6599,7 @@ list_profiles() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
normalized_response=$(echo "$response" | _normalizeJson)
|
normalized_response=$(echo "$response" | _normalizeJson)
|
||||||
profiles_json=$(echo "$normalized_response" | _egrep_o '"profiles" *: *\{[^\}]*\}')
|
profiles_json=$(echo "$normalized_response" | _egrep_o '"profiles" *: *[{][^}]*[}]')
|
||||||
|
|
||||||
if [ -z "$profiles_json" ]; then
|
if [ -z "$profiles_json" ]; then
|
||||||
_info "The CA '$_l_server_name' does not publish certificate profiles via its directory endpoint."
|
_info "The CA '$_l_server_name' does not publish certificate profiles via its directory endpoint."
|
||||||
|
|
@ -6997,15 +7021,39 @@ installcronjob() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_info "Installing cron job"
|
_info "Installing cron job"
|
||||||
if ! $_CRONTAB -l 2>/dev/null | grep "$PROJECT_ENTRY --cron"; then
|
_cron_entry="$random_minute $random_hour,$(_math "$random_hour" + 6),$(_math "$random_hour" + 12),$(_math "$random_hour" + 18) * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
||||||
|
_cron_entries="$($_CRONTAB -l 2>/dev/null)"
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
#when the user has no crontab yet, crontab -l also exits non-zero;
|
||||||
|
#only that case may proceed with an empty list. Any other listing
|
||||||
|
#failure must abort: piping an incomplete list back into 'crontab -'
|
||||||
|
#would wipe the user's existing cron jobs (issue 3079)
|
||||||
|
_cron_list_err="$($_CRONTAB -l 2>&1 >/dev/null)"
|
||||||
|
#separate greps: BRE alternation \| is a GNU extension and Solaris
|
||||||
|
#grep takes only a single -e pattern
|
||||||
|
if echo "$_cron_list_err" | grep -i "no crontab" >/dev/null ||
|
||||||
|
echo "$_cron_list_err" | grep -i "no fcrontab" >/dev/null ||
|
||||||
|
echo "$_cron_list_err" | grep -i "can't open" >/dev/null; then
|
||||||
|
_cron_entries=""
|
||||||
|
else
|
||||||
|
_err "Can not list the current cron jobs: $_cron_list_err"
|
||||||
|
_err "Refusing to install the cron job, that could wipe your existing cron jobs."
|
||||||
|
_err "Please add this cron job manually:"
|
||||||
|
_err "$_cron_entry"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if ! echo "$_cron_entries" | grep "$PROJECT_ENTRY --cron"; then
|
||||||
if _exists uname && uname -a | grep SunOS >/dev/null; then
|
if _exists uname && uname -a | grep SunOS >/dev/null; then
|
||||||
_CRONTAB_STDIN="$_CRONTAB --"
|
_CRONTAB_STDIN="$_CRONTAB --"
|
||||||
else
|
else
|
||||||
_CRONTAB_STDIN="$_CRONTAB -"
|
_CRONTAB_STDIN="$_CRONTAB -"
|
||||||
fi
|
fi
|
||||||
$_CRONTAB -l 2>/dev/null | {
|
{
|
||||||
cat
|
if [ "$_cron_entries" ]; then
|
||||||
echo "$random_minute $random_hour,$(_math $random_hour + 6),$(_math $random_hour + 12),$(_math $random_hour + 18) * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
echo "$_cron_entries"
|
||||||
|
fi
|
||||||
|
echo "$_cron_entry"
|
||||||
} | $_CRONTAB_STDIN
|
} | $_CRONTAB_STDIN
|
||||||
fi
|
fi
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
|
|
@ -7234,7 +7282,7 @@ _deactivate() {
|
||||||
_debug "Trigger validation."
|
_debug "Trigger validation."
|
||||||
vtype="$(_getIdType "$_d_domain")"
|
vtype="$(_getIdType "$_d_domain")"
|
||||||
# Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018
|
# Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018
|
||||||
entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
|
entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^{]*"type":"'$vtype'"[^}]*')"
|
||||||
_debug entry "$entry"
|
_debug entry "$entry"
|
||||||
if [ -z "$entry" ]; then
|
if [ -z "$entry" ]; then
|
||||||
_err "$d: Cannot get domain token"
|
_err "$d: Cannot get domain token"
|
||||||
|
|
@ -8020,6 +8068,7 @@ Parameters:
|
||||||
Multiple emails can be given as a comma-separated list: 'a@example.com,b@example.com'
|
Multiple emails can be given as a comma-separated list: 'a@example.com,b@example.com'
|
||||||
--accountkey <file> Specifies the account key path, only valid for the '--install' command.
|
--accountkey <file> Specifies the account key path, only valid for the '--install' command.
|
||||||
--days <ndays> Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
|
--days <ndays> Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
|
||||||
|
A negative value renews that many days before the cert expiry.
|
||||||
Negative values could be used to specify a number of days relative to the expiration date of the certificate.
|
Negative values could be used to specify a number of days relative to the expiration date of the certificate.
|
||||||
--httpport <port> Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
--httpport <port> Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
||||||
--tlsport <port> Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
--tlsport <port> Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
||||||
|
|
@ -9014,13 +9063,20 @@ _process() {
|
||||||
|
|
||||||
_debug2 LE_WORKING_DIR "$LE_WORKING_DIR"
|
_debug2 LE_WORKING_DIR "$LE_WORKING_DIR"
|
||||||
|
|
||||||
# --days and --valid-to are mutually exclusive by design: --valid-to pins
|
# --valid-to pins the cert lifetime, so a creation-anchored (positive)
|
||||||
# the cert lifetime and the renewal time follows the expiry, so a
|
# --days schedule can not apply and is rejected. A negative --days is
|
||||||
# creation-based --days schedule can not apply.
|
# anchored to the expiry and composes with a relative --valid-to: the
|
||||||
|
# cert renews that many days before the expiry.
|
||||||
if [ "$_days" ] && [ "$_valid_to" ]; then
|
if [ "$_days" ] && [ "$_valid_to" ]; then
|
||||||
_err "--days can not be used together with --valid-to."
|
if ! _startswith "$_valid_to" "+"; then
|
||||||
_err "With --valid-to, the renewal time is derived from the expiry time automatically."
|
_err "--days can not be used together with a fixed-date --valid-to: such a cert can not be renewed automatically."
|
||||||
return 1
|
return 1
|
||||||
|
fi
|
||||||
|
if ! _startswith "$_days" "-"; then
|
||||||
|
_err "A positive --days can not be used together with --valid-to, the renewal time is derived from the expiry time."
|
||||||
|
_err "Use a negative --days to renew that many days before the expiry, or omit --days to renew 1 day before the expiry."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DEBUG" ]; then
|
if [ "$DEBUG" ]; then
|
||||||
|
|
|
||||||
222
deploy/baidu_cdn.sh
Normal file
222
deploy/baidu_cdn.sh
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# shellcheck disable=SC2034,SC2154
|
||||||
|
|
||||||
|
# Deploy hook: Baidu Cloud CDN
|
||||||
|
#
|
||||||
|
# Code generated by GitHub Copilot with Claude Sonnet 4.6 and OpenAI Codex with GPT-5.6 Sol
|
||||||
|
#
|
||||||
|
# API Doc: https://cloud.baidu.com/doc/CDN/s/Zkna2r57w
|
||||||
|
#
|
||||||
|
# Uses the same credential variables as dnsapi/dns_baidu.sh:
|
||||||
|
# export Baidu_AK="your-access-key-id"
|
||||||
|
# export Baidu_SK="your-secret-access-key"
|
||||||
|
#
|
||||||
|
# To deploy to a CDN domain different from the certificate CN
|
||||||
|
# (e.g. wildcard or multi-domain certs):
|
||||||
|
# export DEPLOY_BAIDU_CDN_DOMAIN="cdn.example.com"
|
||||||
|
#
|
||||||
|
# Multiple CDN domains sharing the same certificate:
|
||||||
|
# export DEPLOY_BAIDU_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
|
||||||
|
|
||||||
|
BAIDU_CDN_HOST="cdn.baidubce.com"
|
||||||
|
_BAIDU_CDN_BCE_AUTH_RESULT=""
|
||||||
|
|
||||||
|
baidu_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"
|
||||||
|
|
||||||
|
if ! _baidu_cdn_load_credentials; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_getdeployconf DEPLOY_BAIDU_CDN_DOMAIN
|
||||||
|
if [ "$DEPLOY_BAIDU_CDN_DOMAIN" ]; then
|
||||||
|
_savedeployconf DEPLOY_BAIDU_CDN_DOMAIN "$DEPLOY_BAIDU_CDN_DOMAIN"
|
||||||
|
else
|
||||||
|
DEPLOY_BAIDU_CDN_DOMAIN="$_cdomain"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build JSON "domains" array from space-separated domain list
|
||||||
|
_domains_json=""
|
||||||
|
for _d in $DEPLOY_BAIDU_CDN_DOMAIN; do
|
||||||
|
_d_e="$(_baidu_cdn_json_escape "$_d")"
|
||||||
|
if [ -z "$_domains_json" ]; then
|
||||||
|
_domains_json="\"${_d_e}\""
|
||||||
|
else
|
||||||
|
_domains_json="${_domains_json},\"${_d_e}\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build a valid cert name: must start with a letter, allow [A-Za-z0-9-/.], max 65 chars
|
||||||
|
_cert_name="$(printf "%s" "$_cdomain" | sed 's/\*\./wildcard./g;s/[^A-Za-z0-9./]/-/g' | cut -c 1-65)"
|
||||||
|
case "$_cert_name" in
|
||||||
|
[A-Za-z]*) ;;
|
||||||
|
*) _cert_name="c${_cert_name}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# PEM content is already Base64 inside the -----BEGIN/END----- wrappers.
|
||||||
|
# The API expects the raw PEM as a JSON string, so newlines must be escaped as \n.
|
||||||
|
_cert_pem="$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')"
|
||||||
|
_key_pem="$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')"
|
||||||
|
|
||||||
|
_debug2 _cert_name "$_cert_name"
|
||||||
|
_debug2 _domains_json "[$_domains_json]"
|
||||||
|
|
||||||
|
# Build JSON payload
|
||||||
|
_payload="{\"domains\":[${_domains_json}],\"certificate\":{\"certName\":\"${_cert_name}\",\"certServerData\":\"${_cert_pem}\",\"certPrivateData\":\"${_key_pem}\"}}"
|
||||||
|
|
||||||
|
# Generate BCE v1 authorization header (query string included in canonical request)
|
||||||
|
_cdn_path="/v2/domain/certificate"
|
||||||
|
_cdn_query="action=put"
|
||||||
|
_ts="$(_utc_date | sed 's/ /T/')Z"
|
||||||
|
_content_type="application/json; charset=utf-8"
|
||||||
|
_payload_hash="$(printf "%s" "$_payload" | _digest sha256 hex)"
|
||||||
|
|
||||||
|
if ! _baidu_cdn_bce_auth "POST" "$_cdn_path" "$_cdn_query" "$BAIDU_CDN_HOST" "$_ts" "3600" "$_content_type" "$_payload_hash"; then
|
||||||
|
_err "Failed to sign request"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_H1="Authorization: $_BAIDU_CDN_BCE_AUTH_RESULT"
|
||||||
|
_H2="x-bce-date: $_ts"
|
||||||
|
_H3="x-bce-content-sha256: $_payload_hash"
|
||||||
|
_H4="Host: $BAIDU_CDN_HOST"
|
||||||
|
_H5=""
|
||||||
|
|
||||||
|
_url="https://${BAIDU_CDN_HOST}${_cdn_path}?${_cdn_query}"
|
||||||
|
response="$(_post "$_payload" "$_url" "" "POST" "$_content_type")"
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "Failed to call Baidu Cloud CDN API"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
if _contains "$response" "\"certId\""; then
|
||||||
|
_info "Certificate deployed to Baidu Cloud CDN for: $DEPLOY_BAIDU_CDN_DOMAIN"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_err "Failed to deploy certificate to Baidu Cloud CDN: $response"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# BCE v1 signing with canonical query string support.
|
||||||
|
# The CDN endpoint uses ?action=put so it must be included in the canonical request.
|
||||||
|
_baidu_cdn_bce_auth() {
|
||||||
|
_method="$1"
|
||||||
|
_uri="$2"
|
||||||
|
_query="$3"
|
||||||
|
_host="$4"
|
||||||
|
_ts="$5"
|
||||||
|
_expire="$6"
|
||||||
|
_ct="$7"
|
||||||
|
_payload_hash="$8"
|
||||||
|
|
||||||
|
_BAIDU_CDN_BCE_AUTH_RESULT=""
|
||||||
|
|
||||||
|
_auth_prefix="bce-auth-v1/${Baidu_AK}/${_ts}/${_expire}"
|
||||||
|
_signed_headers="content-type;host;x-bce-content-sha256;x-bce-date"
|
||||||
|
_canonical_uri="$(_baidu_cdn_bce_encode_path "$_uri")"
|
||||||
|
|
||||||
|
_host_e="$(printf "%s" "$_host" | _url_encode upper-hex)"
|
||||||
|
_date_e="$(printf "%s" "$_ts" | _url_encode upper-hex)"
|
||||||
|
_ct_e="$(printf "%s" "$_ct" | _url_encode upper-hex)"
|
||||||
|
_hash_e="$(printf "%s" "$_payload_hash" | _url_encode upper-hex)"
|
||||||
|
|
||||||
|
_canonical_headers="content-type:${_ct_e}
|
||||||
|
host:${_host_e}
|
||||||
|
x-bce-content-sha256:${_hash_e}
|
||||||
|
x-bce-date:${_date_e}"
|
||||||
|
|
||||||
|
_canonical_request="${_method}
|
||||||
|
${_canonical_uri}
|
||||||
|
${_query}
|
||||||
|
${_canonical_headers}"
|
||||||
|
|
||||||
|
_sk_hex="$(printf "%s" "$Baidu_SK" | _hex_dump | tr -d " ")"
|
||||||
|
_signing_key="$(_baidu_cdn_hmac_sha256_hexkey "$_sk_hex" "$_auth_prefix")"
|
||||||
|
_signing_key_hex="$(printf "%s" "$_signing_key" | _hex_dump | tr -d " ")"
|
||||||
|
_signature="$(_baidu_cdn_hmac_sha256_hexkey "$_signing_key_hex" "$_canonical_request")"
|
||||||
|
|
||||||
|
_BAIDU_CDN_BCE_AUTH_RESULT="${_auth_prefix}/${_signed_headers}/${_signature}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_load_credentials() {
|
||||||
|
Baidu_AK="${Baidu_AK:-$(_readaccountconf_mutable Baidu_AK)}"
|
||||||
|
Baidu_SK="${Baidu_SK:-$(_readaccountconf_mutable Baidu_SK)}"
|
||||||
|
|
||||||
|
Baidu_AK="$(_baidu_cdn_trim_ws "$Baidu_AK")"
|
||||||
|
Baidu_SK="$(_baidu_cdn_trim_ws "$Baidu_SK")"
|
||||||
|
|
||||||
|
if [ -z "$Baidu_AK" ] || [ -z "$Baidu_SK" ]; then
|
||||||
|
_err "Baidu_AK and Baidu_SK are required"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_saveaccountconf_mutable Baidu_AK "$Baidu_AK"
|
||||||
|
_saveaccountconf_mutable Baidu_SK "$Baidu_SK"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_bce_encode_path() {
|
||||||
|
_p="$1"
|
||||||
|
_out=""
|
||||||
|
if [ "${_p#"/"}" != "$_p" ]; then
|
||||||
|
_out="/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_rest="${_p#/}"
|
||||||
|
while [ -n "$_rest" ]; do
|
||||||
|
_seg="${_rest%%/*}"
|
||||||
|
if [ "$_seg" ]; then
|
||||||
|
if [ -z "$_out" ] || [ "$_out" = "/" ]; then
|
||||||
|
_out="${_out}$(printf "%s" "$_seg" | _url_encode upper-hex)"
|
||||||
|
else
|
||||||
|
_out="${_out}/$(printf "%s" "$_seg" | _url_encode upper-hex)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "${_rest#*/}" = "$_rest" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_rest="${_rest#*/}"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$_out" ]; then
|
||||||
|
_out="/"
|
||||||
|
fi
|
||||||
|
printf "%s" "$_out"
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_trim_ws() {
|
||||||
|
printf "%s" "$1" | tr '\r\n\t' ' ' | tr -s ' ' | sed 's/^ *//;s/ *$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_json_escape() {
|
||||||
|
_s="$1"
|
||||||
|
_s="$(printf "%s" "$_s" | tr -d '\r\n')"
|
||||||
|
printf "%s" "$_s" |
|
||||||
|
sed 's/\\/\\\\/g; s/ /\\t/g' |
|
||||||
|
_baidu_cdn_json_encode
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_json_encode() {
|
||||||
|
_j_str="$(sed 's/"/\\"/g' | sed "s/\r/\\r/g")"
|
||||||
|
printf "%s" "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
_baidu_cdn_hmac_sha256_hexkey() {
|
||||||
|
_key_hex="$1"
|
||||||
|
_msg="$2"
|
||||||
|
printf "%s" "$_msg" | _hmac sha256 "$_key_hex" hex
|
||||||
|
}
|
||||||
175
deploy/fortigate.sh
Normal file
175
deploy/fortigate.sh
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# Script to deploy a certificate to FortiGate via API and set it as the current web GUI certificate.
|
||||||
|
#
|
||||||
|
# FortiGate's native ACME integration does not support wildcard certificates or domain validation,
|
||||||
|
# and is not supported if you have a custom management web port (eg. DNAT web traffic).
|
||||||
|
#
|
||||||
|
# REQUIRED:
|
||||||
|
# export FGT_HOST="fortigate_hostname-or-ip"
|
||||||
|
# export FGT_TOKEN="fortigate_api_token"
|
||||||
|
#
|
||||||
|
# OPTIONAL:
|
||||||
|
# export FGT_PORT="10443" # Custom HTTPS port (defaults to 443 if not set)
|
||||||
|
#
|
||||||
|
# Run `acme.sh --deploy -d example.com --deploy-hook fortigate --insecure` to use this script.
|
||||||
|
# `--insecure` is required on first run if not already using a valid SSL certificate on firewall.
|
||||||
|
|
||||||
|
# Function to parse a FortiGate API response
|
||||||
|
_fortigate_parse_response() {
|
||||||
|
_fortigate_response="$1"
|
||||||
|
_fortigate_func="$2"
|
||||||
|
_fortigate_status=$(echo "$_fortigate_response" | _egrep_o '"status":[ ]*"[^"]*"' | cut -d '"' -f 4)
|
||||||
|
|
||||||
|
if [ "$_fortigate_status" != "success" ]; then
|
||||||
|
_err "[$_fortigate_func] Operation failed. Deploy with --insecure if current certificate is invalid. Try deploying with --debug to troubleshoot."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "[$_fortigate_func] Operation successful."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to deploy a base64-encoded certificate to the firewall
|
||||||
|
_fortigate_deployer() {
|
||||||
|
_fortigate_cert_base64=$(_base64 <"$_fortigate_cfullchain" | tr -d '\n')
|
||||||
|
_fortigate_key_base64=$(_base64 <"$_fortigate_ckey" | tr -d '\n')
|
||||||
|
_fortigate_payload=$(
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
"type": "regular",
|
||||||
|
"scope": "global",
|
||||||
|
"certname": "$_fortigate_cert_name",
|
||||||
|
"key_file_content": "$_fortigate_key_base64",
|
||||||
|
"file_content": "$_fortigate_cert_base64"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
_fortigate_url="https://${FGT_HOST}:${FGT_PORT}/api/v2/monitor/vpn-certificate/local/import"
|
||||||
|
_debug "Uploading certificate via URL: $_fortigate_url"
|
||||||
|
|
||||||
|
_H1="Authorization: Bearer $FGT_TOKEN"
|
||||||
|
_fortigate_response=$(_post "$_fortigate_payload" "$_fortigate_url" "" "POST" "application/json")
|
||||||
|
_debug "FortiGate API Response: $_fortigate_response"
|
||||||
|
|
||||||
|
_fortigate_parse_response "$_fortigate_response" "Deploying certificate" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to upload a CA certificate to the firewall
|
||||||
|
# FortiGate does not automatically extract the CA from the full chain.
|
||||||
|
_fortigate_upload_ca_cert() {
|
||||||
|
_fortigate_ca_base64=$(_base64 <"$_fortigate_cca" | tr -d '\n')
|
||||||
|
_fortigate_payload=$(
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
"import_method": "file",
|
||||||
|
"scope": "global",
|
||||||
|
"file_content": "$_fortigate_ca_base64"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
_fortigate_url="https://${FGT_HOST}:${FGT_PORT}/api/v2/monitor/vpn-certificate/ca/import"
|
||||||
|
_debug "Uploading CA certificate via URL: $_fortigate_url"
|
||||||
|
|
||||||
|
_H1="Authorization: Bearer $FGT_TOKEN"
|
||||||
|
_fortigate_response=$(_post "$_fortigate_payload" "$_fortigate_url" "" "POST" "application/json")
|
||||||
|
_debug "FortiGate API CA Response: $_fortigate_response"
|
||||||
|
|
||||||
|
# FortiGate error -328 means that the CA certificate already exists.
|
||||||
|
if echo "$_fortigate_response" | grep -q '"error":[ ]*-328'; then
|
||||||
|
_debug "CA certificate already exists. Skipping CA upload."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_fortigate_parse_response "$_fortigate_response" "Deploying CA certificate" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to activate the new certificate
|
||||||
|
_fortigate_set_active_web_cert() {
|
||||||
|
_fortigate_payload=$(
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
"admin-server-cert": "$_fortigate_cert_name"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
_fortigate_url="https://${FGT_HOST}:${FGT_PORT}/api/v2/cmdb/system/global"
|
||||||
|
_debug "Setting GUI certificate..."
|
||||||
|
|
||||||
|
_H1="Authorization: Bearer $FGT_TOKEN"
|
||||||
|
_fortigate_response=$(_post "$_fortigate_payload" "$_fortigate_url" "" "PUT" "application/json")
|
||||||
|
|
||||||
|
_fortigate_parse_response "$_fortigate_response" "Assigning active certificate" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to clean up the previously deployed certificate
|
||||||
|
_fortigate_cleanup_previous_certificate() {
|
||||||
|
_getdeployconf FGT_LAST_CERT
|
||||||
|
|
||||||
|
if [ -n "$FGT_LAST_CERT" ] && [ "$FGT_LAST_CERT" != "$_fortigate_cert_name" ]; then
|
||||||
|
_debug "Found previously deployed certificate: $FGT_LAST_CERT. Deleting it."
|
||||||
|
|
||||||
|
_fortigate_url="https://${FGT_HOST}:${FGT_PORT}/api/v2/cmdb/vpn.certificate/local/${FGT_LAST_CERT}"
|
||||||
|
_H1="Authorization: Bearer $FGT_TOKEN"
|
||||||
|
_fortigate_response=$(_post "" "$_fortigate_url" "" "DELETE" "application/json")
|
||||||
|
_debug "Delete certificate API response: $_fortigate_response"
|
||||||
|
|
||||||
|
_fortigate_parse_response "$_fortigate_response" "Delete previous certificate" || return 1
|
||||||
|
else
|
||||||
|
_debug "No previous certificate found."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main deploy-hook function
|
||||||
|
fortigate_deploy() {
|
||||||
|
# Include date and time to ensure unique names.
|
||||||
|
_fortigate_cert_name="$(echo "$1" | sed 's/*/WILDCARD_/g')_$(date -u +"%Y-%m-%d_%H-%M-%S")"
|
||||||
|
_fortigate_ckey="$2"
|
||||||
|
_fortigate_cca="$4"
|
||||||
|
_fortigate_cfullchain="$5"
|
||||||
|
|
||||||
|
if [ ! -f "$_fortigate_ckey" ] || [ ! -f "$_fortigate_cfullchain" ]; then
|
||||||
|
_err "Valid key and/or certificate not found."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Save required environment variables if set; otherwise load saved values.
|
||||||
|
for _fortigate_var in FGT_HOST FGT_TOKEN FGT_PORT; do
|
||||||
|
if [ -n "$(eval echo "\$$_fortigate_var")" ]; then
|
||||||
|
_debug "Detected ENV variable $_fortigate_var. Saving to file."
|
||||||
|
_savedeployconf "$_fortigate_var" "$(eval echo "\$$_fortigate_var")" 1
|
||||||
|
else
|
||||||
|
_debug "Attempting to load variable $_fortigate_var from file."
|
||||||
|
_getdeployconf "$_fortigate_var"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$FGT_HOST" ] || [ -z "$FGT_TOKEN" ]; then
|
||||||
|
_err "FGT_HOST and FGT_TOKEN must be set."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FGT_PORT="${FGT_PORT:-443}"
|
||||||
|
_debug "Using FortiGate port: $FGT_PORT"
|
||||||
|
|
||||||
|
# Upload the new certificate.
|
||||||
|
_fortigate_deployer || return 1
|
||||||
|
|
||||||
|
# Upload the CA certificate.
|
||||||
|
if [ -n "$_fortigate_cca" ] && [ -f "$_fortigate_cca" ]; then
|
||||||
|
_fortigate_upload_ca_cert || return 1
|
||||||
|
else
|
||||||
|
_debug "No CA certificate provided."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate the new certificate.
|
||||||
|
_fortigate_set_active_web_cert || return 1
|
||||||
|
|
||||||
|
# Delete the previously deployed certificate only after successful activation.
|
||||||
|
_fortigate_cleanup_previous_certificate || return 1
|
||||||
|
|
||||||
|
# Save the new certificate name for cleanup during the next deployment.
|
||||||
|
_savedeployconf "FGT_LAST_CERT" "$_fortigate_cert_name" 1
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,9 @@ Ali_DNS_API="https://alidns.aliyuncs.com/"
|
||||||
|
|
||||||
#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
dns_ali_add() {
|
dns_ali_add() {
|
||||||
fulldomain=$1
|
# the API only accepts punycode for IDN domains, and a raw UTF-8 domain
|
||||||
|
# also breaks the request signature (issue 4733)
|
||||||
|
fulldomain=$(_idn "$1")
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
_prepare_ali_credentials || return 1
|
_prepare_ali_credentials || return 1
|
||||||
|
|
@ -33,7 +35,7 @@ dns_ali_add() {
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_ali_rm() {
|
dns_ali_rm() {
|
||||||
fulldomain=$1
|
fulldomain=$(_idn "$1")
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
|
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
|
||||||
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
|
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
|
||||||
|
|
|
||||||
248
dnsapi/dns_comlaude.sh
Normal file
248
dnsapi/dns_comlaude.sh
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
dns_comlaude_info='comlaude.com
|
||||||
|
Site: comlaude.com
|
||||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_comlaude
|
||||||
|
Options:
|
||||||
|
COMLAUDE_USERNAME User account
|
||||||
|
COMLAUDE_PASSWORD User password
|
||||||
|
COMLAUDE_API_KEY generated API key
|
||||||
|
COMLAUDE_GROUP_ID Group ID in comlaude user profile
|
||||||
|
Get it from the https://www.comlaude.com
|
||||||
|
Issues: github.com/acmesh-official/acme.sh/issues/7112
|
||||||
|
'
|
||||||
|
# ===== CONFIG =====
|
||||||
|
COMLAUDE_API="https://api.comlaude.com"
|
||||||
|
|
||||||
|
########## AUTH ##########
|
||||||
|
|
||||||
|
_comlaude_auth() {
|
||||||
|
_debug "Checking cached ComLaude token"
|
||||||
|
|
||||||
|
# Try to get token from account.conf
|
||||||
|
if [ -z "$COMLAUDE_ACCESS_TOKEN" ]; then
|
||||||
|
COMLAUDE_ACCESS_TOKEN="$(_readaccountconf_mutable COMLAUDE_ACCESS_TOKEN)"
|
||||||
|
COMLAUDE_TOKEN_EXPIRY="$(_readaccountconf_mutable COMLAUDE_TOKEN_EXPIRY)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_now=$(_time)
|
||||||
|
if [ -n "$COMLAUDE_ACCESS_TOKEN" ] && [ -n "$COMLAUDE_TOKEN_EXPIRY" ] && [ "$_now" -lt "$COMLAUDE_TOKEN_EXPIRY" ]; then
|
||||||
|
_debug "Using cached ComLaude token (valid ${COMLAUDE_TOKEN_EXPIRY} > ${_now})"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "ComLaude auth..."
|
||||||
|
_comlaude_body="{\"username\":\"$COMLAUDE_USERNAME\",\"password\":\"$COMLAUDE_PASSWORD\",\"api_key\":\"$COMLAUDE_API_KEY\"}"
|
||||||
|
_comlaude_response="$(_post "$_comlaude_body" "$COMLAUDE_API/api_login" "" "POST" "application/json")"
|
||||||
|
|
||||||
|
if ! _contains "$_comlaude_response" "access_token"; then
|
||||||
|
_err "Auth failed: $_comlaude_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMLAUDE_ACCESS_TOKEN=$(echo "$_comlaude_response" | _egrep_o '"access_token":"[^"]*"' | cut -d'"' -f4)
|
||||||
|
# store expiracy from api reply l'API ("expires_in" in seconds)
|
||||||
|
_comlaude_expires_in=$(echo "$_comlaude_response" | _egrep_o '"expires_in":[0-9]*' | cut -d: -f2)
|
||||||
|
[ -z "$_comlaude_expires_in" ] && _comlaude_expires_in=3000 # fallback if no info
|
||||||
|
|
||||||
|
COMLAUDE_TOKEN_EXPIRY=$(($(_time) + _comlaude_expires_in - 60)) # margin of 60s to secure renew
|
||||||
|
|
||||||
|
_saveaccountconf_mutable COMLAUDE_ACCESS_TOKEN "$COMLAUDE_ACCESS_TOKEN"
|
||||||
|
_saveaccountconf_mutable COMLAUDE_TOKEN_EXPIRY "$COMLAUDE_TOKEN_EXPIRY"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
########## DOMAIN RESOLUTION ##########
|
||||||
|
|
||||||
|
_comlaude_get_root() {
|
||||||
|
COMLAUDE_GROUP_ID="${COMLAUDE_GROUP_ID:-$(_readaccountconf_mutable COMLAUDE_GROUP_ID)}"
|
||||||
|
if [ -z "$COMLAUDE_GROUP_ID" ]; then
|
||||||
|
_err "Missing COMLAUDE_GROUP_ID"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_comlaude_input_domain="$1"
|
||||||
|
_comlaude_input_domain="${_comlaude_input_domain#_acme-challenge.}"
|
||||||
|
case "$_comlaude_input_domain" in
|
||||||
|
\*.*) _comlaude_input_domain="${_comlaude_input_domain#*.}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
_debug "Normalized domain: $_comlaude_input_domain"
|
||||||
|
|
||||||
|
_comlaude_i=1
|
||||||
|
while true; do
|
||||||
|
_comlaude_d=$(printf "%s" "$_comlaude_input_domain" | cut -d . -f "$_comlaude_i-")
|
||||||
|
[ -z "$_comlaude_d" ] && {
|
||||||
|
_debug "No matching domain found for $_comlaude_input_domain"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# don't test unnecessary levels
|
||||||
|
# registered domain : TLD only (no dot after cut).
|
||||||
|
case "$_comlaude_d" in
|
||||||
|
*.*) : ;;
|
||||||
|
*)
|
||||||
|
_debug "Skipping bare TLD candidate: $_comlaude_d"
|
||||||
|
_comlaude_i=$((_comlaude_i + 1))
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
_debug "Checking domain: $_comlaude_d"
|
||||||
|
|
||||||
|
_comlaude_retry=0
|
||||||
|
_comlaude_max_retry=3 # to avoid network errors
|
||||||
|
_comlaude_DOM_ID=""
|
||||||
|
_comlaude_Z_ID=""
|
||||||
|
|
||||||
|
while [ "$_comlaude_retry" -lt "$_comlaude_max_retry" ]; do
|
||||||
|
export _H1="Authorization: Bearer $COMLAUDE_ACCESS_TOKEN"
|
||||||
|
_debug "Full URL: $COMLAUDE_API/groups/$COMLAUDE_GROUP_ID/domains?filter[name]=$_comlaude_d&fields=id,name,active_zone"
|
||||||
|
_comlaude_response="$(_get "$COMLAUDE_API/groups/$COMLAUDE_GROUP_ID/domains?filter[name]=$_comlaude_d&fields=id,name,active_zone")"
|
||||||
|
_H1=""
|
||||||
|
|
||||||
|
_debug "RAW response for $_comlaude_d (try $((_comlaude_retry + 1))): $_comlaude_response"
|
||||||
|
|
||||||
|
# If empty -> true network issue, we retry
|
||||||
|
if [ -z "$_comlaude_response" ]; then
|
||||||
|
_comlaude_retry=$((_comlaude_retry + 1))
|
||||||
|
[ "$_comlaude_retry" -lt "$_comlaude_max_retry" ] && sleep 2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 404 -> domain not found in that level. no retry : continue
|
||||||
|
if echo "$_comlaude_response" | grep -q '"status_code":404'; then
|
||||||
|
_debug "404 for $_comlaude_d, moving to next level (not retrying)"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Domain missing (200 reply, data empty) -> continue
|
||||||
|
if echo "$_comlaude_response" | grep -q '"data":\[\]'; then
|
||||||
|
_debug "Empty data for $_comlaude_d, moving to next level"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extraction via _egrep_o
|
||||||
|
_comlaude_DOM_ID="$(echo "$_comlaude_response" | _egrep_o '"id":"[^"]*"' | head -n1 | cut -d':' -f2 | tr -d '"')"
|
||||||
|
_comlaude_Z_ID="$(echo "$_comlaude_response" | _egrep_o '"active_zone":\{"id":"[^"]*"' | _egrep_o '"id":"[^"]*"$' | cut -d':' -f2 | tr -d '"')"
|
||||||
|
|
||||||
|
if [ -n "$_comlaude_DOM_ID" ] && [ -n "$_comlaude_Z_ID" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 200 reply but malformed data / noid -> retry transport
|
||||||
|
_comlaude_retry=$((_comlaude_retry + 1))
|
||||||
|
[ "$_comlaude_retry" -lt "$_comlaude_max_retry" ] && sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
_debug "_comlaude_DOM_ID=$_comlaude_DOM_ID"
|
||||||
|
_debug "_comlaude_Z_ID=$_comlaude_Z_ID"
|
||||||
|
|
||||||
|
if [ -n "$_comlaude_DOM_ID" ] && [ -n "$_comlaude_Z_ID" ]; then
|
||||||
|
_comlaude_domain="$_comlaude_d"
|
||||||
|
_comlaude_domain_id="$_comlaude_DOM_ID"
|
||||||
|
_comlaude_zone_id="$_comlaude_Z_ID"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_comlaude_i=$((_comlaude_i + 1))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
########## ADD TXT ##########
|
||||||
|
|
||||||
|
dns_comlaude_add() {
|
||||||
|
fulldomain="$1"
|
||||||
|
txtvalue="$2"
|
||||||
|
|
||||||
|
COMLAUDE_USERNAME="${COMLAUDE_USERNAME:-$(_readaccountconf_mutable COMLAUDE_USERNAME)}"
|
||||||
|
COMLAUDE_PASSWORD="${COMLAUDE_PASSWORD:-$(_readaccountconf_mutable COMLAUDE_PASSWORD)}"
|
||||||
|
COMLAUDE_API_KEY="${COMLAUDE_API_KEY:-$(_readaccountconf_mutable COMLAUDE_API_KEY)}"
|
||||||
|
COMLAUDE_GROUP_ID="${COMLAUDE_GROUP_ID:-$(_readaccountconf_mutable COMLAUDE_GROUP_ID)}"
|
||||||
|
|
||||||
|
if [ -z "$COMLAUDE_USERNAME" ] || [ -z "$COMLAUDE_PASSWORD" ] || [ -z "$COMLAUDE_API_KEY" ]; then
|
||||||
|
_err "You didn't specify ComLaude credentials (COMLAUDE_USERNAME, COMLAUDE_PASSWORD, COMLAUDE_API_KEY)."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Backup variable after validation
|
||||||
|
_saveaccountconf_mutable COMLAUDE_USERNAME "$COMLAUDE_USERNAME"
|
||||||
|
_saveaccountconf_mutable COMLAUDE_PASSWORD "$COMLAUDE_PASSWORD"
|
||||||
|
_saveaccountconf_mutable COMLAUDE_API_KEY "$COMLAUDE_API_KEY"
|
||||||
|
_saveaccountconf_mutable COMLAUDE_GROUP_ID "$COMLAUDE_GROUP_ID"
|
||||||
|
|
||||||
|
_info "Adding TXT: $fulldomain"
|
||||||
|
_comlaude_auth || return 1
|
||||||
|
_comlaude_get_root "$fulldomain" || return 1
|
||||||
|
|
||||||
|
_debug "Root: $_comlaude_domain"
|
||||||
|
|
||||||
|
_comlaude_data="{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"value\":\"$txtvalue\",\"ttl\":60}"
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $COMLAUDE_ACCESS_TOKEN"
|
||||||
|
export _H2="Content-Type: application/json"
|
||||||
|
|
||||||
|
_comlaude_response="$(_post "$_comlaude_data" "$COMLAUDE_API/groups/$COMLAUDE_GROUP_ID/zones/$_comlaude_zone_id/records")"
|
||||||
|
|
||||||
|
_H1=""
|
||||||
|
_H2=""
|
||||||
|
if ! echo "$_comlaude_response" | grep -q '"id"'; then
|
||||||
|
_err "Failed to create TXT"
|
||||||
|
_debug "$_comlaude_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
########## REMOVE TXT ##########
|
||||||
|
|
||||||
|
dns_comlaude_rm() {
|
||||||
|
fulldomain="$1"
|
||||||
|
txtvalue="$2"
|
||||||
|
|
||||||
|
COMLAUDE_USERNAME="${COMLAUDE_USERNAME:-$(_readaccountconf_mutable COMLAUDE_USERNAME)}"
|
||||||
|
COMLAUDE_PASSWORD="${COMLAUDE_PASSWORD:-$(_readaccountconf_mutable COMLAUDE_PASSWORD)}"
|
||||||
|
COMLAUDE_API_KEY="${COMLAUDE_API_KEY:-$(_readaccountconf_mutable COMLAUDE_API_KEY)}"
|
||||||
|
COMLAUDE_GROUP_ID="${COMLAUDE_GROUP_ID:-$(_readaccountconf_mutable COMLAUDE_GROUP_ID)}"
|
||||||
|
|
||||||
|
_info "Removing TXT: $fulldomain"
|
||||||
|
|
||||||
|
_comlaude_auth || return 1
|
||||||
|
_comlaude_get_root "$fulldomain" || return 1
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $COMLAUDE_ACCESS_TOKEN"
|
||||||
|
_comlaude_encoded_name="$(printf '%s' "$fulldomain" | _url_encode)"
|
||||||
|
_comlaude_encoded_value="$(printf '%s' "$txtvalue" | _url_encode)"
|
||||||
|
_comlaude_url="$COMLAUDE_API/groups/$COMLAUDE_GROUP_ID/zones/$_comlaude_zone_id/records?filter[type]=TXT&filter[name]=$_comlaude_encoded_name&filter[value]=$_comlaude_encoded_value"
|
||||||
|
_comlaude_response="$(_get "$_comlaude_url")"
|
||||||
|
_H1=""
|
||||||
|
|
||||||
|
_debug "Filtered records response: $_comlaude_response"
|
||||||
|
|
||||||
|
# first "id" top-level of reply (record itself,
|
||||||
|
# always on first position of each data[] object)
|
||||||
|
_comlaude_record_id="$(echo "$_comlaude_response" | _egrep_o '"data":\[\{"id":"[^"]*"' | _egrep_o '"[^"]*"$' | tr -d '"')"
|
||||||
|
|
||||||
|
if [ -z "$_comlaude_record_id" ]; then
|
||||||
|
_info "No matching TXT record found to delete for $fulldomain / $txtvalue"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "Deleting record $_comlaude_record_id"
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $COMLAUDE_ACCESS_TOKEN"
|
||||||
|
_comlaude_del_url="$COMLAUDE_API/groups/$COMLAUDE_GROUP_ID/zones/$_comlaude_zone_id/records/$_comlaude_record_id"
|
||||||
|
_comlaude_del_resp="$(_post "" "$_comlaude_del_url" "" "DELETE")"
|
||||||
|
_H1=""
|
||||||
|
|
||||||
|
if echo "$_comlaude_del_resp" | grep -q '"error"'; then
|
||||||
|
_err "Delete failed for $_comlaude_record_id"
|
||||||
|
_debug "$_comlaude_del_resp"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Deleted record $_comlaude_record_id"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ dns_dnsexit_add() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_dnsexit_zone_op add ',"ttl":0,"overwrite":false'
|
_dnsexit_zone_op add ',"ttl":1,"overwrite":false'
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: fulldomain txtvalue
|
#Usage: fulldomain txtvalue
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ dns_dnsimple_add() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
|
DNSimple_OAUTH_TOKEN="${DNSimple_OAUTH_TOKEN:-$(_readaccountconf_mutable DNSimple_OAUTH_TOKEN)}"
|
||||||
if [ -z "$DNSimple_OAUTH_TOKEN" ]; then
|
if [ -z "$DNSimple_OAUTH_TOKEN" ]; then
|
||||||
DNSimple_OAUTH_TOKEN=""
|
DNSimple_OAUTH_TOKEN=""
|
||||||
_err "You have not set the dnsimple oauth token yet."
|
_err "You have not set the dnsimple oauth token yet."
|
||||||
|
|
@ -26,7 +27,7 @@ dns_dnsimple_add() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# save the oauth token for later
|
# save the oauth token for later
|
||||||
_saveaccountconf DNSimple_OAUTH_TOKEN "$DNSimple_OAUTH_TOKEN"
|
_saveaccountconf_mutable DNSimple_OAUTH_TOKEN "$DNSimple_OAUTH_TOKEN"
|
||||||
|
|
||||||
if ! _get_account_id; then
|
if ! _get_account_id; then
|
||||||
_err "failed to retrieve account id"
|
_err "failed to retrieve account id"
|
||||||
|
|
@ -57,6 +58,12 @@ dns_dnsimple_add() {
|
||||||
dns_dnsimple_rm() {
|
dns_dnsimple_rm() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
|
|
||||||
|
DNSimple_OAUTH_TOKEN="${DNSimple_OAUTH_TOKEN:-$(_readaccountconf_mutable DNSimple_OAUTH_TOKEN)}"
|
||||||
|
if [ -z "$DNSimple_OAUTH_TOKEN" ]; then
|
||||||
|
_err "You have not set the dnsimple oauth token yet."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if ! _get_account_id; then
|
if ! _get_account_id; then
|
||||||
_err "failed to retrieve account id"
|
_err "failed to retrieve account id"
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -123,9 +130,9 @@ _get_root() {
|
||||||
|
|
||||||
# returns _account_id
|
# returns _account_id
|
||||||
_get_account_id() {
|
_get_account_id() {
|
||||||
DNSimple_ACCOUNT_ID="${DNSimple_ACCOUNT_ID:-$(_readaccountconf DNSimple_ACCOUNT_ID)}"
|
DNSimple_ACCOUNT_ID="${DNSimple_ACCOUNT_ID:-$(_readaccountconf_mutable DNSimple_ACCOUNT_ID)}"
|
||||||
if [ "$DNSimple_ACCOUNT_ID" ]; then
|
if [ "$DNSimple_ACCOUNT_ID" ]; then
|
||||||
_saveaccountconf DNSimple_ACCOUNT_ID "$DNSimple_ACCOUNT_ID"
|
_saveaccountconf_mutable DNSimple_ACCOUNT_ID "$DNSimple_ACCOUNT_ID"
|
||||||
_account_id="$DNSimple_ACCOUNT_ID"
|
_account_id="$DNSimple_ACCOUNT_ID"
|
||||||
_debug _account_id "$_account_id"
|
_debug _account_id "$_account_id"
|
||||||
return 0
|
return 0
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ dns_dynu_add() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
|
Dynu_ClientId="${Dynu_ClientId:-$(_readaccountconf_mutable Dynu_ClientId)}"
|
||||||
|
Dynu_Secret="${Dynu_Secret:-$(_readaccountconf_mutable Dynu_Secret)}"
|
||||||
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
|
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
|
||||||
Dynu_ClientId=""
|
Dynu_ClientId=""
|
||||||
Dynu_Secret=""
|
Dynu_Secret=""
|
||||||
|
|
@ -32,8 +34,8 @@ dns_dynu_add() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the client id and secret to the account conf file.
|
#save the client id and secret to the account conf file.
|
||||||
_saveaccountconf Dynu_ClientId "$Dynu_ClientId"
|
_saveaccountconf_mutable Dynu_ClientId "$Dynu_ClientId"
|
||||||
_saveaccountconf Dynu_Secret "$Dynu_Secret"
|
_saveaccountconf_mutable Dynu_Secret "$Dynu_Secret"
|
||||||
|
|
||||||
if [ -z "$Dynu_Token" ]; then
|
if [ -z "$Dynu_Token" ]; then
|
||||||
_info "Getting Dynu token."
|
_info "Getting Dynu token."
|
||||||
|
|
@ -69,6 +71,8 @@ dns_dynu_rm() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
|
Dynu_ClientId="${Dynu_ClientId:-$(_readaccountconf_mutable Dynu_ClientId)}"
|
||||||
|
Dynu_Secret="${Dynu_Secret:-$(_readaccountconf_mutable Dynu_Secret)}"
|
||||||
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
|
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
|
||||||
Dynu_ClientId=""
|
Dynu_ClientId=""
|
||||||
Dynu_Secret=""
|
Dynu_Secret=""
|
||||||
|
|
@ -78,8 +82,8 @@ dns_dynu_rm() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the client id and secret to the account conf file.
|
#save the client id and secret to the account conf file.
|
||||||
_saveaccountconf Dynu_ClientId "$Dynu_ClientId"
|
_saveaccountconf_mutable Dynu_ClientId "$Dynu_ClientId"
|
||||||
_saveaccountconf Dynu_Secret "$Dynu_Secret"
|
_saveaccountconf_mutable Dynu_Secret "$Dynu_Secret"
|
||||||
|
|
||||||
if [ -z "$Dynu_Token" ]; then
|
if [ -z "$Dynu_Token" ]; then
|
||||||
_info "Getting Dynu token."
|
_info "Getting Dynu token."
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,11 @@ dns_infomaniak_rm() {
|
||||||
_get_zone() {
|
_get_zone() {
|
||||||
domain="$1"
|
domain="$1"
|
||||||
# Whatever the domain is, you can get the fqdn with the following.
|
# Whatever the domain is, you can get the fqdn with the following.
|
||||||
# shellcheck disable=SC1004
|
response=$(_get "${INFOMANIAK_API_URL}/2/domains/${domain}/zones")
|
||||||
response=$(_get "${INFOMANIAK_API_URL}/2/domains/${domain}/zones" | sed 's/.*\[{"fqdn"\:"\(.*\)/\1/')
|
_debug2 "_get_zone response" "$response"
|
||||||
echo "${response%%\"*}"
|
if ! _contains "$response" '"result":"success"'; then
|
||||||
|
_err "cannot get zones for ${domain}, response: ${response}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$response" | _egrep_o '"fqdn" *: *"[^"]*"' | _head_n 1 | cut -d '"' -f 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_knot
|
||||||
Options:
|
Options:
|
||||||
KNOT_SERVER Server hostname. Default: "localhost".
|
KNOT_SERVER Server hostname. Default: "localhost".
|
||||||
KNOT_KEY TSIG key data, not a file path. knsupdate "key" statement format: "[alg:]name secret". E.g. "hmac-sha256:acme_key BASE64SECRET="
|
KNOT_KEY TSIG key data, not a file path. knsupdate "key" statement format: "[alg:]name secret". E.g. "hmac-sha256:acme_key BASE64SECRET="
|
||||||
|
KNOT_ZONE Zone name. Optional, set it when the challenge record lives in a delegated subdomain zone. Default: the parent domain of the challenge record.
|
||||||
'
|
'
|
||||||
|
|
||||||
# See also dns_nsupdate.sh
|
# See also dns_nsupdate.sh
|
||||||
|
|
@ -21,6 +22,9 @@ dns_knot_add() {
|
||||||
# save the dns server and key to the account.conf file.
|
# save the dns server and key to the account.conf file.
|
||||||
_saveaccountconf KNOT_SERVER "${KNOT_SERVER}"
|
_saveaccountconf KNOT_SERVER "${KNOT_SERVER}"
|
||||||
_saveaccountconf KNOT_KEY "${KNOT_KEY}"
|
_saveaccountconf KNOT_KEY "${KNOT_KEY}"
|
||||||
|
if [ -n "${KNOT_ZONE}" ]; then
|
||||||
|
_saveaccountconf KNOT_ZONE "${KNOT_ZONE}"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
_err "Domain does not exist."
|
_err "Domain does not exist."
|
||||||
|
|
@ -84,6 +88,13 @@ EOF
|
||||||
# _domain=domain.com
|
# _domain=domain.com
|
||||||
_get_root() {
|
_get_root() {
|
||||||
domain=$1
|
domain=$1
|
||||||
|
# a delegated subdomain zone cannot be derived from the record name;
|
||||||
|
# let the user name the zone explicitly (issue 2881)
|
||||||
|
if [ -n "${KNOT_ZONE}" ]; then
|
||||||
|
_domain="${KNOT_ZONE%.}"
|
||||||
|
_debug "Using KNOT_ZONE zone" "${_domain}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
|
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
|
||||||
i=$(_math "$i" - 1)
|
i=$(_math "$i" - 1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,12 +115,15 @@ _oci_config() {
|
||||||
_clearaccountconf_mutable OCI_CLI_PROFILE
|
_clearaccountconf_mutable OCI_CLI_PROFILE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}"
|
if [ -z "$OCI_CLI_TENANCY" ] && [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
||||||
|
_debug "Reading OCI_CLI_TENANCY value from: $OCI_CLI_CONFIG_FILE"
|
||||||
|
OCI_CLI_TENANCY=$(_readini "$OCI_CLI_CONFIG_FILE" tenancy "$OCI_CLI_PROFILE")
|
||||||
|
fi
|
||||||
|
if [ -z "$OCI_CLI_TENANCY" ]; then
|
||||||
|
OCI_CLI_TENANCY=$(_readaccountconf_mutable OCI_CLI_TENANCY)
|
||||||
|
fi
|
||||||
if [ "$OCI_CLI_TENANCY" ]; then
|
if [ "$OCI_CLI_TENANCY" ]; then
|
||||||
_saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY"
|
_saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY"
|
||||||
elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
|
||||||
_debug "Reading OCI_CLI_TENANCY value from: $OCI_CLI_CONFIG_FILE"
|
|
||||||
OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readini "$OCI_CLI_CONFIG_FILE" tenancy "$OCI_CLI_PROFILE")}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$OCI_CLI_TENANCY" ]; then
|
if [ -z "$OCI_CLI_TENANCY" ]; then
|
||||||
|
|
@ -128,41 +131,47 @@ _oci_config() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}"
|
if [ -z "$OCI_CLI_USER" ] && [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
||||||
|
_debug "Reading OCI_CLI_USER value from: $OCI_CLI_CONFIG_FILE"
|
||||||
|
OCI_CLI_USER=$(_readini "$OCI_CLI_CONFIG_FILE" user "$OCI_CLI_PROFILE")
|
||||||
|
fi
|
||||||
|
if [ -z "$OCI_CLI_USER" ]; then
|
||||||
|
OCI_CLI_USER=$(_readaccountconf_mutable OCI_CLI_USER)
|
||||||
|
fi
|
||||||
if [ "$OCI_CLI_USER" ]; then
|
if [ "$OCI_CLI_USER" ]; then
|
||||||
_saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER"
|
_saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER"
|
||||||
elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
|
||||||
_debug "Reading OCI_CLI_USER value from: $OCI_CLI_CONFIG_FILE"
|
|
||||||
OCI_CLI_USER="${OCI_CLI_USER:-$(_readini "$OCI_CLI_CONFIG_FILE" user "$OCI_CLI_PROFILE")}"
|
|
||||||
fi
|
fi
|
||||||
if [ -z "$OCI_CLI_USER" ]; then
|
if [ -z "$OCI_CLI_USER" ]; then
|
||||||
_err "Error: unable to read OCI_CLI_USER from config file or environment variable."
|
_err "Error: unable to read OCI_CLI_USER from config file or environment variable."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}"
|
if [ -z "$OCI_CLI_REGION" ] && [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
||||||
|
_debug "Reading OCI_CLI_REGION value from: $OCI_CLI_CONFIG_FILE"
|
||||||
|
OCI_CLI_REGION=$(_readini "$OCI_CLI_CONFIG_FILE" region "$OCI_CLI_PROFILE")
|
||||||
|
fi
|
||||||
|
if [ -z "$OCI_CLI_REGION" ]; then
|
||||||
|
OCI_CLI_REGION=$(_readaccountconf_mutable OCI_CLI_REGION)
|
||||||
|
fi
|
||||||
if [ "$OCI_CLI_REGION" ]; then
|
if [ "$OCI_CLI_REGION" ]; then
|
||||||
_saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION"
|
_saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION"
|
||||||
elif [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
|
||||||
_debug "Reading OCI_CLI_REGION value from: $OCI_CLI_CONFIG_FILE"
|
|
||||||
OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readini "$OCI_CLI_CONFIG_FILE" region "$OCI_CLI_PROFILE")}"
|
|
||||||
fi
|
fi
|
||||||
if [ -z "$OCI_CLI_REGION" ]; then
|
if [ -z "$OCI_CLI_REGION" ]; then
|
||||||
_err "Error: unable to read OCI_CLI_REGION from config file or environment variable."
|
_err "Error: unable to read OCI_CLI_REGION from config file or environment variable."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}"
|
if [ -z "$OCI_CLI_KEY_FILE" ] && [ -f "$OCI_CLI_CONFIG_FILE" ]; then
|
||||||
if [ -z "$OCI_CLI_KEY" ]; then
|
OCI_CLI_KEY_FILE=$(_readini "$OCI_CLI_CONFIG_FILE" key_file "$OCI_CLI_PROFILE")
|
||||||
_clearaccountconf_mutable OCI_CLI_KEY
|
fi
|
||||||
OCI_CLI_KEY_FILE="${OCI_CLI_KEY_FILE:-$(_readini "$OCI_CLI_CONFIG_FILE" key_file "$OCI_CLI_PROFILE")}"
|
if [ "$OCI_CLI_KEY" ]; then
|
||||||
if [ "$OCI_CLI_KEY_FILE" ] && [ -f "$OCI_CLI_KEY_FILE" ]; then
|
|
||||||
_debug "Reading OCI_CLI_KEY value from: $OCI_CLI_KEY_FILE"
|
|
||||||
OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE")
|
|
||||||
_saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
_saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
|
_saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
|
||||||
|
elif [ "$OCI_CLI_KEY_FILE" ] && [ -f "$OCI_CLI_KEY_FILE" ]; then
|
||||||
|
_debug "Reading OCI_CLI_KEY value from: $OCI_CLI_KEY_FILE"
|
||||||
|
OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE")
|
||||||
|
_saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
|
||||||
|
else
|
||||||
|
OCI_CLI_KEY=$(_readaccountconf_mutable OCI_CLI_KEY)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
|
if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ _ovh_authentication() {
|
||||||
_H3=""
|
_H3=""
|
||||||
_H4=""
|
_H4=""
|
||||||
|
|
||||||
_ovhdata='{"accessRules": [{"method": "GET","path": "/auth/time"},{"method": "GET","path": "/domain"},{"method": "GET","path": "/domain/zone/*"},{"method": "GET","path": "/domain/zone/*/record"},{"method": "POST","path": "/domain/zone/*/record"},{"method": "POST","path": "/domain/zone/*/refresh"},{"method": "PUT","path": "/domain/zone/*/record/*"},{"method": "DELETE","path": "/domain/zone/*/record/*"}],"redirection":"'$ovh_success'"}'
|
_ovhdata='{"accessRules": [{"method": "GET","path": "/auth/time"},{"method": "GET","path": "/domain"},{"method": "GET","path": "/domain/zone/*"},{"method": "GET","path": "/domain/zone/*/record"},{"method": "GET","path": "/domain/zone/*/record/*"},{"method": "POST","path": "/domain/zone/*/record"},{"method": "POST","path": "/domain/zone/*/refresh"},{"method": "PUT","path": "/domain/zone/*/record/*"},{"method": "DELETE","path": "/domain/zone/*/record/*"}],"redirection":"'$ovh_success'"}'
|
||||||
|
|
||||||
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
|
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
|
||||||
_debug3 response "$response"
|
_debug3 response "$response"
|
||||||
|
|
|
||||||
|
|
@ -71,4 +71,4 @@ waha_send() {
|
||||||
_err "waha send error."
|
_err "waha send error."
|
||||||
_err "$response"
|
_err "$response"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue