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
9.0 KiB

  1. #!/usr/bin/env sh
  2. #Name: dns_miab.sh
  3. #
  4. #Authors:
  5. # Darven Dissek 2018
  6. # William Gertz 2019
  7. #
  8. # Thanks to Neil Pang for the code reused from acme.sh from HTTP-01 validation
  9. # used to communicate with the MailintheBox Custom DNS API
  10. #Report Bugs here:
  11. # https://github.com/billgertz/MIAB_dns_api (for dns_miab.sh)
  12. # https://github.com/Neilpang/acme.sh (for acme.sh)
  13. #
  14. ######## Public functions #####################
  15. #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  16. dns_miab_add() {
  17. fulldomain=$1
  18. txtvalue=$2
  19. _info "Using miab"
  20. _debug fulldomain "$fulldomain"
  21. _debug txtvalue "$txtvalue"
  22. MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}"
  23. MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}"
  24. MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}"
  25. #debug log the environmental variables
  26. _debug MIAB_Username "$MIAB_Username"
  27. _debug MIAB_Password "$MIAB_Password"
  28. _debug MIAB_Server "$MIAB_Server"
  29. if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then
  30. MIAB_Username=""
  31. MIAB_Password=""
  32. MIAB_Server=""
  33. _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server."
  34. _err "Please try again."
  35. return 1
  36. fi
  37. #save the credentials to the account conf file.
  38. _saveaccountconf_mutable MIAB_Username "$MIAB_Username"
  39. _saveaccountconf_mutable MIAB_Password "$MIAB_Password"
  40. _saveaccountconf_mutable MIAB_Server "$MIAB_Server"
  41. baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt"
  42. #Add the challenge record
  43. result="$(_miab_post "$txtvalue" "$baseurl" "" "POST" "" "$MIAB_Username" "$MIAB_Password")"
  44. _debug result "$result"
  45. #check if result was good
  46. if _contains "$result" "updated DNS"; then
  47. _info "Successfully created the txt record"
  48. return 0
  49. else
  50. _err "Error encountered during record addition"
  51. _err "$result"
  52. return 1
  53. fi
  54. }
  55. #Usage: fulldomain txtvalue
  56. #Remove the txt record after validation.
  57. dns_miab_rm() {
  58. fulldomain=$1
  59. txtvalue=$2
  60. _info "Using miab"
  61. _debug fulldomain "$fulldomain"
  62. _debug txtvalue "$txtvalue"
  63. MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}"
  64. MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}"
  65. MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}"
  66. #debug log the environmental variables
  67. _debug MIAB_Username "$MIAB_Username"
  68. _debug MIAB_Password "$MIAB_Password"
  69. _debug MIAB_Server "$MIAB_Server"
  70. if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then
  71. MIAB_Username=""
  72. MIAB_Password=""
  73. MIAB_Server=""
  74. _err "You didn't specify MIAB_Username or MIAB_Password or MIAB_Server."
  75. _err "Please try again."
  76. return 1
  77. fi
  78. #save the credentials to the account conf file.
  79. _saveaccountconf_mutable MIAB_Username "$MIAB_Username"
  80. _saveaccountconf_mutable MIAB_Password "$MIAB_Password"
  81. _saveaccountconf_mutable MIAB_Server "$MIAB_Server"
  82. baseurl="https://$MIAB_Server/admin/dns/custom/$fulldomain/txt"
  83. #Remove the challenge record
  84. result="$(_miab_post "$txtvalue" "$baseurl" "" "DELETE" "" "$MIAB_Username" "$MIAB_Password")"
  85. _debug result $result
  86. #check if result was good
  87. if _contains "$result" "updated DNS"; then
  88. _info "Successfully created the txt record"
  89. return 0
  90. else
  91. _err "Error encountered during record addition"
  92. _err "$result"
  93. return 1
  94. fi
  95. }
  96. #################### Private functions below ##################################
  97. #_acme-challenge.www.domain.com
  98. #returns
  99. # _sub_domain=_acme-challenge.www
  100. # _domain=domain.com
  101. # _domain_id=sdjkglgdfewsdfg
  102. _get_root() {
  103. domain=$1
  104. i=2
  105. p=1
  106. while true; do
  107. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  108. _debug h "$h"
  109. if [ -z "$h" ]; then
  110. #not valid
  111. return 1
  112. fi
  113. if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
  114. _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \")
  115. if [ "$_domain_id" ]; then
  116. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  117. _domain=$h
  118. return 0
  119. fi
  120. return 1
  121. fi
  122. p=$i
  123. i=$(_math "$i" + 1)
  124. done
  125. return 1
  126. }
  127. # post changes to MIAB dns (taken from acme.sh)
  128. _miab_post() {
  129. body="$1"
  130. _post_url="$2"
  131. needbase64="$3"
  132. httpmethod="$4"
  133. _postContentType="$5"
  134. username="$6"
  135. password="$7"
  136. if [ -z "$httpmethod" ]; then
  137. httpmethod="POST"
  138. fi
  139. _debug $httpmethod
  140. _debug "_post_url" "$_post_url"
  141. _debug2 "body" "$body"
  142. _debug2 "_postContentType" "$_postContentType"
  143. _inithttp
  144. if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
  145. _CURL="$_ACME_CURL"
  146. if [ "$HTTPS_INSECURE" ]; then
  147. _CURL="$_CURL --insecure "
  148. fi
  149. _debug "_CURL" "$_CURL"
  150. if [ "$needbase64" ]; then
  151. if [ "$_postContentType" ]; then
  152. response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
  153. else
  154. response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
  155. fi
  156. else
  157. if [ "$_postContentType" ]; then
  158. response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
  159. else
  160. response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod --user "$username:$password" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
  161. fi
  162. fi
  163. _ret="$?"
  164. if [ "$_ret" != "0" ]; then
  165. _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
  166. if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
  167. _err "Here is the curl dump log:"
  168. _err "$(cat "$_CURL_DUMP")"
  169. fi
  170. fi
  171. elif [ "$_ACME_WGET" ]; then
  172. _WGET="$_ACME_WGET"
  173. if [ "$HTTPS_INSECURE" ]; then
  174. _WGET="$_WGET --no-check-certificate "
  175. fi
  176. _debug "_WGET" "$_WGET"
  177. if [ "$needbase64" ]; then
  178. if [ "$httpmethod" = "POST" ]; then
  179. if [ "$_postContentType" ]; then
  180. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
  181. else
  182. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
  183. fi
  184. else
  185. if [ "$_postContentType" ]; then
  186. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
  187. else
  188. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
  189. fi
  190. fi
  191. else
  192. if [ "$httpmethod" = "POST" ]; then
  193. if [ "$_postContentType" ]; then
  194. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
  195. else
  196. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
  197. fi
  198. else
  199. if [ "$_postContentType" ]; then
  200. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
  201. else
  202. response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
  203. fi
  204. fi
  205. fi
  206. _ret="$?"
  207. if [ "$_ret" = "8" ]; then
  208. _ret=0
  209. _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
  210. fi
  211. if [ "$_ret" != "0" ]; then
  212. _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
  213. fi
  214. _sed_i "s/^ *//g" "$HTTP_HEADER"
  215. else
  216. _ret="$?"
  217. _err "Neither curl nor wget was found, cannot do $httpmethod."
  218. fi
  219. _debug "_ret" "$_ret"
  220. printf "%s" "$response"
  221. return $_ret
  222. }