]>
Commit | Line | Data |
---|---|---|
94f91ae6 M |
1 | #!/usr/bin/env sh |
2 | ||
3 | #This is the euserv.eu api wrapper for acme.sh | |
4 | # | |
5 | #Author: Michael Brueckner | |
6 | #Report Bugs: https://www.github.com/initit/acme.sh or mbr@initit.de | |
7 | ||
8 | # | |
9 | #EUSERV_Username="username" | |
10 | # | |
11 | #EUSERV_Password="password" | |
12 | # | |
13 | # Dependencies: | |
14 | # ------------- | |
15 | # - none - | |
16 | ||
17 | EUSERV_Api="https://api.euserv.net" | |
18 | ||
19 | ######## Public functions ##################### | |
20 | ||
21 | #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" | |
22 | dns_euserv_add() { | |
23 | fulldomain="$(echo "$1" | _lower_case)" | |
24 | txtvalue=$2 | |
25 | ||
26 | EUSERV_Username="${EUSERV_Username:-$(_readaccountconf_mutable EUSERV_Username)}" | |
27 | EUSERV_Password="${EUSERV_Password:-$(_readaccountconf_mutable EUSERV_Password)}" | |
28 | if [ -z "$EUSERV_Username" ] || [ -z "$EUSERV_Password" ]; then | |
29 | EUSERV_Username="" | |
30 | EUSERV_Password="" | |
31 | _err "You don't specify euserv user and password yet." | |
32 | _err "Please create your key and try again." | |
33 | return 1 | |
34 | fi | |
35 | ||
36 | #save the user and email to the account conf file. | |
37 | _saveaccountconf_mutable EUSERV_Username "$EUSERV_Username" | |
38 | _saveaccountconf_mutable EUSERV_Password "$EUSERV_Password" | |
39 | ||
40 | _debug "First detect the root zone" | |
41 | if ! _get_root "$fulldomain"; then | |
42 | _err "invalid domain" | |
43 | return 1 | |
44 | fi | |
616b0b6b | 45 | _debug "_sub_domain" "$_sub_domain" |
261cc448 | 46 | _debug "_domain" "$_domain" |
94f91ae6 | 47 | _info "Adding record" |
261cc448 M |
48 | if ! _euserv_add_record "$_domain" "$_sub_domain" "$txtvalue"; then |
49 | return 1 | |
616b0b6b | 50 | fi |
94f91ae6 M |
51 | |
52 | } | |
53 | ||
54 | #fulldomain txtvalue | |
55 | dns_euserv_rm() { | |
56 | ||
57 | fulldomain="$(echo "$1" | _lower_case)" | |
58 | txtvalue=$2 | |
59 | ||
60 | EUSERV_Username="${EUSERV_Username:-$(_readaccountconf_mutable EUSERV_Username)}" | |
61 | EUSERV_Password="${EUSERV_Password:-$(_readaccountconf_mutable EUSERV_Password)}" | |
62 | if [ -z "$EUSERV_Username" ] || [ -z "$EUSERV_Password" ]; then | |
63 | EUSERV_Username="" | |
64 | EUSERV_Password="" | |
65 | _err "You don't specify euserv user and password yet." | |
66 | _err "Please create your key and try again." | |
67 | return 1 | |
68 | fi | |
69 | ||
70 | #save the user and email to the account conf file. | |
71 | _saveaccountconf_mutable EUSERV_Username "$EUSERV_Username" | |
72 | _saveaccountconf_mutable EUSERV_Password "$EUSERV_Password" | |
73 | ||
74 | _debug "First detect the root zone" | |
75 | if ! _get_root "$fulldomain"; then | |
76 | _err "invalid domain" | |
77 | return 1 | |
78 | fi | |
79 | _debug "_sub_domain" "$_sub_domain" | |
80 | _debug "_domain" "$_domain" | |
81 | ||
82 | _debug "Getting txt records" | |
261cc448 | 83 | |
94f91ae6 M |
84 | xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?> |
85 | <methodCall> | |
86 | <methodName>domain.dns_get_active_records</methodName> | |
87 | <params> | |
88 | <param> | |
89 | <value> | |
90 | <struct> | |
91 | <member> | |
92 | <name>login</name> | |
93 | <value> | |
94 | <string>%s</string> | |
95 | </value> | |
96 | </member> | |
97 | <member> | |
98 | <name>password</name> | |
99 | <value> | |
100 | <string>%s</string> | |
101 | </value> | |
102 | </member> | |
103 | <member> | |
104 | <name>domain_id</name> | |
105 | <value> | |
106 | <int>%s</int> | |
107 | </value> | |
108 | </member> | |
109 | </struct> | |
110 | </value> | |
111 | </param> | |
112 | </params> | |
113 | </methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$_euserv_domain_id") | |
261cc448 | 114 | |
94f91ae6 M |
115 | export _H1="Content-Type: text/xml" |
116 | response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")" | |
117 | ||
616b0b6b M |
118 | if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then |
119 | _err "Error could not get txt records" | |
94f91ae6 M |
120 | _debug "xml_content" "$xml_content" |
121 | _debug "response" "$response" | |
122 | return 1 | |
123 | fi | |
124 | ||
2945b230 | 125 | if ! echo "$response" | grep '>dns_record_content<.*>'"$txtvalue"'<' >/dev/null; then |
94f91ae6 M |
126 | _info "Do not need to delete record" |
127 | else | |
616b0b6b | 128 | # find XML block where txtvalue is in. The record_id is allways prior this line! |
2945b230 | 129 | _endLine=$(echo "$response" | grep -n '>dns_record_content<.*>'"$txtvalue"'<' | cut -d ':' -f 1) |
ac9f6e3a | 130 | # record_id is the last <name> Tag with a number before the row _endLine, identified by </name><value><struct> |
2945b230 | 131 | _record_id=$(echo "$response" | sed -n '1,'"$_endLine"'p' | grep '</name><value><struct>' | _tail_n 1 | sed 's/.*<name>\([0-9]*\)<\/name>.*/\1/') |
94f91ae6 M |
132 | _info "Deleting record" |
133 | _euserv_delete_record "$_record_id" | |
134 | fi | |
135 | ||
136 | } | |
137 | ||
138 | #################### Private functions below ################################## | |
139 | ||
616b0b6b M |
140 | _get_root() { |
141 | domain=$1 | |
142 | _debug "get root" | |
143 | ||
144 | # Just to read the domain_orders once | |
145 | ||
146 | domain=$1 | |
147 | i=2 | |
148 | p=1 | |
149 | ||
150 | if ! _euserv_get_domain_orders; then | |
151 | return 1 | |
152 | fi | |
153 | ||
154 | # Get saved response with domain_orders | |
155 | response="$_euserv_domain_orders" | |
156 | ||
157 | while true; do | |
2945b230 | 158 | h=$(echo "$domain" | cut -d . -f $i-100) |
616b0b6b M |
159 | _debug h "$h" |
160 | if [ -z "$h" ]; then | |
161 | #not valid | |
162 | return 1 | |
163 | fi | |
164 | ||
165 | if _contains "$response" "$h"; then | |
2945b230 | 166 | _sub_domain=$(echo "$domain" | cut -d . -f 1-$p) |
616b0b6b M |
167 | _domain="$h" |
168 | if ! _euserv_get_domain_id "$_domain"; then | |
169 | _err "invalid domain" | |
170 | return 1 | |
261cc448 | 171 | fi |
616b0b6b M |
172 | return 0 |
173 | fi | |
174 | p=$i | |
175 | i=$(_math "$i" + 1) | |
176 | done | |
177 | ||
178 | return 1 | |
179 | } | |
180 | ||
94f91ae6 | 181 | _euserv_get_domain_orders() { |
616b0b6b | 182 | # returns: _euserv_domain_orders |
94f91ae6 M |
183 | |
184 | _debug "get domain_orders" | |
616b0b6b | 185 | |
94f91ae6 M |
186 | xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?> |
187 | <methodCall> | |
188 | <methodName>domain.get_domain_orders</methodName> | |
189 | <params> | |
190 | <param> | |
191 | <value> | |
192 | <struct> | |
193 | <member> | |
194 | <name>login</name> | |
195 | <value><string>%s</string></value> | |
196 | </member> | |
197 | <member> | |
198 | <name>password</name> | |
199 | <value><string>%s</string></value> | |
200 | </member> | |
201 | </struct> | |
202 | </value> | |
203 | </param> | |
204 | </params> | |
205 | </methodCall>' "$EUSERV_Username" "$EUSERV_Password") | |
616b0b6b | 206 | |
94f91ae6 M |
207 | export _H1="Content-Type: text/xml" |
208 | response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")" | |
616b0b6b M |
209 | |
210 | if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then | |
94f91ae6 M |
211 | _err "Error could not get domain orders" |
212 | _debug "xml_content" "$xml_content" | |
213 | _debug "response" "$response" | |
214 | return 1 | |
215 | fi | |
616b0b6b M |
216 | |
217 | # save response to reduce API calls | |
94f91ae6 M |
218 | _euserv_domain_orders="$response" |
219 | return 0 | |
220 | } | |
221 | ||
222 | _euserv_get_domain_id() { | |
616b0b6b | 223 | # returns: _euserv_domain_id |
94f91ae6 M |
224 | domain=$1 |
225 | _debug "get domain_id" | |
226 | ||
616b0b6b | 227 | # find line where the domain name is within the $response |
2945b230 | 228 | _startLine=$(echo "$_euserv_domain_orders" | grep -n '>domain_name<.*>'"$domain"'<' | cut -d ':' -f 1) |
616b0b6b | 229 | # next occurency of domain_id after the domain_name is the correct one |
2945b230 | 230 | _euserv_domain_id=$(echo "$_euserv_domain_orders" | sed -n "$_startLine"',$p' | grep '>domain_id<' | _head_n 1 | sed 's/.*<i4>\([0-9]*\)<\/i4>.*/\1/') |
94f91ae6 | 231 | |
616b0b6b | 232 | if [ -z "$_euserv_domain_id" ]; then |
94f91ae6 M |
233 | _err "Could not find domain_id for domain $domain" |
234 | _debug "_euserv_domain_orders" "$_euserv_domain_orders" | |
235 | return 1 | |
236 | fi | |
94f91ae6 | 237 | |
616b0b6b | 238 | return 0 |
94f91ae6 M |
239 | } |
240 | ||
94f91ae6 M |
241 | _euserv_delete_record() { |
242 | record_id=$1 | |
243 | xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?> | |
244 | <methodCall> | |
245 | <methodName>domain.dns_delete_record</methodName> | |
246 | <params> | |
247 | <param> | |
248 | <value> | |
249 | <struct> | |
250 | <member> | |
251 | <name>login</name> | |
252 | <value> | |
253 | <string>%s</string> | |
254 | </value> | |
255 | </member> | |
256 | <member> | |
257 | <name>password</name> | |
258 | <value> | |
259 | <string>%s</string> | |
260 | </value> | |
261 | </member> | |
262 | <member> | |
263 | <name>dns_record_id</name> | |
264 | <value> | |
265 | <int>%s</int> | |
266 | </value> | |
267 | </member> | |
268 | </struct> | |
269 | </value> | |
270 | </param> | |
271 | </params> | |
272 | </methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$record_id") | |
273 | ||
274 | export _H1="Content-Type: text/xml" | |
275 | response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")" | |
276 | ||
616b0b6b | 277 | if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then |
94f91ae6 M |
278 | _err "Error deleting record" |
279 | _debug "xml_content" "$xml_content" | |
280 | _debug "response" "$response" | |
281 | return 1 | |
282 | fi | |
616b0b6b | 283 | |
94f91ae6 M |
284 | return 0 |
285 | ||
286 | } | |
287 | ||
288 | _euserv_add_record() { | |
289 | domain=$1 | |
290 | sub_domain=$2 | |
291 | txtval=$3 | |
292 | ||
293 | xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?> | |
294 | <methodCall> | |
295 | <methodName>domain.dns_create_record</methodName> | |
296 | <params> | |
297 | <param> | |
298 | <value> | |
299 | <struct> | |
300 | <member> | |
301 | <name>login</name> | |
302 | <value> | |
303 | <string>%s</string> | |
304 | </value> | |
305 | </member> | |
306 | <member> | |
307 | <name>password</name> | |
308 | <value> | |
309 | <string>%s</string></value> | |
310 | </member> | |
311 | <member> | |
312 | <name>domain_id</name> | |
313 | <value> | |
314 | <int>%s</int> | |
315 | </value> | |
316 | </member> | |
317 | <member> | |
318 | <name>dns_record_subdomain</name> | |
319 | <value> | |
320 | <string>%s</string> | |
321 | </value> | |
322 | </member> | |
323 | <member> | |
324 | <name>dns_record_type</name> | |
325 | <value> | |
326 | <string>TXT</string> | |
327 | </value> | |
328 | </member> | |
329 | <member> | |
330 | <name>dns_record_value</name> | |
331 | <value> | |
332 | <string>%s</string> | |
333 | </value> | |
334 | </member> | |
335 | <member> | |
336 | <name>dns_record_ttl</name> | |
337 | <value> | |
338 | <int>300</int> | |
339 | </value> | |
340 | </member> | |
341 | </struct> | |
342 | </value> | |
343 | </param> | |
344 | </params> | |
616b0b6b | 345 | </methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$_euserv_domain_id" "$sub_domain" "$txtval") |
261cc448 | 346 | |
94f91ae6 M |
347 | export _H1="Content-Type: text/xml" |
348 | response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")" | |
349 | ||
616b0b6b | 350 | if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then |
94f91ae6 M |
351 | _err "Error could not create record" |
352 | _debug "xml_content" "$xml_content" | |
353 | _debug "response" "$response" | |
354 | return 1 | |
355 | fi | |
616b0b6b | 356 | |
94f91ae6 M |
357 | return 0 |
358 | } |