#!/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 }