]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_inwx.sh
Merge with latest dev branch.
[mirror_acme.sh.git] / dnsapi / dns_inwx.sh
1 #!/usr/bin/env sh
2
3 #
4 #INWX_User="username"
5 #
6 #INWX_Password="password"
7 #
8 # Dependencies:
9 # -------------
10 # - oathtool (When using 2 Factor Authentication)
11
12 INWX_Api="https://api.domrobot.com/xmlrpc/"
13
14 ######## Public functions #####################
15
16 #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
17 dns_inwx_add() {
18 fulldomain=$1
19 txtvalue=$2
20
21 INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
22 INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
23 INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
24 if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
25 INWX_User=""
26 INWX_Password=""
27 _err "You don't specify inwx user and password yet."
28 _err "Please create you key and try again."
29 return 1
30 fi
31
32 #save the api key and email to the account conf file.
33 _saveaccountconf_mutable INWX_User "$INWX_User"
34 _saveaccountconf_mutable INWX_Password "$INWX_Password"
35 _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
36
37 _debug "First detect the root zone"
38 if ! _get_root "$fulldomain"; then
39 _err "invalid domain"
40 return 1
41 fi
42 _debug _sub_domain "$_sub_domain"
43 _debug _domain "$_domain"
44
45 _info "Adding record"
46 _inwx_add_record "$_domain" "$_sub_domain" "$txtvalue"
47
48 }
49
50 #fulldomain txtvalue
51 dns_inwx_rm() {
52
53 fulldomain=$1
54 txtvalue=$2
55
56 INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
57 INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
58 if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
59 INWX_User=""
60 INWX_Password=""
61 _err "You don't specify inwx user and password yet."
62 _err "Please create you key and try again."
63 return 1
64 fi
65
66 #save the api key and email to the account conf file.
67 _saveaccountconf_mutable INWX_User "$INWX_User"
68 _saveaccountconf_mutable INWX_Password "$INWX_Password"
69
70 _debug "First detect the root zone"
71 if ! _get_root "$fulldomain"; then
72 _err "invalid domain"
73 return 1
74 fi
75 _debug _sub_domain "$_sub_domain"
76 _debug _domain "$_domain"
77
78 _debug "Getting txt records"
79
80 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
81 <methodCall>
82 <methodName>nameserver.info</methodName>
83 <params>
84 <param>
85 <value>
86 <struct>
87 <member>
88 <name>domain</name>
89 <value>
90 <string>%s</string>
91 </value>
92 </member>
93 <member>
94 <name>type</name>
95 <value>
96 <string>TXT</string>
97 </value>
98 </member>
99 <member>
100 <name>name</name>
101 <value>
102 <string>%s</string>
103 </value>
104 </member>
105 </struct>
106 </value>
107 </param>
108 </params>
109 </methodCall>' "$_domain" "$_sub_domain")
110 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
111
112 if ! _contains "$response" "Command completed successfully"; then
113 _err "Error could not get txt records"
114 return 1
115 fi
116
117 if ! printf "%s" "$response" | grep "count" >/dev/null; then
118 _info "Do not need to delete record"
119 else
120 _record_id=$(printf '%s' "$response" | _egrep_o '.*(<member><name>record){1}(.*)([0-9]+){1}' | _egrep_o '<name>id<\/name><value><int>[0-9]+' | _egrep_o '[0-9]+')
121 _info "Deleting record"
122 _inwx_delete_record "$_record_id"
123 fi
124
125 }
126
127 #################### Private functions below ##################################
128
129 _inwx_login() {
130
131 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
132 <methodCall>
133 <methodName>account.login</methodName>
134 <params>
135 <param>
136 <value>
137 <struct>
138 <member>
139 <name>user</name>
140 <value>
141 <string>%s</string>
142 </value>
143 </member>
144 <member>
145 <name>pass</name>
146 <value>
147 <string>%s</string>
148 </value>
149 </member>
150 </struct>
151 </value>
152 </param>
153 </params>
154 </methodCall>' $INWX_User $INWX_Password)
155
156 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
157 _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
158 export _H1
159
160 #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
161 if _contains "$response" "tfa"; then
162 if [ -z "$INWX_Shared_Secret" ]; then
163 _err "Mobile TAN detected."
164 _err "Please define a shared secret."
165 return 1
166 fi
167
168 if ! _exists oathtool; then
169 _err "Please install oathtool to use 2 Factor Authentication."
170 _err ""
171 return 1
172 fi
173
174 tan="$(oathtool --base32 --totp "${INWX_Shared_Secret}" 2>/dev/null)"
175
176 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
177 <methodCall>
178 <methodName>account.unlock</methodName>
179 <params>
180 <param>
181 <value>
182 <struct>
183 <member>
184 <name>tan</name>
185 <value>
186 <string>%s</string>
187 </value>
188 </member>
189 </struct>
190 </value>
191 </param>
192 </params>
193 </methodCall>' "$tan")
194
195 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
196 fi
197
198 }
199
200 _get_root() {
201 domain=$1
202 _debug "get root"
203
204 domain=$1
205 i=2
206 p=1
207
208 _inwx_login
209
210 xml_content='<?xml version="1.0" encoding="UTF-8"?>
211 <methodCall>
212 <methodName>nameserver.list</methodName>
213 </methodCall>'
214
215 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
216 while true; do
217 h=$(printf "%s" "$domain" | cut -d . -f $i-100)
218 _debug h "$h"
219 if [ -z "$h" ]; then
220 #not valid
221 return 1
222 fi
223
224 if _contains "$response" "$h"; then
225 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
226 _domain="$h"
227 return 0
228 fi
229 p=$i
230 i=$(_math "$i" + 1)
231 done
232 return 1
233
234 }
235
236 _inwx_delete_record() {
237 record_id=$1
238 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
239 <methodCall>
240 <methodName>nameserver.deleteRecord</methodName>
241 <params>
242 <param>
243 <value>
244 <struct>
245 <member>
246 <name>id</name>
247 <value>
248 <int>%s</int>
249 </value>
250 </member>
251 </struct>
252 </value>
253 </param>
254 </params>
255 </methodCall>' "$record_id")
256
257 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
258
259 if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
260 _err "Error"
261 return 1
262 fi
263 return 0
264
265 }
266
267 _inwx_update_record() {
268 record_id=$1
269 txtval=$2
270 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
271 <methodCall>
272 <methodName>nameserver.updateRecord</methodName>
273 <params>
274 <param>
275 <value>
276 <struct>
277 <member>
278 <name>content</name>
279 <value>
280 <string>%s</string>
281 </value>
282 </member>
283 <member>
284 <name>id</name>
285 <value>
286 <int>%s</int>
287 </value>
288 </member>
289 </struct>
290 </value>
291 </param>
292 </params>
293 </methodCall>' "$txtval" "$record_id")
294
295 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
296
297 if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
298 _err "Error"
299 return 1
300 fi
301 return 0
302
303 }
304
305 _inwx_add_record() {
306
307 domain=$1
308 sub_domain=$2
309 txtval=$3
310
311 xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
312 <methodCall>
313 <methodName>nameserver.createRecord</methodName>
314 <params>
315 <param>
316 <value>
317 <struct>
318 <member>
319 <name>domain</name>
320 <value>
321 <string>%s</string>
322 </value>
323 </member>
324 <member>
325 <name>type</name>
326 <value>
327 <string>TXT</string>
328 </value>
329 </member>
330 <member>
331 <name>content</name>
332 <value>
333 <string>%s</string>
334 </value>
335 </member>
336 <member>
337 <name>name</name>
338 <value>
339 <string>%s</string>
340 </value>
341 </member>
342 </struct>
343 </value>
344 </param>
345 </params>
346 </methodCall>' "$domain" "$txtval" "$sub_domain")
347
348 response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
349
350 if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
351 _err "Error"
352 return 1
353 fi
354 return 0
355 }