#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-

ROLE=proxy
export PATH=$PATH:/usr/local/sbin:/usr/local/bin

# . /usr/local/sbin/proxy_whonix_lib.bash || { echo ERROR: loading /usr/local/sbin/proxy_whonix_lib.bash ; exit 2; }
. /usr/local/bin/proxy_ping_lib.bash || \
    { echo ERROR: loading /usr/local/bin/proxy_ping_lib.bash ; exit 2; }

## proxy_guest_firewall_config -- /etc/firewall.conf.ws.new
proxy_guest_firewall_config () {
    . /usr/local/sbin/proxy_whonix_guest_workstation-firewall.bash || return 2$?
    source_config_folder
    iptables_cmd="echo iptables"
    ip6tables_cmd="echo # ip6tables"
    main > /etc/firewall.conf.ws.new

    return $?
}

## proxy_whonix_guest_config
proxy_whonix_guest_config () {
    return 0
}

## proxy_whonix_guest_start
proxy_whonix_guest_start () {
    local dire=$1

    [ ! -f /etc/init.d/qemu-guest-agent ] || \
    proxy_rc_service qemu-guest-agent status >/dev/null \
	|| proxy_rc_service qemu-guest-agent start || return 2$?

    return 0
}

## proxy_whonix_guest_test
proxy_whonix_guest_test () {
    [ -e /dev/virtio-ports/org.qemu.guest_agent.0 ] || \
	echo WARN: /dev/virtio-ports/org.qemu.guest_agent.0 not created
    proxy_rc_service qemu-guest-agent status
    
    return 0
}

## proxy_whonix_gateway_config
proxy_whonix_gateway_config () {
    proxy_whonix_dnsmasq_config gateway 10.0.2.15
    return 0
}

## proxy_whonix_dnsmasq_config
proxy_whonix_dnsmasq_config () {
    local dire

    [ "$#" -eq 0 ] || dire=$1
    [ -z "$dire" ] && MODE="$( proxy_whonix_mode )" && dire=$MODE
    [ -n "$MODE" ] || MODE=host

    proxy_dest_port_wlan_config
    [ -z "$PORT" -o -z "$DEST" ] && return 1

    # 9040 - no wgetrc polipo
    # need dnsmasq to 127
    file=/etc/dnsmasq.conf
    if [ ! -f $file.$dire ] ; then
        cp -p $file $file.$dire
	cat >> $file.conf <<EOF
log-facility=/var/log/dnsmasq.log
no-resolv
listen-address=127.0.0.1
server=${DEST}#$PORT
port=53
# wlan4
interface=$PROXY_WLAN
bind-interfaces
no-dhcp-interface=$PROXY_WLAN
EOF
      fi
    return 0
}

## proxy_whonix_polipo_config
proxy_whonix_polipo_config () {
    local dire
    local file
    [ "$#" -eq 0 ] &&  { echo ERROR: proxy_whonix_polipo_config no dire ; return 1; }
    dire=$1
    
    file=/etc/polipo/config
    if [ $dire = whonix ]; then
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
proxyAddress=127.0.0.1
proxyPort=3128
proxyName=127.0.0.1
socksParentProxy=10.0.2.15:9050
socksProxyType=socks5
#?ssocksUserName=foo
EOF
	fi
    else	
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
proxyAddress=127.0.0.1
proxyPort=3128
proxyName=127.0.0.1
socksParentProxy=${DEST}:$PORT
socksProxyType=socks5
EOF
	fi
    fi
    return 0
}

## proxy_whonix_polipo_config
proxy_whonix_polipo_config () {
    local dire
    local file
    dire=$1 ; shift

    file=/etc/polipo/config
    if [ $dire = whonix ]; then
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
proxyAddress=127.0.0.1
proxyPort=3128
proxyName=127.0.0.1
socksParentProxy=10.0.2.15:9050
socksProxyType=socks5
#?ssocksUserName=foo
EOF
	fi
    else	
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
proxyAddress=127.0.0.1
proxyPort=3128
proxyName=127.0.0.1
socksParentProxy=${DEST}:$PORT
socksProxyType=socks5
EOF
	fi
    fi
    return 0
}

## proxy_whonix_privoxy_config
proxy_whonix_privoxy_config () {
    local dire
    local file
    dire=$1 ; shift

    file=/etc/privoxy/config
    if [ $dire = whonix ]; then
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
listen-address  127.0.0.1:3128
forward-socks5t   /               10.0.2.15:9050 .
EOF
	fi
    else	
	if [ ! -f $file.$dire ] ; then
            cp -p $file $file.$dire
	    cat >> $file.conf <<EOF
listen-address  127.0.0.1:3128
forward-socks5t   /               127.0.0.1:9050 .
EOF
	fi
    fi
    return 0
}

## proxy_whonix_dnsmasq_config
proxy_whonix_dnsmasq_config () {
    local dire

    [ "$#" -eq 0 ] && set - tor
    dire=$1 ; shift
    proxy_dest_port_wlan_config $*
    [ -z "$PORT" -o -z "$DEST" ] && return 1

    # 9040 - no wgetrc
    # need dnsmasq to 127
    file=/etc/dnsmasq.conf
    if [ ! -f $file.$dire ] ; then
        cp -p $file $file.$dire
	cat >> $file.$dire <<EOF
log-facility=/var/log/dnsmasq.log
no-resolv
listen-address=127.0.0.1
server=${DEST}#$PORT
port=53
# wlan4
interface=$PROXY_WLAN
bind-interfaces
no-dhcp-interface=$PROXY_WLAN
EOF
      fi
    return 0
}

## proxy_whonix_tor_config
proxy_whonix_tor_config () {
    proxy_host_tor_config tor 127.0.0.1
    return $?
}

## proxy_host_tor_config
proxy_host_tor_config () {
    local dir
    local file
    dire=tor
    DEST=127.0.0.1
    PORT=9050

#?    [ -z "$DEST" ] && proxy_dest_port_wlan_config || return 1$?

    [ -z "$PORT" -o -z "$DEST" ] && return 2
    proxy_whonix_polipo_config $dire || return 3$?
    proxy_whonix_dnsmasq_config $dire || return 4$?

    if proxy_ping_online ; then
	proxy_ping_test_resolv $dire || { echo ERROR: proxy_host_tor_config 5$?; return 5 ; }
    fi
    
    return 0
}

## proxy_host_from_config
proxy_host_whonix_config () {
    local dire=whonix
    local file
    
    proxy_dest_port_wlan_config || return 1$?
    DEST=10.0.2.15
    PORT=9053
    [ -z "$PORT" -o -z "$DEST" ] && return 2
    proxy_whonix_polipo_config $dire
    proxy_ping_test_resolv $dire || return 4$?
    proxy_whonix_dnsmasq_config $dire || return 5$?
            
    return 0
}

## proxy_host_gateway
proxy_whonix_gateway () {
    local dire=gateway
    debug proxy_whonix_gateway $dire

    PROXY_WLAN=$( proxy_get_if ) || return 1$?
    proxy_whonix_config $dire || return 2$?

    # works?
    proxy_ping_set_resolv gateway
            
    return 0
}

## proxy_whonix_from_config
proxy_whonix_config () {
    local dire=$1
    [ -z "$DEST" ] && proxy_dest_port_wlan_config

    if [ ! -f /etc/tor/torsocks.conf.$dire ] ; then
       cp -p /etc/tor/torsocks.conf /etc/tor/torsocks.conf.$dire
       # TorAddress 127.0.0.1
       # TorPort 9050
      fi
    sed -e "s@^#* *TorAddress.*@TorAddress $DEST@" -i /etc/tor/torsocks.conf
    sed -e "s@^#* *TorPort.*@TorPort 9050@" -i /etc/tor/torsocks.conf
    
    # proxy_whonix_start_wget

    proxy_host_${dire}_config 

    return $?
}

## proxy_ws_whonix_config
proxy_ws_whonix_config () {
    local dir=ws

    DEST=10.152.152.10
    PROXY_WLAN=eth0
    proxy_host_whonix_config $dire $DEST 9053 $PROXY_WLAN
    
    return $?
}

## proxy_whonix_libvirt_status
proxy_whonix_libvirt_status () {
    proxy_rc_service libvirtd status >/dev/null || \
	proxy_rc_service libvirtd start || \
	echo WARN: libvirtd crashed - see /var/log/libvirt/libvirtd.log # 2>&1|tee $WLOG
    proxy_libvirt_status
    return 0
}

## proxy_whonix_libvirt_start
proxy_whonix_libvirt_start () {

    return 0
}

## proxy_whonix_libvirt_start
proxy_whonix_libvirt_start () {
    local domain
    [ "$#" -ge 1 ] && domain=$1

    if [ ! -e /run/libvirt/libvirt-sock ] || ! proxy_rc_service libvirtd status >/dev/null ; then
	cp /dev/null /var/log/libvirt/libvirtd.log
        /etc/init.d/libvirtd status
        retval=$?
	[ $retval -eq 32 ] && WARN libvirtd crashed - zapping && /etc/init.d/libvirtd zap
	[ $retval -eq 0 ]  || /etc/init.d/libvirtd start || return 5$? # error: Failed to start livirtd
	proxy_rc_service libvirtd start || return 3
	sleep $DELAY
    fi
    proxy_libvirt_no_autostart
    proxy_libvirt_start
    proxy_libvirt_status
    proxy_virsh net-list | grep -q Whonix-Internal || virsh net-start Whonix-Internal || return 3
    proxy_virsh net-list | grep -q Whonix-External || virsh net-start Whonix-External || return 4

    [ -z "$domain" ] && domain="$( proxy_testforge_get_gateway_dom )"
    [ -z "$domain" ] && echo WARN: null  proxy_testforge_get_gateway_dom && \
	domain=Whonix-Gateway && \
	echo INFO: set proxy_testforge_get_gateway_dom $domain
    proxy_libvirt_list | grep -v grep | grep "$domain" || \
	virsh start $domain || {
	    ret=$?
	    echo ERROR: proxy_whonix_libvirt_start failed virsh start $domain ret=$ret
	    return 5$ret
	}
    
    return 0
}

## proxy_whonix_test
proxy_whonix_test () {
    local dire
    DEBUG proxy_whonix_test $dire
    [ "$#" -eq 0 ] && dire=$MODE || dire=$1

    [ $dire = ws -o $dire = workstation ] && dire=vda

    if [ $dire = client ] ; then
	:
	# dunno - look at netstat? -nle4
	
    elif [ $dire = vda -o $dire = gateway ] ; then
	proxy_whonix_guest_test

    elif [ $dire = tor ] ; then
	proxy_rc_service tor status >/dev/null || \
	    { echo ERROR: $prog tor is not running ; return 2 ; }

	/usr/local/bin/proxy_ping_test.bash to_tor || return 6$?

    elif [ $dire = whonix ] ; then
	proxy_libvirt_no_autostart
	proxy_libvirt_clean_virbr1_rules
	
	proxy_whonix_get_gateway_dom
	[ -z "$GATEW_DOM" ] && echo WARN: $prog DOM proxy_whonix_get_gateway_dom assuming Whonix-Gateway && DOM=Whonix-Gateway || DOM=$GATEW_DOM
	
	proxy_virsh list | grep -q $DOM || { echo ERROR: $prog $DOM not running ; return 2 ; }
        
	/usr/local/bin/proxy_ping_test.bash from_tor || return 6$?
    fi

    #? gateway
    if [ $dire = whonix -o $dire = vda -o $dire = tor ] ; then
	proxy_rc_service polipo status >/dev/null >/dev/null || \
	    { echo ERROR: $prog polipo not running ; return 4 ; }
	/usr/local/bin/proxy_ping_test.bash polipo || return 9$?
    elif [ $dire = host -o $dire = tor ] ; then
	proxy_rc_service privoxy status >/dev/null >/dev/null || \
	    { echo ERROR: $prog privoxy not running ; return 4 ; }
	/usr/local/bin/proxy_ping_test.bash privoxy || return 9$?
    fi

    if [ $dire = vda -o $dire = ws -o $dire = workstation ] ; then
	    proxy_clobber_resolv_local 10.152.152.10
    elif [ $dire = gateway -o $dire = whonix -o $dire = tor ] ; then
	proxy_rc_service dnsmasq status 2>/dev/null >/dev/null || \
	    { echo ERROR: $prog dnsmasq not running ; return 5 ; }
	proxy_clobber_resolv_local 127.0.0.1
    fi
    /usr/local/bin/proxy_ping_test.bash dns # || return 9$?
    
    /usr/local/bin/proxy_ping_test.bash $dire || return 6$?
    
    return 0
}

# Weher was this
## rc_host_symlink_etc_fstab
rc_host_symlink_etc_fstab () {
    grep -q root=/dev/vda /proc/cmdline
    PROXY_IS_VDA=$?
if [ $PROXY_IS_VDA -eq 0 ] ; then
    [ -h /etc/fstab ] && [ -f /etc/fstab.vda ] && \
	rm -f /etc/fstab && ln -s /etc/fstab.vda /etc/fstab
    return 1
#  else
#    [ -h /etc/fstab ] && [ -f /etc/fstab.4TA ] && \
#	rm -f /etc/fstab && ln -s /etc/fstab.4TA /etc/fstab
 fi
    
    return 0
}

## proxy_vda_config
proxy_vda_config () {

    rc_host_symlink_etc_fstab        
    sed -e 's/^#x1/x1/' -i /etc/inittab #

    if false ; then    
    sed -e 's/^#//' -i $PREFIX/etc/modules_load.d/vda*conf
    if [ ! -h /etc/modules_load.d/vda_mods.conf ] ; then
	ln -s  $PREFIX/etc/modules_load.d/vda*conf /etc/modules_load.d/
    fi
    fi
    if false ; then    
    [ -f /etc/firewall.conf.vda ] && \
	cp -p /etc/firewall.conf.vda /etc/firewall.conf
    fi
    return 0
}

## 
old_proxy_vda_config () {

    [ -f /etc/inittab ] && sed -e 's/^#x1/x1/' -i /etc/inittab
    
    return 0
}

## proxy_vda_whonix_config
proxy_vda_whonix_config () {
    local dir=vda

    DEST=10.152.152.10
    PROXY_WLAN=eth0
    proxy_host_whonix_config $dire $DEST 9053 $PROXY_WLAN
    
    return $?
}

## proxy_quest_config
proxy_quest_config () {

    proxy_vda_config
 
    sed -e 's/^#//' -i $PREFIX/etc/modules_load.d/vda*conf
    if [ ! -h /etc/modules_load.d/vda_mods.conf ] ; then
	cp -np  $PREFIX/etc/modules_load.d/vda*conf /etc/modules-load.d/
    fi
    return 0
}

## proxy_whonix_dnsmasq_start
proxy_whonix_dnsmasq_start () {
    local dire
    local service=dnsmasq

    [ "$#" -eq 0 ] || dire=$1
    [ -z "$dire" ] && MODE="$( proxy_whonix_mode )" && dire=$MODE
    [ -n "$MODE" ] || MODE=host

    DEBUG proxy_whonix_dnsmasq_start $dire $PROXY_WLAN

    proxy_whonix_config $dire || return 1$?

    PROXY_WLAN=$( proxy_get_if )
    [ -z "$PROXY_WLAN" ] && echo ERROR: $prog empty PROXY_WLAN && return 4

    sed -e "s/wlan[0-9]/$PROXY_WLAN/" -i /etc/dnsmasq.conf.$dire
    if diff /etc/dnsmasq.conf.$dire /etc/dnsmasq.conf >/dev/null ; then
	proxy_rc_service dnsmasq status >/dev/null || \
	    proxy_ping_dnsmasq_start || return 8$?
    else
	proxy_rc_service dnsmasq status >/dev/null && \
	    proxy_ping_dnsmasq_stop
	cp -p /etc/dnsmasq.conf.$dire /etc/dnsmasq.conf
	proxy_ping_dnsmasq_start || return 8$?
      fi

    return 0
}

## proxy_whonix_privoxy_start
proxy_whonix_polipo_start () {
    local dire
    local service=polipo
    
    [ $# -eq 1 ] && dire=$1
    [ -z "$dire" ] && dire="$( proxy_whonix_mode )" 
    DEBUG proxy_whonix_start_$service $dire
    
    proxy_whonix_config $dire || \
	echo WARN: proxy_whonix_polipo_start proxy_whonix_config $dire $? # return 1$?

    sed -e "s/wlan[0-9]/$PROXY_WLAN/" -e "s/eth[0-9]/$PROXY_WLAN/" -i /etc/polipo/config.$dire
    
    if ! diff /etc/polipo/config.$dire /etc/polipo/config ; then
	cp -p /etc/polipo/config.$dire /etc/polipo/config
	proxy_rc_service $service restart || return 2$?
    else
	proxy_rc_service $service status >/dev/null || \
	  proxy_rc_service $service start||return 3$
    fi

    return 0
}

## proxy_whonix_host_prepare_blocks
proxy_whonix_host_prepare_blocks () {
    if [ ! -s /etc/firewall.conf.block ] ; then
	if [ -f /usr/local/etc/firewall.conf.block ] ; then
	    echo "WARN: $prog copying /usr/local/etc/firewall.conf.block"
	    cp -p /usr/local/etc/firewall.conf.block /etc/firewall.conf.block
	else
	    echo "ERROR: $prog missing /usr/local/etc/firewall.conf.block"
	    return 1
	fi
    fi
    return 0
}

## proxy_whonix_host_add_block
proxy_whonix_host_add_block () {
    local elt tab ip
    
    # PROXY_WLAN=$( proxy_get_if )
    # [ $? -ne 0 -o -z "$PROXY_WLAN" ] && echo ERROR: $prog null interface && return 1 
    if [ "$#" -eq 0 ] ; then
	proxy_whonix_host_prepare_blocks \| return 1$?
	set - $( cat /etc/firewall.conf.block )
    fi
    # DEBUG "$prog adding $*"
    [ -f  /etc/firewall.conf.newer ] || \
	cp -p /etc/firewall.conf /etc/firewall.conf.newer
    for elt in wlan virbr1 ; do
	[ $elt = wlan ] && tab=INPUT || tab=LIBVIRT_FWI
	grep -q "^# blocks $elt" /etc/firewall.conf.newer || {
	    echo ERROR: maker not found "^# blocks $elt" in /etc/firewall.conf.newer
	    return 2
	    }
	sed -e "/^# blocks $elt/,\$d" /etc/firewall.conf.newer > /etc/firewall.conf.$$
	echo "# blocks $elt" >> /etc/firewall.conf.$$
	for ip in $* ; do
	    grep -q $ip /etc/firewall.conf.block || \
		grep -q $ip /etc/firewall.conf.block.newer || \
		echo $ip >> /etc/firewall.conf.block.newer
	    grep -q -e  "A $tab -s $ip" /etc/firewall.conf.newer && continue
	    echo "-A $tab -s $ip -p tcp -j DROP" >> /etc/firewall.conf.$$
	    DEBUG "$prog -A $tab -s $ip -m tcp -p tcp -j DROP" 
	done
	sed -e "1,/^# blocks $elt/d" /etc/firewall.conf.newer >> /etc/firewall.conf.$$
	mv  /etc/firewall.conf.$$  /etc/firewall.conf.newer
    done
    return 0
}

## proxy_whonix_host_online
proxy_whonix_host_online () {
    [ -n "$PROXY_WLAN" ] || PROXY_WLAN=$( proxy_get_if ) || return 1$?
    [ -z "$PROXY_WLAN" ] && echo ERROR: empty PROXY_WLAN  && return 2
    if [ -x /etc/init.d/NetworkManager ] ; then
    /etc/init.d/NetworkManager status || /etc/init.d/NetworkManager start || return 3
else
    proxy_rc_service NetworkManager status >/dev/null \
	|| proxy_rc_service NetworkManager start || return 3$?
fi
    nm-online -t 0 -x || return 4$?
    
    return 0
}

## proxy_whonix_down - call when the network goes down
proxy_whonix_down () {
#    $PREFIX/bin/proxy_ping_test.bash "$MODE" || return 1$?
    proxy_ping_online && return 0 # dont do anything
    # nothing to do?
    return 0
}

## proxy_whonix_up - call when the network comes up
proxy_whonix_up () {
    #    $PREFIX/bin/proxy_ping_test.bash "$MODE" || return 1$?
    proxy_ping_online || return 0 # dont do anything
    return 0
}

## proxy_whonix_start_wget
proxy_whonix_start_wget () {
    return 0
    if [ -f /etc/wgetrc ] ; then
	sp=https://127.0.0.1:3128
	grep -q ^https_proxy /etc/wgetrc && \
	    sed -e "s@https_proxy.*@https_proxy = $sp@" -i /etc/wgetrc
	grep -q ^https_proxy /etc/wgetrc && \
	    echo "https_proxy = $sp" >> /etc/wgetrc
	grep -q ^http_proxy /etc/wgetrc && \
  	    sed -e "s@http_proxy.*@http_proxy = $sp@" -i /etc/wgetrc
	grep -q ^http_proxy /etc/wgetrc || \
	    echo "http_proxy = $sp" >> /etc/wgetrc
    fi

	sp=http://127.0.0.1:3128
	for elt in http https ; do
	grep -q ^$elt_proxy /etc/wgetrc && \
	    sed -e "s@$elt_proxy.*@$elt_proxy = $sp@" -i /etc/wgetrc || \
		echo "$elt_proxy = $sp" >> /etc/wgetrc
	done


    return 0
}

proxy_libvirt_clean_iptables () {
    local i int dir dcp prot port
    
    for dir in i ; do
	for int in virbr2 virbr1; do
	    dcp=67
	    [ $dir = i ] || dcp=68
	    for port in 53 $dcp ; do
		[ $dir = i ] && table=INP || table=OUT
		for prot in udp tcp; do
		    proxy_iptables_save | grep -q -e "-A LIBVIRT_$table -i $int -p $prot -m $prot --dport $port -j ACCEPT" || continue
		    iptables -D LIBVIRT_$table -$dir $int -p $prot -m $prot --dport $port -j ACCEPT || \
			echo WARN: $?  -D LIBVIRT_$table -$dir $int -p $prot -m $prot --dport $port -j ACCEPT
		done
	    done
	done
    done

    for dir in o ; do
	for int in virbr2 virbr1; do
	    dcp=68
	    [ $dir = o ] || dcp=67
	    for port in 53 68 ; do
		table=OUT
		[ $dir = i ] && table=INP
		for prot in udp tcp; do
		    proxy_iptables_save | grep -q -e "-A LIBVIRT_$table -i $int -p $prot -m $prot --dport $port -j ACCEPT" || continue
		    iptables -D LIBVIRT_$table -$dir $int -p $prot -m $prot --dport $port -j ACCEPT || \
			echo WARN: $?  -D LIBVIRT_$table -$dir $int -p $prot -m $prot --dport $port -j ACCEPT
		done
	    done
	done
    done

    return 0
}

base=proxy_whonix_lib
if [ -x /usr/bin/basename ] && [ $( /usr/bin/basename -- $0 .bash ) = $base ] ; then
    [ "$#" -eq 0 ] && exit 0
    [ "$#" -eq 1 ] && [ "$1" = '-h' -o "$1" = '--help' ] && \
	echo USAGE: $0 && grep '^[a-z].*()\|^## ' $0 | sed -e 's/().*//'|sort && \
	exit 0
    DEBUG $base "$@"
    eval "$@"
    exit $?
  fi
