initial checkin

This commit is contained in:
Rob Pearce 2023-10-05 09:28:25 +11:00
commit f65fd91d2c
2 changed files with 229 additions and 0 deletions

22
README.md Executable file
View File

@ -0,0 +1,22 @@
# Overview
Simple CLI wrapper for Cisco's Anyconnect client.
# Usage
```text
/Users/rob/scripts/cvpn [OPTIONS] on|off [vpnname]
Wrapper for cisco anyconnect 'vpn' script.
-p profile Use selected connection profile
-c file Use selected config file (default is /Users/rob/.vpn/config
Config file format:
#default:myvpn2
myvpn1,username_1,password_1,vpngroup_1
myvpn2,username_2,password_2,vpngroup_2
# This one has no 'group'
myvpn3,username_3,password_3ofile Use selected connection profile
```

207
cvpn Executable file
View File

@ -0,0 +1,207 @@
#!/bin/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
DEFAULTCONF=${CONFDIR}/config
CONFFILE=${DEFAULTCONF}
VPN=/opt/cisco/anyconnect/bin/vpn
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
DEFAULTPROFILE=""
if [[ -e ${CONFFILE} ]]; then
DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://')
if [[ -n ${DEFAULTPROFILE} ]]; then
inform "[default VPN: ^b$DEFAULTPROFILE^p]"
fi
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}")
profile[$nvpns]="${thisprofile}"
user[$nvpns]="${thisuser}"
pw[$nvpns]="${thispw}"
group[$nvpns]="${thisgroup}"
nvpns=$((nvpns + 1))
done <<< ${CONFLINES}
else
error "Config file '$CONFFILE' not found"
return 1
fi
return 0
}
function usage() {
echo "$0 [OPTIONS] on|off [vpnname]"
echo
echo "Wrapper for cisco anyconnect 'vpn' script."
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 " #default:myvpn2"
echo " myvpn1,username_1,password_1,vpngroup_1"
echo " myvpn2,username_2,password_2,vpngroup_2"
echo " # This one has no 'group'"
echo " myvpn3,username_3,password_3"
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
}
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
PROFILE="$DEFAULTPROFILE"
if [[ $cmd == "list" ]]; then
F="%s,%s,%s,%s\n"
(
printf "${F}" "Profile" "Username" "Password" "Group"
for x in ${!profile[@]}; do
printf "${F}" "${profile[$x]}" "${user[$x]}" "${pw[$x]}" "${group[$x]:-(n/a)}"
done
) | column -s, -t
exit 0
elif [[ $cmd == "on" ]]; then
if [[ -z ${PROFILE} ]]; then
error "No default VPN is 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
curuser=${user[$id]}
curpw=${pw[$id]}
curgroup=${group[$id]}
else
exit 1
fi
nstr="Connecting to ^b${PROFILE}^p as user ^b${curuser}^p"
[[ -n $curgroup ]] && nstr="${nstr} group ${curgroup}"
notify "${nstr}"
if [[ -n $curgroup ]]; then
answers="y\n${curgroup}\n${curuser}\n${curpw}\n"
else
answers="y\n${curuser}\n${curpw}\n"
fi
res=$(echo -e "$answers" | ${VPN} -s connect "$PROFILE" 2>&1 | tee ${LOGFILE})
grep -q 'state: Connected' <<< "$res$"
if [[ $? -eq 0 ]]; then
ok "connected"
else
fail
error "Connection failed, logs are in ^b${LOGFILE}^p."
fi
elif [[ $cmd == "status" ]]; then
notify "Checking VPN status"
res=$(${VPN} stats 2>&1)
if [[ $? -eq 0 ]]; then
ok
echo "$res" > z
status=$(grep 'Connection State:' <<< "$res" | grep -v Manage | awk '{ print $3 }' )
[[ -z $status ]] && status="Unknown"
if [[ $status == "Connected" ]]; then
col="$GREEN"
dst=$(grep 'Server Address:' <<< "$res" | awk '{ print $3 }' )
else
col="$RED"
dst=""
fi
BASECOL="$ORANGE"
csecho -n "$BASECOL" "VPN status: ${col}${BOLD}${status}^p"
[[ -n $dst ]] && csecho "$BASECOL" " to ${dst}" || echo
else
fail
error "Status check failed."
fi
elif [[ $cmd == "off" ]]; then
notify "Disconnecting from VPN"
${VPN} disconnect > ${LOGFILE} 2>&1
if [[ $? -eq 0 ]]; then
ok
else
fail
error "Connection failed, logs are in ^b${LOGFILE}^p."
fi
else
usage
exit 1
fi