]> git.proxmox.com Git - mirror_acme.sh.git/commitdiff
Merge pull request #3499 from acmesh-official/dev 2.8.9
authorneil <github@neilpang.com>
Mon, 3 May 2021 14:20:20 +0000 (22:20 +0800)
committerGitHub <noreply@github.com>
Mon, 3 May 2021 14:20:20 +0000 (22:20 +0800)
sync

.github/workflows/DNS.yml
.github/workflows/LetsEncrypt.yml
acme.sh
deploy/synology_dsm.sh
dnsapi/dns_aurora.sh [new file with mode: 0644]
dnsapi/dns_one.sh
dnsapi/dns_websupport.sh [new file with mode: 0644]
notify/mail.sh
notify/telegram.sh

index 5ff1f8abdf587c6cc6b8f4b2286de10d6dfdad37..f8e501ed783cdee63be8a1a6816151e03d4a35b2 100644 (file)
@@ -184,7 +184,7 @@ jobs:
     - uses: actions/checkout@v2\r
     - name: Clone acmetest\r
       run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/\r
-    - uses: vmactions/freebsd-vm@v0.1.3\r
+    - uses: vmactions/freebsd-vm@v0.1.4\r
       with:\r
         envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'\r
         prepare: pkg install -y socat curl\r
index 7193d88de1b95af4eae2393443aaf49931e56b3f..ba9a531718d7da9a8d28246b55183b46979414e5 100644 (file)
@@ -111,7 +111,7 @@ jobs:
     - uses: actions/checkout@v2\r
     - name: Clone acmetest\r
       run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/\r
-    - uses: vmactions/freebsd-vm@v0.1.3\r
+    - uses: vmactions/freebsd-vm@v0.1.4\r
       with:\r
         envs: 'NGROK_TOKEN TEST_LOCAL'\r
         prepare: pkg install -y socat curl\r
diff --git a/acme.sh b/acme.sh
index 8d422719e3ee372fa3e79dfd432800803fac999e..0ea93cf78e09e0c140e28690fc76c1d0f5b370b2 100755 (executable)
--- a/acme.sh
+++ b/acme.sh
@@ -102,6 +102,8 @@ DEBUG_LEVEL_NONE=0
 
 DOH_CLOUDFLARE=1
 DOH_GOOGLE=2
+DOH_ALI=3
+DOH_DP=4
 
 HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)"
 
@@ -2038,7 +2040,7 @@ _send_signed_request() {
         if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then
           _headers="$(cat "$HTTP_HEADER")"
           _debug2 _headers "$_headers"
-          _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
+          _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)"
         fi
       fi
       if [ -z "$_CACHED_NONCE" ]; then
@@ -2118,7 +2120,7 @@ _send_signed_request() {
     fi
     _debug2 response "$response"
 
-    _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
+    _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)"
 
     if ! _startswith "$code" "2"; then
       _body="$response"
@@ -2266,7 +2268,7 @@ _getdeployconf() {
     return 0 # do nothing
   fi
   _saved=$(_readdomainconf "SAVED_$_rac_key")
-  eval "export $_rac_key=\"$_saved\""
+  eval "export $_rac_key=\"\$_saved\""
 }
 
 #_saveaccountconf  key  value  base64encode
@@ -2357,7 +2359,7 @@ _startserver() {
 echo 'HTTP/1.0 200 OK'; \
 echo 'Content-Length\: $_content_len'; \
 echo ''; \
-printf -- '$content';" &
+printf '%s' '$content';" &
   serverproc="$!"
 }
 
@@ -3096,6 +3098,11 @@ _checkConf() {
       _debug "Try include files"
       for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do
         _debug "check included $included"
+        if !_startswith "$included" "/" && _exists dirname; then
+          _relpath="$(dirname "$_c_file")"
+          _debug "_relpath" "$_relpath"
+          included="$_relpath/included"
+        fi
         if _checkConf "$1" "$included"; then
           return 0
         fi
@@ -3916,7 +3923,15 @@ _ns_purge_cf() {
 
 #checks if cf server is available
 _ns_is_available_cf() {
-  if _get "https://cloudflare-dns.com" >/dev/null 2>&1; then
+  if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+_ns_is_available_google() {
+  if _get "https://dns.google" "" 1 >/dev/null 2>&1; then
     return 0
   else
     return 1
@@ -3931,6 +3946,38 @@ _ns_lookup_google() {
   _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
 }
 
+_ns_is_available_ali() {
+  if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+#domain, type
+_ns_lookup_ali() {
+  _cf_ld="$1"
+  _cf_ld_type="$2"
+  _cf_ep="https://dns.alidns.com/resolve"
+  _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
+}
+
+_ns_is_available_dp() {
+  if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+#dnspod
+_ns_lookup_dp() {
+  _cf_ld="$1"
+  _cf_ld_type="$2"
+  _cf_ep="https://doh.pub/dns-query"
+  _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
+}
+
 #domain, type
 _ns_lookup() {
   if [ -z "$DOH_USE" ]; then
@@ -3938,16 +3985,30 @@ _ns_lookup() {
     if _ns_is_available_cf; then
       _debug "Use cloudflare doh server"
       export DOH_USE=$DOH_CLOUDFLARE
-    else
+    elif _ns_is_available_google; then
       _debug "Use google doh server"
       export DOH_USE=$DOH_GOOGLE
+    elif _ns_is_available_ali; then
+      _debug "Use aliyun doh server"
+      export DOH_USE=$DOH_ALI
+    elif _ns_is_available_dp; then
+      _debug "Use dns pod doh server"
+      export DOH_USE=$DOH_DP
+    else
+      _err "No doh"
     fi
   fi
 
   if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
     _ns_lookup_cf "$@"
-  else
+  elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
     _ns_lookup_google "$@"
+  elif [ "$DOH_USE" = "$DOH_ALI" ]; then
+    _ns_lookup_ali "$@"
+  elif [ "$DOH_USE" = "$DOH_DP" ]; then
+    _ns_lookup_dp "$@"
+  else
+    _err "Unknown doh provider: DOH_USE=$DOH_USE"
   fi
 
 }
@@ -3972,7 +4033,7 @@ __purge_txt() {
   if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
     _ns_purge_cf "$_p_txtdomain" "TXT"
   else
-    _debug "no purge api for google dns api, just sleep 5 secs"
+    _debug "no purge api for this doh api, just sleep 5 secs"
     _sleep 5
   fi
 
@@ -4720,7 +4781,7 @@ $_authorizations_map"
       _debug2 response "$response"
 
       status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
-      if [ "$status" = "valid" ]; then
+      if _contains "$status" "valid"; then
         _info "$(__green Success)"
         _stopserver "$serverproc"
         serverproc=""
index 35d332099a15118a148ed7f28fd222c96a7a0c1e..25d43efbc3073ed14a70336351ac29dd1636e2b3 100644 (file)
@@ -121,7 +121,7 @@ synology_dsm_deploy() {
   # we've verified this certificate description is a thing, so save it
   _savedeployconf SYNO_Certificate "$SYNO_Certificate"
 
-  default=false
+  default=""
   if echo "$response" | sed -n "s/.*\"desc\":\"$SYNO_Certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then
     default=true
   fi
diff --git a/dnsapi/dns_aurora.sh b/dnsapi/dns_aurora.sh
new file mode 100644 (file)
index 0000000..00f4473
--- /dev/null
@@ -0,0 +1,171 @@
+#!/usr/bin/env sh
+
+#
+#AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
+#
+#AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje"
+
+AURORA_Api="https://api.auroradns.eu"
+
+########  Public functions #####################
+
+#Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_aurora_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  AURORA_Key="${AURORA_Key:-$(_readaccountconf_mutable AURORA_Key)}"
+  AURORA_Secret="${AURORA_Secret:-$(_readaccountconf_mutable AURORA_Secret)}"
+
+  if [ -z "$AURORA_Key" ] || [ -z "$AURORA_Secret" ]; then
+    AURORA_Key=""
+    AURORA_Secret=""
+    _err "You didn't specify an Aurora api key and secret yet."
+    _err "You can get yours from here https://cp.pcextreme.nl/auroradns/users."
+    return 1
+  fi
+
+  #save the api key and secret to the account conf file.
+  _saveaccountconf_mutable AURORA_Key "$AURORA_Key"
+  _saveaccountconf_mutable AURORA_Secret "$AURORA_Secret"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+  _debug _domain_id "$_domain_id"
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  _info "Adding record"
+  if _aurora_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":300}"; then
+    if _contains "$response" "$txtvalue"; then
+      _info "Added, OK"
+      return 0
+    elif _contains "$response" "RecordExistsError"; then
+      _info "Already exists, OK"
+      return 0
+    else
+      _err "Add txt record error."
+      return 1
+    fi
+  fi
+  _err "Add txt record error."
+  return 1
+
+}
+
+#fulldomain txtvalue
+dns_aurora_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  AURORA_Key="${AURORA_Key:-$(_readaccountconf_mutable AURORA_Key)}"
+  AURORA_Secret="${AURORA_Secret:-$(_readaccountconf_mutable AURORA_Secret)}"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+  _debug _domain_id "$_domain_id"
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  _debug "Getting records"
+  _aurora_rest GET "zones/${_domain_id}/records"
+
+  if ! _contains "$response" "$txtvalue"; then
+    _info "Don't need to remove."
+  else
+    records=$(echo "$response" | _normalizeJson | tr -d "[]" | sed "s/},{/}|{/g" | tr "|" "\n")
+    if [ "$(echo "$records" | wc -l)" -le 2 ]; then
+      _err "Can not parse records."
+      return 1
+    fi
+    record_id=$(echo "$records" | grep "\"type\": *\"TXT\"" | grep "\"name\": *\"$_sub_domain\"" | grep "\"content\": *\"$txtvalue\"" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ")
+    _debug "record_id" "$record_id"
+    if [ -z "$record_id" ]; then
+      _err "Can not get record id to remove."
+      return 1
+    fi
+    if ! _aurora_rest DELETE "zones/$_domain_id/records/$record_id"; then
+      _err "Delete record error."
+      return 1
+    fi
+  fi
+  return 0
+
+}
+
+####################  Private functions below ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+# _domain_id=sdjkglgdfewsdfg
+_get_root() {
+  domain=$1
+  i=1
+  p=1
+
+  while true; do
+    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
+    _debug h "$h"
+    if [ -z "$h" ]; then
+      #not valid
+      return 1
+    fi
+
+    if ! _aurora_rest GET "zones/$h"; then
+      return 1
+    fi
+
+    if _contains "$response" "\"name\": \"$h\""; then
+      _domain_id=$(echo "$response" | _normalizeJson | tr -d "{}" | tr "," "\n" | grep "\"id\": *\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ")
+      _debug _domain_id "$_domain_id"
+      if [ "$_domain_id" ]; then
+        _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
+        _domain=$h
+        return 0
+      fi
+      return 1
+    fi
+    p=$i
+    i=$(_math "$i" + 1)
+  done
+  return 1
+}
+
+_aurora_rest() {
+  m=$1
+  ep="$2"
+  data="$3"
+  _debug "$ep"
+
+  key_trimmed=$(echo "$AURORA_Key" | tr -d '"')
+  secret_trimmed=$(echo "$AURORA_Secret" | tr -d '"')
+
+  timestamp=$(date -u +"%Y%m%dT%H%M%SZ")
+  signature=$(printf "%s/%s%s" "$m" "$ep" "$timestamp" | _hmac sha256 "$(printf "%s" "$secret_trimmed" | _hex_dump | tr -d " ")" | _base64)
+  authorization=$(printf "AuroraDNSv1 %s" "$(printf "%s:%s" "$key_trimmed" "$signature" | _base64)")
+
+  export _H1="Content-Type: application/json; charset=UTF-8"
+  export _H2="X-AuroraDNS-Date: $timestamp"
+  export _H3="Authorization: $authorization"
+
+  if [ "$m" != "GET" ]; then
+    _debug data "$data"
+    response="$(_post "$data" "$AURORA_Api/$ep" "" "$m")"
+  else
+    response="$(_get "$AURORA_Api/$ep")"
+  fi
+
+  if [ "$?" != "0" ]; then
+    _err "error $ep"
+    return 1
+  fi
+  _debug2 response "$response"
+  return 0
+}
index 890cc804c7b43b0f6031265156d1a9d6fc7011d4..1565b767c2090c79404979fccc6957bcfcb72bae 100644 (file)
@@ -1,22 +1,9 @@
 #!/usr/bin/env sh
-# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
-
 # one.com ui wrapper for acme.sh
-# Author: github: @diseq
-# Created: 2019-02-17
-# Fixed by: @der-berni
-# Modified: 2020-04-07
-#
-#     Use ONECOM_KeepCnameProxy to keep the CNAME DNS record
-#     export ONECOM_KeepCnameProxy="1"
+
 #
 #     export ONECOM_User="username"
 #     export ONECOM_Password="password"
-#
-# Usage:
-#     acme.sh --issue --dns dns_one -d example.com
-#
-#     only single domain supported atm
 
 dns_one_add() {
   fulldomain=$1
@@ -36,27 +23,9 @@ dns_one_add() {
   subdomain="${_sub_domain}"
   maindomain=${_domain}
 
-  useProxy=0
-  if [ "${_sub_domain}" = "_acme-challenge" ]; then
-    subdomain="proxy${_sub_domain}"
-    useProxy=1
-  fi
-
   _debug subdomain "$subdomain"
   _debug maindomain "$maindomain"
 
-  if [ $useProxy -eq 1 ]; then
-    #Check if the CNAME exists
-    _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
-    if [ -z "$id" ]; then
-      _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
-      _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
-
-      _info "Not valid yet, let's wait 1 hour to take effect."
-      _sleep 3600
-    fi
-  fi
-
   #Check if the TXT exists
   _dns_one_getrecord "TXT" "$subdomain" "$txtvalue"
   if [ -n "$id" ]; then
@@ -92,26 +61,8 @@ dns_one_rm() {
   subdomain="${_sub_domain}"
   maindomain=${_domain}
 
-  useProxy=0
-  if [ "${_sub_domain}" = "_acme-challenge" ]; then
-    subdomain="proxy${_sub_domain}"
-    useProxy=1
-  fi
-
   _debug subdomain "$subdomain"
   _debug maindomain "$maindomain"
-  if [ $useProxy -eq 1 ]; then
-    if [ "$ONECOM_KeepCnameProxy" = "1" ]; then
-      _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
-    else
-      #Check if the CNAME exists
-      _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
-      if [ -n "$id" ]; then
-        _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
-        _dns_one_delrecord "$id"
-      fi
-    fi
-  fi
 
   #Check if the TXT exists
   _dns_one_getrecord "TXT" "$subdomain" "$txtvalue"
@@ -136,7 +87,7 @@ dns_one_rm() {
 # _domain=domain.com
 _get_root() {
   domain="$1"
-  i=2
+  i=1
   p=1
   while true; do
     h=$(printf "%s" "$domain" | cut -d . -f $i-100)
@@ -163,8 +114,6 @@ _get_root() {
 _dns_one_login() {
 
   # get credentials
-  ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}"
-  ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-0}"
   ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
   ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
   if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
@@ -176,7 +125,6 @@ _dns_one_login() {
   fi
 
   #save the api key and email to the account conf file.
-  _saveaccountconf_mutable ONECOM_KeepCnameProxy "$ONECOM_KeepCnameProxy"
   _saveaccountconf_mutable ONECOM_User "$ONECOM_User"
   _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
 
diff --git a/dnsapi/dns_websupport.sh b/dnsapi/dns_websupport.sh
new file mode 100644 (file)
index 0000000..e824c9c
--- /dev/null
@@ -0,0 +1,207 @@
+#!/usr/bin/env sh
+
+# Acme.sh DNS API wrapper for websupport.sk
+#
+# Original author: trgo.sk (https://github.com/trgosk)
+# Tweaks by: akulumbeg (https://github.com/akulumbeg)
+# Report Bugs here: https://github.com/akulumbeg/acme.sh
+
+# Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey
+#
+# WS_ApiKey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+# (called "Identifier" in the WS Admin)
+#
+# WS_ApiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+# (called "Secret key" in the WS Admin)
+
+WS_Api="https://rest.websupport.sk"
+
+########  Public functions #####################
+
+dns_websupport_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  WS_ApiKey="${WS_ApiKey:-$(_readaccountconf_mutable WS_ApiKey)}"
+  WS_ApiSecret="${WS_ApiSecret:-$(_readaccountconf_mutable WS_ApiSecret)}"
+
+  if [ "$WS_ApiKey" ] && [ "$WS_ApiSecret" ]; then
+    _saveaccountconf_mutable WS_ApiKey "$WS_ApiKey"
+    _saveaccountconf_mutable WS_ApiSecret "$WS_ApiSecret"
+  else
+    WS_ApiKey=""
+    WS_ApiSecret=""
+    _err "You did not specify the API Key and/or API Secret"
+    _err "You can get the API login credentials from https://admin.websupport.sk/en/auth/apiKey"
+    return 1
+  fi
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
+  # we can not use updating anymore.
+  #  count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
+  #  _debug count "$count"
+  #  if [ "$count" = "0" ]; then
+  _info "Adding record"
+  if _ws_rest POST "/v1/user/self/zone/$_domain/record" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
+    if _contains "$response" "$txtvalue"; then
+      _info "Added, OK"
+      return 0
+    elif _contains "$response" "The record already exists"; then
+      _info "Already exists, OK"
+      return 0
+    else
+      _err "Add txt record error."
+      return 1
+    fi
+  fi
+  _err "Add txt record error."
+  return 1
+
+}
+
+dns_websupport_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  _debug2 fulldomain "$fulldomain"
+  _debug2 txtvalue "$txtvalue"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  _debug "Getting txt records"
+  _ws_rest GET "/v1/user/self/zone/$_domain/record"
+
+  if [ "$(printf "%s" "$response" | tr -d " " | grep -c \"items\")" -lt "1" ]; then
+    _err "Error: $response"
+    return 1
+  fi
+
+  record_line="$(_get_from_array "$response" "$txtvalue")"
+  _debug record_line "$record_line"
+  if [ -z "$record_line" ]; then
+    _info "Don't need to remove."
+  else
+    record_id=$(echo "$record_line" | _egrep_o "\"id\": *[^,]*" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ")
+    _debug "record_id" "$record_id"
+    if [ -z "$record_id" ]; then
+      _err "Can not get record id to remove."
+      return 1
+    fi
+    if ! _ws_rest DELETE "/v1/user/self/zone/$_domain/record/$record_id"; then
+      _err "Delete record error."
+      return 1
+    fi
+    if [ "$(printf "%s" "$response" | tr -d " " | grep -c \"success\")" -lt "1" ]; then
+      return 1
+    else
+      return 0
+    fi
+  fi
+
+}
+
+####################  Private Functions ##################################
+
+_get_root() {
+  domain=$1
+  i=1
+  p=1
+
+  while true; do
+    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
+    _debug h "$h"
+    if [ -z "$h" ]; then
+      #not valid
+      return 1
+    fi
+
+    if ! _ws_rest GET "/v1/user/self/zone"; then
+      return 1
+    fi
+
+    if _contains "$response" "\"name\":\"$h\""; then
+      _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *[^,]*" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ")
+      if [ "$_domain_id" ]; then
+        _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
+        _domain=$h
+        return 0
+      fi
+      return 1
+    fi
+    p=$i
+    i=$(_math "$i" + 1)
+  done
+  return 1
+}
+
+_ws_rest() {
+  me=$1
+  pa="$2"
+  da="$3"
+
+  _debug2 api_key "$WS_ApiKey"
+  _debug2 api_secret "$WS_ApiSecret"
+
+  timestamp=$(_time)
+  datez="$(_utc_date | sed "s/ /T/" | sed "s/$/+0000/")"
+  canonical_request="${me} ${pa} ${timestamp}"
+  signature_hash=$(printf "%s" "$canonical_request" | _hmac sha1 "$(printf "%s" "$WS_ApiSecret" | _hex_dump | tr -d " ")" hex)
+  basicauth="$(printf "%s:%s" "$WS_ApiKey" "$signature_hash" | _base64)"
+
+  _debug2 method "$me"
+  _debug2 path "$pa"
+  _debug2 data "$da"
+  _debug2 timestamp "$timestamp"
+  _debug2 datez "$datez"
+  _debug2 canonical_request "$canonical_request"
+  _debug2 signature_hash "$signature_hash"
+  _debug2 basicauth "$basicauth"
+
+  export _H1="Accept: application/json"
+  export _H2="Content-Type: application/json"
+  export _H3="Authorization: Basic ${basicauth}"
+  export _H4="Date: ${datez}"
+
+  _debug2 H1 "$_H1"
+  _debug2 H2 "$_H2"
+  _debug2 H3 "$_H3"
+  _debug2 H4 "$_H4"
+
+  if [ "$me" != "GET" ]; then
+    _debug2 "${me} $WS_Api${pa}"
+    _debug data "$da"
+    response="$(_post "$da" "${WS_Api}${pa}" "" "$me")"
+  else
+    _debug2 "GET $WS_Api${pa}"
+    response="$(_get "$WS_Api${pa}")"
+  fi
+
+  _debug2 response "$response"
+  return "$?"
+}
+
+_get_from_array() {
+  va="$1"
+  fi="$2"
+  for i in $(echo "$va" | sed "s/{/ /g"); do
+    if _contains "$i" "$fi"; then
+      echo "$i"
+      break
+    fi
+  done
+}
index d33fd0d2881db89f373a41197238b7e78afe39f5..2cbddb631db086dd7d7d37ab8dabdeb92da8128b 100644 (file)
@@ -79,7 +79,7 @@ mail_send() {
 _mail_bin() {
   _MAIL_BIN=""
 
-  for b in "$MAIL_BIN" sendmail ssmtp mutt mail msmtp; do
+  for b in $MAIL_BIN sendmail ssmtp mutt mail msmtp; do
     if _exists "$b"; then
       _MAIL_BIN="$b"
       break
index b1306ee1257fcc97bc7e6db51009b3f98851163b..d16f3a982ad440ee965be7cf9e1860716b66dc03 100644 (file)
@@ -27,15 +27,18 @@ telegram_send() {
   fi
   _saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID"
 
+  _content="$(printf "%s" "$_content" | sed -e 's/*/\\\\*/')"
   _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
   _data="{\"text\": \"$_content\", "
   _data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", "
   _data="$_data\"parse_mode\": \"markdown\", "
   _data="$_data\"disable_web_page_preview\": \"1\"}"
 
+  _debug "$_data"
+
   export _H1="Content-Type: application/json"
   _telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage"
-  if _post "$_data" "$_telegram_bot_url"; then
+  if _post "$_data" "$_telegram_bot_url" >/dev/null; then
     # shellcheck disable=SC2154
     _message=$(printf "%s\n" "$response" | sed -n 's/.*"ok":\([^,]*\).*/\1/p')
     if [ "$_message" = "true" ]; then