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.

269 lines
6.4 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. #!/usr/bin/env sh
  2. # Namecheap API
  3. # https://www.namecheap.com/support/api/intro.aspx
  4. #
  5. # Requires Namecheap API key set in NAMECHEAP_API_KEY and NAMECHEAP_USERNAME set as environment variable
  6. #
  7. ######## Public functions #####################
  8. if [ "$STAGE" -eq 1 ]; then
  9. NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response"
  10. else
  11. NAMECHEAP_API="https://api.namecheap.com/xml.response"
  12. fi
  13. #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  14. dns_namecheap_add() {
  15. fulldomain=$1
  16. txtvalue=$2
  17. if ! _namecheap_check_config; then
  18. _err "$error"
  19. return 1
  20. fi
  21. if ! _namecheap_set_publicip; then
  22. return 1
  23. fi
  24. _debug "First detect the root zone"
  25. if ! _get_root "$fulldomain"; then
  26. _err "invalid domain"
  27. return 1
  28. fi
  29. _debug fulldomain "$fulldomain"
  30. _debug txtvalue "$txtvalue"
  31. _debug domain "$_domain"
  32. _debug sub_domain "$_sub_domain"
  33. _set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  34. }
  35. #Usage: fulldomain txtvalue
  36. #Remove the txt record after validation.
  37. dns_namecheap_rm() {
  38. fulldomain=$1
  39. txtvalue=$2
  40. if ! _namecheap_set_publicip; then
  41. return 1
  42. fi
  43. if ! _namecheap_check_config; then
  44. _err "$error"
  45. return 1
  46. fi
  47. _debug "First detect the root zone"
  48. if ! _get_root "$fulldomain"; then
  49. _err "invalid domain"
  50. return 1
  51. fi
  52. _debug fulldomain "$fulldomain"
  53. _debug txtvalue "$txtvalue"
  54. _debug domain "$_domain"
  55. _debug sub_domain "$_sub_domain"
  56. _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  57. }
  58. #################### Private functions below ##################################
  59. #_acme-challenge.www.domain.com
  60. #returns
  61. # _sub_domain=_acme-challenge.www
  62. # _domain=domain.com
  63. _get_root() {
  64. domain=$1
  65. if ! _namecheap_post "namecheap.domains.getList"; then
  66. _err "$error"
  67. return 1
  68. fi
  69. i=2
  70. p=1
  71. while true; do
  72. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  73. _debug h "$h"
  74. if [ -z "$h" ]; then
  75. #not valid
  76. return 1
  77. fi
  78. if ! _contains "$response" "$h"; then
  79. _debug "$h not found"
  80. else
  81. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  82. _domain="$h"
  83. return 0
  84. fi
  85. p="$i"
  86. i=$(_math "$i" + 1)
  87. done
  88. return 1
  89. }
  90. _namecheap_set_publicip() {
  91. if [ -z "$NAMECHEAP_SOURCEIP" ]; then
  92. _err "No Source IP specified for Namecheap API."
  93. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  94. return 1
  95. else
  96. _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
  97. _debug sourceip "$NAMECHEAP_SOURCEIP"
  98. ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
  99. addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
  100. _debug2 ip "$ip"
  101. _debug2 addr "$addr"
  102. if [ -n "$ip" ]; then
  103. _publicip="$ip"
  104. elif [ -n "$addr" ]; then
  105. _publicip=$(_get "$addr")
  106. else
  107. _err "No Source IP specified for Namecheap API."
  108. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  109. return 1
  110. fi
  111. fi
  112. _debug publicip "$_publicip"
  113. return 0
  114. }
  115. _namecheap_post() {
  116. command=$1
  117. data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
  118. response="$(_post "$data" "$NAMECHEAP_API" "" "POST")"
  119. _debug2 response "$response"
  120. if _contains "$response" "Status=\"ERROR\"" >/dev/null; then
  121. error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>')
  122. _err "error $error"
  123. return 1
  124. fi
  125. return 0
  126. }
  127. _namecheap_parse_host() {
  128. _host=$1
  129. _debug _host "$_host"
  130. _hostid=$(echo "$_host" | _egrep_o 'HostId=".*"' | cut -d '"' -f 2)
  131. _hostname=$(echo "$_host" | _egrep_o 'Name=".*"' | cut -d '"' -f 2)
  132. _hosttype=$(echo "$_host" | _egrep_o 'Type=".*"' | cut -d '"' -f 2)
  133. _hostaddress=$(echo "$_host" | _egrep_o 'Address=".*"' | cut -d '"' -f 2)
  134. _hostmxpref=$(echo "$_host" | _egrep_o 'MXPref=".*"' | cut -d '"' -f 2)
  135. _hostttl=$(echo "$_host" | _egrep_o 'TTL=".*"' | cut -d '"' -f 2)
  136. _debug hostid "$_hostid"
  137. _debug hostname "$_hostname"
  138. _debug hosttype "$_hosttype"
  139. _debug hostaddress "$_hostaddress"
  140. _debug hostmxpref "$_hostmxpref"
  141. _debug hostttl "$_hostttl"
  142. }
  143. _namecheap_check_config() {
  144. if [ -z "$NAMECHEAP_API_KEY" ]; then
  145. _err "No API key specified for Namecheap API."
  146. _err "Create your key and export it as NAMECHEAP_API_KEY"
  147. return 1
  148. fi
  149. if [ -z "$NAMECHEAP_USERNAME" ]; then
  150. _err "No username key specified for Namecheap API."
  151. _err "Create your key and export it as NAMECHEAP_USERNAME"
  152. return 1
  153. fi
  154. _saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
  155. _saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
  156. return 0
  157. }
  158. _set_namecheap_TXT() {
  159. subdomain=$2
  160. txt=$3
  161. tld=$(echo "$1" | cut -d '.' -f 2)
  162. sld=$(echo "$1" | cut -d '.' -f 1)
  163. request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
  164. if ! _namecheap_post "$request"; then
  165. _err "$error"
  166. return 1
  167. fi
  168. hosts=$(echo "$response" | _egrep_o '<host .+ />')
  169. _debug hosts "$hosts"
  170. if [ -z "$hosts" ]; then
  171. _error "Hosts not found"
  172. return 1
  173. fi
  174. _namecheap_reset_hostList
  175. found=0
  176. while read -r host; do
  177. if _contains "$host" "<host"; then
  178. _namecheap_parse_host "$host"
  179. if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ]; then
  180. _namecheap_add_host "$_hostname" "$_hosttype" "$txt" "$_hostmxpref" "$_hostttl"
  181. found=1
  182. else
  183. _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
  184. fi
  185. fi
  186. done <<EOT
  187. echo "$hosts"
  188. EOT
  189. if [ $found -eq 0 ]; then
  190. _namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
  191. _debug "not found"
  192. fi
  193. _debug hostrequestfinal "$_hostrequest"
  194. request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
  195. if ! _namecheap_post "$request"; then
  196. _err "$error"
  197. return 1
  198. fi
  199. return 0
  200. }
  201. _namecheap_reset_hostList() {
  202. _hostindex=0
  203. _hostrequest=""
  204. }
  205. #Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
  206. _namecheap_add_host() {
  207. _hostindex=$(_math "$_hostindex" + 1)
  208. _hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5")
  209. }