107 lines
4.3 KiB
Bash
Executable File
107 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# FILE: admin/user/del
|
|
# DESCRIPTION: Delete a user from admin UI
|
|
# USAGE: del $remote_ip $querystring
|
|
# QUERYSTRING: ?t=$token&user=$username&un=$usernumber
|
|
|
|
source /etc/wgapi/config
|
|
ip="${1}"; qs="$(<<<"${2}" tr '&' '\n' | sed 's/?//')"
|
|
|
|
# Check token
|
|
token_fail(){
|
|
printf 'Rejecting admin %s request for new peer due to %s token\n' "${ip}" "${1}" >&2
|
|
printf 'Invalid token\n' | /usr/lib/wgapi/http_res 403; exit
|
|
}
|
|
saved_token="$(grep "${ip}" /var/local/wgapi/tokens | cut -f2)"
|
|
[ "${saved_token}" == "" ] && token_fail 'missing' &
|
|
<<<"${qs}" grep -qx "t=${saved_token}" || token_fail 'mismatched'
|
|
printf '%s token was valid\n' "${ip}" >&2
|
|
|
|
# Check username and usernumber
|
|
username="$(<<<"${qs}" grep -oP 'user=(.*)' | sed 's/^user=//')"
|
|
usernumber="$(<<<"${qs}" grep -oP 'un=(.*)' | sed 's/^un=//')"
|
|
if [[ "${username}" == "" ]]; then
|
|
printf 'ERROR! Username missing!\n' | tee >(cat 1>&2) | /usr/lib/wgapi/http_res 400; exit
|
|
elif [[ "${usernumber}" == "" ]]; then
|
|
printf 'ERROR! Usernumber missing!\n' | tee >(cat 1>&2) |/usr/lib/wgapi/http_res 400; exit
|
|
else
|
|
printf 'Admin %s requested deletion of user "%s" with usernumber "%s"\n' "${ip}" "${username}" "${usernumber}" >&2
|
|
fi
|
|
|
|
# Get all peer IPs
|
|
if ! wg_output="$(sudo /usr/bin/wg show "${TLD}" allowed-ips)"; then
|
|
printf 'ERROR! Wireguard failed!\n' >&2
|
|
/usr/lib/wgapi/http_res 500; exit
|
|
fi
|
|
|
|
# Filter out the user's
|
|
user_peers="$(grep "${IPV4_NET%.*.*}.${usernumber}." <<<"${wg_output}" 2>/dev/null)"
|
|
if [ "${user_peers}" == "" ]; then
|
|
printf "ERROR! Couldn't find any peers for %s!\n" "${IPV4_NET%.*.*}.${usernumber}." >&2
|
|
/usr/lib/wgapi/http_res 500; exit
|
|
fi
|
|
|
|
# Get user peer domains
|
|
if ! peers="$(/usr/lib/wgapi/ips_to_peers tsv <<<"${user_peers}")"; then
|
|
printf 'ERROR! Failed to retrieve domains for peers for %s!\n' "${IPV4_NET%.*.*}.${usernumber}" >&2
|
|
/usr/lib/wgapi/http_res 500; exit
|
|
fi
|
|
|
|
# Run this function in parallel in the while loop below
|
|
# https://stackoverflow.com/a/33058618
|
|
for_server_do() {
|
|
[[ ${server_hostname:0:1} = \# ]] && return # Ignore comments
|
|
server_hostname="${1}"; server_ipv4="${2}"; server_ipv6="${3}"; server_pubkey="${4}"
|
|
server_endpoint="${5}"; server_url="${6}"; server_secret="${7}"
|
|
if [ "${server_hostname}" == "${LOCAL_SERVER}" ]; then
|
|
# Local server
|
|
if /usr/lib/wgapi/wg_peer_del "${pubkey}"; then
|
|
printf 'Deleted %s from local wireguard server.\n' "${domain}" >&2
|
|
else
|
|
printf 'ERROR! Failed to delete %s from local wireguard server!\n' "${domain}" >&2
|
|
# TODO: clear existing progress
|
|
/usr/lib/wgapi/http_res 500; exit
|
|
fi
|
|
else
|
|
# Federated server
|
|
if /usr/lib/wgapi/fed_peer_del "${server_url}" "${server_secret}" "${pubkey}"; then
|
|
printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >&2
|
|
else
|
|
printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2
|
|
/usr/lib/wgapi/http_res 500; exit
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Delete user peers (in parallel)
|
|
delete_peer() {
|
|
domain="${1}"; ipv4="${2}"; ipv6="${3}"; pubkey="${4}"
|
|
username="$(<<<"${domain}" cut -d'.' -f2)"
|
|
printf 'Deleting peer %s\n' "${domain}" >&2
|
|
|
|
# Remove peer from wireguard
|
|
while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey server_endpoint server_url server_secret
|
|
do for_server_do "${server_hostname}" "${server_ipv4}" "${server_ipv6}" "${server_pubkey}" "${server_endpoint}" "${server_url}" "${server_secret}" &
|
|
done </etc/wgapi/servers &
|
|
|
|
# Remove peer from nameserver
|
|
if /usr/lib/wgapi/ns_update_del "${domain:?}" "${ipv4:?}" "${ipv6:?}"
|
|
then printf 'Successfully deleted %s from DNS server.\n' "${domain}" >&2
|
|
else printf 'ERROR! Failed to delete %s %s %s from DNS server!\n' "${domain}" "${ipv4}" "${ipv6}" >&2
|
|
fi
|
|
}
|
|
printf '%s\n' "${peers}" | while IFS=$'\t' read -r domain ipv4 ipv6 pubkey
|
|
do delete_peer "${domain}" "${ipv4}" "${ipv6}" "${pubkey}" &
|
|
[ "$(jobs | wc -l)" -ge "$(nproc)" ] && wait
|
|
done
|
|
|
|
# Delete SSL cert directory
|
|
if ! sudo rm -rf "${SSL_CONFIG_DIR:?}/${username:?}/"; then
|
|
printf 'Failed to delete user SSL directory %s/%s/:\n' "${SSL_CONFIG_DIR}" "${username}" >&2
|
|
fi
|
|
|
|
# Respond to user
|
|
# Do it before updating nameserver and certs because
|
|
# if wireguard worked, there's no going back. The admin
|
|
# can clean up missing records and certs after checking the logs
|
|
printf 'Deleted %s' "${username}" | /usr/lib/wgapi/http_res 202 |