From f65fd91d2c684298470db39edef2fa99dd5ac042 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Thu, 5 Oct 2023 09:28:25 +1100 Subject: [PATCH] initial checkin --- README.md | 22 ++++++ cvpn | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100755 README.md create mode 100755 cvpn diff --git a/README.md b/README.md new file mode 100755 index 0000000..3e28147 --- /dev/null +++ b/README.md @@ -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 + +``` diff --git a/cvpn b/cvpn new file mode 100755 index 0000000..2e69137 --- /dev/null +++ b/cvpn @@ -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 +