diff --git a/1 b/1 deleted file mode 100644 index 4524b1d..0000000 --- a/1 +++ /dev/null @@ -1,382 +0,0 @@ -#!/usr/bin/env bash - -. ${HOME}/code/bashtools/bashtools.sh -if [[ -z $HAVE_BASHTOOLS ]]; then - echo "ERROR: bashtools not installed download from https://git.nethack.net/rob/bashtools" >/dev/stderr - exit 1 -fi -CONFDIR=${HOME}/.vpn -LOGFILE=${CONFDIR}/log -VPNPIDFILE=${CONFDIR}/vpnpid -DEFAULTCONF=${CONFDIR}/config -CONFFILE=${DEFAULTCONF} - -cp -p "$LOGFILE" "${LOGFILE}.0" -cp /dev/null "$LOGFILE" - -err=0 -OPENCONNECT=$(which openconnect 2>/dev/null) -if [[ $? -ne 0 ]]; then - error "Can't find openconnect binary" - err=$((err + 1)) -fi -VPNSLICE=$(which vpn-slice 2>/dev/null) -if [[ $? -ne 0 ]]; then - error "Can't find vpn-slice binary" - err=$((err + 1)) -fi -if [[ $ree -ne 0 ]]; then - exit 1 -fi - -mkdir -p "${CONFDIR}" - -function alias_to_cmd() { - local input="$1" - local output="$input" - - case $input in - "l") output="list";; - "ls") output="list";; - "start") output="on";; - "u") output="on";; - "up") output="on";; - "stop") output="off";; - "d") output="off";; - "down") output="off";; - "check") output="status";; - "stat") output="status";; - "info") output="status";; - "i") output="status";; - esac - echo "$output" -} - -function load_config() { - local CONFLINES line thisprofile thisuser thispw thisgroup thisroutes thisservercert - DEFAULTPROFILE="" - if [[ -e ${CONFFILE} ]]; then - DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://') - CONFLINES=$(egrep -v "^#" ${CONFFILE} 2>/dev/null | awk NF) - nvpns=0 - while read line; do - [[ $line =~ ^# ]] && continue - thisprofile=$(cut -d, -f1 <<< "${line}") - thisuser=$(cut -d, -f2 <<< "${line}") - thispw=$(cut -d, -f3 <<< "${line}") - thisgroup=$(cut -d, -f4 <<< "${line}") - thisvpntype=$(cut -d, -f5 <<< "${line}") - thisserver=$(cut -d, -f6 <<< "${line}") - thisroutes=$(cut -d, -f7 <<< "${line}") - thisservercert=$(cut -d, -f8 <<< "${line}") - case $thisvpntype in - "") thisvpntype="anyconnect"; - "cisco") thisvpntype="anyconnect"; - "bigip") thisvpntype="anyconnect"; - esac - if [[ -z $thisserver ]]; then - error "Missing server IP for profile '$thisprofile'" - cecho -s "$RED" "^bBad line:^p $line" - exit 1 - fi - profile[$nvpns]="${thisprofile}" - user[$nvpns]="${thisuser}" - pw[$nvpns]="${thispw}" - group[$nvpns]="${thisgroup}" - vpntype[$nvpns]="${thisvpntype}" - server[$nvpns]="${thisserver}" - routes[$nvpns]="${thisroutes}" - servercert[$nvpns]="${thisservercert}" - nvpns=$((nvpns + 1)) - done <<< "${CONFLINES}" - else - error "Config file '$CONFFILE' not found" - return 1 - fi - return 0 -} - -function usage() { - echo "$0 [OPTIONS] on|off|status|list [vpnname]" - echo - echo "Wrapper for openconnect to support multiple VPN profiles." - echo - echo " -h show this help" - echo " -p profile Use selected connection profile" - echo " -c file Use selected config file (default is ${DEFAULTCONF})" - echo - echo "Config file format:" - echo " #Specify default profile like this:" - echo " #default:myvpn2" - echo " #Profile,Username,Password,VPNGroup,VPNType,ServerIP,VPNRoutes,ServerCert(script will obtain this and auto-update config file)" - echo " myvpn1,username_1,password_1,vpngroup_1,anyconnect,3.3.3.3,10.0.0.0/24 192.168.0.0/24," - echo " myvpn2,username_2,password_2,vpngroup_2,anyconnect,1.1.1.1,172.16.0.0/12," - echo " myvpn3,username_3,password_3,,f5,1.1.1.1,172.16.0.0/12," - echo -} - -function get_profile_id() { #1=profile_to_check - local x lookfor="$1" - for x in ${!profile[@]}; do - if [[ ${profile[$x],,} == ${lookfor,,} ]]; then - echo "${x}" - return 0 - fi - done - error "No credentials found for the VPN profile ^b${PROFILE}^p." >&2 - csecho "$RED" "Add a line of this format to ^b${CONFFILE}^p:" >&2 - csecho "$RED" "${PROFILE},^iusername^p,^ipassword^p[,^igroup]^p" >&2 - return 1 -} - -function get_vpn_status() { # populates vprofile vuser vstatus vserver vvpntype, return 0 if vpn up - local rv=0 vpnpid pname - vprofile="" - vuser="" - vstatus="Disconnected" - vserver="" - vvpntype="" - - if [[ -e $VPNPIDFILE ]]; then - vpnpid=$(cat $VPNPIDFILE 2>/dev/null) - pname=$(ps -p $vpnpid -o command="" 2>/dev/null) - vstatus="Connected" - vserver=$(echo "$pname" | awk '{ print $NF }') - vuser=$(echo "$pname" | sed 's/^.*-u //;s/ .*//g') - vvpntype=$(echo "$pname" | sed 's/^.*--protocol=//;s/ .*//g') - else - rv=1 - fi - - if [[ $vstatus == "Connected" ]]; then - # find matching profile - for x in ${!profile[@]}; do - if [[ $vserver == ${server[$x]} ]]; then - vprofile="${profile[$x]}" - [[ -z $vuser ]] && vuser=${user[$x]} - [[ -z $vvpntype ]] && vvpntype=${vvpntype[$x]} - fi - done - fi - return $rv -} - -PROFILE="" - -ARGS="hp:" -while getopts "$ARGS" i; do - case "$i" in - p) - profile="$OPTARG"; - exit 1; - ;; - h) - usage; - exit 1; - ;; - *) - error "invalid argument: $i"; - usage; - ;; - esac -done -shift $((OPTIND - 1)) - -if [[ $# -lt 1 ]]; then - usage - exit 1 -fi - -cmd=$(alias_to_cmd "$1") - -load_config || exit 1 - -usingdefault=0 -PROFILE="$2" -if [[ -z $PROFILE ]]; then - if [[ -n ${DEFAULTPROFILE} ]]; then - PROFILE="${DEFAULTPROFILE}" - usingdefault=1 - fi -fi - -if [[ $cmd == "list" ]]; then - F="%s,%s,%s,%s,%s,%s\n" - table=$( - ( - printf "${F}" "Profile" "Username" "Password" "Group" "Server" "Type" - for x in ${!profile[@]}; do - p="${pw[$x]:0:2}....${pw[$x]: (-2)}" - prof="${profile[$x]}" - [[ $prof == $DEFAULTPROFILE ]] && prof="*${prof}" - printf "${F}" "${prof}" "${user[$x]}" "${p}" "${group[$x]:-(n/a)}" "${server[$x]:-(n/a)}" "${vpntype[$x]}" - done - ) | column -s, -t - ) - table=$(echo "$table" | sed "s/^\(Profile.*\)$/^b^u\1^p/;s/\(n\/a\)/^i\1^p/g") - csecho "$WHITE" "$table" - echo - echo "(* = default VPN)" - exit 0 -elif [[ $cmd == "on" ]]; then - [[ $usingdefault -eq 1 ]] && inform "[using default VPN: ^b$DEFAULTPROFILE^p]" - get_vpn_status - if [[ $vstatus == "Connected" ]]; then - error "VPN profile $vprofile is already connected" - exit 1 - fi - - if [[ -z ${PROFILE} ]]; then - error "No VPN profile provided and no default VPN profile set." - csecho "$RED" "Either specify on commandline, or add this to ^b${CONFFILE}^p:" - csecho "$RED" "#default:^ivpn_name^p" - exit 1 - fi - id=$(get_profile_id "${PROFILE}") - if [[ -n $id ]]; then - curprofile=${profile[$id]} - curuser=${user[$id]} - curpw=${pw[$id]} - curgroup=${group[$id]} - curvpntype=${vpntype[$id]} - curserver=${server[$id]} - curservercert=${servercert[$id]} - curroutes=${routes[$id]} - else - error "Could not determine VPN ID for profile ^b${PROFILE}^p." - exit 1 - fi - - if [[ -n $curgroup ]]; then - grouparg="--authgroup=$curgroup" - else - grouparg="" - fi - - if [[ -z $curservercert ]]; then - inform "No server certificate is defined for ^b$curprofile^p." - notify "Trying to obtain server certificate" - foundcert=$(sudo ${OPENCONNECT} --non-inter --protocol=anyconnect -u "$curuser" $grouparg "$curserver" 2>&1 | grep -- --servercert | awk '{ print $NF }') - if [[ -n $foundcert ]]; then - ok - inform "Got server certificate '^b${foundcert}^p'" - notify "Updating configuration file ^b$CONFFILE^p" - bakfile="${CONFFILE}".backup - prevlines=$(cat "$CONFFILE" | awk NF | wc -l | bc) - newconfig=$(cat "${CONFFILE}" | awk -v p="$curprofile" -v c="$foundcert" -F, '{ OFS=","; if ($1 == p) { $8 = c; } print }') - newlines=$(echo "$newconfig" | awk NF | wc -l | bc) - - err="" - if [[ $newlines -ne $prevlines ]]; then - err="line count different" - elif ! grep -q pin-sha256 <<<"$newconfig"; then - err="new config missing server cert" - fi - - if [[ -z $err ]]; then - ok - cp -p "${CONFFILE}" "${bakfile}" - echo "$newconfig" > ${CONFFILE} - curservercert="$foundcert" - else - fail - error "Regenerated config file seems wrong ($err)" - cecho -s "$RED" "Current config:" - cecho -s "$RED" "$(cat "$CONFFILE")" | sed 's/^/ /' - echo - cecho -s "$RED" "Newly generated config:" - cecho -s "$RED" "$newconfig" | sed 's/^/ /' - echo - exit 1 - fi - else - fail - exit 1 - fi - fi - - nstr="Connecting to ^b${PROFILE}^p as user ^b${curuser}^p" - [[ -n $curgroup ]] && nstr="${nstr} group ${curgroup}" - [[ -n $curserver ]] && nstr="${nstr} server ${curserver}" - - notify "${nstr}" - - rm -f "$VPNPIDFILE" - if [[ -n $curroutes ]]; then - printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$vpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE $curroutes" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1 - else - printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$vpntype -u "$curuser" --passwd-on-stdin $grouparg --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1 - fi - rv=$? - res=$(cat "$LOGFILE") - if [[ $rv -eq 0 ]]; then - cpid=$(pgrep openconnect) - if [[ $? -eq 0 ]]; then - echo "$cpid" > "$VPNPIDFILE" - else - rv=1 - fi - fi - if [[ $rv -eq 0 ]]; then - ok "connected" - else - fail - error "Connection failed, logs are below:" - cecho -s "$RED" "$res" | sed 's/^/ /' - fi -elif [[ $cmd == "status" ]]; then - BASECOL="$ORANGE" - notify "Checking VPN status" - get_vpn_status - [[ $? -eq 0 ]] && ok || fail - if [[ $vstatus == "Connected" ]]; then - col="$GREEN" - else - col="$RED" - fi - csecho -n "$BASECOL" "VPN status: ${col}${BOLD}${vstatus}^p" - if [[ ${vstatus,,} =~ "connected" ]]; then - [[ -n $vserver ]] && csecho "$BASECOL" " to ^b${vprofile}^p (${vvpntype}:${vuser}@${vserver})" || echo - fi -elif [[ $cmd == "off" ]]; then - rv=1 - get_vpn_status - if [[ $vstatus == "Connected" ]]; then - notify "Disconnecting from ${vvpntype} VPN ^b${vprofile}^p" - errstring="" - errdata="" - - thepid=$(cat $VPNPIDFILE) - if [[ -n $thepid ]]; then - sudo kill $thepid - sleep 2 # give it some time - res=$(ps -p $thepid 2>&1) - if [[ $? -ne 0 ]]; then - rm -f "${VPNPIDFILE}" - rv=0 - else - errstring="could not kill pid $thepid:" - errdata="$res" - rv=1 - fi - else - errstring="Cannot determine current VPN PID to kill." - rv=1 - fi - - if [[ $rv -eq 0 ]]; then - ok - else - fail - error "$errstring" - [[ -n $errdata ]] && cecho -s "$RED" "$errdata" | sed 's/^/ /' - fi - else - fail - error "All VPNs are already disconnected" - fi -else - usage - exit 1 -fi -