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.

233 lines
5.6 KiB

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