Rewritten to support connecting to multiple vpns simultaneously.
This commit is contained in:
parent
839244cd61
commit
3852304c59
237
cvpn
237
cvpn
|
@ -70,6 +70,7 @@ function load_config() {
|
||||||
thisroutes=$(cut -d, -f7 <<< "${line}")
|
thisroutes=$(cut -d, -f7 <<< "${line}")
|
||||||
thisdomains=$(cut -d, -f8 <<< "${line}")
|
thisdomains=$(cut -d, -f8 <<< "${line}")
|
||||||
thisservercert=$(cut -d, -f9 <<< "${line}")
|
thisservercert=$(cut -d, -f9 <<< "${line}")
|
||||||
|
thispidfile=${CONFDIR}/${thisprofile// /}.pid
|
||||||
case $thisvpntype in
|
case $thisvpntype in
|
||||||
"") thisvpntype="anyconnect";;
|
"") thisvpntype="anyconnect";;
|
||||||
"cisco") thisvpntype="anyconnect";;
|
"cisco") thisvpntype="anyconnect";;
|
||||||
|
@ -90,6 +91,7 @@ function load_config() {
|
||||||
routes[$nvpns]="${thisroutes}"
|
routes[$nvpns]="${thisroutes}"
|
||||||
domains[$nvpns]="${thisdomains}"
|
domains[$nvpns]="${thisdomains}"
|
||||||
servercert[$nvpns]="${thisservercert}"
|
servercert[$nvpns]="${thisservercert}"
|
||||||
|
pidfile[$nvpns]="${thispidfile}"
|
||||||
nvpns=$((nvpns + 1))
|
nvpns=$((nvpns + 1))
|
||||||
done <<< "${CONFLINES}"
|
done <<< "${CONFLINES}"
|
||||||
else
|
else
|
||||||
|
@ -132,36 +134,51 @@ function get_profile_id() { #1=profile_to_check
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_vpn_status() { # populates vprofile vuser vstatus vserver vvpntype, return 0 if vpn up
|
function vpnisup() { # 1=profile
|
||||||
local rv=0 vpnpid pname
|
local idx pf rv pid
|
||||||
vprofile=""
|
idx=$(get_profile_id "$1")
|
||||||
vuser=""
|
rv=$?
|
||||||
vstatus="Disconnected"
|
if [[ $rv -ne 0 || -z $idx ]]; then
|
||||||
vserver=""
|
return 1
|
||||||
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
|
fi
|
||||||
|
pf=${pidfile[$idx]}
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
if [[ -n $pf && -e $pf ]]; then
|
||||||
# find matching profile
|
pid=$(cat $pf)
|
||||||
for x in ${!profile[@]}; do
|
ps -p $pid >/dev/null 2>&1
|
||||||
if [[ $vserver == ${server[$x]} ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
vprofile="${profile[$x]}"
|
return 0
|
||||||
[[ -z $vuser ]] && vuser=${user[$x]}
|
else
|
||||||
[[ -z $vvpntype ]] && vvpntype=${vvpntype[$x]}
|
return 1
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
return $rv
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_vpn_status() { # populates vprofile[] vpid[] vuser[] vstatus[] vserver[] vvpntype[] nup, return true if any vpns are up
|
||||||
|
local rv=0 vpnpid pname x
|
||||||
|
unset vprofile
|
||||||
|
unset vpnpid
|
||||||
|
unset vstatus
|
||||||
|
unset vserver
|
||||||
|
unset vuser
|
||||||
|
unset vvpntype
|
||||||
|
nup=0
|
||||||
|
|
||||||
|
for x in ${!profile[@]}; do
|
||||||
|
vpnisup "${profile[$x]}"
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
vprofile+=(${profile[$x]})
|
||||||
|
vpid+=($(cat ${pidfile[$x]}))
|
||||||
|
vstatus+=("Connected")
|
||||||
|
vserver+=(${server[$x]})
|
||||||
|
vuser+=(${user[$x]})
|
||||||
|
vvpntype+=(${vpntype[$x]})
|
||||||
|
nup=$((nup + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[[ $nup -eq 0 ]] && return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILE=""
|
PROFILE=""
|
||||||
|
@ -196,7 +213,7 @@ load_config || exit 1
|
||||||
|
|
||||||
usingdefault=0
|
usingdefault=0
|
||||||
PROFILE="$2"
|
PROFILE="$2"
|
||||||
if [[ -z $PROFILE ]]; then
|
if [[ -z $PROFILE && $cmd == "up" ]]; then
|
||||||
if [[ -n ${DEFAULTPROFILE} ]]; then
|
if [[ -n ${DEFAULTPROFILE} ]]; then
|
||||||
PROFILE="${DEFAULTPROFILE}"
|
PROFILE="${DEFAULTPROFILE}"
|
||||||
usingdefault=1
|
usingdefault=1
|
||||||
|
@ -204,28 +221,56 @@ if [[ -z $PROFILE ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $cmd == "list" ]]; then
|
if [[ $cmd == "list" ]]; then
|
||||||
F="%s,%s,%s,%s,%s,%s\n"
|
F="%s,%s,%s,%s,%s,%s,%s,%s\n"
|
||||||
|
|
||||||
table=$(
|
table=$(
|
||||||
(
|
(
|
||||||
printf "${F}" "Profile" "Username" "Password" "Group" "Server" "Type"
|
printf "${F}" "Profile" "Up?" "Username" "Password" "Group" "Server" "Type" "Scope"
|
||||||
for x in ${!profile[@]}; do
|
for x in ${!profile[@]}; do
|
||||||
p="${pw[$x]:0:2}....${pw[$x]: (-2)}"
|
p="${pw[$x]:0:2}....${pw[$x]: (-2)}"
|
||||||
prof="${profile[$x]}"
|
prof="${profile[$x]}"
|
||||||
[[ $prof == $DEFAULTPROFILE ]] && prof="*${prof}"
|
[[ $prof == $DEFAULTPROFILE ]] && prof="${prof}*"
|
||||||
printf "${F}" "${prof}" "${user[$x]}" "${p}" "${group[$x]:-(n/a)}" "${server[$x]:-(n/a)}" "${vpntype[$x]}"
|
vpnisup "${prof}"
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
yn="Yes"
|
||||||
|
c="${GREEN}"
|
||||||
|
else
|
||||||
|
yn="No"
|
||||||
|
c="${GREY}"
|
||||||
|
fi
|
||||||
|
scope="${domains[$x]} ${routes[$x]}"
|
||||||
|
vt=${vpntype[$x]}
|
||||||
|
[[ ${vt,,} == "anyconnect" ]] && vt=Cisco
|
||||||
|
printf "${F}" "${prof}" "$yn" "${user[$x]}" "${p}" "${group[$x]:-(n/a)}" "${server[$x]:-(n/a)}" "${vt}" "${scope%% *}"
|
||||||
|
|
||||||
|
# show one route/domain per row
|
||||||
|
scope_a=( ${scope} )
|
||||||
|
#echo "${profile[$x]} scope: [${scope}]" >&2
|
||||||
|
#echo "${profile[$x]} scope_a: [${scope_a[@]}]" >&2
|
||||||
|
if [[ ${#scope_a[@]} -ge 2 ]]; then
|
||||||
|
i=1 # skip first one
|
||||||
|
while [[ $i -lt ${#scope_a[@]} ]]; do
|
||||||
|
printf "${F}" " " " " " " " " " " " " " " "${scope_a[$i]}"
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
) | column -s, -t
|
) | column -s, -t
|
||||||
)
|
)
|
||||||
table=$(echo "$table" | sed "s/^\(Profile.*\)$/^b^u\1^p/;s/\(n\/a\)/^i\1^p/g")
|
|
||||||
|
# underline heading
|
||||||
|
table=$(echo "$table" | sed "s/^\(Profile.*\)$/^b^u\1^p/;")
|
||||||
|
table=$(awk -v G="$GREEN" -v P="$PLAIN" '($2 == "Yes") { printf(G); } ($2 == "No") { printf(P); } { print }' <<<"$table")
|
||||||
|
|
||||||
csecho "$WHITE" "$table"
|
csecho "$WHITE" "$table"
|
||||||
echo
|
echo
|
||||||
echo "(* = default VPN)"
|
echo "(* = default VPN)"
|
||||||
exit 0
|
exit 0
|
||||||
elif [[ $cmd == "on" ]]; then
|
elif [[ $cmd == "on" ]]; then
|
||||||
[[ $usingdefault -eq 1 ]] && inform "[using default VPN: ^b$DEFAULTPROFILE^p]"
|
[[ $usingdefault -eq 1 ]] && inform "[using default VPN: ^b$DEFAULTPROFILE^p]"
|
||||||
get_vpn_status
|
vpnisup "${PROFILE}"
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
error "VPN profile $vprofile is already connected"
|
error "VPN profile $PROFILE is already connected"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -246,6 +291,7 @@ elif [[ $cmd == "on" ]]; then
|
||||||
curservercert=${servercert[$id]}
|
curservercert=${servercert[$id]}
|
||||||
curroutes=${routes[$id]}
|
curroutes=${routes[$id]}
|
||||||
curdomains=${domains[$id]}
|
curdomains=${domains[$id]}
|
||||||
|
curpidfile=${pidfile[$id]}
|
||||||
#echo "got curprofile=${profile[$id]}"
|
#echo "got curprofile=${profile[$id]}"
|
||||||
#echo "got curuser=${user[$id]}"
|
#echo "got curuser=${user[$id]}"
|
||||||
#echo "got curpw=${pw[$id]}"
|
#echo "got curpw=${pw[$id]}"
|
||||||
|
@ -255,6 +301,7 @@ elif [[ $cmd == "on" ]]; then
|
||||||
#echo "got curservercert=${servercert[$id]}"
|
#echo "got curservercert=${servercert[$id]}"
|
||||||
#echo "got curroutes=${routes[$id]}"
|
#echo "got curroutes=${routes[$id]}"
|
||||||
#echo "got curdomains=${domains[$id]}"
|
#echo "got curdomains=${domains[$id]}"
|
||||||
|
#echo "got curpidfile=${pidfile[$id]}"
|
||||||
else
|
else
|
||||||
error "Could not determine VPN ID for profile ^b${PROFILE}^p."
|
error "Could not determine VPN ID for profile ^b${PROFILE}^p."
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -314,22 +361,26 @@ elif [[ $cmd == "on" ]]; then
|
||||||
|
|
||||||
notify "${nstr}"
|
notify "${nstr}"
|
||||||
|
|
||||||
rm -f "$VPNPIDFILE"
|
rm -f "$curpidfile"
|
||||||
if [[ -n $curroutes && -n $curdomains]]; then
|
if [[ -n $curroutes && -n $curdomains ]]; then
|
||||||
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE --domains-vpn-dns ${curdomains// /,} $curroutes" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE --domains-vpn-dns ${curdomains// /,} $curroutes" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
|
rv=$?
|
||||||
elif [[ -n $curroutes ]]; then
|
elif [[ -n $curroutes ]]; then
|
||||||
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE $curroutes" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE $curroutes" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
|
rv=$?
|
||||||
elif [[ -n $curdomains ]]; then
|
elif [[ -n $curdomains ]]; then
|
||||||
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE --domains-vpn-dns $curdomains" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg -s "$VPNSLICE --domains-vpn-dns $curdomains" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
|
rv=$?
|
||||||
else
|
else
|
||||||
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=$curvpntype -u "$curuser" --passwd-on-stdin $grouparg --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
|
rv=$?
|
||||||
fi
|
fi
|
||||||
rv=$?
|
|
||||||
res=$(cat "$LOGFILE")
|
res=$(cat "$LOGFILE")
|
||||||
if [[ $rv -eq 0 ]]; then
|
if [[ $rv -eq 0 ]]; then
|
||||||
cpid=$(pgrep openconnect)
|
cpid=$(pgrep -f "openconnect.* ${curserver}")
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
echo "$cpid" > "$VPNPIDFILE"
|
echo "$cpid" > "$curpidfile"
|
||||||
|
rv=0
|
||||||
else
|
else
|
||||||
rv=1
|
rv=1
|
||||||
fi
|
fi
|
||||||
|
@ -345,55 +396,75 @@ elif [[ $cmd == "status" ]]; then
|
||||||
BASECOL="$ORANGE"
|
BASECOL="$ORANGE"
|
||||||
notify "Checking VPN status"
|
notify "Checking VPN status"
|
||||||
get_vpn_status
|
get_vpn_status
|
||||||
[[ $? -eq 0 ]] && ok || fail
|
ok
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
if [[ $nup -eq 0 ]]; then
|
||||||
col="$GREEN"
|
csecho "$ORANGE" "Not connected to any VPNs"
|
||||||
|
exit 0
|
||||||
|
elif [[ $nup -eq 1 ]]; then
|
||||||
|
ess=""
|
||||||
else
|
else
|
||||||
col="$RED"
|
ess="s"
|
||||||
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
|
fi
|
||||||
|
csecho "$ORANGE" "Connected to ^b$nup^p VPN${ess}:"
|
||||||
|
for x in ${!vstatus[@]}; do
|
||||||
|
col="$GREEN"
|
||||||
|
csecho "$BASECOL" " ${col}${BOLD}${vstatus[$x]}^p ${BASECOL}to ^b${vprofile[$x]}^p (${vvpntype[$x]}:${vuser[$x]}@${vserver[$x]})"
|
||||||
|
done
|
||||||
elif [[ $cmd == "off" ]]; then
|
elif [[ $cmd == "off" ]]; then
|
||||||
rv=1
|
if [[ -n $PROFILE ]]; then
|
||||||
get_vpn_status
|
# bring down just one vpn
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
idxlist=$(get_profile_id "$PROFILE")
|
||||||
notify "Disconnecting from ${vvpntype} VPN ^b${vprofile}^p"
|
else
|
||||||
errstring=""
|
# bring down all vpns
|
||||||
errdata=""
|
idxlist="${!profile[@]}"
|
||||||
|
fi
|
||||||
|
ntried=0
|
||||||
|
for x in $idxlist; do
|
||||||
|
vpnisup "${profile[$x]}"
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
rv=1
|
||||||
|
ntried=$((ntried + 1))
|
||||||
|
notify "Disconnecting from ^b${profile[$x]}^p VPN"
|
||||||
|
errstring=""
|
||||||
|
errdata=""
|
||||||
|
|
||||||
thepid=$(cat $VPNPIDFILE)
|
thepid=$(cat ${pidfile[$x]})
|
||||||
if [[ -n $thepid ]]; then
|
if [[ -n $thepid ]]; then
|
||||||
sudo kill $thepid
|
sudo kill $thepid
|
||||||
sleep 2 # give it some time
|
sleep 2 # give it some time
|
||||||
res=$(ps -p $thepid 2>&1)
|
res=$(ps -p $thepid 2>&1)
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
rm -f "${VPNPIDFILE}"
|
rm -f "${pidfile[$x]}"
|
||||||
rv=0
|
rv=0
|
||||||
|
else
|
||||||
|
errstring="could not kill pid $thepid:"
|
||||||
|
errdata="$res"
|
||||||
|
rv=1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
errstring="could not kill pid $thepid:"
|
errstring="Cannot determine current VPN PID to kill."
|
||||||
errdata="$res"
|
|
||||||
rv=1
|
rv=1
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
errstring="Cannot determine current VPN PID to kill."
|
|
||||||
rv=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $rv -eq 0 ]]; then
|
if [[ $rv -eq 0 ]]; then
|
||||||
ok
|
ok
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
error "$errstring"
|
error "$errstring"
|
||||||
[[ -n $errdata ]] && cecho -s "$RED" "$errdata" | sed 's/^/ /'
|
[[ -n $errdata ]] && cecho -s "$RED" "$errdata" | sed 's/^/ /'
|
||||||
|
fi
|
||||||
|
elif [[ -n $PROFILE ]]; then
|
||||||
|
error "The VPN ^b${PROFILE}^p is already disconnected"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
done
|
||||||
fail
|
if [[ $ntried -eq 0 && -z $PROFILE ]]; then
|
||||||
error "All VPNs are already disconnected"
|
error "All VPNs are already disconnected"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue