]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_namecheap.sh
Staging
[mirror_acme.sh.git] / dnsapi / dns_namecheap.sh
1 #!/usr/bin/env sh
2
3 # Namecheap API
4 # https://www.namecheap.com/support/api/intro.aspx
5 #
6 # Requires Namecheap API key set in NAMECHEAP_API_KEY and NAMECHEAP_USERNAME set as environment variable
7 #
8 ######## Public functions #####################
9
10 if [ "$STAGE" -eq 1 ]; then
11 NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response"
12 else
13 NAMECHEAP_API="https://api.namecheap.com/xml.response"
14 fi
15
16 #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
17 dns_namecheap_add() {
18 fulldomain=$1
19 txtvalue=$2
20
21 if ! _namecheap_check_config; then
22 _err "$error"
23 return 1
24 fi
25
26 if ! _namecheap_set_publicip; then
27 return 1
28 fi
29
30 _debug "First detect the root zone"
31 if ! _get_root "$fulldomain"; then
32 _err "invalid domain"
33 return 1
34 fi
35
36 _debug fulldomain "$fulldomain"
37 _debug txtvalue "$txtvalue"
38 _debug domain "$_domain"
39 _debug sub_domain "$_sub_domain"
40
41 _set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
42 }
43
44 #Usage: fulldomain txtvalue
45 #Remove the txt record after validation.
46 dns_namecheap_rm() {
47 fulldomain=$1
48 txtvalue=$2
49
50 if ! _namecheap_set_publicip; then
51 return 1
52 fi
53
54 if ! _namecheap_check_config; then
55 _err "$error"
56 return 1
57 fi
58
59 _debug "First detect the root zone"
60 if ! _get_root "$fulldomain"; then
61 _err "invalid domain"
62 return 1
63 fi
64
65 _debug fulldomain "$fulldomain"
66 _debug txtvalue "$txtvalue"
67 _debug domain "$_domain"
68 _debug sub_domain "$_sub_domain"
69
70 _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
71
72 }
73
74 #################### Private functions below ##################################
75 #_acme-challenge.www.domain.com
76 #returns
77 # _sub_domain=_acme-challenge.www
78 # _domain=domain.com
79 _get_root() {
80 domain=$1
81
82 if ! _namecheap_post "namecheap.domains.getList"; then
83 _err "$error"
84 return 1
85 fi
86
87 i=2
88 p=1
89
90 while true; do
91
92 h=$(printf "%s" "$domain" | cut -d . -f $i-100)
93 _debug h "$h"
94 if [ -z "$h" ]; then
95 #not valid
96 return 1
97 fi
98
99 if ! _contains "$response" "$h"; then
100 _debug "$h not found"
101 else
102 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
103 _domain="$h"
104 return 0
105 fi
106 p="$i"
107 i=$(_math "$i" + 1)
108 done
109 return 1
110 }
111
112 _namecheap_set_publicip() {
113
114 if [ -z "$NAMECHEAP_SOURCEIP" ]; then
115 _err "No Source IP specified for Namecheap API."
116 _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
117 return 1
118 else
119 _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
120 _debug sourceip "$NAMECHEAP_SOURCEIP"
121
122 ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
123 addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
124
125 _debug2 ip "$ip"
126 _debug2 addr "$addr"
127
128 if [ -n "$ip" ]; then
129 _publicip="$ip"
130 elif [ -n "$addr" ]; then
131 _publicip=$(_get "$addr")
132 else
133 _err "No Source IP specified for Namecheap API."
134 _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
135 return 1
136 fi
137 fi
138
139 _debug publicip "$_publicip"
140
141 return 0
142 }
143
144 _namecheap_post() {
145 command=$1
146 data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
147
148 response="$(_post "$data" "$NAMECHEAP_API" "" "POST")"
149 _debug2 response "$response"
150
151 if _contains "$response" "Status=\"ERROR\"" >/dev/null; then
152 error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>')
153 _err "error $error"
154 return 1
155 fi
156
157 return 0
158 }
159
160
161 _namecheap_parse_host() {
162 _host=$1
163 _debug _host "$_host"
164
165 _hostid=$(echo "$_host" | _egrep_o 'HostId=".*"' | cut -d '"' -f 2)
166 _hostname=$(echo "$_host" | _egrep_o 'Name=".*"' | cut -d '"' -f 2)
167 _hosttype=$(echo "$_host" | _egrep_o 'Type=".*"' | cut -d '"' -f 2)
168 _hostaddress=$(echo "$_host" | _egrep_o 'Address=".*"' | cut -d '"' -f 2)
169 _hostmxpref=$(echo "$_host" | _egrep_o 'MXPref=".*"' | cut -d '"' -f 2)
170 _hostttl=$(echo "$_host" | _egrep_o 'TTL=".*"' | cut -d '"' -f 2)
171
172 _debug hostid "$_hostid"
173 _debug hostname "$_hostname"
174 _debug hosttype "$_hosttype"
175 _debug hostaddress "$_hostaddress"
176 _debug hostmxpref "$_hostmxpref"
177 _debug hostttl "$_hostttl"
178
179 }
180
181 _namecheap_check_config() {
182
183 if [ -z "$NAMECHEAP_API_KEY" ]; then
184 _err "No API key specified for Namecheap API."
185 _err "Create your key and export it as NAMECHEAP_API_KEY"
186 return 1
187 fi
188
189 if [ -z "$NAMECHEAP_USERNAME" ]; then
190 _err "No username key specified for Namecheap API."
191 _err "Create your key and export it as NAMECHEAP_USERNAME"
192 return 1
193 fi
194
195 _saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
196 _saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
197
198 return 0
199 }
200
201 _set_namecheap_TXT() {
202 subdomain=$2
203 txt=$3
204 tld=$(echo "$1" | cut -d '.' -f 2)
205 sld=$(echo "$1" | cut -d '.' -f 1)
206 request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
207
208 if ! _namecheap_post "$request"; then
209 _err "$error"
210 return 1
211 fi
212
213 hosts=$(echo "$response" | _egrep_o '<host .+ />')
214 _debug hosts "$hosts"
215
216 if [ -z "$hosts" ]; then
217 _error "Hosts not found"
218 return 1
219 fi
220
221 _namecheap_reset_hostList
222 found=0
223
224 while read -r host; do
225
226 if _contains "$host" "<host"; then
227 _namecheap_parse_host "$host"
228
229 if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ]; then
230 _namecheap_add_host "$_hostname" "$_hosttype" "$txt" "$_hostmxpref" "$_hostttl"
231 found=1
232 else
233 _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
234 fi
235
236 fi
237
238 done <<EOT
239 echo "$hosts"
240 EOT
241
242 if [ $found -eq 0 ]; then
243 _namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
244 _debug "not found"
245 fi
246
247 _debug hostrequestfinal "$_hostrequest"
248
249 request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
250
251 if ! _namecheap_post "$request"; then
252 _err "$error"
253 return 1
254 fi
255
256 return 0
257 }
258
259
260 _namecheap_reset_hostList() {
261 _hostindex=0
262 _hostrequest=""
263 }
264
265 #Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
266 _namecheap_add_host() {
267 _hostindex=$(_math "$_hostindex" + 1)
268 _hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5")
269 }