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.

362 lines
8.2 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. #!/usr/bin/env sh
  2. #
  3. #INWX_User="username"
  4. #
  5. #INWX_Password="password"
  6. #
  7. # Dependencies:
  8. # -------------
  9. # - oathtool (When using 2 Factor Authentication)
  10. INWX_Api="https://api.domrobot.com/xmlrpc/"
  11. ######## Public functions #####################
  12. #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  13. dns_inwx_add() {
  14. fulldomain=$1
  15. txtvalue=$2
  16. INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
  17. INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
  18. INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
  19. if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
  20. INWX_User=""
  21. INWX_Password=""
  22. _err "You don't specify inwx user and password yet."
  23. _err "Please create you key and try again."
  24. return 1
  25. fi
  26. #save the api key and email to the account conf file.
  27. _saveaccountconf_mutable INWX_User "$INWX_User"
  28. _saveaccountconf_mutable INWX_Password "$INWX_Password"
  29. _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
  30. _debug "First detect the root zone"
  31. if ! _get_root "$fulldomain"; then
  32. _err "invalid domain"
  33. return 1
  34. fi
  35. _debug _sub_domain "$_sub_domain"
  36. _debug _domain "$_domain"
  37. _info "Adding record"
  38. _inwx_add_record "$_domain" "$_sub_domain" "$txtvalue"
  39. }
  40. #fulldomain txtvalue
  41. dns_inwx_rm() {
  42. fulldomain=$1
  43. txtvalue=$2
  44. INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
  45. INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
  46. INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
  47. if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
  48. INWX_User=""
  49. INWX_Password=""
  50. _err "You don't specify inwx user and password yet."
  51. _err "Please create you key and try again."
  52. return 1
  53. fi
  54. _debug "First detect the root zone"
  55. if ! _get_root "$fulldomain"; then
  56. _err "invalid domain"
  57. return 1
  58. fi
  59. _debug _sub_domain "$_sub_domain"
  60. _debug _domain "$_domain"
  61. _debug "Getting txt records"
  62. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  63. <methodCall>
  64. <methodName>nameserver.info</methodName>
  65. <params>
  66. <param>
  67. <value>
  68. <struct>
  69. <member>
  70. <name>domain</name>
  71. <value>
  72. <string>%s</string>
  73. </value>
  74. </member>
  75. <member>
  76. <name>type</name>
  77. <value>
  78. <string>TXT</string>
  79. </value>
  80. </member>
  81. <member>
  82. <name>name</name>
  83. <value>
  84. <string>%s</string>
  85. </value>
  86. </member>
  87. </struct>
  88. </value>
  89. </param>
  90. </params>
  91. </methodCall>' "$_domain" "$_sub_domain")
  92. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  93. if ! _contains "$response" "Command completed successfully"; then
  94. _err "Error could not get txt records"
  95. return 1
  96. fi
  97. if ! printf "%s" "$response" | grep "count" >/dev/null; then
  98. _info "Do not need to delete record"
  99. else
  100. _record_id=$(printf '%s' "$response" | _egrep_o '.*(<member><name>record){1}(.*)([0-9]+){1}' | _egrep_o '<name>id<\/name><value><int>[0-9]+' | _egrep_o '[0-9]+')
  101. _info "Deleting record"
  102. _inwx_delete_record "$_record_id"
  103. fi
  104. }
  105. #################### Private functions below ##################################
  106. _inwx_login() {
  107. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  108. <methodCall>
  109. <methodName>account.login</methodName>
  110. <params>
  111. <param>
  112. <value>
  113. <struct>
  114. <member>
  115. <name>user</name>
  116. <value>
  117. <string>%s</string>
  118. </value>
  119. </member>
  120. <member>
  121. <name>pass</name>
  122. <value>
  123. <string>%s</string>
  124. </value>
  125. </member>
  126. </struct>
  127. </value>
  128. </param>
  129. </params>
  130. </methodCall>' "$INWX_User" "$INWX_Password")
  131. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  132. _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
  133. export _H1
  134. if ! _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>"; then
  135. _err "INWX API: Authentication error (username/password correct?)"
  136. return 1
  137. fi
  138. #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
  139. if _contains "$response" "<member><name>tfa</name><value><string>GOOGLE-AUTH</string></value></member>"; then
  140. if [ -z "$INWX_Shared_Secret" ]; then
  141. _err "INWX API: Mobile TAN detected."
  142. _err "Please define a shared secret."
  143. return 1
  144. fi
  145. if ! _exists oathtool; then
  146. _err "Please install oathtool to use 2 Factor Authentication."
  147. _err ""
  148. return 1
  149. fi
  150. tan="$(oathtool --base32 --totp "${INWX_Shared_Secret}" 2>/dev/null)"
  151. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  152. <methodCall>
  153. <methodName>account.unlock</methodName>
  154. <params>
  155. <param>
  156. <value>
  157. <struct>
  158. <member>
  159. <name>tan</name>
  160. <value>
  161. <string>%s</string>
  162. </value>
  163. </member>
  164. </struct>
  165. </value>
  166. </param>
  167. </params>
  168. </methodCall>' "$tan")
  169. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  170. if ! _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>"; then
  171. _err "INWX API: Mobile TAN not correct."
  172. return 1
  173. fi
  174. fi
  175. }
  176. _get_root() {
  177. domain=$1
  178. _debug "get root"
  179. domain=$1
  180. i=2
  181. p=1
  182. _inwx_login
  183. xml_content='<?xml version="1.0" encoding="UTF-8"?>
  184. <methodCall>
  185. <methodName>nameserver.list</methodName>
  186. </methodCall>'
  187. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  188. while true; do
  189. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  190. _debug h "$h"
  191. if [ -z "$h" ]; then
  192. #not valid
  193. return 1
  194. fi
  195. if _contains "$response" "$h"; then
  196. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  197. _domain="$h"
  198. return 0
  199. fi
  200. p=$i
  201. i=$(_math "$i" + 1)
  202. done
  203. return 1
  204. }
  205. _inwx_delete_record() {
  206. record_id=$1
  207. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  208. <methodCall>
  209. <methodName>nameserver.deleteRecord</methodName>
  210. <params>
  211. <param>
  212. <value>
  213. <struct>
  214. <member>
  215. <name>id</name>
  216. <value>
  217. <int>%s</int>
  218. </value>
  219. </member>
  220. </struct>
  221. </value>
  222. </param>
  223. </params>
  224. </methodCall>' "$record_id")
  225. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  226. if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
  227. _err "Error"
  228. return 1
  229. fi
  230. return 0
  231. }
  232. _inwx_update_record() {
  233. record_id=$1
  234. txtval=$2
  235. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  236. <methodCall>
  237. <methodName>nameserver.updateRecord</methodName>
  238. <params>
  239. <param>
  240. <value>
  241. <struct>
  242. <member>
  243. <name>content</name>
  244. <value>
  245. <string>%s</string>
  246. </value>
  247. </member>
  248. <member>
  249. <name>id</name>
  250. <value>
  251. <int>%s</int>
  252. </value>
  253. </member>
  254. </struct>
  255. </value>
  256. </param>
  257. </params>
  258. </methodCall>' "$txtval" "$record_id")
  259. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  260. if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
  261. _err "Error"
  262. return 1
  263. fi
  264. return 0
  265. }
  266. _inwx_add_record() {
  267. domain=$1
  268. sub_domain=$2
  269. txtval=$3
  270. xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
  271. <methodCall>
  272. <methodName>nameserver.createRecord</methodName>
  273. <params>
  274. <param>
  275. <value>
  276. <struct>
  277. <member>
  278. <name>domain</name>
  279. <value>
  280. <string>%s</string>
  281. </value>
  282. </member>
  283. <member>
  284. <name>type</name>
  285. <value>
  286. <string>TXT</string>
  287. </value>
  288. </member>
  289. <member>
  290. <name>content</name>
  291. <value>
  292. <string>%s</string>
  293. </value>
  294. </member>
  295. <member>
  296. <name>name</name>
  297. <value>
  298. <string>%s</string>
  299. </value>
  300. </member>
  301. </struct>
  302. </value>
  303. </param>
  304. </params>
  305. </methodCall>' "$domain" "$txtval" "$sub_domain")
  306. response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
  307. if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
  308. _err "Error"
  309. return 1
  310. fi
  311. return 0
  312. }