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.

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