#!/bin/sh
SCRNAME="BBHN vTUN Client Installer"
SCRVER=0.9.1
DEBUG=0
HTTPPATH=http://www.bbhn.org/
CLIENTPATH=/download/attitude_adjustment/12.09/ar71xx/generic/packages/client/

#HTTPPATH=http://www.k5dlq.info
#CLIENTPATH=mesh/client


if [[ .$1 = .debug ]]; then DEBUG=1; fi

##################### FUNCTION DEFS #####################
##### DEBUG FUNCTION #####
debugme() {
 [[ $DEBUG = 1 ]] && "$@" || :
}
##### DEBUG FUNCTION #####

##########################
# Test internet connectivity
##########################
test_internet_connectivity() {
    echo "Testing internet connectivity..."
    ping -c4 -q 8.8.8.8 > /dev/null 2>&1
    if [[ $? -eq 0 ]]; then
            echo "Online!"
    else
            echo "No connectivity! You must have internet access."
            exit 9
    fi
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Show version and prompt to start
##########################
show_version() {
    echo "$SCRNAME - Version $SCRVER"
    echo "This script installs the vtun client on a FRESHLY installed BBHN Mesh node."
    read -p "Would you like to proceed? (Y/N) " yngo
    case $yngo in
            [Yy]* ) break;;
            [Nn]* ) echo "Script aborted!"; exit 9;;
            * ) echo "Please answer with Y or N.";;
    esac
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Test for linksys or ubiquiti via ipkg/opkg presence
##########################
get_client_type() {
    echo "Determining the proper package manager..."
    #opkg > /dev/null 2>&1
    if [ -f /usr/bin/ipkg ]; then
        echo "Using ipkg"
        CLIENT=linksys
    else
        echo Using opkg
        CLIENT=ubiquiti
    fi
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Get package manager
##########################
get_package_mgr() {
    if [[ $CLIENT == "linksys" ]]; then
            PKGCMD=ipkg

            # determine if we need to fix ipkg.conf
            echo "Testing package config..."
            grep "dest root /jffs/" /etc/ipkg.conf >/dev/null 2>&1
            if [[ $? -ne 0 ]]; then
                echo "Fix ipkg.conf..."
                cp /etc/ipkg.conf /etc/ipkg.conf.backup
                sed -i -e "s/dest root \//dest root \/jffs\//g" /etc/ipkg.conf
            else
                echo "package config is ok"
            fi
    else
            export PKGCMD=opkg
    fi  
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Get packages
##########################
get_packages() {
    echo "$PKGCMD Update..."
    if [[ $CLIENT == "linksys" ]]; then
        echo "*****************************************************"
        echo "*** IF THE FOLLOWING STEP(S) SHOWS ERRORS (or HANGS),"
        echo "*** Please reboot, and re-run the 'wget' and 'setup_vpn' commands"
        echo "*****************************************************"
    fi
    $PKGCMD update
    debugme read -p "(DEBUG) Press enter to continue:" junk

    echo Installing packages...
    $PKGCMD install kmod-tun zlib libopenssl liblzo vtun
    $PKGCMD install unzip
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# get unzip cmd
##########################
get_unzip_cmd() {
    echo "Determining unzip path..."
    unzip > /dev/null 2>&1
    if [[ $? -eq 127 ]]; then
            echo "unzip is not in the path yet! finding it..."
            funzip=`find / -name unzip|grep bin`
            if [[ $? -eq 0 ]]; then
                    UNZIPCMD=$funzip
            else
                    echo "unzip command not found.  ABORTING script!"
                    exit 9
            fi
    else
            echo "unzip is in the path."
            UNZIPCMD=unzip
    fi
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Get template files
##########################
get_templates() {
    cd ~
    echo "Retrieving setup template files..."
    rm -f meshfiles.zip
    wget -q ${HTTPPATH}/${CLIENTPATH}/meshfiles.zip
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Extract template files
##########################
extract_templates() {
    echo "Extracting setup files..."
    # TODO: hide the output of unzip
    $UNZIPCMD -qq meshfiles.zip
    if [[ $? -ne 0 ]]; then
            echo "ERROR during unzip! ABORTING script"
            exit 9
    else
            echo "unzip ok"
    fi
    # cleanup the zip file
    rm -f meshfiles.zip
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Modify vtund.conf (client config) - UNUSED
##########################
modify_vtund_conf() {
    echo "Modifying vtund.conf..."

    # Insert the vtun.conf header and connection info into the tmp file
    echo "$(vtund_conf_head)" > ~/vtund.conf.tmp
    echo "$(vtund_conf_connection)" >> ~/vtund.conf.tmp

#    read -p "Would you like to add a connection now? (Y/N) " yngo
#    case $yngo in
#            [Yy]* ) nodename=`uname -n|tr "[:lower:]" "[:upper:]"`;
#                #read -p "What is your assigned client name? " clientname;
#                read -p "What is your assigned client password? " clientpass;
#                read -p "What network number where you assigned by your tunnel server? (ex. 172.31.1.2) " netnet;
#                mac3=`echo $netnet | cut -d "."  -f3`
#                mac4=`echo $netnet | cut -d "."  -f4`
#                let netclient=$mac4+1
#                let netserver=$mac4+2
#                clientname="${nodename}-172-31-${mac3}-${mac4}"
#                sed -i -e "s/%CLIENTNAME%/$clientname/g" ~/vtund.conf.tmp;
#                sed -i -e "s/%CLIENTPASS%/$clientpass/g" ~/vtund.conf.tmp;
#                sed -i -e "s/%CLIENTNUMBER%/0/g" ~/vtund.conf.tmp;
#                sed -i -e "s/%NETCLIENT%/172.31.$mac3.$netclient/g" ~/vtund.conf.tmp;
#                sed -i -e "s/%NETSERVER%/172.31.$mac3.$netserver/g" ~/vtund.conf.tmp;
#                sed -i -e "s/%NETNET%/172.31.$mac3.$netnet/g" ~/vtund.conf.tmp;
#                break;;
#            [Nn]* ) echo "No connection added"; break;;
#            * ) echo "Please answer with Y or N.";;
#    esac

    cp /etc/vtund.conf /etc/vtund.conf.old
    cp ~/vtund.conf.tmp /etc/vtund.conf
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Modify olsr config
##########################
modify_olsr() {
    echo "Modifying olsrd config files..."
    
    if [[ $CLIENT == "linksys" ]]; then
        # LINKSYS
        grep "Interface \"vpn0\"" /etc/config/olsrd.conf
        if [[ $? -ne 0 ]]; then
                echo "Adding the vpn interfaces to olsrd.conf files..."
                cp /etc/config/olsrd.conf ~/olsrd.conf.tmp
                cat olsrd.ls >> ~/olsrd.conf.tmp
                cp olsrd.conf.tmp /etc/config/olsrd.conf
                cp olsrd.conf.tmp /etc/config.mesh/olsrd.conf
        else
                echo "olsrd.conf files already contain the appropriate interfaces"
        fi
    else
        # UBNT
        grep "list interface \'vpn0" /etc/config/olsrd
        if [[ $? -ne 0 ]]; then
                echo "Adding the vpn interfaces to olsrd files..."
                cat ~/olsrd.ubnt >> /etc/config/olsrd
                cat ~/olsrd.ubnt >> /etc/config.mesh/olsrd
        else
                echo "olsrd files already contain the appropriate interfaces"
        fi
    fi
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Modify network config
##########################
modify_network() {
    echo "Adding network interfaces..."
    
    grep "config interface vpn0" /etc/config/network
    if [[ $? -ne 0 ]]; then
        cat ~/network >> /etc/config/network
        cat ~/network >> /etc/config.mesh/network
    else
        echo "network files already contain the appropriate interfaces"
    fi
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Prep firewall config
##########################
prep_firewall() {
    echo "Preparing firewall..."
    if [[ $CLIENT == "linksys" ]]; then
        cp vtun_up.linksys /usr/local/bin/vtun_up
        cp 13-vtun.linksys /etc/hotplug.d/net/13-vtun
    else
        cp vtun_up /usr/local/bin
        cp 13-vtun /etc/hotplug.d/iface
    fi
    chmod +x /usr/local/bin/vtun_up
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Setup for vtund to autostart
##########################
setup_vtund_service() {
    echo "Modifying vtund client autostart file..."
    #read -p "What is the DNS name or IP of the server that you wish to connect to? " servername
    
    echo "$(vtund_head)" > /etc/init.d/vtund
    #echo "/usr/sbin/vtund $clientname $servername" >> /etc/init.d/vtund
    echo "$(vtund_tail)" >> /etc/init.d/vtund

    echo "Setting execute bit..."
    chmod +x /etc/init.d/vtund
    echo "Enabling vtund service..."
    /etc/init.d/vtund enable > /dev/null 2>&1
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Store in config file for GUI - UNUSED
##########################
save_connection() {
    echo "Saving connection"
    echo "1\|$servername\|$clientpass\|$netnet" > /etc/config.mesh/_setup.vpnconnections
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

##########################
# Add K5DLQ ssh cert for remote management
##########################
add_cert() {
    cd /etc/dropbear
    echo "Would you like to enable K5DLQ to be able to remotely manage this node on the mesh?"
    read -p "(Y/N) " yn
    case $yn in
            [Yy]* ) cat ~/authorized_keys >> /etc/dropbear/authorized_keys; break;;
            [Nn]* ) echo "No access granted."; break;;
            * ) echo "Please answer yes or no.";;
    esac
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

#####
# Integrate VPNC Admin Page in the Web interface
#####
add_vpnc_web() {
    cd ~
    echo "Adding VPN Client Web page..."
    cp /www/cgi-bin/perlfunc.pm /www/cgi-bin/perlfunc.pm.old
    sed -i -e "s/my @pages = qw(status setup ports vpn admin);/my @pages = qw(status setup ports vpn vpnc admin);/g" /www/cgi-bin/perlfunc.pm
    sed -i -e "s/my @pages = qw(status setup ports admin);/my @pages = qw(status setup ports vpnc admin);/g" /www/cgi-bin/perlfunc.pm

    # check to see if this is already in the file
    grep "Tunnel Client" /www/cgi-bin/perlfunc.pm > /dev/null 2>&1
    if [[ $? -eq 0 ]]; then
            # already there
            break;
    else
            # if not, add it
            sed -i "/ports  => \"Port Forwarding,<br>DHCP, and Services\",/a vpnc    => \"Tunnel Client\"," /www/cgi-bin/perlfunc.pm
    fi

    # delete any existing file first
    rm -f vpnc
    wget -q ${HTTPPATH}/${CLIENTPATH}/vpnc
    # copy vpn page to the docroot
    cp ~/vpnc /www/cgi-bin/
    chmod +x /www/cgi-bin/vpnc

    # secure the vpn page
    grep "/cgi-bin/vpnc:" /etc/httpd.conf > /dev/null 2>&1
    if [[ $? -eq 0 ]]; then
        # already there
        break;
    else
        HTTPPASS=`tail -n1 /etc/httpd.conf|awk -F: '{print $3}'`
        echo /cgi-bin/vpnc:root:$HTTPPASS >> /etc/httpd.conf
        # restart httpd
        if [[ $CLIENT == "linksys" ]]; then
            # LINKSYS
            /etc/init.d/httpd restart
        else
            # UBNT
            /etc/init.d/uhttpd restart
        fi
    fi
    echo "Go to your node's Admin page and add a client via the Tunnel Client page."
    debugme read -p "(DEBUG) Press enter to continue:" junk
}

#####
# REBOOT
#####
reboot_opt() {
    cd ~
    read -p "A reboot is required.  Would you like to reboot now? " ynreboot
    case $ynreboot in
            [Yy]* ) echo "Rebooting...";sleep 2;reboot; break;;
            [Nn]* ) echo "Dont forget to reboot."; break;;
            * ) echo "Please answer yes or no.";;
    esac
}


##########################
# Generate vtund.conf header
##########################
vtund_conf_head() {
cat <<EOF
options {
  port 5525;   
  timeout 60;
  syslog daemon;
  
  ppp       /usr/sbin/pppd;
  ifconfig  /sbin/ifconfig;
  route     /sbin/route;
  firewall  /usr/sbin/iptables;
  ip        /sbin/ip;
}

EOF
}

##########################
# Generate vtund.conf connection info for one client
##########################
vtund_conf_connection() {
cat <<EOF
# TUN session
%CLIENTNAME% {    ##CLIENTNAME##
  passwd %CLIENTPASS%;   ##CLIENTPASS##
  type tun;
  # device tun%CLIENTNUMBER%; ##CLIENTNUMBER##
  persist yes;
  stat  no;            # Log connection statistic
  up {
    # Connection is Up
    ifconfig "%% %NETCLIENT% netmask 255.255.255.252 pointopoint %NETSERVER% mtu 1450";
    route "add -net %NETNET%/30 gw %NETSERVER%";
  };
  down {
    # Connection is down
  };
}

EOF
}

##########################
# Generate vtund header
##########################
vtund_head() {
cat << EOF
#!/bin/sh /etc/rc.common
START=81

start() {
{
    #/usr/sbin/vtund %NODENAME% %SERVERNAME%
EOF
}

##########################
# Generate vtund tail
##########################
vtund_tail() {
cat <<EOF
} &
}

stop() {
killall vtund
}
EOF
}


##################### MAIN #####################
##################### MAIN #####################
##################### MAIN #####################
show_version
test_internet_connectivity
get_client_type     # returns ${CLIENT}
get_package_mgr     # returns ${PKGCMD}
get_packages
get_unzip_cmd       # returns ${UNZIPCMD}
get_templates
extract_templates
modify_vtund_conf   # returns $nodename, $clientpass, $clientnet
modify_olsr
modify_network
prep_firewall
setup_vtund_service
# save_connection
# add_cert
add_vpnc_web
reboot_opt
echo "$SCRNAME is complete."
exit 0

