| 
					
				 | 
			
			
				@@ -1,4 +1,4 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#!/usr/bin/env sh 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#!/usr/bin/env bash 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # ISPConfig 3.1 API 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9,7 +9,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Values to export: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # export ISPC_User="remoteUser" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# export ISPC_Password="remotePasword" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# export ISPC_Password="remotePassword" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # export ISPC_Api_Insecure=1     # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -19,12 +19,14 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 dns_ispconfig_add() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   fulldomain="${1}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   txtvalue="${2}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Calling: dns_ispconfig_add() '${fulldomain}' '${txtvalue}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   _ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #Usage: dns_myapi_rm   _acme-challenge.www.domain.com 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 dns_ispconfig_rm() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   fulldomain="${1}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Calling: dns_ispconfig_rm() '${fulldomain}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   _ISPC_credentials && _ISPC_login && _ISPC_rmTxt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -52,9 +54,12 @@ _ISPC_login() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   _info "Getting Session ID" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curResult="$(_post "${curData}" "${ISPC_Api}?login")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Calling _ISPC_login: '${curData}' '${ISPC_Api}?login'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Result of _ISPC_login: '$curResult'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if _contains "${curResult}" '"code":"ok"'; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     _info "Retrieved Session ID." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Session ID: '${sessionID}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     _err "Couldn't retrieve the Session ID." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return 1 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -69,12 +74,15 @@ _ISPC_getZoneInfo() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # we can strip the first part of the fulldomain, since it's just the _acme-challenge string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     curZone="${curZone#*.}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # suffix . needed for zone -> domain.tld. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    curData="{\"session_id\":\"${sessionID}\",\"primary_id\":[{\"origin\":\"${curZone}.\"}]}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Result of _ISPC_getZoneInfo: '$curResult'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if _contains "${curResult}" '"id":"'; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       zoneFound=true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       zoneEnd=true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       _info "Retrieved zone data." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      _debug "Zone data: '${curResult}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fi 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if [ "${curZone#*.}" != "$curZone" ]; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       _debug2 "$curZone still contains a '.' - so we can check next higher level" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -86,6 +94,7 @@ _ISPC_getZoneInfo() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if [ "${zoneFound}" ]; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Server ID: '${server_id}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case "${server_id}" in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       '' | *[!0-9]*) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _err "Server ID is not numeric." 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -94,6 +103,7 @@ _ISPC_getZoneInfo() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       *) _info "Retrieved Server ID" ;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     esac 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Zone: '${zone}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case "${zone}" in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       '' | *[!0-9]*) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _err "Zone ID is not numeric." 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -102,6 +112,7 @@ _ISPC_getZoneInfo() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       *) _info "Retrieved Zone ID" ;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     esac 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Client ID: '${client_id}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case "${client_id}" in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       '' | *[!0-9]*) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _err "Client ID is not numeric." 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -120,7 +131,10 @@ _ISPC_addTxt() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\"" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Result of _ISPC_addTxt: '$curResult'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Record ID: '${record_id}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   case "${record_id}" in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     '' | *[!0-9]*) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       _err "Couldn't add ACME Challenge TXT record to zone." 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -134,8 +148,11 @@ _ISPC_rmTxt() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   # Need to get the record ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_get'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  _debug "Result of _ISPC_rmTxt: '$curResult'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if _contains "${curResult}" '"code":"ok"'; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _debug "Record ID: '${record_id}'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case "${record_id}" in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       '' | *[!0-9]*) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _err "Record ID is not numeric." 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -146,6 +163,8 @@ _ISPC_rmTxt() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _info "Retrieved Record ID." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _debug "Result of _ISPC_rmTxt: '$curResult'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if _contains "${curResult}" '"code":"ok"'; then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           _info "Removed ACME Challenge TXT record from zone." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else 
			 |