Browse Source

Merge branch 'acmesh-official:master' into master

pull/4757/head
laraveluser 9 months ago
committed by GitHub
parent
commit
c8604255e4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      .github/workflows/DNS.yml
  2. 4
      .github/workflows/NetBSD.yml
  3. 3
      .github/workflows/pr_dns.yml
  4. 49
      acme.sh
  5. 6
      deploy/routeros.sh
  6. 92
      deploy/synology_dsm.sh
  7. 148
      dnsapi/dns_do.sh
  8. 12
      dnsapi/dns_gandi_livedns.sh

4
.github/workflows/DNS.yml

@ -332,7 +332,7 @@ jobs:
with: 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}}' 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: | prepare: |
pkg_add curl socat
/usr/sbin/pkg_add curl socat
usesh: true usesh: true
copyback: false copyback: false
run: | run: |
@ -493,8 +493,6 @@ jobs:
copyback: false copyback: false
prepare: pkg install socat prepare: pkg install socat
run: | run: |
pkg set-mediator -v -I default@1.1 openssl
export PATH=/usr/gnu/bin:$PATH
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi fi

4
.github/workflows/NetBSD.yml

@ -20,7 +20,6 @@ concurrency:
jobs: jobs:
NetBSD: NetBSD:
strategy: strategy:
@ -44,6 +43,7 @@ jobs:
CA: ${{ matrix.CA }} CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }} CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
@ -57,7 +57,7 @@ jobs:
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/netbsd-vm@v1 - uses: vmactions/netbsd-vm@v1
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: | nat: |
"8080": "80" "8080": "80"
prepare: | prepare: |

3
.github/workflows/pr_dns.yml

@ -4,8 +4,6 @@ on:
pull_request_target: pull_request_target:
types: types:
- opened - opened
branches:
- 'dev'
paths: paths:
- 'dnsapi/*.sh' - 'dnsapi/*.sh'
@ -22,6 +20,7 @@ jobs:
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
body: `**Welcome** body: `**Welcome**
First thing: don't send PR to the master branch, please send to the dev branch instead.
Please make sure you've read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test). Please make sure you've read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
Then reply on this message, otherwise, your code will not be reviewed or merged. Then reply on this message, otherwise, your code will not be reviewed or merged.
We look forward to reviewing your Pull request shortly ✨ We look forward to reviewing your Pull request shortly ✨

49
acme.sh

@ -2499,10 +2499,10 @@ _startserver() {
_debug Le_Listen_V6 "$Le_Listen_V6" _debug Le_Listen_V6 "$Le_Listen_V6"
_NC="socat" _NC="socat"
if [ "$Le_Listen_V4" ]; then
_NC="$_NC -4"
elif [ "$Le_Listen_V6" ]; then
if [ "$Le_Listen_V6" ]; then
_NC="$_NC -6" _NC="$_NC -6"
else
_NC="$_NC -4"
fi fi
if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then
@ -2519,22 +2519,34 @@ _startserver() {
_content_len="$(printf "%s" "$content" | wc -c)" _content_len="$(printf "%s" "$content" | wc -c)"
_debug _content_len "$_content_len" _debug _content_len "$_content_len"
_debug "_NC" "$_NC $SOCAT_OPTIONS" _debug "_NC" "$_NC $SOCAT_OPTIONS"
export _SOCAT_ERR="$(_mktemp)"
$_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \ $_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; \
echo 'HTTP/1.0 200 OK'; \ echo 'HTTP/1.0 200 OK'; \
echo 'Content-Length\: $_content_len'; \ echo 'Content-Length\: $_content_len'; \
echo ''; \ echo ''; \
printf '%s' '$content';" &
printf '%s' '$content';" 2>"$_SOCAT_ERR" &
serverproc="$!" serverproc="$!"
if [ -f "$_SOCAT_ERR" ]; then
if grep "Permission denied" "$_SOCAT_ERR" >/dev/null; then
_err "socat: $(cat $_SOCAT_ERR)"
_err "Can not listen for user: $(whoami)"
_err "Maybe try with root again?"
rm -f "$_SOCAT_ERR"
return 1
fi
fi
} }
_stopserver() { _stopserver() {
pid="$1" pid="$1"
_debug "pid" "$pid" _debug "pid" "$pid"
if [ -z "$pid" ]; then if [ -z "$pid" ]; then
rm -f "$_SOCAT_ERR"
return return
fi fi
kill $pid kill $pid
rm -f "$_SOCAT_ERR"
} }
@ -3183,7 +3195,8 @@ _setNginx() {
return 1 return 1
fi fi
_info "Check the nginx conf before setting up." _info "Check the nginx conf before setting up."
if ! nginx -t >/dev/null; then
if ! nginx -t >/dev/null 2>&1; then
_err "It seems that nginx conf is not correct, cannot continue."
return 1 return 1
fi fi
@ -3210,14 +3223,14 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" {
fi fi
_debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)" _debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)"
_info "nginx conf is done, let's check it again." _info "nginx conf is done, let's check it again."
if ! nginx -t >/dev/null; then
if ! nginx -t >/dev/null 2>&1; then
_err "It seems that nginx conf was broken, let's restore." _err "It seems that nginx conf was broken, let's restore."
cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF"
return 1 return 1
fi fi
_info "Reload nginx" _info "Reload nginx"
if ! nginx -s reload >/dev/null; then
if ! nginx -s reload >/dev/null 2>&1; then
_err "It seems that nginx reload error, let's restore." _err "It seems that nginx reload error, let's restore."
cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF" cat "$_backup_conf" >"$FOUND_REAL_NGINX_CONF"
return 1 return 1
@ -4515,7 +4528,7 @@ issue() {
vlist="$Le_Vlist" vlist="$Le_Vlist"
_cleardomainconf "Le_Vlist" _cleardomainconf "Le_Vlist"
_info "Getting domain auth token for each domain"
_debug "Getting domain auth token for each domain"
sep='#' sep='#'
dvsep=',' dvsep=','
if [ -z "$vlist" ]; then if [ -z "$vlist" ]; then
@ -4571,12 +4584,22 @@ issue() {
if [ "$_notAfter" ]; then if [ "$_notAfter" ]; then
_newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\"" _newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\""
fi fi
_debug "STEP 1, Ordering a Certificate"
if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then
_err "Create new order error." _err "Create new order error."
_clearup _clearup
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
if _contains "$response" "invalid"; then
if echo "$response" | _normalizeJson | grep '"status":"invalid"' >/dev/null 2>&1; then
_err "Create new order with invalid status."
_err "$response"
_clearup
_on_issue_err "$_post_hook"
return 1
fi
fi
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)" Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)"
_debug Le_LinkOrder "$Le_LinkOrder" _debug Le_LinkOrder "$Le_LinkOrder"
@ -4601,6 +4624,7 @@ issue() {
return 1 return 1
fi fi
_debug "STEP 2, Get the authorizations of each domain"
#domain and authz map #domain and authz map
_authorizations_map="" _authorizations_map=""
for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do
@ -4609,6 +4633,7 @@ issue() {
_err "get to authz error." _err "get to authz error."
_err "_authorizations_seg" "$_authorizations_seg" _err "_authorizations_seg" "$_authorizations_seg"
_err "_authz_url" "$_authz_url" _err "_authz_url" "$_authz_url"
_err "$response"
_clearup _clearup
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
@ -4616,6 +4641,14 @@ issue() {
response="$(echo "$response" | _normalizeJson)" response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response" _debug2 response "$response"
if echo "$response" | grep '"status":"invalid"' >/dev/null 2>&1; then
_err "get authz objec with invalid status, please try again later."
_err "_authorizations_seg" "$_authorizations_seg"
_err "$response"
_clearup
_on_issue_err "$_post_hook"
return 1
fi
_d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "')" _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "')"
if _contains "$response" "\"wildcard\" *: *true"; then if _contains "$response" "\"wildcard\" *: *true"; then
_d="*.$_d" _d="*.$_d"

6
deploy/routeros.sh

@ -137,7 +137,7 @@ routeros_deploy() {
return $_err_code return $_err_code
fi fi
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \
DEPLOY_SCRIPT_CMD="/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \
comment=\"generated by routeros deploy script in acme.sh\" \ comment=\"generated by routeros deploy script in acme.sh\" \
source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
\n/certificate remove [ find name=$_cdomain.cer_1 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\
@ -158,11 +158,11 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
return $_err_code return $_err_code
fi fi
if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then
if ! _ssh_remote_cmd "/system script run \"LECertDeploy-$_cdomain\""; then
return $_err_code return $_err_code
fi fi
if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then
if ! _ssh_remote_cmd "/system script remove \"LECertDeploy-$_cdomain\""; then
return $_err_code return $_err_code
fi fi

92
deploy/synology_dsm.sh

@ -9,19 +9,24 @@
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727 # Issues: https://github.com/acmesh-official/acme.sh/issues/2727
################################################################################ ################################################################################
# Usage: # Usage:
# - Create temp admin user automatically:
# export SYNO_USE_TEMP_ADMIN=1
# - Or provide your own admin user credential:
# 1. export SYNO_Username="adminUser" # 1. export SYNO_Username="adminUser"
# 2. export SYNO_Password="adminPassword" # 2. export SYNO_Password="adminPassword"
# Optional exports (shown values are the defaults): # 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_Scheme="http"
# - export SYNO_Hostname="localhost" # - export SYNO_Hostname="localhost"
# - export SYNO_Port="5000" # - 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 # - export SYNO_Device_ID="" - required for skipping 2FA-OTP
# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com # 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com
################################################################################ ################################################################################
# Dependencies: # Dependencies:
# - jq & curl # - jq & curl
# - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set)
################################################################################ ################################################################################
# Return value: # Return value:
# 0 means success, otherwise error. # 0 means success, otherwise error.
@ -38,6 +43,7 @@ synology_dsm_deploy() {
_debug _cdomain "$_cdomain" _debug _cdomain "$_cdomain"
# Get username & password, but don't save until we authenticated successfully # Get username & password, but don't save until we authenticated successfully
_getdeployconf SYNO_USE_TEMP_ADMIN
_getdeployconf SYNO_Username _getdeployconf SYNO_Username
_getdeployconf SYNO_Password _getdeployconf SYNO_Password
_getdeployconf SYNO_Create _getdeployconf SYNO_Create
@ -45,12 +51,25 @@ synology_dsm_deploy() {
_getdeployconf SYNO_TOTP_SECRET _getdeployconf SYNO_TOTP_SECRET
_getdeployconf SYNO_Device_Name _getdeployconf SYNO_Device_Name
_getdeployconf SYNO_Device_ID _getdeployconf SYNO_Device_ID
if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
_err "SYNO_Username & SYNO_Password must be set"
# Prepare temp admin user info if SYNO_USE_TEMP_ADMIN is set
if [ -n "${SYNO_USE_TEMP_ADMIN:-}" ]; then
if ! _exists synouser; then
if ! _exists synogroup; then
_err "Tools are missing for creating temp admin user, please set SYNO_Username & SYNO_Password instead."
return 1 return 1
fi fi
if [ -n "${SYNO_Device_Name:-}" ] && [ -z "${SYNO_Device_ID:-}" ]; then
_err "SYNO_Device_Name set, but SYNO_Device_ID is empty"
fi
_debug "Setting temp admin user credential..."
SYNO_Username=sc-acmesh-tmp
SYNO_Password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
# Ignore 2FA-OTP settings which won't be needed.
SYNO_Device_Name=
SYNO_Device_ID=
fi
if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
_err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password."
return 1 return 1
fi fi
_debug2 SYNO_Username "$SYNO_Username" _debug2 SYNO_Username "$SYNO_Username"
@ -69,6 +88,7 @@ synology_dsm_deploy() {
[ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http"
[ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost"
[ -n "${SYNO_Port}" ] || SYNO_Port="5000" [ -n "${SYNO_Port}" ] || SYNO_Port="5000"
_savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
_savedeployconf SYNO_Scheme "$SYNO_Scheme" _savedeployconf SYNO_Scheme "$SYNO_Scheme"
_savedeployconf SYNO_Hostname "$SYNO_Hostname" _savedeployconf SYNO_Hostname "$SYNO_Hostname"
_savedeployconf SYNO_Port "$SYNO_Port" _savedeployconf SYNO_Port "$SYNO_Port"
@ -108,13 +128,11 @@ synology_dsm_deploy() {
_info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" _info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
_info " See synology_dsm.sh script or ACME.sh Wiki page for details:" _info " See synology_dsm.sh script or ACME.sh Wiki page for details:"
_info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide" _info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
DEPRECATED_otp_code=""
if _exists oathtool; then
DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
else
if ! _exists oathtool; then
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return 1 return 1
fi fi
DEPRECATED_otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
if [ -n "$SYNO_DID" ]; then if [ -n "$SYNO_DID" ]; then
_H1="Cookie: did=$SYNO_DID" _H1="Cookie: did=$SYNO_DID"
@ -125,16 +143,21 @@ synology_dsm_deploy() {
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes") response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
_debug3 response "$response" _debug3 response "$response"
# END - DEPRECATED, only kept for legacy compatibility reasons # END - DEPRECATED, only kept for legacy compatibility reasons
# If SYNO_DeviceDevice_ID & SYNO_Device_Name both empty, just log in normally
elif [ -z "${SYNO_Device_ID:-}" ] && [ -z "${SYNO_Device_Name:-}" ]; then
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_debug "Creating temp admin user in Synology DSM"
synouser --del "$SYNO_Username" >/dev/null 2>/dev/null
synouser --add "$SYNO_Username" "$SYNO_Password" "" 0 "" 0 >/dev/null
synogroup --memberadd administrators "$SYNO_Username" >/dev/null
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")
_debug3 response "$response"
# Get device ID if still empty first, otherwise log in right away # Get device ID if still empty first, otherwise log in right away
elif [ -z "${SYNO_Device_ID:-}" ]; then
# 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" printf "Enter OTP code for user '%s': " "$SYNO_Username"
read -r otp_code read -r otp_code
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/$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") 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" _secure_debug3 response "$response"
@ -142,18 +165,27 @@ synology_dsm_deploy() {
[ "${api_version}" -gt '6' ] || id_property='did' [ "${api_version}" -gt '6' ] || id_property='did'
SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p') SYNO_Device_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p')
_secure_debug2 SYNO_Device_ID "$SYNO_Device_ID" _secure_debug2 SYNO_Device_ID "$SYNO_Device_ID"
# Otherwise, if SYNO_Device_ID is set, we can just use it to login.
else 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/$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") 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")
_debug3 response "$response"
_secure_debug3 response "$response"
fi fi
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p') sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug "Session ID" "$sid" _debug "Session ID" "$sid"
_debug SynoToken "$token" _debug SynoToken "$token"
if [ -z "$SYNO_DID" ] && [ -z "$SYNO_Device_ID" ] || [ -z "$sid" ] || [ -z "$token" ]; then
if [ -z "$sid" ] || [ -z "$token" ]; then
_err "Unable to authenticate to $_base_url - check your username & password." _err "Unable to authenticate to $_base_url - check your username & password."
_err "If two-factor authentication is enabled for the user, set SYNO_Device_ID."
_err "If two-factor authentication is enabled for the user:"
_err "- set SYNO_Device_Name then input *correct* OTP-code manually"
_err "- get & set SYNO_Device_ID via your browser cookies"
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
return 1 return 1
fi fi
@ -164,8 +196,10 @@ synology_dsm_deploy() {
# Now that we know the username & password are good, save them # Now that we know the username & password are good, save them
_savedeployconf SYNO_Username "$SYNO_Username" _savedeployconf SYNO_Username "$SYNO_Username"
_savedeployconf SYNO_Password "$SYNO_Password" _savedeployconf SYNO_Password "$SYNO_Password"
if [ -z "${SYNO_USE_TEMP_ADMIN:-}" ]; then
_savedeployconf SYNO_Device_Name "$SYNO_Device_Name" _savedeployconf SYNO_Device_Name "$SYNO_Device_Name"
_savedeployconf SYNO_Device_ID "$SYNO_Device_ID" _savedeployconf SYNO_Device_ID "$SYNO_Device_ID"
fi
_info "Getting certificates in Synology DSM" _info "Getting certificates in Synology DSM"
response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi")
@ -177,6 +211,7 @@ synology_dsm_deploy() {
if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then
_err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set" _err "Unable to find certificate: $SYNO_Certificate & \$SYNO_Create is not set"
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
return 1 return 1
fi fi
@ -211,10 +246,11 @@ synology_dsm_deploy() {
else else
_info "Restarting HTTP services failed" _info "Restarting HTTP services failed"
fi fi
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
_logout _logout
return 0 return 0
else else
_remove_temp_admin "$SYNO_USE_TEMP_ADMIN" "$SYNO_Username"
_err "Unable to update certificate, error code $response" _err "Unable to update certificate, error code $response"
_logout _logout
return 1 return 1
@ -223,7 +259,17 @@ synology_dsm_deploy() {
#################### Private functions below ################################## #################### Private functions below ##################################
_logout() { _logout() {
# Logout to not occupy a permanent session, e.g. in DSM's "Connected Users" widget
response=$(_get "$_base_url/webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version&method=logout")
# Logout CERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables)
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid")
_debug3 response "$response" _debug3 response "$response"
} }
_remove_temp_admin() {
flag=$1
username=$2
if [ -n "${flag}" ]; then
_debug "Removing temp admin user in Synology DSM"
synouser --del "$username" >/dev/null
fi
}

148
dnsapi/dns_do.sh

@ -1,148 +0,0 @@
#!/usr/bin/env sh
# DNS API for Domain-Offensive / Resellerinterface / Domainrobot
# Report bugs at https://github.com/seidler2547/acme.sh/issues
# set these environment variables to match your customer ID and password:
# DO_PID="KD-1234567"
# DO_PW="cdfkjl3n2"
DO_URL="https://soap.resellerinterface.de/"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_do_add() {
fulldomain=$1
txtvalue=$2
if _dns_do_authenticate; then
_info "Adding TXT record to ${_domain} as ${fulldomain}"
_dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300
if _contains "${response}" '>success<'; then
return 0
fi
_err "Could not create resource record, check logs"
fi
return 1
}
#fulldomain
dns_do_rm() {
fulldomain=$1
if _dns_do_authenticate; then
if _dns_do_list_rrs; then
_dns_do_had_error=0
for _rrid in ${_rr_list}; do
_info "Deleting resource record $_rrid for $_domain"
_dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}"
if ! _contains "${response}" '>success<'; then
_dns_do_had_error=1
_err "Could not delete resource record for ${_domain}, id ${_rrid}"
fi
done
return $_dns_do_had_error
fi
fi
return 1
}
#################### Private functions below ##################################
_dns_do_authenticate() {
_info "Authenticating as ${DO_PID}"
_dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}"
if _contains "${response}" '>success<'; then
_get_root "$fulldomain"
_debug "_domain $_domain"
return 0
else
_err "Authentication failed, are DO_PID and DO_PW set correctly?"
fi
return 1
}
_dns_do_list_rrs() {
_dns_do_soap getRRList origin "${_domain}"
if ! _contains "${response}" 'SOAP-ENC:Array'; then
_err "getRRList origin ${_domain} failed"
return 1
fi
_rr_list="$(echo "${response}" |
tr -d "\n\r\t" |
sed -e 's/<item xsi:type="ns2:Map">/\n/g' |
grep ">$(_regexcape "$fulldomain")</value>" |
sed -e 's/<\/item>/\n/g' |
grep '>id</key><value' |
_egrep_o '>[0-9]{1,16}<' |
tr -d '><')"
[ "${_rr_list}" ]
}
_dns_do_soap() {
func="$1"
shift
# put the parameters to xml
body="<tns:${func} xmlns:tns=\"${DO_URL}\">"
while [ "$1" ]; do
_k="$1"
shift
_v="$1"
shift
body="$body<$_k>$_v</$_k>"
done
body="$body</tns:${func}>"
_debug2 "SOAP request ${body}"
# build SOAP XML
_xml='<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>'"$body"'</env:Body>
</env:Envelope>'
# set SOAP headers
export _H1="SOAPAction: ${DO_URL}#${func}"
if ! response="$(_post "${_xml}" "${DO_URL}")"; then
_err "Error <$1>"
return 1
fi
_debug2 "SOAP response $response"
# retrieve cookie header
_H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)"
export _H2
return 0
}
_get_root() {
domain=$1
i=1
_dns_do_soap getDomainList
_all_domains="$(echo "${response}" |
tr -d "\n\r\t " |
_egrep_o 'domain</key><value[^>]+>[^<]+' |
sed -e 's/^domain<\/key><value[^>]*>//g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi
if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then
_domain="$h"
return 0
fi
i=$(_math $i + 1)
done
_debug "$domain not found"
return 1
}
_regexcape() {
echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g'
}

12
dnsapi/dns_gandi_livedns.sh

@ -13,7 +13,7 @@
# #
######## Public functions ##################### ######## Public functions #####################
GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
GANDI_LIVEDNS_API="https://api.gandi.net/v5/livedns"
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gandi_livedns_add() { dns_gandi_livedns_add() {
@ -78,7 +78,7 @@ dns_gandi_livedns_rm() {
_gandi_livedns_rest PUT \ _gandi_livedns_rest PUT \
"domains/$_domain/records/$_sub_domain/TXT" \ "domains/$_domain/records/$_sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
_contains "$response" '{"message": "DNS Record Created"}' &&
_contains "$response" '{"message":"DNS Record Created"}' &&
_info "Removing record $(__green "success")" _info "Removing record $(__green "success")"
} }
@ -134,7 +134,7 @@ _dns_gandi_append_record() {
_debug new_rrset_values "$_rrset_values" _debug new_rrset_values "$_rrset_values"
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" &&
_contains "$response" '{"message": "DNS Record Created"}' &&
_contains "$response" '{"message":"DNS Record Created"}' &&
_info "Adding record $(__green "success")" _info "Adding record $(__green "success")"
} }
@ -144,11 +144,11 @@ _dns_gandi_existing_rrset_values() {
if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
return 1 return 1
fi fi
if ! _contains "$response" '"rrset_type": "TXT"'; then
if ! _contains "$response" '"rrset_type":"TXT"'; then
_debug "Does not have a _acme-challenge TXT record yet." _debug "Does not have a _acme-challenge TXT record yet."
return 1 return 1
fi fi
if _contains "$response" '"rrset_values": \[\]'; then
if _contains "$response" '"rrset_values":\[\]'; then
_debug "Empty rrset_values for TXT record, no previous TXT record." _debug "Empty rrset_values for TXT record, no previous TXT record."
return 1 return 1
fi fi
@ -169,7 +169,7 @@ _gandi_livedns_rest() {
if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then
export _H2="Authorization: Bearer $GANDI_LIVEDNS_TOKEN" export _H2="Authorization: Bearer $GANDI_LIVEDNS_TOKEN"
else else
export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
export _H2="Authorization: Apikey $GANDI_LIVEDNS_KEY"
fi fi
if [ "$m" = "GET" ]; then if [ "$m" = "GET" ]; then

Loading…
Cancel
Save