From 0e2b77577dfc23458cd332c22f694de0e80fe15a Mon Sep 17 00:00:00 2001 From: diginc Date: Sat, 13 May 2017 18:43:34 -0500 Subject: [PATCH] adding a alpine compatible list.sh --- alpine.docker | 5 +- s6/alpine-root/usr/bin/list.sh | 235 +++++++++++++++++++++++++++++++++ test/test_bash_functions.py | 5 - test/test_shellcheck.py | 2 +- 4 files changed, 237 insertions(+), 10 deletions(-) create mode 100755 s6/alpine-root/usr/bin/list.sh diff --git a/alpine.docker b/alpine.docker index 35a153d..43b0abe 100644 --- a/alpine.docker +++ b/alpine.docker @@ -38,12 +38,9 @@ RUN mkdir -p /etc/pihole/ && \ chown dnsmasq:root /var/log/pihole.log && \ sed -i "s/@INT@/eth0/" /etc/dnsmasq.d/01-pihole.conf && \ setcap CAP_NET_BIND_SERVICE=+eip `which dnsmasq` && \ + cp -f /usr/bin/list.sh /opt/pihole/list.sh && \ echo 'Done!' - #sed -i 's|"cd /etc/.pihole/ && git describe --tags --abbrev=0"|"cat /etc/pi-hole_version.txt"|g' /var/www/html/admin/footer.php && \ - #sed -i 's|"git describe --tags --abbrev=0"|"cat /etc/AdminLTE_version.txt"|g' /var/www/html/admin/footer.php && \ - #sed -i 's|www-data|nginx|g' /etc/sudoers.d/pihole && \ - # php config start passes special ENVs into ENV PHP_ENV_CONFIG '/etc/php5/fpm.d/envs.conf' ENV PHP_ERROR_LOG '/var/log/nginx/error.log' diff --git a/s6/alpine-root/usr/bin/list.sh b/s6/alpine-root/usr/bin/list.sh new file mode 100755 index 0000000..36e836b --- /dev/null +++ b/s6/alpine-root/usr/bin/list.sh @@ -0,0 +1,235 @@ +#!/usr/bin/env bash +# Pi-hole: A black hole for Internet advertisements +# (c) 2017 Pi-hole, LLC (https://pi-hole.net) +# Network-wide ad blocking via your own hardware. +# +# Whitelists and blacklists domains +# +# This file is copyright under the latest version of the EUPL. +# Please see LICENSE file for your rights under this license. + + + +#globals +basename=pihole +piholeDir=/etc/${basename} +whitelist=${piholeDir}/whitelist.txt +blacklist=${piholeDir}/blacklist.txt +readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" +reload=false +addmode=true +verbose=true + +domList=() +domToRemoveList=() + +listMain="" +listAlt="" + +helpFunc() { + + if [[ ${listMain} == ${whitelist} ]]; then + letter="w" + word="white" + else + letter="b" + word="black" + fi + + cat << EOM +::: Immediately ${word}lists one or more domains in the hosts file +::: +::: Usage: pihole -${letter} domain1 [domain2 ...] +::: +::: Options: +::: -d, --delmode Remove domains from the ${word}list +::: -nr, --noreload Update ${word}list without refreshing dnsmasq +::: -q, --quiet Output is less verbose +::: -h, --help Show this help dialog +::: -l, --list Display your ${word}listed domains +EOM +if [[ "${letter}" == "b" ]]; then + echo "::: -wild, --wildcard Add wildcard entry (only blacklist)" +fi + exit 0 +} + +EscapeRegexp() { + # This way we may safely insert an arbitrary + # string in our regular expressions + # Also remove leading "." if present + echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g" +} + +HandleOther(){ + # First, convert everything to lowercase + domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1") + + #check validity of domain + validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/') + if [ -z "${validDomain}" ]; then + echo "::: $1 is not a valid argument or domain name" + else + domList=("${domList[@]}" ${validDomain}) + fi +} + +PoplistFile() { + #check whitelist file exists, and if not, create it + if [[ ! -f ${whitelist} ]]; then + touch ${whitelist} + fi + for dom in "${domList[@]}"; do + # Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other + if ${addmode}; then + AddDomain "${dom}" "${listMain}" + RemoveDomain "${dom}" "${listAlt}" + if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then + RemoveDomain "${dom}" "${wildcardlist}" + fi + else + RemoveDomain "${dom}" "${listMain}" + fi + done +} + +AddDomain() { + list="$2" + domain=$(EscapeRegexp "$1") + + if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then + + bool=true + #Is the domain in the list we want to add it to? + grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false + + if [[ "${bool}" == false ]]; then + #domain not found in the whitelist file, add it! + if [[ "${verbose}" == true ]]; then + echo "::: Adding $1 to $list..." + fi + reload=true + # Add it to the list we want to add it to + echo "$1" >> "${list}" + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} already exists in ${list}, no need to add!" + fi + fi + + elif [[ "${list}" == "${wildcardlist}" ]]; then + + source "${piholeDir}/setupVars.conf" + #Remove the /* from the end of the IPv4addr. + IPV4_ADDRESS=${IPV4_ADDRESS%/*} + IPV6_ADDRESS=${IPV6_ADDRESS} + + bool=true + #Is the domain in the list? + grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false + + if [[ "${bool}" == false ]]; then + if [[ "${verbose}" == true ]]; then + echo "::: Adding $1 to wildcard blacklist..." + fi + reload=true + echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" + if [[ ${#IPV6_ADDRESS} > 0 ]] ; then + echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" + fi + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} already exists in wildcard blacklist, no need to add!" + fi + fi + fi +} + +RemoveDomain() { + list="$2" + domain=$(EscapeRegexp "$1") + + if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then + + bool=true + #Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa + grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false + if [[ "${bool}" == true ]]; then + # Remove it from the other one + echo "::: Removing $1 from $list..." + # Busybox sed compatible case-insensitive domain removal + sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list} + reload=true + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} does not exist in ${list}, no need to remove!" + fi + fi + + elif [[ "${list}" == "${wildcardlist}" ]]; then + + bool=true + #Is it in the list? + grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false + if [[ "${bool}" == true ]]; then + # Remove it from the other one + echo "::: Removing $1 from $list..." + # Busybox sed compatible case-insensitive domain removal + sed -i "$(grep -in "/${domain}/" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list} + reload=true + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} does not exist in ${list}, no need to remove!" + fi + fi + fi +} + +Reload() { + # Reload hosts file + pihole -g -sd +} + +Displaylist() { + if [[ ${listMain} == ${whitelist} ]]; then + string="gravity resistant domains" + else + string="domains caught in the sinkhole" + fi + verbose=false + echo -e " Displaying $string \n" + count=1 + while IFS= read -r RD; do + echo "${count}: ${RD}" + count=$((count+1)) + done < "${listMain}" + exit 0; +} + +for var in "$@"; do + case "${var}" in + "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";; + "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";; + "-wild" | "wildcard" ) listMain="${wildcardlist}";; + "-nr"| "--noreload" ) reload=false;; + "-d" | "--delmode" ) addmode=false;; + "-f" | "--force" ) force=true;; + "-q" | "--quiet" ) verbose=false;; + "-h" | "--help" ) helpFunc;; + "-l" | "--list" ) Displaylist;; + * ) HandleOther "${var}";; + esac +done + +shift + +if [[ $# = 0 ]]; then + helpFunc +fi + +PoplistFile + +if ${reload}; then + Reload +fi + diff --git a/test/test_bash_functions.py b/test/test_bash_functions.py index 11bdb5e..552067b 100644 --- a/test/test_bash_functions.py +++ b/test/test_bash_functions.py @@ -3,11 +3,6 @@ import re DEFAULTARGS = '-e ServerIP="127.0.0.1" ' -# Override these docker command pieces to minimize parameter repititon -@pytest.fixture() -def cmd(request): - return 'tail -f /dev/null' - @pytest.mark.parametrize('args,expected_ipv6,expected_stdout', [ (DEFAULTARGS, True, 'IPv4 and IPv6'), (DEFAULTARGS + '-e "IPv6=True"', True, 'IPv4 and IPv6'), diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py index 7206a13..0de2951 100644 --- a/test/test_shellcheck.py +++ b/test/test_shellcheck.py @@ -7,7 +7,7 @@ run_local = testinfra.get_backend( def test_scripts_pass_shellcheck(): ''' Make sure shellcheck does not find anything wrong with our shell scripts ''' - shellcheck = "find . -name '*.sh' | while read file; do shellcheck -e SC1008 $file; done;" + shellcheck = "find . -name '*.sh' -a ! ( -name 'list.sh' ) | while read file; do shellcheck -e SC1008 $file; done;" results = run_local(shellcheck) print results.stdout assert '' == results.stdout