#!/bin/sh
# helper script to resolve domains for adding to banIP-related IPSets
# Copyright (c) 2020-2021 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.

# (s)hellcheck exceptions
# shellcheck disable=1091,3040

export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
set -o pipefail

. "/lib/functions.sh"

ban_src_name="${1}"
ban_src_file="${2}"
ban_tmpbase="$(uci_get banip global ban_tmpbase "/tmp")"
ban_backupdir="$(uci_get banip global ban_backupdir "${ban_tmpbase}/banIP-Backup")"
ban_proto4_enabled="$(uci_get banip global ban_proto4_enabled "0")"
ban_proto6_enabled="$(uci_get banip global ban_proto6_enabled "0")"
ban_ipset_cmd="$(command -v ipset)"
ban_lookup_cmd="$(command -v nslookup)"
ban_logger_cmd="$(command -v logger)"
ban_cnt_err="0"
ban_message=""

rm -f "${ban_backupdir}/banIP.${ban_src_name}_addon_4" "${ban_backupdir}/banIP.${ban_src_name}_addon_6"
while read -r domain; do
	result="$(
		"${ban_lookup_cmd}" "${domain}" 2>/dev/null
		printf "%s" "${?}"
	)"
	if [ "$(printf "%s" "${result}" | tail -1)" = "0" ]; then
		ips="$(printf "%s" "${result}" | awk '/^Address[ 0-9]*: /{ORS=" ";print $NF}')"
		for ip in ${ips}; do
			for proto in "4" "6"; do
				if { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] &&
					[ -n "$(printf "%s" "${ip}" | awk '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print $1}')" ]; } ||
					{ [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ] && [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] &&
						[ -n "$(printf "%s" "${ip}" | awk '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{print $1}')" ]; }; then
					printf "%s\n" "add ${ban_src_name}_${proto} ${ip}" >>"${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}"
				fi
			done
		done
		[ -n "${ips}" ] && "${ban_logger_cmd}" -p "debug" -t "banIP-resolve [${$}]" "added IPs of '${domain}' to ${ban_src_name} (${ips})" 2>/dev/null
	else
		ban_cnt_err=$((ban_cnt_err + 1))
	fi
done <"${ban_src_file}"

for proto in "4" "6"; do
	if { { [ "${proto}" = "4" ] && [ "${ban_proto4_enabled}" = "1" ]; } || { [ "${proto}" = "6" ] && [ "${ban_proto6_enabled}" = "1" ]; }; } &&
		[ ! -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" ] && [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}.gz" ]; then
		gzip -df "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}.gz" 2>/dev/null
		"${ban_ipset_cmd}" -q -! restore <"${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}"
		ban_message="backup used"
	elif [ -n "$("${ban_ipset_cmd}" -q -n list "${ban_src_name}_${proto}")" ] && [ -s "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" ]; then
		"${ban_ipset_cmd}" -q -! restore <"${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}"
		ban_message="${ban_cnt_err} lookup errors"
	fi
	gzip -f "${ban_backupdir}/banIP.${ban_src_name}_addon_${proto}" 2>/dev/null
done
"${ban_logger_cmd}" -p "info" -t "banIP-resolve [${$}]" "${ban_src_name} domain import has been finished (${ban_message:-"-"})" 2>/dev/null
rm -f "${ban_src_file}"