Skip to content

Commit 9500ff5

Browse files
committed
add gname dns acme.sh
1 parent f39d066 commit 9500ff5

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

dnsapi/dns_gname.sh

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
#!/usr/bin/env sh
2+
# shellcheck disable=SC2034
3+
dns_gname_info='GNAME
4+
Site: gname.com
5+
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gname
6+
Options:
7+
GNAME_APPID Your APPID
8+
GNAME_APPKEY Your APPKEY
9+
OptionsAlt:
10+
'
11+
12+
GNAME_TLD_Api="https://gname.com/request/tlds?lx=all"
13+
GNAME_Api="https://api.gname.com"
14+
GNAME_TLDS_CACHE=""
15+
16+
######## Public functions #####################
17+
18+
#Usage: add _acme-challenge.www.domain.com "T1rxqRBosdIK90xWCG3KLZNf6q_0HG9i01zxXp5CASc"
19+
dns_gname_add() {
20+
fulldomain=$1
21+
txtvalue=$(printf "%s" "$2" | _url_encode)
22+
23+
GNAME_APPID="${GNAME_APPID:-$(_readaccountconf_mutable GNAME_APPID)}"
24+
GNAME_APPKEY="${GNAME_APPKEY:-$(_readaccountconf_mutable GNAME_APPKEY)}"
25+
26+
if [ -z "$GNAME_APPID" ] || [ -z "$GNAME_APPKEY" ]; then
27+
GNAME_APPID=""
28+
GNAME_APPKEY=""
29+
_err "You have not configured the APPID and APPKEY for the GNAME API."
30+
_err "You can get yours from here http://gname.com/domain/api."
31+
return 1
32+
fi
33+
34+
_saveaccountconf_mutable GNAME_APPID "$GNAME_APPID"
35+
_saveaccountconf_mutable GNAME_APPKEY "$GNAME_APPKEY"
36+
37+
if ! _extract_domain "$fulldomain"; then
38+
_err "Failed to extract domain. Please check your network or API response."
39+
return 1
40+
fi
41+
42+
gntime=$(date +%s)
43+
44+
#If the hostname is empty, you need to replace it with @.
45+
final_hostname=$(printf "%s" "${ext_hostname:-@}" | _url_encode)
46+
47+
# Parameters need to be sorted by key
48+
body="appid=$GNAME_APPID&gntime=$gntime&jlz=$txtvalue&lang=us&lx=TXT&mx=0&ttl=600&xl=0&ym=$ext_domain&zj=$final_hostname"
49+
50+
_info "Adding TXT record for $ext_domain, host: $final_hostname"
51+
52+
if _post_to_api "/api/resolution/add" "$body"; then
53+
_info "Successfully added DNS record."
54+
return 0
55+
else
56+
if _contains "$post_response" "the same host records and record values"; then
57+
_info "Successfully DNS record already exists."
58+
return 0
59+
fi
60+
_err "Failed to add DNS record via Gname API."
61+
return 1
62+
fi
63+
}
64+
65+
#Usage: remove _acme-challenge.www.domain.com "T1rxqRBosdIK90xWCG3KLZNf6q_0HG9i01zxXp5CASc"
66+
dns_gname_rm() {
67+
fulldomain=$1
68+
txtvalue=$2
69+
70+
GNAME_APPID="${GNAME_APPID:-$(_readaccountconf_mutable GNAME_APPID)}"
71+
GNAME_APPKEY="${GNAME_APPKEY:-$(_readaccountconf_mutable GNAME_APPKEY)}"
72+
73+
if [ -z "$GNAME_APPID" ] || [ -z "$GNAME_APPKEY" ]; then
74+
GNAME_APPID=""
75+
GNAME_APPKEY=""
76+
_err "You have not configured the APPID and APPKEY for the GNAME API."
77+
_err "You can get yours from here http://gname.com/domain/api."
78+
return 1
79+
fi
80+
81+
_saveaccountconf_mutable GNAME_APPID "$GNAME_APPID"
82+
_saveaccountconf_mutable GNAME_APPKEY "$GNAME_APPKEY"
83+
84+
if ! _extract_domain "$fulldomain"; then
85+
_err "Failed to extract domain. Please check your network or API response."
86+
return 1
87+
fi
88+
89+
final_hostname="${ext_hostname:-@}"
90+
91+
_debug "Query DNS record ID $ext_domain $final_hostname $txtvalue"
92+
93+
record_id=$(_get_record_id $ext_domain $final_hostname $txtvalue)
94+
95+
if [ -z "$record_id" ]; then
96+
_err "No DNS record found"
97+
return 1
98+
fi
99+
100+
_debug "DNS record ID:$record_id";
101+
gntime=$(date +%s)
102+
body="appid=$GNAME_APPID&gntime=$gntime&jxid=$record_id&lang=us&ym=$ext_domain"
103+
104+
if ! _post_to_api "/api/resolution/delete" "$body"; then
105+
_info "DNS record deletion failed"
106+
return 1
107+
fi
108+
109+
_info "DNS record deletion successful"
110+
return 0
111+
}
112+
113+
# Find the DNS record ID by hostname, record type, and record value.
114+
_get_record_id() {
115+
target_ym="$1"
116+
target_zjt="$2"
117+
target_jxz="$3"
118+
target_lx="TXT"
119+
120+
GNAME_APPID="${GNAME_APPID:-$(_readaccountconf_mutable GNAME_APPID)}"
121+
GNAME_APPKEY="${GNAME_APPKEY:-$(_readaccountconf_mutable GNAME_APPKEY)}"
122+
gntime=$(date +%s)
123+
body="appid=$GNAME_APPID&gntime=$gntime&limit=1000&lx=$target_lx&page=1&ym=$target_ym"
124+
125+
if ! _post_to_api "/api/resolution/list" "$body"; then
126+
_err "Query and parsing records failed"
127+
return 1
128+
fi
129+
130+
clean_response=$(echo "$post_response" | tr -d '\r')
131+
records=$(echo "$clean_response" | sed 's/.*"data":\[//; s/\],"count".*//; s/},/}\n/g')
132+
133+
_debug "Cleaned Formatted Records:\n$records"
134+
135+
jxz_feature=$(printf "%s" "$target_jxz" | cut -c 1-10)
136+
137+
_debug "Searching with host: $target_zjt and feature: $jxz_feature"
138+
139+
matched_row=$(echo "$records" | grep "\"zjt\":\"$target_zjt\"" | grep "\"jxz\":\"$jxz_feature")
140+
141+
_debug "Final Matched Row: $matched_row"
142+
143+
if [ -z "$matched_row" ]; then
144+
_err "Still can not find record row. Please check if host $target_zjt is correct."
145+
return 1
146+
fi
147+
148+
dns_record_id=$(echo "$matched_row" | _egrep_o "\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d '"')
149+
150+
if [ -n "$dns_record_id" ]; then
151+
_debug "Successfully found record ID: $dns_record_id"
152+
printf "%s" "$dns_record_id"
153+
return 0
154+
fi
155+
156+
return 1
157+
}
158+
159+
# Request GNAME API,post_response: Response content
160+
_post_to_api() {
161+
uri=$1
162+
body=$2
163+
url="$GNAME_Api$uri"
164+
gntoken=$(_gntoken $body)
165+
body="$body&gntoken=$gntoken"
166+
post_response="$(_post "$body" "$url" "" "POST" "application/x-www-form-urlencoded")"
167+
168+
curl_err_code=$?
169+
if [ "$curl_err_code" != "0" ]; then
170+
_err "POST API $url curl error:$curl_err_code"
171+
return 1
172+
fi
173+
174+
ret_code=$(echo "$post_response" | sed 's/.*"code":\([-0-9]*\).*/\1/')
175+
if [ "$ret_code" = "1" ]; then
176+
return 0
177+
else
178+
ret_msg=$(echo "$post_response" | sed 's/.*"msg":"\([^"]*\)".*/\1/')
179+
_err "POST API $url error: [$ret_code] $ret_msg"
180+
_debug "Full response: $post_response"
181+
return 1
182+
fi
183+
}
184+
185+
# Split the complete domain into a host and a main domain.
186+
# example, www.gname.com can be split into ext_hostname=www,ext_domain=gname.com
187+
_extract_domain() {
188+
189+
host="$1"
190+
191+
# Prioritize reading from the cache and reduce network caching
192+
if [ -z "$GNAME_TLDS_CACHE" ]; then
193+
GNAME_TLDS_CACHE=$(_get_suffixes_json)
194+
fi
195+
196+
if [ -z "$GNAME_TLDS_CACHE" ]; then
197+
_err "The list of domain suffixes is empty 02"
198+
return 1
199+
fi
200+
201+
main_part=$(echo "$GNAME_TLDS_CACHE" | sed 's/.*"main":\[\([^]]*\)\].*/\1/' | tr -d '"' | tr ',' ' ')
202+
sub_part=$(echo "$GNAME_TLDS_CACHE" | sed 's/.*"sub":\[\([^]]*\)\].*/\1/' | tr -d '"' | tr ',' ' ')
203+
suffix_list=$(echo "$main_part $sub_part" | tr -s ' ' | sed 's/^[ ]//;s/[ ]$//')
204+
205+
dot_count=$(echo "$host" | grep -o "\." | wc -l)
206+
207+
if [ "$dot_count" -eq 1 ]; then
208+
ext_hostname=""
209+
ext_domain="$host"
210+
211+
elif [ "$dot_count" -gt 1 ]; then
212+
matched_suffix=""
213+
for suffix in $suffix_list; do
214+
case "$host" in
215+
*".$suffix")
216+
if [ -z "$matched_suffix" ] || [ "${#suffix}" -gt "${#matched_suffix}" ]; then
217+
matched_suffix="$suffix"
218+
fi
219+
;;
220+
esac
221+
done
222+
223+
if [ -n "$matched_suffix" ]; then
224+
prefix="${host%.$matched_suffix}"
225+
main_name="${prefix##*.}"
226+
227+
ext_domain="$main_name.$matched_suffix"
228+
229+
if [ "$host" = "$ext_domain" ]; then
230+
ext_hostname=""
231+
else
232+
ext_hostname="${host%.$ext_domain}"
233+
fi
234+
235+
else
236+
ext_domain=$(echo "$host" | awk -F. '{print $(NF-1)"."$NF}')
237+
ext_hostname=$(echo "$host" | rev | cut -d. -f3- | rev)
238+
fi
239+
fi
240+
_debug "ext_hostname:$ext_hostname"
241+
_debug "ext_domain:$ext_domain"
242+
}
243+
244+
# Obtain the list of domain suffixes via API
245+
_get_suffixes_json() {
246+
_debug "GET request URL: $GNAME_TLD_Api Retrieves a list of domain suffixes."
247+
248+
response="$(_get "$GNAME_TLD_Api")"
249+
250+
if [ "$?" != "0" ]; then
251+
_err "Failed to retrieve list of domain suffixes"
252+
return 1
253+
fi
254+
255+
if [ -z "$response" ]; then
256+
_err "The list of domain suffixes is empty"
257+
return 1
258+
fi
259+
260+
if ! _contains "$response" "\"code\":1"; then
261+
_err "Failed to retrieve list of domain name suffixes; code is not 1"
262+
return 1
263+
fi
264+
265+
echo "$response"
266+
return 0
267+
}
268+
269+
# Generate API authentication signature
270+
_gntoken() {
271+
_debug "String to be signed:$1"
272+
data_to_sign="$1"
273+
full_data="${data_to_sign}${GNAME_APPKEY}"
274+
hash=$(printf "%s" "$full_data" | _digest md5 hex | tr -d ' ')
275+
hash_upper=$(printf "%s" "$hash" | tr 'a-z' 'A-Z')
276+
_debug "Signature value: $hash_upper"
277+
printf "%s" "$hash_upper"
278+
}

0 commit comments

Comments
 (0)