]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_geoscaling.sh
Merge pull request #4542 from alexleigh/master
[mirror_acme.sh.git] / dnsapi / dns_geoscaling.sh
1 #!/usr/bin/env sh
2
3 ########################################################################
4 # Geoscaling hook script for acme.sh
5 #
6 # Environment variables:
7 #
8 # - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address)
9 # - $GEOSCALING_Password (your Geoscaling password)
10
11 #-- dns_geoscaling_add() - Add TXT record --------------------------------------
12 # Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..."
13
14 dns_geoscaling_add() {
15 full_domain=$1
16 txt_value=$2
17 _info "Using DNS-01 Geoscaling DNS2 hook"
18
19 GEOSCALING_Username="${GEOSCALING_Username:-$(_readaccountconf_mutable GEOSCALING_Username)}"
20 GEOSCALING_Password="${GEOSCALING_Password:-$(_readaccountconf_mutable GEOSCALING_Password)}"
21 if [ -z "$GEOSCALING_Username" ] || [ -z "$GEOSCALING_Password" ]; then
22 GEOSCALING_Username=
23 GEOSCALING_Password=
24 _err "No auth details provided. Please set user credentials using the \$GEOSCALING_Username and \$GEOSCALING_Password environment variables."
25 return 1
26 fi
27 _saveaccountconf_mutable GEOSCALING_Username "${GEOSCALING_Username}"
28 _saveaccountconf_mutable GEOSCALING_Password "${GEOSCALING_Password}"
29
30 # Fills in the $zone_id and $zone_name
31 find_zone "${full_domain}" || return 1
32 _debug "Zone id '${zone_id}' will be used."
33
34 # We're logged in here
35
36 # we should add ${full_domain} minus the trailing ${zone_name}
37
38 prefix=$(echo "${full_domain}" | sed "s|\\.${zone_name}\$||")
39
40 body="id=${zone_id}&name=${prefix}&type=TXT&content=${txt_value}&ttl=300&prio=0"
41
42 do_post "$body" "https://www.geoscaling.com/dns2/ajax/add_record.php"
43 exit_code="$?"
44 if [ "${exit_code}" -eq 0 ]; then
45 _info "TXT record added successfully."
46 else
47 _err "Couldn't add the TXT record."
48 fi
49 do_logout
50 return "${exit_code}"
51 }
52
53 #-- dns_geoscaling_rm() - Remove TXT record ------------------------------------
54 # Usage: dns_geoscaling_rm _acme-challenge.subdomain.domain.com "XyZ123..."
55
56 dns_geoscaling_rm() {
57 full_domain=$1
58 txt_value=$2
59 _info "Cleaning up after DNS-01 Geoscaling DNS2 hook"
60
61 GEOSCALING_Username="${GEOSCALING_Username:-$(_readaccountconf_mutable GEOSCALING_Username)}"
62 GEOSCALING_Password="${GEOSCALING_Password:-$(_readaccountconf_mutable GEOSCALING_Password)}"
63 if [ -z "$GEOSCALING_Username" ] || [ -z "$GEOSCALING_Password" ]; then
64 GEOSCALING_Username=
65 GEOSCALING_Password=
66 _err "No auth details provided. Please set user credentials using the \$GEOSCALING_Username and \$GEOSCALING_Password environment variables."
67 return 1
68 fi
69 _saveaccountconf_mutable GEOSCALING_Username "${GEOSCALING_Username}"
70 _saveaccountconf_mutable GEOSCALING_Password "${GEOSCALING_Password}"
71
72 # fills in the $zone_id
73 find_zone "${full_domain}" || return 1
74 _debug "Zone id '${zone_id}' will be used."
75
76 # Here we're logged in
77 # Find the record id to clean
78
79 # get the domain
80 response=$(do_get "https://www.geoscaling.com/dns2/index.php?module=domain&id=${zone_id}")
81 _debug2 "response" "$response"
82
83 table="$(echo "${response}" | tr -d '\n' | sed 's|.*<div class="box"><div class="boxtitle">Basic Records</div><div class="boxtext"><table|<table|; s|</table>.*|</table>|')"
84 _debug2 table "${table}"
85 names=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*</td>' | sed 's|</td>||; s|.*>||')
86 ids=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*</td>' | sed 's|\.name">.*||; s|id="||')
87 types=$(echo "${table}" | _egrep_o 'id="[0-9]+\.type">[^<]*</td>' | sed 's|</td>||; s|.*>||')
88 values=$(echo "${table}" | _egrep_o 'id="[0-9]+\.content">[^<]*</td>' | sed 's|</td>||; s|.*>||')
89
90 _debug2 names "${names}"
91 _debug2 ids "${ids}"
92 _debug2 types "${types}"
93 _debug2 values "${values}"
94
95 # look for line whose name is ${full_domain}, whose type is TXT, and whose value is ${txt_value}
96 line_num="$(echo "${values}" | grep -F -n -- "${txt_value}" | _head_n 1 | cut -d ':' -f 1)"
97 _debug2 line_num "${line_num}"
98 found_id=
99 if [ -n "$line_num" ]; then
100 type=$(echo "${types}" | sed -n "${line_num}p")
101 name=$(echo "${names}" | sed -n "${line_num}p")
102 id=$(echo "${ids}" | sed -n "${line_num}p")
103
104 _debug2 type "$type"
105 _debug2 name "$name"
106 _debug2 id "$id"
107 _debug2 full_domain "$full_domain"
108
109 if [ "${type}" = "TXT" ] && [ "${name}" = "${full_domain}" ]; then
110 found_id=${id}
111 fi
112 fi
113
114 if [ "${found_id}" = "" ]; then
115 _err "Can not find record id."
116 return 0
117 fi
118
119 # Remove the record
120 body="id=${zone_id}&record_id=${found_id}"
121 response=$(do_post "$body" "https://www.geoscaling.com/dns2/ajax/delete_record.php")
122 exit_code="$?"
123 if [ "$exit_code" -eq 0 ]; then
124 _info "Record removed successfully."
125 else
126 _err "Could not clean (remove) up the record. Please go to Geoscaling administration interface and clean it by hand."
127 fi
128 do_logout
129 return "${exit_code}"
130 }
131
132 ########################## PRIVATE FUNCTIONS ###########################
133
134 do_get() {
135 _url=$1
136 export _H1="Cookie: $geoscaling_phpsessid_cookie"
137 _get "${_url}"
138 }
139
140 do_post() {
141 _body=$1
142 _url=$2
143 export _H1="Cookie: $geoscaling_phpsessid_cookie"
144 _post "${_body}" "${_url}"
145 }
146
147 do_login() {
148
149 _info "Logging in..."
150
151 username_encoded="$(printf "%s" "${GEOSCALING_Username}" | _url_encode)"
152 password_encoded="$(printf "%s" "${GEOSCALING_Password}" | _url_encode)"
153 body="username=${username_encoded}&password=${password_encoded}"
154
155 response=$(_post "$body" "https://www.geoscaling.com/dns2/index.php?module=auth")
156 _debug2 response "${response}"
157
158 #retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | _egrep_o '[0-9]+$')
159 retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | cut -d ' ' -f 2)
160
161 if [ "$retcode" != "302" ]; then
162 _err "Geoscaling login failed for user ${GEOSCALING_Username}. Check ${HTTP_HEADER} file"
163 return 1
164 fi
165
166 geoscaling_phpsessid_cookie="$(grep -i '^set-cookie:' "${HTTP_HEADER}" | _egrep_o 'PHPSESSID=[^;]*;' | tr -d ';')"
167 return 0
168
169 }
170
171 do_logout() {
172 _info "Logging out."
173 response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=auth")"
174 _debug2 response "$response"
175 return 0
176 }
177
178 find_zone() {
179 domain="$1"
180
181 # do login
182 do_login || return 1
183
184 # get zones
185 response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=domains")"
186
187 table="$(echo "${response}" | tr -d '\n' | sed 's|.*<div class="box"><div class="boxtitle">Your domains</div><div class="boxtext"><table|<table|; s|</table>.*|</table>|')"
188 _debug2 table "${table}"
189 zone_names="$(echo "${table}" | _egrep_o '<b>[^<]*</b>' | sed 's|<b>||;s|</b>||')"
190 _debug2 _matches "${zone_names}"
191 # Zone names and zone IDs are in same order
192 zone_ids=$(echo "${table}" | _egrep_o '<a href=.index\.php\?module=domain&id=[0-9]+. onclick="javascript:show_loader\(\);">' | sed 's|.*id=||;s|. .*||')
193
194 _debug2 "These are the zones on this Geoscaling account:"
195 _debug2 "zone_names" "${zone_names}"
196 _debug2 "And these are their respective IDs:"
197 _debug2 "zone_ids" "${zone_ids}"
198 if [ -z "${zone_names}" ] || [ -z "${zone_ids}" ]; then
199 _err "Can not get zone names or IDs."
200 return 1
201 fi
202 # Walk through all possible zone names
203 strip_counter=1
204 while true; do
205 attempted_zone=$(echo "${domain}" | cut -d . -f ${strip_counter}-)
206
207 # All possible zone names have been tried
208 if [ -z "${attempted_zone}" ]; then
209 _err "No zone for domain '${domain}' found."
210 return 1
211 fi
212
213 _debug "Looking for zone '${attempted_zone}'"
214
215 line_num="$(echo "${zone_names}" | grep -n "^${attempted_zone}\$" | _head_n 1 | cut -d : -f 1)"
216 _debug2 line_num "${line_num}"
217 if [ "$line_num" ]; then
218 zone_id=$(echo "${zone_ids}" | sed -n "${line_num}p")
219 zone_name=$(echo "${zone_names}" | sed -n "${line_num}p")
220 if [ -z "${zone_id}" ]; then
221 _err "Can not find zone id."
222 return 1
223 fi
224 _debug "Found relevant zone '${attempted_zone}' with id '${zone_id}' - will be used for domain '${domain}'."
225 return 0
226 fi
227
228 _debug "Zone '${attempted_zone}' doesn't exist, let's try a less specific zone."
229 strip_counter=$(_math "${strip_counter}" + 1)
230 done
231 }
232 # vim: et:ts=2:sw=2: