#!/bin/bash

########################
#
# AUTOMATED MAC OS CORPORATE NETWORK PROXY CONFIGURATION
# @author: Vincent, Koc <vincent.koc@team.telstra.com>
# 
# Set your Configuration Below for
#   - Network Location Names
#   - Bypass Proxy List
#   - Proxy Port Number
#   
# Changelog
#   - 2018.10.17 Updated Proxy Bypass and added Yarn
#   - 2018.10.19 Updated auto-loader moved from Bash profile to the script, added "ALL_PROXY" for some terminal applications
#   - 2018.10.31 Bug-fix on proxy URL
#   - 2018.10.31 Bug-fix resolved issue with NPM, GIT and Yarn not setting proxy
#   - 2019.05.08 Added NoMad auto-launch, ARP cache clear for VPN issues
#   - 2019.05.08 WIP for Tinyproxy bypass for hardcoded apps on proxy
#   - 2019.05.08 PID style temp file with status of proxy for any automation of status of proxy
#   - 2019.05.27 Support for setting and unsetting Corkscrew for SSH proxy support in terminal
#
########################

tconfiglocation_corp='Telstra EDN'
tconfiglocation_vpn='Telstra VPN'
tconfiguser='<Your D NUMBER>'
tconfigproxyhost='127.0.0.1'
tconfigproxyport='8079'
tconfigproxybypass="*.local, local, 127.0.0.*, 169.254/16, localhost, *.localhost, 192.169.*, *.home, *.dev, pi.hole, 10.97.0.193, 10.97.0.194, 10.97.0.230, 10.97.0.233, 149.135.1.*, 149.135.82.*, 149.135.114.122, 149.135.114.123, 149.135.121.*, 149.135.128.*, 169.254/16, *.ae.sda.corp.telstra.com, *.autodiscover.countrywide.telstra.com, *.cdn.telstra.com.au, *.collab.telstra.com, *.corp.telstra.com, *.dir.telstra.com, *.dir.telstra.com.au, *.in-control.telstra.com.au, *.in.telstra.com.au, *.localhost, *.nexus.telstra.com.au, *.team.telstra.com, *.telecom.com.au, *.thyra.telstra.com, *.tig.telstra.com, *.vpn.inside.telstra.com, .local, domino-u2, in-control.telstra.com.au, in.telstra.com.au, localhost, wpad.in.telstra.com.au, www.in.telstra.com.au, *.dev, *.home"
tconfigcntlmconfig="<Your CNTLM Config Location>"
tconfigtinyconfig="<Your TinyProxy Config Location>"

########################
#
# DO NOT EDIT BELOW THIS LINE
#
########################

# Kerberos
alias tlogin="kinit --renewable -l 90d -r 90d $tconfiguser@CORE.DIR.TELSTRA.COM ; klist"

# Checks which location you are in and set's your proxy settings
function tproxyauto() {
    
    # Location Detection
    # http://blog.hoachuck.biz/blog/2013/03/21/howto-set-cntlm-on-mac-os-x/
    tlocation=`/usr/sbin/networksetup -getcurrentlocation`

    # Print Location
    echo
    printf "\t\033[0;33m[ PROXY ]\033[0m Location Detected:\033[0;33m $tlocation ...\033[0m"
    echo

    # Check if proxy app was detected
    tproxyapp
    if [ "$tapp" = "No Proxy Applications Found" ]; then
        printf "\t\033[0;31m[ PROXY ]\033[0m No Proxy Application Detected"
        echo
        echo
    else
        printf "\t\033[0;33m[ PROXY ]\033[0m Proxy Application Detected:\033[0;33m $tapp ...\033[0m"
        echo
        echo
    fi

    # Start or Stop proxy based on location
    if [ "$tlocation" = "$tconfiglocation_corp" ]; then
        tproxyset
    elif [ "$tlocation" = "$tconfiglocation_vpn" ]; then
        tproxyset
    else
        tproxyunset
    fi
}

# Detects Which Proxy App/Solution You Are Using
function tproxyapp() {
    unset tpapp

    if [ -e "/usr/local/bin/cntlm" ] ; then
        tapp='CNTLM'
    elif [ -d "/Applications/Preproxy.app/" ] ; then
        tapp='Preproxy'
    else
        tapp='No Proxy Applications Found'
    fi
}

function tproxyset() {

    # Start/Stop for CNTLM
    if [ -e "/usr/local/bin/cntlm" ] ; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Killing any existing CNTLM dameons running ...\033[0m"
        echo
        killall -9 cntlm &> /dev/null

        printf "\t\033[0;33m[ PROXY ]\033[0m Starting CNTLM in dameon mode ...\033[0m"
        echo

        if [ -e "$tconfigcntlmconfig" ] ; then
            cntlm -c $tconfigcntlmconfig &> /dev/null
            # verberose
            #cntlm -c $tconfigcntlmconfig &> /dev/null
        else
            printf "\t\033[0;31m[  !!!  ]\033[0m Can't Start CNTLM config file not found...\033[0m"
        fi

    # Start/Stop for Preproxy
    elif [ -d "/Applications/Preproxy.app/" ] ; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Starting Preproxy...\033[0m"
        echo

        if [ -e "/usr/libexec/networkserviceproxy" ] ; then
            printf "\t\033[0;31m[  !!!  ]\033[0m Can't Start Preproxy as its running in service mode...\033[0m"
            echo
        else
            printf "\t\033[0;33m[ PROXY ]\033[0m Starting Preproxy...\033[0m"
            # can use -j for silent launch
            # https://macosx.com/threads/how-to-launch-application-from-terminal.29520/
            open /Applications/Preproxy.app &> /dev/null
        fi
    fi
    echo

    # Start/Stop for Terminal
    printf "\t\033[0;33m[ PROXY ]\033[0m Setting proxy settings for Terminal Applications...\033[0m"
    echo
    export tproxy='Online'
    export HTTP_PROXY="http://$tconfigproxyhost:$tconfigproxyport"
    export HTTPS_PROXY=$HTTP_PROXY
    export http_proxy=$HTTP_PROXY
    export https_proxy=$HTTP_PROXY
    export FTP_PROXY=$HTTP_PROXY
    export ftp_proxy=$HTTP_PROXY
    export ALL_PROXY=$HTTP_PROXY
    export all_proxy=$HTTP_PROXY

    export HTTP_PROXY_REQUEST_FULLURI=0 # or false
    export HTTPS_PROXY_REQUEST_FULLURI=0 #
    export NO_PROXY=$tconfigproxybypass
    export no_proxy=$tconfigproxybypass

    # Start/Stop for 3rd Party Apps
    if tproxyexists git; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Setting proxy settings for Git...\033[0m"
        echo
        git config --global http.proxy $HTTP_PROXY
        git config --global https.proxy $HTTPS_PROXY
    fi
    if tproxyexists npm; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Setting proxy settings for NPM...\033[0m"
        echo
        npm config set proxy $HTTP_PROXY
        npm config set https-proxy $HTTP_PROXY
        #npm config set strict-ssl false
        #npm config set registry "http://registry.npmjs.org/"
        #set NODE_TLS_REJECT_UNAUTHORIZED=0
    fi
    if tproxyexists yarn; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Setting proxy settings for Yarn...\033[0m"
        echo
        yarn config set proxy $HTTP_PROXY
        yarn config set https-proxy $HTTP_PROXY
    fi
    if tproxyexists corkscrew; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Enabling proxy settings for SSH (corkscrew)...\033[0m"
        echo
        sed -i '' '/ProxyCommand corkscrew/s/^#*//g' ~/.ssh/config
    fi 

    # Additional Applications
    if [ -d "/Applications/NoMAD.app" ]; then
        if [ $(ps ax | grep -v grep | grep -c -i "NoMAD.app") -eq "0" ]; then
            echo
            printf "\t\033[0;33m[ PROXY ]\033[0m Launching NoMAD for Kerberos...\033[0m"
            echo
            open /Applications/NoMAD.app &> /dev/null
        fi
    fi

#    if [ -e "/usr/local/bin/tinyproxy" ] ; then
#        if [ $(ps ax | grep -v grep | grep -c -i "tinyproxy") -ne "0" ]; then
#            echo
#            printf "\t\033[0;33m[ PROXY ]\033[0m Killing Tinyproxy used for hardcoded proxy apps...\033[0m"
#            echo
#            killall -9 tinyproxy &> /dev/null
#        fi
#    fi

    # Clear DNS Cache
    tproxycleardns
    echo

    # Finished Message
    printf "\t\033[0;32m[ ONLINE ]\033[0m Proxy switch completed\033[0m"
    echo "$tproxy" > /tmp/cntlmrunner
    chmod 755 /tmp/cntlmrunner
    echo

}

function tproxyunset() {
    # Start/Stop for CNTLM
    if [ -e "/usr/local/bin/cntlm" ] ; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Killing any CNTLM dameons running ...\033[0m"
        echo
        killall -9 cntlm &> /dev/null

    # Start/Stop for Preproxy
    elif [ -d "/Applications/Preproxy.app/" ] ; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Stopping Preproxy...\033[0m"
        echo

        if [ -e "/usr/libexec/networkserviceproxy" ] ; then
            printf "\t\033[0;31m[  !!!  ]\033[0m Can't Stop Preproxy as its running in service mode...\033[0m"
            echo
        else
            printf "\t\033[0;33m[ PROXY ]\033[0m Stopping Preproxy...\033[0m"
            killall -9 Preproxy &> /dev/null
        fi
    fi
    echo

    # Start/Stop for Terminal
    printf "\t\033[0;33m[ PROXY ]\033[0m Removing proxy settings for Terminal Applications...\033[0m"
    echo
	export tproxy='Offline'
    unset HTTP_PROXY
    unset HTTPS_PROXY
    unset http_proxy
    unset https_proxy
    unset FTP_PROXY
    unset ftp_proxy
    unset ALL_PROXY
    unset all_proxy

    unset HTTP_PROXY_REQUEST_FULLURI
    unset HTTPS_PROXY_REQUEST_FULLURI   
    unset NO_PROXY
    unset no_proxy

    # Start/Stop for 3rd Party Apps
    if tproxyexists git; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Removing proxy settings for Git...\033[0m"
        echo
        git config --global --unset http.proxy
        git config --global --unset https.proxy
    fi
    if tproxyexists npm; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Removing proxy settings for NPN...\033[0m"
        echo
        npm config delete proxy
        npm config delete https-proxy
    fi
    if tproxyexists yarn; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Removing proxy settings for Yarn...\033[0m"
        echo
        yarn config delete proxy
        yarn config delete https-proxy
    fi 
    if tproxyexists corkscrew; then
        printf "\t\033[0;33m[ PROXY ]\033[0m Disabling proxy settings for SSH (corkscrew)...\033[0m"
        echo
        sed -i '' '/ProxyCommand corkscrew/s/^#*/#/g' ~/.ssh/config
    fi 

    # Start/Stop for CNTLM
    #if [ -e "/usr/local/bin/tinyproxy" ] ; then
    #    printf "\t\033[0;33m[ PROXY ]\033[0m Killing any existing Tinyproxy dameons running ...\033[0m"
    #    echo
    #    killall -9 tinyproxy &> /dev/null

    #    printf "\t\033[0;33m[ PROXY ]\033[0m Starting Tinyproxy in dameon mode ...\033[0m"
    #    echo

    #    if [ -e "$tconfigcntlmconfig" ] ; then
    #        tinyproxy -v $tconfigtinyconfig &> /dev/null
    #    else
    #        printf "\t\033[0;31m[  !!!  ]\033[0m Can't Start CNTLM config file not found...\033[0m"
    #    fi
    #fi
    
    #if [ -e "/usr/local/bin/tinyproxy" ] ; then
    #    echo
    #    if [ $(ps ax | grep -v grep | grep -c -i "tinyproxy") -ne "0" ]; then
    #        printf "\t\033[0;33m[ PROXY ]\033[0m Killing any existing Tinyproxy dameons running...\033[0m"
    #        echo
    #        killall -9 tinyproxy 2> /dev/null
    #    fi
    #
    #    printf "\t\033[0;33m[ PROXY ]\033[0m Starting Tinyproxy in dameon mode ...\033[0m"
    #    echo
    #
    #    if [ -e "$tconfigtinyconfig" ] ; then
    #        printf "\t\033[0;33m[ PROXY ]\033[0m Starting Tinyproxy in dameon mode for hardcoded apps...\033[0m"
    #        echo
    #        tinyproxy -c $tconfigtinyconfig &> /dev/null
    #    else
    #        printf "\t\033[0;31m[  !!!  ]\033[0m Can't Start Tinyproxy config file not found...\033[0m"
    #        echo
    #    fi
    #fi

    # Clear DNS
    tproxycleardns
    echo

    # Finished Message
    printf "\t\033[0;31m[ OFFLINE ]\033[0m Proxy switch completed\033[0m"
    echo
}

# Clear Mac DNS Cache, using 2 methods depending on Mac OS version
function tproxycleardns() {
    echo
    
    dcacheutil -flushcache &> /dev/null
    killall -HUP mDNSResponder &> /dev/null
    printf "\t\033[0;33m[ CACHE ]\033[0m Mac OS DNS Cache Cleared...\033[0m"
    echo

    arp -ad &> /dev/null
    printf "\t\033[0;33m[ CACHE ]\033[0m Mac OS ARP Tables Flushed...\033[0m"

    echo
}

function tproxyexists {
    #this should be a very portable way of checking if something is on the path
    #usage: "if tproxyexists foo; then echo it exists; fi"
    type "$1" &> /dev/null
}

#function tproxyphpstart(){
#    nohup php -S localhost:8000 2>/dev/null;
#    PROXY_PHP_SERVER_PID=$!
#}
#function tproxyphpstop(){
#    kill -3 $PHP_SERVER_PID
#}

# Now we need to run on launch
if [ ! -f "/tmp/cntlmrunner" ]; then
    touch /tmp/cntlmrunner
    chmod 755 /tmp/cntlmrunner
    tproxyauto > /dev/null
    echo "$tproxy" > /tmp/cntlmrunner
else
    tproxy=$(cat /tmp/cntlmrunner)
fi

# Further Links
# other sources https://digitaldrummerj.me/proxy-configurations/
# https://medium.com/platform-engineer/proxy-config-handbook-for-software-engineers-90de2a95ebdc
# https://medium.com/@magician03/proxy-config-in-bash-npm-bower-atom-git-ionic-56b545b76a6d
# https://www.jhipster.tech/configuring-a-corporate-proxy/