[go: up one dir, main page]

File: dns_omglol.sh

package info (click to toggle)
acme.sh 3.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,704 kB
  • sloc: sh: 36,037; makefile: 12
file content (391 lines) | stat: -rw-r--r-- 10,571 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_omglol_info='omg.lol
Site: omg.lol
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_omglol
Options:
 OMG_ApiKey API Key. This is accessible from the bottom of the account page at https://home.omg.lol/account
 OMG_Address Address. This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard
Issues: github.com/acmesh-official/acme.sh/issues/5299
Author: @Kholin <kholin+acme.omglolapi@omg.lol>
'

# See API Docs https://api.omg.lol/

########  Public functions #####################

#Usage: dns_myapi_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_omglol_add() {
  fulldomain=$1
  txtvalue=$2
  OMG_ApiKey="${OMG_ApiKey:-$(_readaccountconf_mutable OMG_ApiKey)}"
  OMG_Address="${OMG_Address:-$(_readaccountconf_mutable OMG_Address)}"

  # As omg.lol includes a leading @ for their addresses, pre-strip this before save
  OMG_Address="$(echo "$OMG_Address" | tr -d '@')"

  _saveaccountconf_mutable OMG_ApiKey "$OMG_ApiKey"
  _saveaccountconf_mutable OMG_Address "$OMG_Address"

  _info "Using omg.lol."
  _debug "Function" "dns_omglol_add()"
  _debug "Full Domain Name" "$fulldomain"
  _debug "txt Record Value" "$txtvalue"
  _secure_debug "omg.lol API key" "$OMG_ApiKey"
  _debug "omg.lol Address" "$OMG_Address"

  omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain"
  if [ ! $? ]; then
    return 1
  fi

  dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address")
  authHeader="$(_createAuthHeader "$OMG_ApiKey")"

  _debug2 "dns_omglol_add(): Address" "$dnsName"

  omg_add "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue"

}

#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_omglol_rm() {
  fulldomain=$1
  txtvalue=$2
  OMG_ApiKey="${OMG_ApiKey:-$(_readaccountconf_mutable OMG_ApiKey)}"
  OMG_Address="${OMG_Address:-$(_readaccountconf_mutable OMG_Address)}"

  # As omg.lol includes a leading @ for their addresses, strip this in case provided
  OMG_Address="$(echo "$OMG_Address" | tr -d '@')"

  _info "Using omg.lol"
  _debug "Function" "dns_omglol_rm()"
  _debug "Full Domain Name" "$fulldomain"
  _debug "txt Record Value" "$txtvalue"
  _secure_debug "omg.lol API key" "$OMG_ApiKey"
  _debug "omg.lol Address" "$OMG_Address"

  omg_validate "$OMG_ApiKey" "$OMG_Address" "$fulldomain"
  if [ ! $? ]; then
    return 1
  fi

  dnsName=$(_getDnsRecordName "$fulldomain" "$OMG_Address")
  authHeader="$(_createAuthHeader "$OMG_ApiKey")"

  omg_delete "$OMG_Address" "$authHeader" "$dnsName" "$txtvalue"
}

####################  Private functions below ##################################
# Check that the minimum requirements are present.  Close ungracefully if not
omg_validate() {
  omg_apikey=$1
  omg_address=$2
  fulldomain=$3

  _debug2 "Function" "dns_validate()"
  _secure_debug2 "omg.lol API key" "$omg_apikey"
  _debug2 "omg.lol Address" "$omg_address"
  _debug2 "Full Domain Name" "$fulldomain"

  if [ "" = "$omg_address" ]; then
    _err "omg.lol base address not provided.  Exiting"
    return 1
  fi

  if [ "" = "$omg_apikey" ]; then
    _err "omg.lol API key not provided.  Exiting"
    return 1
  fi

  _endswith "$fulldomain" "omg.lol"
  if [ ! $? ]; then
    _err "Domain name requested is not under omg.lol"
    return 1
  fi

  _endswith "$fulldomain" "$omg_address.omg.lol"
  if [ ! $? ]; then
    _err "Domain name is not a subdomain of provided omg.lol address $omg_address"
    return 1
  fi

  _debug "Required environment parameters are all present"
}

# Add (or modify) an entry for a new ACME query
omg_add() {
  address=$1
  authHeader=$2
  dnsName=$3
  txtvalue=$4

  _info "Creating DNS entry for $dnsName"
  _debug2 "omg_add()"
  _debug2 "omg.lol Address: " "$address"
  _secure_debug2 "omg.lol authorization header: " "$authHeader"
  _debug2 "Full Domain name:" "$dnsName.$address.omg.lol"
  _debug2 "TXT value to set:" "$txtvalue"

  export _H1="$authHeader"

  endpoint="https://api.omg.lol/address/$address/dns"
  _debug2 "Endpoint" "$endpoint"

  payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}'
  _debug2 "Payload" "$payload"

  response=$(_post "$payload" "$endpoint" "" "POST" "application/json")

  omg_validate_add "$response" "$dnsName.$address" "$txtvalue"
}

omg_validate_add() {
  response=$1
  name=$2
  content=$3

  _debug "Validating DNS record addition"
  _debug2 "omg_validate_add()"
  _debug2 "Response" "$response"
  _debug2 "DNS Name" "$name"
  _debug2 "DNS value" "$content"

  _jsonResponseCheck "$response" "success" "true"
  if [ "1" = "$?" ]; then
    _err "Response did not report success"
    return 1
  fi

  _jsonResponseCheck "$response" "message" "Your DNS record was created successfully."
  if [ "1" = "$?" ]; then
    _err "Response message did not indicate DNS record was successfully created"
    return 1
  fi

  _jsonResponseCheck "$response" "name" "$name"
  if [ "1" = "$?" ]; then
    _err "Response DNS Name did not match the response received"
    return 1
  fi

  _jsonResponseCheck "$response" "content" "$content"
  if [ "1" = "$?" ]; then
    _err "Response DNS Name did not match the response received"
    return 1
  fi

  _info "Record Created successfully"
  return 0
}

omg_getRecords() {
  address=$1
  authHeader=$2
  dnsName=$3
  txtValue=$4

  _debug2 "omg_getRecords()"
  _debug2 "omg.lol Address: " "$address"
  _secure_debug2 "omg.lol Auth Header: " "$authHeader"
  _debug2 "omg.lol DNS name:" "$dnsName"
  _debug2 "txt Value" "$txtValue"

  export _H1="$authHeader"

  endpoint="https://api.omg.lol/address/$address/dns"
  _debug2 "Endpoint" "$endpoint"

  payload=$(_get "$endpoint")

  _debug2 "Received Payload:" "$payload"

  # Reformat the JSON to be more parseable
  recordID=$(echo "$payload" | _stripWhitespace)
  recordID=$(echo "$recordID" | _exposeJsonArray)

  # Now find the one with the right value, and caputre its ID
  recordID=$(echo "$recordID" | grep -- "$txtValue" | grep -i -- "$dnsName.$address")
  _getJsonElement "$recordID" "id"
}

omg_delete() {
  address=$1
  authHeader=$2
  dnsName=$3
  txtValue=$4

  _info "Deleting DNS entry for $dnsName with value $txtValue"
  _debug2 "omg_delete()"
  _debug2 "omg.lol Address: " "$address"
  _secure_debug2 "omg.lol Auth Header: " "$authHeader"
  _debug2 "Full Domain name:" "$dnsName.$address.omg.lol"
  _debug2 "txt Value" "$txtValue"

  record=$(omg_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue")
  if [ "" = "$record" ]; then
    _err "DNS record $address not found!"
    return 1
  fi

  endpoint="https://api.omg.lol/address/$address/dns/$record"
  _debug2 "Endpoint" "$endpoint"

  export _H1="$authHeader"
  output=$(_post "" "$endpoint" "" "DELETE")

  _debug2 "Response" "$output"

  omg_validate_delete "$output"
}

# Validate the response on request to delete.
# Confirm status is success and message indicates deletion was successful.
# Input: Response - HTTP response received from delete request
omg_validate_delete() {
  response=$1

  _info "Validating DNS record deletion"
  _debug2 "omg_validate_delete()"
  _debug2 "Response" "$response"

  _jsonResponseCheck "$output" "success" "true"
  if [ "1" = "$?" ]; then
    _err "Response did not report success"
    return 1
  fi

  _jsonResponseCheck "$output" "message" "OK, your DNS record has been deleted."
  if [ "1" = "$?" ]; then
    _err "Response message did not indicate DNS record was successfully deleted"
    return 1
  fi

  _info "Record deleted successfully"
  return 0
}

########## Utility Functions #####################################
# All utility functions only log at debug3
_jsonResponseCheck() {
  response=$1
  field=$2
  correct=$3

  correct=$(echo "$correct" | _lower_case)

  _debug3 "jsonResponseCheck()"
  _debug3 "Response to parse" "$response"
  _debug3 "Field to get response from" "$field"
  _debug3 "What is the correct response" "$correct"

  responseValue=$(_jsonGetLastResponse "$response" "$field")

  if [ "$responseValue" != "$correct" ]; then
    _debug3 "Expected: $correct"
    _debug3 "Actual: $responseValue"
    return 1
  else
    _debug3 "Matched: $responseValue"
  fi
  return 0
}

_jsonGetLastResponse() {
  response=$1
  field=$2

  _debug3 "jsonGetLastResponse()"
  _debug3 "Response provided" "$response"
  _debug3 "Field to get responses for" "$field"

  responseValue=$(echo "$response" | grep -- "\"$field\"" | cut -f2 -d":")

  _debug3 "Response lines found:" "$responseValue"

  responseValue=$(echo "$responseValue" | sed 's/^ //g' | sed 's/^"//g' | sed 's/\\"//g')
  responseValue=$(echo "$responseValue" | sed 's/,$//g' | sed 's/"$//g')
  responseValue=$(echo "$responseValue" | _lower_case)

  _debug3 "Responses found" "$responseValue"
  _debug3 "Response Selected" "$(echo "$responseValue" | tail -1)"

  echo "$responseValue" | tail -1
}

_stripWhitespace() {
  tr -d '\n' | tr -d '\r' | tr -d '\t' | sed -r 's/ +/ /g' | sed 's/\\"//g'
}

_exposeJsonArray() {
  sed -r 's/.*\[//g' | tr '}' '|' | tr '{' '|' | sed 's/|, |/|/g' | tr '|' '\n'
}

_getJsonElement() {
  content=$1
  field=$2

  _debug3 "_getJsonElement()"
  _debug3 "Input JSON element" "$content"
  _debug3 "JSON element to isolate" "$field"

  # With a single JSON entry to parse, convert commas to newlines puts each element on
  # its own line - which then allows us to just grep teh name, remove the key, and
  # isolate the value
  output=$(echo "$content" | tr ',' '\n' | grep -- "\"$field\":" | sed 's/.*: //g')

  _debug3 "String before unquoting: $output"

  _unquoteString "$output"
}

_createAuthHeader() {
  apikey=$1

  _debug3 "_createAuthHeader()"
  _secure_debug3 "Provided API Key" "$apikey"

  authheader="Authorization: Bearer $apikey"
  _secure_debug3 "Authorization Header" "$authheader"
  echo "$authheader"
}

_getDnsRecordName() {
  fqdn=$1
  address=$2

  _debug3 "_getDnsRecordName()"
  _debug3 "FQDN" "$fqdn"
  _debug3 "omg.lol Address" "$address"

  echo "$fqdn" | sed 's/\.omg\.lol//g' | sed 's/\.'"$address"'$//g'
}

_unquoteString() {
  output=$1
  quotes=0

  _debug3 "_unquoteString()"
  _debug3 "Possibly quoted string" "$output"

  _startswith "$output" "\""
  if [ $? ]; then
    quotes=$((quotes + 1))
  fi

  _endswith "$output" "\""
  if [ $? ]; then
    quotes=$((quotes + 1))
  fi

  _debug3 "Original String: $output"
  _debug3 "Quotes found: $quotes"

  if [ $((quotes)) -gt 1 ]; then
    output=$(echo "$output" | sed 's/^"//g' | sed 's/"$//g')
    _debug3 "Quotes removed: $output"
  fi

  echo "$output"
}