From 63f32835917a1d1eaec380ceb07e0985e0dd58e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= <mail@jkroepke.de>
Date: Mon, 9 Apr 2018 00:10:27 +0200
Subject: [PATCH] Add Support for inwx mobile tan

---
 dnsapi/README.md   |  8 ++++++++
 dnsapi/dns_inwx.sh | 50 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/dnsapi/README.md b/dnsapi/README.md
index b8bdbbb2..a90b3f75 100644
--- a/dnsapi/README.md
+++ b/dnsapi/README.md
@@ -641,6 +641,14 @@ acme.sh --issue --dns dns_inwx -d example.com -d www.example.com
 
 The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 
+If your account is secured by mobile tan you have also defined the shared secret.
+
+```
+export INWX_Shared_Secret="shared secret"
+```
+
+You may need to re-enable the mobile tan to gain the shared secret.
+
 ## 34. User Servercow API v1
 
 Create a new user from the servercow control center. Don't forget to activate **DNS API** for this user.
diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh
index 5dfba7d1..cd5af91b 100755
--- a/dnsapi/dns_inwx.sh
+++ b/dnsapi/dns_inwx.sh
@@ -4,6 +4,10 @@
 #INWX_User="username"
 #
 #INWX_Password="password"
+#
+# Dependencies:
+# -------------
+# - oathtool (When using 2 Factor Authentication)
 
 INWX_Api="https://api.domrobot.com/xmlrpc/"
 
@@ -16,6 +20,7 @@ dns_inwx_add() {
 
   INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
   INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
+  INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
   if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
     INWX_User=""
     INWX_Password=""
@@ -27,6 +32,7 @@ dns_inwx_add() {
   #save the api key and email to the account conf file.
   _saveaccountconf_mutable INWX_User "$INWX_User"
   _saveaccountconf_mutable INWX_Password "$INWX_Password"
+  _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
 
   _debug "First detect the root zone"
   if ! _get_root "$fulldomain"; then
@@ -148,8 +154,46 @@ _inwx_login() {
   </methodCall>' $INWX_User $INWX_Password)
 
   response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
+  _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
+  export _H1
 
-  printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')"
+  #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
+  if _contains "$response" "tfa"; then
+    if [ -z "$INWX_Shared_Secret" ]; then
+      _err "Mobile TAN detected."
+      _err "Please define a shared secret."
+      return 1
+    fi
+
+    if ! _exists oathtool; then
+      _err "Please install oathtool to use 2 Factor Authentication."
+      _err ""
+      return 1
+    fi
+
+    tan="$(oathtool --base32 --totp "${INWX_Shared_Secret}" 2>/dev/null)"
+
+    xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
+    <methodCall>
+    <methodName>account.unlock</methodName>
+    <params>
+     <param>
+      <value>
+       <struct>
+        <member>
+         <name>tan</name>
+         <value>
+          <string>%s</string>
+         </value>
+        </member>
+       </struct>
+      </value>
+     </param>
+    </params>
+    </methodCall>' "$tan")
+
+    response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
+  fi
 
 }
 
@@ -161,8 +205,8 @@ _get_root() {
   i=2
   p=1
 
-  _H1=$(_inwx_login)
-  export _H1
+  _inwx_login
+
   xml_content='<?xml version="1.0" encoding="UTF-8"?>
   <methodCall>
   <methodName>nameserver.list</methodName>