You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
8.9 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. #!/usr/bin/env sh
  2. # This file name is "dns_1984hosting.sh"
  3. # So, here must be a method dns_1984hosting_add()
  4. # Which will be called by acme.sh to add the txt record to your api system.
  5. # returns 0 means success, otherwise error.
  6. # Author: Adrian Fedoreanu
  7. # Report Bugs here: https://github.com/acmesh-official/acme.sh
  8. # or here... https://github.com/acmesh-official/acme.sh/issues/2851
  9. ######## Public functions #####################
  10. # Export 1984HOSTING username and password in following variables
  11. #
  12. # One984HOSTING_Username=username
  13. # One984HOSTING_Password=password
  14. #
  15. # username/password and csrftoken/sessionid cookies are saved in ~/.acme.sh/account.conf
  16. # Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  17. # Add a text record.
  18. dns_1984hosting_add() {
  19. fulldomain=$1
  20. txtvalue=$2
  21. _info "Add TXT record using 1984Hosting."
  22. _debug fulldomain "$fulldomain"
  23. _debug txtvalue "$txtvalue"
  24. if ! _1984hosting_login; then
  25. _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file."
  26. return 1
  27. fi
  28. _debug "First detect the root zone."
  29. if ! _get_root "$fulldomain"; then
  30. _err "Invalid domain '$fulldomain'."
  31. return 1
  32. fi
  33. _debug _sub_domain "$_sub_domain"
  34. _debug _domain "$_domain"
  35. _debug "Add TXT record $fulldomain with value '$txtvalue'."
  36. value="$(printf '%s' "$txtvalue" | _url_encode)"
  37. url="https://1984.hosting/domains/entry/"
  38. postdata="entry=new"
  39. postdata="$postdata&type=TXT"
  40. postdata="$postdata&ttl=900"
  41. postdata="$postdata&zone=$_domain"
  42. postdata="$postdata&host=$_sub_domain"
  43. postdata="$postdata&rdata=%22$value%22"
  44. _debug2 postdata "$postdata"
  45. _authpost "$postdata" "$url"
  46. if _contains "$_response" '"haserrors": true'; then
  47. _err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post."
  48. return 1
  49. elif _contains "$_response" "html>"; then
  50. _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file."
  51. return 1
  52. elif _contains "$_response" '"auth": false'; then
  53. _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie."
  54. return 1
  55. fi
  56. _info "Added acme challenge TXT record for $fulldomain at 1984Hosting."
  57. return 0
  58. }
  59. # Usage: fulldomain txtvalue
  60. # Remove the txt record after validation.
  61. dns_1984hosting_rm() {
  62. fulldomain=$1
  63. txtvalue=$2
  64. _info "Delete TXT record using 1984Hosting."
  65. _debug fulldomain "$fulldomain"
  66. _debug txtvalue "$txtvalue"
  67. if ! _1984hosting_login; then
  68. _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file."
  69. return 1
  70. fi
  71. _debug "First detect the root zone."
  72. if ! _get_root "$fulldomain"; then
  73. _err "Invalid domain '$fulldomain'."
  74. return 1
  75. fi
  76. _debug _sub_domain "$_sub_domain"
  77. _debug _domain "$_domain"
  78. _debug "Delete $fulldomain TXT record."
  79. url="https://1984.hosting/domains"
  80. if ! _get_zone_id "$url" "$_domain"; then
  81. _err "Invalid zone '$_domain'."
  82. return 1
  83. fi
  84. _htmlget "$url/$_zone_id" "$txtvalue"
  85. entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
  86. _debug2 entry_id "$entry_id"
  87. if [ -z "$entry_id" ]; then
  88. _err "Error getting TXT entry_id for $1."
  89. return 1
  90. fi
  91. _authpost "entry=$entry_id" "$url/delentry/"
  92. if ! _contains "$_response" '"ok": true'; then
  93. _err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post."
  94. return 1
  95. fi
  96. _info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting."
  97. return 0
  98. }
  99. #################### Private functions below ##################################
  100. _1984hosting_login() {
  101. if ! _check_credentials; then return 1; fi
  102. if _check_cookies; then
  103. _debug "Already logged in."
  104. return 0
  105. fi
  106. _debug "Login to 1984Hosting as user $One984HOSTING_Username."
  107. username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
  108. password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
  109. url="https://1984.hosting/api/auth/"
  110. _get "https://1984.hosting/accounts/login/" | grep "csrfmiddlewaretoken"
  111. csrftoken="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
  112. sessionid="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
  113. if [ -z "$csrftoken" ] || [ -z "$sessionid" ]; then
  114. _err "One or more cookies are empty: '$csrftoken', '$sessionid'."
  115. return 1
  116. fi
  117. export _H1="Cookie: $csrftoken; $sessionid"
  118. export _H2="Referer: https://1984.hosting/accounts/login/"
  119. csrf_header=$(echo "$csrftoken" | sed 's/csrftoken=//' | _head_n 1)
  120. export _H3="X-CSRFToken: $csrf_header"
  121. response="$(_post "username=$username&password=$password&otpkey=" $url)"
  122. response="$(echo "$response" | _normalizeJson)"
  123. _debug2 response "$response"
  124. if _contains "$response" '"loggedin": true'; then
  125. One984HOSTING_SESSIONID_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
  126. One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
  127. export One984HOSTING_SESSIONID_COOKIE
  128. export One984HOSTING_CSRFTOKEN_COOKIE
  129. _saveaccountconf_mutable One984HOSTING_Username "$One984HOSTING_Username"
  130. _saveaccountconf_mutable One984HOSTING_Password "$One984HOSTING_Password"
  131. _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
  132. _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
  133. return 0
  134. fi
  135. return 1
  136. }
  137. _check_credentials() {
  138. One984HOSTING_Username="${One984HOSTING_Username:-$(_readaccountconf_mutable One984HOSTING_Username)}"
  139. One984HOSTING_Password="${One984HOSTING_Password:-$(_readaccountconf_mutable One984HOSTING_Password)}"
  140. if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then
  141. One984HOSTING_Username=""
  142. One984HOSTING_Password=""
  143. _clearaccountconf_mutable One984HOSTING_Username
  144. _clearaccountconf_mutable One984HOSTING_Password
  145. _err "You haven't specified 1984Hosting username or password yet."
  146. _err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again."
  147. return 1
  148. fi
  149. return 0
  150. }
  151. _check_cookies() {
  152. One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}"
  153. One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}"
  154. if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then
  155. _debug "No cached cookie(s) found."
  156. return 1
  157. fi
  158. _authget "https://1984.hosting/api/auth/"
  159. if _contains "$_response" '"ok": true'; then
  160. _debug "Cached cookies still valid."
  161. return 0
  162. fi
  163. _debug "Cached cookies no longer valid. Clearing cookies."
  164. One984HOSTING_SESSIONID_COOKIE=""
  165. One984HOSTING_CSRFTOKEN_COOKIE=""
  166. _clearaccountconf_mutable One984HOSTING_SESSIONID_COOKIE
  167. _clearaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE
  168. return 1
  169. }
  170. # _acme-challenge.www.domain.com
  171. # Returns
  172. # _sub_domain=_acme-challenge.www
  173. # _domain=domain.com
  174. _get_root() {
  175. domain="$1"
  176. i=1
  177. p=1
  178. while true; do
  179. h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
  180. # not valid
  181. if [ -z "$h" ]; then
  182. return 1
  183. fi
  184. _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
  185. if _contains "$_response" "serial" && ! _contains "$_response" "null"; then
  186. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
  187. _domain="$h"
  188. return 0
  189. fi
  190. p=$i
  191. i=$(_math "$i" + 1)
  192. done
  193. return 1
  194. }
  195. # Usage: _get_zone_id url domain.com
  196. # Returns zone id for domain.com
  197. _get_zone_id() {
  198. url=$1
  199. domain=$2
  200. _htmlget "$url" "$domain"
  201. _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)"
  202. _debug2 _zone_id "$_zone_id"
  203. if [ -z "$_zone_id" ]; then
  204. _err "Error getting _zone_id for $2."
  205. return 1
  206. fi
  207. return 0
  208. }
  209. # Add extra headers to request
  210. _authget() {
  211. export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
  212. _response=$(_get "$1" | _normalizeJson)
  213. _debug2 _response "$_response"
  214. }
  215. # Truncate huge HTML response
  216. # Echo: Argument list too long
  217. _htmlget() {
  218. export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
  219. _response=$(_get "$1" | grep "$2")
  220. if _contains "$_response" "@$2"; then
  221. _response=$(echo "$_response" | grep -v "[@]" | _head_n 1)
  222. fi
  223. _debug2 _response "$_response"
  224. }
  225. # Add extra headers to request
  226. _authpost() {
  227. url="https://1984.hosting/domains"
  228. _get_zone_id "$url" "$_domain"
  229. csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")"
  230. export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
  231. export _H2="Referer: https://1984.hosting/domains/$_zone_id"
  232. export _H3="X-CSRFToken: $csrf_header"
  233. _response="$(_post "$1" "$2" | _normalizeJson)"
  234. _debug2 _response "$_response"
  235. }