]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_ispconfig.sh
Merge remote-tracking branch 'upstream/master'
[mirror_acme.sh.git] / dnsapi / dns_ispconfig.sh
1 #!/usr/bin/env sh
2
3 # ISPConfig 3.1 API
4 # User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to:
5 # - DNS zone Functions
6 # - DNS txt Functions
7
8 # Report bugs to https://github.com/sjau/acme.sh
9
10 # Values to export:
11 # export ISPC_User="remoteUser"
12 # export ISPC_Password="remotePassword"
13 # export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php"
14 # 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)
15
16 ######## Public functions #####################
17
18 #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
19 dns_ispconfig_add() {
20 fulldomain="${1}"
21 txtvalue="${2}"
22 _debug "Calling: dns_ispconfig_add() '${fulldomain}' '${txtvalue}'"
23 _ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt
24 }
25
26 #Usage: dns_myapi_rm _acme-challenge.www.domain.com
27 dns_ispconfig_rm() {
28 fulldomain="${1}"
29 _debug "Calling: dns_ispconfig_rm() '${fulldomain}'"
30 _ISPC_credentials && _ISPC_login && _ISPC_rmTxt
31 }
32
33 #################### Private functions below ##################################
34
35 _ISPC_credentials() {
36 if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
37 ISPC_User=""
38 ISPC_Password=""
39 ISPC_Api=""
40 ISPC_Api_Insecure=""
41 _err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
42 return 1
43 else
44 _saveaccountconf ISPC_User "${ISPC_User}"
45 _saveaccountconf ISPC_Password "${ISPC_Password}"
46 _saveaccountconf ISPC_Api "${ISPC_Api}"
47 _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
48 # Set whether curl should use secure or insecure mode
49 export HTTPS_INSECURE="${ISPC_Api_Insecure}"
50 fi
51 }
52
53 _ISPC_login() {
54 _info "Getting Session ID"
55 curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}"
56 curResult="$(_post "${curData}" "${ISPC_Api}?login")"
57 _debug "Calling _ISPC_login: '${curData}' '${ISPC_Api}?login'"
58 _debug "Result of _ISPC_login: '$curResult'"
59 if _contains "${curResult}" '"code":"ok"'; then
60 sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
61 _info "Retrieved Session ID."
62 _debug "Session ID: '${sessionID}'"
63 else
64 _err "Couldn't retrieve the Session ID."
65 return 1
66 fi
67 }
68
69 _ISPC_getZoneInfo() {
70 _info "Getting Zoneinfo"
71 zoneEnd=false
72 curZone="${fulldomain}"
73 while [ "${zoneEnd}" = false ]; do
74 # we can strip the first part of the fulldomain, since it's just the _acme-challenge string
75 curZone="${curZone#*.}"
76 # suffix . needed for zone -> domain.tld.
77 curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}"
78 curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")"
79 _debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'"
80 _debug "Result of _ISPC_getZoneInfo: '$curResult'"
81 if _contains "${curResult}" '"id":"'; then
82 zoneFound=true
83 zoneEnd=true
84 _info "Retrieved zone data."
85 _debug "Zone data: '${curResult}'"
86 fi
87 if [ "${curZone#*.}" != "$curZone" ]; then
88 _debug2 "$curZone still contains a '.' - so we can check next higher level"
89 else
90 zoneEnd=true
91 _err "Couldn't retrieve zone data."
92 return 1
93 fi
94 done
95 if [ "${zoneFound}" ]; then
96 server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
97 _debug "Server ID: '${server_id}'"
98 case "${server_id}" in
99 '' | *[!0-9]*)
100 _err "Server ID is not numeric."
101 return 1
102 ;;
103 *) _info "Retrieved Server ID" ;;
104 esac
105 zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
106 _debug "Zone: '${zone}'"
107 case "${zone}" in
108 '' | *[!0-9]*)
109 _err "Zone ID is not numeric."
110 return 1
111 ;;
112 *) _info "Retrieved Zone ID" ;;
113 esac
114 client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
115 _debug "Client ID: '${client_id}'"
116 case "${client_id}" in
117 '' | *[!0-9]*)
118 _err "Client ID is not numeric."
119 return 1
120 ;;
121 *) _info "Retrieved Client ID." ;;
122 esac
123 zoneFound=""
124 zoneEnd=""
125 fi
126 }
127
128 _ISPC_addTxt() {
129 curSerial="$(date +%s)"
130 curStamp="$(date +'%F %T')"
131 params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\""
132 curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}"
133 curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
134 _debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'"
135 _debug "Result of _ISPC_addTxt: '$curResult'"
136 record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
137 _debug "Record ID: '${record_id}'"
138 case "${record_id}" in
139 '' | *[!0-9]*)
140 _err "Couldn't add ACME Challenge TXT record to zone."
141 return 1
142 ;;
143 *) _info "Added ACME Challenge TXT record to zone." ;;
144 esac
145 }
146
147 _ISPC_rmTxt() {
148 # Need to get the record ID.
149 curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}"
150 curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")"
151 _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_get'"
152 _debug "Result of _ISPC_rmTxt: '$curResult'"
153 if _contains "${curResult}" '"code":"ok"'; then
154 record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
155 _debug "Record ID: '${record_id}'"
156 case "${record_id}" in
157 '' | *[!0-9]*)
158 _err "Record ID is not numeric."
159 return 1
160 ;;
161 *)
162 unset IFS
163 _info "Retrieved Record ID."
164 curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}"
165 curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
166 _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'"
167 _debug "Result of _ISPC_rmTxt: '$curResult'"
168 if _contains "${curResult}" '"code":"ok"'; then
169 _info "Removed ACME Challenge TXT record from zone."
170 else
171 _err "Couldn't remove ACME Challenge TXT record from zone."
172 return 1
173 fi
174 ;;
175 esac
176 fi
177 }