Browse Source

Merge pull request #5294 from PMExtra/refactor/ali_api

refactor: Alibaba Cloud API
neil 1 year ago
parent
commit
114eb6288d
3 changed files with 95 additions and 150 deletions
  1. 5 0
      acme.sh
  2. 18 89
      deploy/ali_cdn.sh
  3. 72 61
      dnsapi/dns_ali.sh

+ 5 - 0
acme.sh

@@ -672,8 +672,10 @@ _hex_dump() {
 #0  1  2  3  4  5  6  7  8  9  -  _  .  ~
 #30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e
 
+#_url_encode [upper-hex]  the encoded hex will be upper-case if the argument upper-hex is followed
 #stdin stdout
 _url_encode() {
+  _upper_hex=$1
   _hex_str=$(_hex_dump)
   _debug3 "_url_encode"
   _debug3 "_hex_str" "$_hex_str"
@@ -883,6 +885,9 @@ _url_encode() {
       ;;
     #other hex
     *)
+      if [ "$_upper_hex" = "upper-hex" ]; then
+        _hex_code=$(printf "%s" "$_hex_code" | _upper_case)
+      fi
       printf '%%%s' "$_hex_code"
       ;;
     esac

+ 18 - 89
deploy/ali_cdn.sh

@@ -1,17 +1,21 @@
 #!/usr/bin/env sh
+# shellcheck disable=SC2034,SC2154
 
 # Script to create certificate to Alibaba Cloud CDN
 #
+# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-alibaba-cloud-cdn-aliyun
+#
 # This deployment required following variables
 # export Ali_Key="ALIACCESSKEY"
 # export Ali_Secret="ALISECRETKEY"
+# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi
+#
+# To specify the CDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates
 # export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com"
-# If you have more than one domain, just
+# If you have multiple CDN domains using the same certificate, just
 # export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
-#
-# The credentials are shared with all domains, also shared with dns_ali api
 
-Ali_API="https://cdn.aliyuncs.com/"
+Ali_CDN_API="https://cdn.aliyuncs.com/"
 
 ali_cdn_deploy() {
   _cdomain="$1"
@@ -26,18 +30,16 @@ ali_cdn_deploy() {
   _debug _cca "$_cca"
   _debug _cfullchain "$_cfullchain"
 
-  Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
-  Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
-  if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
-    Ali_Key=""
-    Ali_Secret=""
-    _err "You don't specify aliyun api key and secret yet."
+  # Load dnsapi/dns_ali.sh to reduce the duplicated codes
+  # https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276
+  dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)"
+  # shellcheck source=/dev/null
+  if ! . "$dnsapi_ali"; then
+    _err "Error loading file $dnsapi_ali. Please check your API file and try again."
     return 1
   fi
 
-  #save the api key and secret to the account conf file.
-  _saveaccountconf_mutable Ali_Key "$Ali_Key"
-  _saveaccountconf_mutable Ali_Secret "$Ali_Secret"
+  _prepare_ali_credentials || return 1
 
   _getdeployconf DEPLOY_ALI_CDN_DOMAIN
   if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then
@@ -47,8 +49,8 @@ ali_cdn_deploy() {
   fi
 
   # read cert and key files and urlencode both
-  _cert=$(_url_encode_upper <"$_cfullchain")
-  _key=$(_url_encode_upper <"$_ckey")
+  _cert=$(_url_encode upper-hex <"$_cfullchain")
+  _key=$(_url_encode upper-hex <"$_ckey")
 
   _debug2 _cert "$_cert"
   _debug2 _key "$_key"
@@ -64,82 +66,9 @@ ali_cdn_deploy() {
   return 0
 }
 
-####################  Private functions below ##################################
-
-# act ign mtd
-_ali_rest() {
-  act="$1"
-  ign="$2"
-  mtd="$3"
-
-  signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
-  signature=$(_ali_urlencode "$signature")
-  url="$Ali_API?$query&Signature=$signature"
-
-  if [ "$mtd" = "GET" ]; then
-    response="$(_get "$url")"
-  else
-    # post payload is not supported yet because of signature
-    response="$(_post "" "$url")"
-  fi
-
-  _ret="$?"
-  _debug2 response "$response"
-  if [ "$_ret" != "0" ]; then
-    _err "Error <$act>"
-    return 1
-  fi
-
-  if [ -z "$ign" ]; then
-    message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
-    if [ "$message" ]; then
-      _err "$message"
-      return 1
-    fi
-  fi
-}
-
-_ali_urlencode() {
-  _str="$1"
-  _str_len=${#_str}
-  _u_i=1
-  while [ "$_u_i" -le "$_str_len" ]; do
-    _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
-    case $_str_c in [a-zA-Z0-9.~_-])
-      printf "%s" "$_str_c"
-      ;;
-    *)
-      printf "%%%02X" "'$_str_c"
-      ;;
-    esac
-    _u_i="$(_math "$_u_i" + 1)"
-  done
-}
-
-_ali_nonce() {
-  #_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
-  #Not so good...
-  date +"%s%N" | sed 's/%N//g'
-}
-
-_timestamp() {
-  date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
-}
-
-# stdin stdout
-_url_encode_upper() {
-  encoded=$(_url_encode)
-
-  for match in $(echo "$encoded" | _egrep_o '%..' | sort -u); do
-    upper=$(echo "$match" | _upper_case)
-    encoded=$(echo "$encoded" | sed "s/$match/$upper/g")
-  done
-
-  echo "$encoded"
-}
-
 # domain pub pri
 _set_cdn_domain_ssl_certificate_query() {
+  endpoint=$Ali_CDN_API
   query=''
   query=$query'AccessKeyId='$Ali_Key
   query=$query'&Action=SetCdnDomainSSLCertificate'

+ 72 - 61
dnsapi/dns_ali.sh

@@ -9,25 +9,19 @@ Options:
  Ali_Secret API Secret
 '
 
-Ali_API="https://alidns.aliyuncs.com/"
+# NOTICE:
+# This file is referenced by Alibaba Cloud Services deploy hooks
+# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276
+# Be careful when modifying this file, especially when making breaking changes for common functions
+
+Ali_DNS_API="https://alidns.aliyuncs.com/"
 
 #Usage: dns_ali_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 dns_ali_add() {
   fulldomain=$1
   txtvalue=$2
 
-  Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
-  Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
-  if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
-    Ali_Key=""
-    Ali_Secret=""
-    _err "You don't specify aliyun api key and secret yet."
-    return 1
-  fi
-
-  #save the api key and secret to the account conf file.
-  _saveaccountconf_mutable Ali_Key "$Ali_Key"
-  _saveaccountconf_mutable Ali_Secret "$Ali_Secret"
+  _prepare_ali_credentials || return 1
 
   _debug "First detect the root zone"
   if ! _get_root "$fulldomain"; then
@@ -52,7 +46,67 @@ dns_ali_rm() {
   _clean
 }
 
-####################  Private functions below ##################################
+####################  Alibaba Cloud common functions below  ####################
+
+_prepare_ali_credentials() {
+  Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
+  Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
+  if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
+    Ali_Key=""
+    Ali_Secret=""
+    _err "You don't specify aliyun api key and secret yet."
+    return 1
+  fi
+
+  #save the api key and secret to the account conf file.
+  _saveaccountconf_mutable Ali_Key "$Ali_Key"
+  _saveaccountconf_mutable Ali_Secret "$Ali_Secret"
+}
+
+# act ign mtd
+_ali_rest() {
+  act="$1"
+  ign="$2"
+  mtd="${3:-GET}"
+
+  signature=$(printf "%s" "$mtd&%2F&$(printf "%s" "$query" | _url_encode upper-hex)" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
+  signature=$(printf "%s" "$signature" | _url_encode upper-hex)
+  url="$endpoint?Signature=$signature"
+
+  if [ "$mtd" = "GET" ]; then
+    url="$url&$query"
+    response="$(_get "$url")"
+  else
+    response="$(_post "$query" "$url" "" "$mtd" "application/x-www-form-urlencoded")"
+  fi
+
+  _ret="$?"
+  _debug2 response "$response"
+  if [ "$_ret" != "0" ]; then
+    _err "Error <$act>"
+    return 1
+  fi
+
+  if [ -z "$ign" ]; then
+    message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
+    if [ "$message" ]; then
+      _err "$message"
+      return 1
+    fi
+  fi
+}
+
+_ali_nonce() {
+  #_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
+  #Not so good...
+  date +"%s%N" | sed 's/%N//g'
+}
+
+_timestamp() {
+  date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
+}
+
+####################  Private functions below  ####################
 
 _get_root() {
   domain=$1
@@ -83,52 +137,10 @@ _get_root() {
   return 1
 }
 
-_ali_rest() {
-  signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
-  signature=$(_ali_urlencode "$signature")
-  url="$Ali_API?$query&Signature=$signature"
-
-  if ! response="$(_get "$url")"; then
-    _err "Error <$1>"
-    return 1
-  fi
-
-  _debug2 response "$response"
-  if [ -z "$2" ]; then
-    message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
-    if [ "$message" ]; then
-      _err "$message"
-      return 1
-    fi
-  fi
-}
-
-_ali_urlencode() {
-  _str="$1"
-  _str_len=${#_str}
-  _u_i=1
-  while [ "$_u_i" -le "$_str_len" ]; do
-    _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
-    case $_str_c in [a-zA-Z0-9.~_-])
-      printf "%s" "$_str_c"
-      ;;
-    *)
-      printf "%%%02X" "'$_str_c"
-      ;;
-    esac
-    _u_i="$(_math "$_u_i" + 1)"
-  done
-}
-
-_ali_nonce() {
-  #_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
-  #Not so good...
-  date +"%s%N" | sed 's/%N//g'
-}
-
 _check_exist_query() {
   _qdomain="$1"
   _qsubdomain="$2"
+  endpoint=$Ali_DNS_API
   query=''
   query=$query'AccessKeyId='$Ali_Key
   query=$query'&Action=DescribeDomainRecords'
@@ -144,6 +156,7 @@ _check_exist_query() {
 }
 
 _add_record_query() {
+  endpoint=$Ali_DNS_API
   query=''
   query=$query'AccessKeyId='$Ali_Key
   query=$query'&Action=AddDomainRecord'
@@ -160,6 +173,7 @@ _add_record_query() {
 }
 
 _delete_record_query() {
+  endpoint=$Ali_DNS_API
   query=''
   query=$query'AccessKeyId='$Ali_Key
   query=$query'&Action=DeleteDomainRecord'
@@ -173,6 +187,7 @@ _delete_record_query() {
 }
 
 _describe_records_query() {
+  endpoint=$Ali_DNS_API
   query=''
   query=$query'AccessKeyId='$Ali_Key
   query=$query'&Action=DescribeDomainRecords'
@@ -203,7 +218,3 @@ _clean() {
   fi
 
 }
-
-_timestamp() {
-  date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
-}