From a0603ad3b701abde6e392a72a407260c012a9a9c Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Tue, 2 May 2017 17:13:55 +1000 Subject: [PATCH 1/2] Update queryFunc() * Allow scanList() to search files using a wildcard by removing quotes wrapped around `${list}` * scanList() will not provide a domain ouput on each string if exact is specified (`grep -l`) * Remove unused processWildcards() function * Return a message if no domain is specified * IDN domains are converted to punycode when running a `pihole -q` search if the `python` package is available, otherwise will revert to current behaviour * Scan Blacklist & Wildcards first, exiting from search if a match is found (Fixes #1330) * Use one `grep` subshell to search for all "*.domains" lists at once (opposed to looping to get every matching file name, and then spawning a `grep` instance for every matching file) * queryFunc() will not return "(0 results)" output from files where no match is found * Sort results based off list number * Return a message if no results are found --- pihole | 83 +++++++++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/pihole b/pihole index 83e13000..eaf4e955 100755 --- a/pihole +++ b/pihole @@ -84,62 +84,45 @@ scanList(){ domain="${1}" list="${2}" method="${3}" - if [[ ${method} == "-exact" ]] ; then - grep -i -E "(^|\s)${domain}($|\s)" "${list}" - else - grep -i "${domain}" "${list}" - fi -} -processWildcards() { - IFS="." read -r -a array <<< "${1}" - for (( i=${#array[@]}-1; i>=0; i-- )); do - ar="" - for (( j=${#array[@]}-1; j>${#array[@]}-i-2; j-- )); do - if [[ $j == $((${#array[@]}-1)) ]]; then - ar="${array[$j]}" - else - ar="${array[$j]}.${ar}" - fi - done - echo "${ar}" - done + if [[ ${method} == "-exact" ]]; then + grep -i -E -l "(^|\/)${domain}($|\/)" ${list} + else + grep -i "${domain}" ${list} + fi } queryFunc() { - domain="${2}" method="${3}" - lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt) - for list in ${lists[@]}; do - if [ -e "${list}" ]; then - result=$(scanList ${domain} ${list} ${method}) - # Remove empty lines before couting number of results - count=$(sed '/^\s*$/d' <<< "$result" | wc -l) - echo "::: ${list} (${count} results)" - if [[ ${count} > 0 ]]; then - echo "${result}" - fi - echo "" - else - echo "::: ${list} does not exist" - echo "" - fi - done - - # Scan for possible wildcard matches - if [ -e "${wildcardlist}" ]; then - local wildcards=($(processWildcards "${domain}")) - for domain in ${wildcards[@]}; do - result=$(scanList "\/${domain}\/" ${wildcardlist}) - # Remove empty lines before couting number of results - count=$(sed '/^\s*$/d' <<< "$result" | wc -l) - if [[ ${count} > 0 ]]; then - echo "::: Wildcard blocking ${domain} (${count} results)" - echo "${result}" - echo "" - fi - done + + # If domain contains non ASCII characters, convert domain to punycode if python exists + # Cr: https://serverfault.com/a/335079 + if [ -z "${2}" ]; then + echo "::: No domain specified" + exit 1 + elif [[ ${2} = *[![:ascii:]]* ]]; then + [ `which python` ] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}") + else + domain="${2}" fi + + # Scan Blacklist and Wildcards + lists="/etc/pihole/blacklist.txt $wildcardlist" + result=$(scanList ${domain} "${lists}" ${method}) + if [ -n "$result" ]; then + echo "$result" + exit 0 + fi + + # Scan Domains lists + result=$(scanList ${domain} "/etc/pihole/*.domains" ${method}) + if [ -n "$result" ]; then + sort -t . -k 2 -g <<< "$result" + else + [ -n "$method" ] && exact="exact " + echo "::: No ${exact}results found for ${domain}" + fi + exit 0 } From 3081c151bd1e88d12ef527d40075cbfc7a18d890 Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Thu, 11 May 2017 09:13:32 +1000 Subject: [PATCH 2/2] Perform EXACT searches on HOSTS lists correctly `\s` on the end may be overkill, but it is the existing scanList() behaviour. --- pihole | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole b/pihole index eaf4e955..6bd5fb1f 100755 --- a/pihole +++ b/pihole @@ -86,7 +86,7 @@ scanList(){ method="${3}" if [[ ${method} == "-exact" ]]; then - grep -i -E -l "(^|\/)${domain}($|\/)" ${list} + grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list} else grep -i "${domain}" ${list} fi