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.

211 lines
5.8 KiB

3 months ago
  1. #!/usr/bin/env sh
  2. # shellcheck disable=SC2034
  3. dns_miab_info='Mail-in-a-Box
  4. Site: MailInaBox.email
  5. Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_miab
  6. Options:
  7. MIAB_Username Admin username
  8. MIAB_Password Admin password
  9. MIAB_Server Server hostname. FQDN of your_MIAB Server
  10. Issues: github.com/acmesh-official/acme.sh/issues/2550
  11. Author: Darven Dissek, William Gertz
  12. '
  13. ######## Public functions #####################
  14. #Usage: dns_miab_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  15. dns_miab_add() {
  16. fulldomain=$1
  17. # Added "value=" and "&ttl=300" to accomodate the new TXT record format used by the MIAB/PMIAB API
  18. txtvalue="value=$2&ttl=300"
  19. _info "Using miab challenge add"
  20. _debug fulldomain "$fulldomain"
  21. _debug txtvalue "$txtvalue"
  22. #retrieve MIAB environemt vars
  23. if ! _retrieve_miab_env; then
  24. return 1
  25. fi
  26. #check domain and seperate into domain and host
  27. if ! _get_root "$fulldomain"; then
  28. _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}"
  29. return 1
  30. fi
  31. _debug2 _sub_domain "$_sub_domain"
  32. _debug2 _domain "$_domain"
  33. #add the challenge record
  34. _api_path="custom/${fulldomain}/txt"
  35. _miab_rest "$txtvalue" "$_api_path" "POST"
  36. #check if result was good
  37. if _contains "$response" "updated DNS"; then
  38. _info "Successfully created the txt record"
  39. return 0
  40. else
  41. _err "Error encountered during record add"
  42. _err "$response"
  43. return 1
  44. fi
  45. }
  46. #Usage: dns_miab_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  47. dns_miab_rm() {
  48. fulldomain=$1
  49. txtvalue=$2
  50. _info "Using miab challenge delete"
  51. _debug fulldomain "$fulldomain"
  52. _debug txtvalue "$txtvalue"
  53. #retrieve MIAB environemt vars
  54. if ! _retrieve_miab_env; then
  55. return 1
  56. fi
  57. #check domain and seperate into doamin and host
  58. if ! _get_root "$fulldomain"; then
  59. _err "Cannot find any part of ${fulldomain} is hosted on ${MIAB_Server}"
  60. return 1
  61. fi
  62. _debug2 _sub_domain "$_sub_domain"
  63. _debug2 _domain "$_domain"
  64. #Remove the challenge record
  65. _api_path="custom/${fulldomain}/txt"
  66. _miab_rest "$txtvalue" "$_api_path" "DELETE"
  67. #check if result was good
  68. if _contains "$response" "updated DNS"; then
  69. _info "Successfully removed the txt record"
  70. return 0
  71. else
  72. _err "Error encountered during record remove"
  73. _err "$response"
  74. return 1
  75. fi
  76. }
  77. #################### Private functions below ##################################
  78. #
  79. #Usage: _get_root _acme-challenge.www.domain.com
  80. #Returns:
  81. # _sub_domain=_acme-challenge.www
  82. # _domain=domain.com
  83. _get_root() {
  84. _passed_domain=$1
  85. _debug _passed_domain "$_passed_domain"
  86. _i=2
  87. _p=1
  88. #get the zones hosed on MIAB server, must be a json stream
  89. _miab_rest "" "zones" "GET"
  90. if ! _is_json "$response"; then
  91. _err "ERROR fetching domain list"
  92. _err "$response"
  93. return 1
  94. fi
  95. #cycle through the passed domain seperating out a test domain discarding
  96. # the subdomain by marching thorugh the dots
  97. while true; do
  98. _test_domain=$(printf "%s" "$_passed_domain" | cut -d . -f ${_i}-100)
  99. _debug _test_domain "$_test_domain"
  100. if [ -z "$_test_domain" ]; then
  101. return 1
  102. fi
  103. #report found if the test domain is in the json response and
  104. # report the subdomain
  105. if _contains "$response" "\"$_test_domain\""; then
  106. _sub_domain=$(printf "%s" "$_passed_domain" | cut -d . -f 1-${_p})
  107. _domain=${_test_domain}
  108. return 0
  109. fi
  110. #cycle to the next dot in the passed domain
  111. _p=${_i}
  112. _i=$(_math "$_i" + 1)
  113. done
  114. return 1
  115. }
  116. #Usage: _retrieve_miab_env
  117. #Returns (from store or environment variables):
  118. # MIAB_Username
  119. # MIAB_Password
  120. # MIAB_Server
  121. #retrieve MIAB environment variables, report errors and quit if problems
  122. _retrieve_miab_env() {
  123. MIAB_Username="${MIAB_Username:-$(_readaccountconf_mutable MIAB_Username)}"
  124. MIAB_Password="${MIAB_Password:-$(_readaccountconf_mutable MIAB_Password)}"
  125. MIAB_Server="${MIAB_Server:-$(_readaccountconf_mutable MIAB_Server)}"
  126. #debug log the environmental variables
  127. _debug MIAB_Username "$MIAB_Username"
  128. _debug MIAB_Password "$MIAB_Password"
  129. _debug MIAB_Server "$MIAB_Server"
  130. #check if MIAB environemt vars set and quit if not
  131. if [ -z "$MIAB_Username" ] || [ -z "$MIAB_Password" ] || [ -z "$MIAB_Server" ]; then
  132. _err "You didn't specify one or more of MIAB_Username, MIAB_Password or MIAB_Server."
  133. _err "Please check these environment variables and try again."
  134. return 1
  135. fi
  136. #save the credentials to the account conf file.
  137. _saveaccountconf_mutable MIAB_Username "$MIAB_Username"
  138. _saveaccountconf_mutable MIAB_Password "$MIAB_Password"
  139. _saveaccountconf_mutable MIAB_Server "$MIAB_Server"
  140. return 0
  141. }
  142. #Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST"
  143. #Returns: "updated DNS: domain.com"
  144. #rest interface MIAB dns
  145. _miab_rest() {
  146. _data="$1"
  147. _api_path="$2"
  148. _httpmethod="$3"
  149. #encode username and password for basic authentication
  150. _credentials="$(printf "%s" "$MIAB_Username:$MIAB_Password" | _base64)"
  151. export _H1="Authorization: Basic $_credentials"
  152. _url="https://${MIAB_Server}/admin/dns/${_api_path}"
  153. _debug2 _data "$_data"
  154. _debug _api_path "$_api_path"
  155. _debug2 _url "$_url"
  156. _debug2 _credentails "$_credentials"
  157. _debug _httpmethod "$_httpmethod"
  158. if [ "$_httpmethod" = "GET" ]; then
  159. response="$(_get "$_url")"
  160. else
  161. response="$(_post "$_data" "$_url" "" "$_httpmethod")"
  162. fi
  163. _retcode="$?"
  164. if [ "$_retcode" != "0" ]; then
  165. _err "MIAB REST authentication failed on $_httpmethod"
  166. return 1
  167. fi
  168. _debug response "$response"
  169. return 0
  170. }
  171. #Usage: _is_json "\[\n "mydomain.com"\n]"
  172. #Reurns "\[\n "mydomain.com"\n]"
  173. #returns the string if it begins and ends with square braces
  174. _is_json() {
  175. _str="$(echo "$1" | _normalizeJson)"
  176. echo "$_str" | grep '^\[.*\]$' >/dev/null 2>&1
  177. }