Use CHAOS TXT local.api.txt instead of trying to parse pihole-FTL --config webserver.ports

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2023-12-01 09:10:06 +01:00
parent 6016131280
commit 96bf07863f
No known key found for this signature in database
GPG key ID: 00135ACBD90B28DD
2 changed files with 47 additions and 49 deletions

View file

@ -21,62 +21,60 @@
TestAPIAvailability() { TestAPIAvailability() {
# as we are running locally, we can get the port value from FTL directly # as we are running locally, we can get the port value from FTL directly
local ports port availabilityResonse local chaos_api_list availabilityResonse
ports="$(pihole-FTL --config webserver.port)"
port="${ports%%,*}"
# Iterate over comma separated list of ports # Query the API URLs from FTL using CHAOS TXT local.api.ftl
while [ -n "${ports}" ]; do # The result is a space-separated enumeration of full URLs
# if the port ends with an "s", it is a secure connection # e.g., "http://localhost:80/api" "https://localhost:443/api"
if [ "${port#"${port%?}"}" = "s" ]; then chaos_api_list="$(dig +short chaos txt local.api.ftl @127.0.0.1)"
# remove the "s" from the port
API_PROT="https" # If the query was not successful, the variable is empty
API_PORT="${port%?}" if [ -z "${chaos_api_list}" ]; then
elif [ "${port#"${port%?}"}" = "r" ]; then echo "API not available. Please check connectivity"
# Ignore this port, the client may not be able to follow the exit 1
# redirected target when FTL is not used as local resolver
API_PORT="0"
else
# otherwise it is an insecure (plain HTTP) connection
API_PROT="http"
API_PORT="${port}"
fi fi
if [ ! "${API_PORT}" = "0" ]; then # Iterate over space-separated list of URLs
# If the port is of form "ip:port", we need to remove everything before while [ -n "${chaos_api_list}" ]; do
# the last ":" in the string, e.g., "[::]:80" -> "80" # Get the first URL
if [ "${API_PORT#*:}" != "${API_PORT}" ]; then API_URL="${chaos_api_list%% *}"
API_PORT="${API_PORT##*:}" # Strip leading and trailing quotes
fi API_URL="${API_URL%\"}"
API_URL="${API_URL#\"}"
API_URL="${API_PROT}://localhost:${API_PORT}/api" # Test if the API is available at this URL
availabilityResonse=$(curl -skS -o /dev/null -w "%{http_code}" "${API_URL}/auth") availabilityResonse=$(curl -skS -o /dev/null -w "%{http_code}" "${API_URL}auth")
# Test if http status code was 200 (OK), 308 (redirect, we follow) 401 (authentication required) # Test if http status code was 200 (OK), 308 (redirect, we follow) 401 (authentication required)
if [ ! "${availabilityResonse}" = 200 ] && [ ! "${availabilityResonse}" = 308 ] && [ ! "${availabilityResonse}" = 401 ]; then if [ ! "${availabilityResonse}" = 200 ] && [ ! "${availabilityResonse}" = 308 ] && [ ! "${availabilityResonse}" = 401 ]; then
# API is not available at this port/protocol combination # API is not available at this port/protocol combination
API_PORT="0" API_PORT=""
else else
# API is available at this port/protocol combination # API is available at this URL combination
break break
fi fi
fi
# If the loop has not been broken, remove the first port from the list # Remove the first URL from the list
# and get the next port local last_api_list
ports="${ports#*,}" last_api_list="${chaos_api_list}"
port="${ports%%,*}" chaos_api_list="${chaos_api_list#* }"
# If the list did not change, we are at the last element
if [ "${last_api_list}" = "${chaos_api_list}" ]; then
# Remove the last element
chaos_api_list=""
fi
done done
# if API_PORT is 0, no working API port was found # if API_PORT is empty, no working API port was found
if [ "${API_PORT}" = "0" ]; then if [ -n "${API_PORT}" ]; then
echo "API not available at: ${API_URL}" echo "API not available at: ${API_URL}"
echo "Exiting." echo "Exiting."
exit 1 exit 1
fi fi
} }
Authenthication() { Authentication() {
# Try to authenticate # Try to authenticate
LoginAPI LoginAPI
@ -96,7 +94,7 @@ Authenthication() {
} }
LoginAPI() { LoginAPI() {
sessionResponse="$(curl -skS -X POST "${API_URL}/auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )" sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )"
if [ -z "${sessionResponse}" ]; then if [ -z "${sessionResponse}" ]; then
echo "No response from FTL server. Please check connectivity" echo "No response from FTL server. Please check connectivity"
@ -108,11 +106,11 @@ LoginAPI() {
} }
DeleteSession() { DeleteSession() {
# if a valid Session exists (no password required or successful authenthication) and # if a valid Session exists (no password required or successful Authentication) and
# SID is not null (successful authenthication only), delete the session # SID is not null (successful Authentication only), delete the session
if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then
# Try to delete the session. Omit the output, but get the http status code # Try to delete the session. Omit the output, but get the http status code
deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}/auth" -H "Accept: application/json" -H "sid: ${SID}") deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}auth" -H "Accept: application/json" -H "sid: ${SID}")
case "${deleteResponse}" in case "${deleteResponse}" in
"200") printf "%b" "A session that was not created cannot be deleted (e.g., empty API password).\n";; "200") printf "%b" "A session that was not created cannot be deleted (e.g., empty API password).\n";;

View file

@ -121,14 +121,14 @@ Main(){
# or b) for the /search endpoint (webserver.api.searchAPIauth) no authentication is required. # or b) for the /search endpoint (webserver.api.searchAPIauth) no authentication is required.
# Therefore, we try to query directly without authentication but do authenticat if 401 is returned # Therefore, we try to query directly without authentication but do authenticat if 401 is returned
data=$(GetFTLData "/search/${domain}?N=${max_results}&partial=${partial}") data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
if [ "${data}" = 401 ]; then if [ "${data}" = 401 ]; then
# Unauthenticated, so authenticate with the FTL server required # Unauthenticated, so authenticate with the FTL server required
Authenthication Authentication
# send query again # send query again
data=$(GetFTLData "/search/${domain}?N=${max_results}&partial=${partial}") data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
fi fi
GenerateOutput "${data}" GenerateOutput "${data}"