Skip to content

Commit

Permalink
Add 'ucsf vpn install-vpnc'
Browse files Browse the repository at this point in the history
  • Loading branch information
HenrikBengtsson committed May 18, 2024
1 parent 6d6c58a commit 4d6fb8b
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ README.md: README.md.tmpl bin/ucsf-vpn
## Check code using static-code analysis
shellcheck:
echo "ShellCheck $$(shellcheck --version | grep version:)"
cd src; shellcheck -x ucsf-vpn.sh vpnc/connect.d/ucsf-vpn-flavors.sh
cd src; shellcheck -x ucsf-vpn.sh vpnc/ucsf-vpn-flavors.sh
shellcheck bin/ucsf
shellcheck bin/ucsf-vpn

Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ ucsf-vpn
* OpenConnect is now the only supported method. Support for Pulse
Secure GUI client has been dropped.

### New Features

* Add `ucsf vpn install-vpnc`, which is required before using
`--flavor=<flavor>`.

### Deprecated and Defunct

* The use of `--method=pulse`, which uses the Pulse Secure GUI client
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Useful resources:
* UCSF Managing Your Passwords:
- https://it.ucsf.edu/services/managing-your-passwords
Version: 5.8.0-9002
Version: 5.8.0-9003
Copyright: Henrik Bengtsson (2016-2024)
License: GPL (>= 2.1) [https://www.gnu.org/licenses/gpl.html]
Source: https://github.com/HenrikBengtsson/ucsf-vpn
Expand Down
133 changes: 122 additions & 11 deletions bin/ucsf-vpn
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
### * UCSF Managing Your Passwords:
### - https://it.ucsf.edu/services/managing-your-passwords
###
### Version: 5.8.0-9002
### Version: 5.8.0-9003
### Copyright: Henrik Bengtsson (2016-2024)
### License: GPL (>= 2.1) [https://www.gnu.org/licenses/gpl.html]
### Source: https://github.com/HenrikBengtsson/ucsf-vpn
Expand Down Expand Up @@ -222,7 +222,7 @@ function help() {
local what res

what=$1
res=$(grep "^###" "$0" | grep -vE '^(####|### whatis: )' | cut -b 5- | sed "s/{{pulsesvc_version}}/$(pulsesvc_version)/" | sed "s/{{openconnect_version}}/$(openconnect_version)/")
res=$(grep "^###" "$0" | grep -vE '^(####|### whatis: )' | cut -b 5- | sed "s/{{openconnect_version}}/$(openconnect_version)/")

if [[ $what == "full" ]]; then
res=$(echo "$res" | sed '/^---/d')
Expand Down Expand Up @@ -851,7 +851,7 @@ function openconnect_start() {

## Assert that --flavor=<flavor> exists, if specified
flavor_home > /dev/null

assert_sudo "start"

## Load user credentials from file?
Expand Down Expand Up @@ -1241,6 +1241,112 @@ function flavor_home() {
}


function find_vpnc-script() {
local file
file=$(openconnect --help | grep -E "vpnc-script" | sed 's/[^"]*"//' | sed 's/".*//')
if [[ -z "${file}" ]]; then
merror "Failed to locate the default 'vpnc-script' script. It appears that openconnect --help does not specify it"
fi
echo "${file}"
}

function find_hooks_dir() {
local file dir
find_vpnc-script > /dev/null
file=$(find_vpnc-script)
dir=$(grep -E "^HOOKS_DIR=" "${file}" | sed 's/[^=]*=//' | sed 's/[[:blank:]]$//')
echo "${dir}"
}


function ucsf-vpn-flavors_code() {
cat << HOOK_SCRIPT_EOF
#!/bin/sh
####################################################################
# Use user-specific UCSF VPN configurations
#
# Install:
# ucsf vpn install-vpnc
#
# Requires:
# https://github.com/HenrikBengtsson/ucsf-vpn
####################################################################
## Called via 'ucsf-vpn'?
if [ -n "\${UCSF_VPN_VERSION}" ]; then
ucsf_vpn_log() {
echo "[\$(date --iso-8601=seconds)] \$*" >> "\${UCSF_VPN_LOGFILE}"
}
ucsf_vpn_log "\$* ..."
ucsf_vpn_log "UCSF_VPN_VERSION=\${UCSF_VPN_VERSION}"
ucsf_vpn_log "UCSF_VPN_FLAVOR=\${UCSF_VPN_FLAVOR}"
if [ "\$1" = "connect" ]; then
_hook_="pre-connect"
else
_hook_="\$1"
fi
ucsf_vpn_log "hook=\${_hook_}"
_hook_file_="\${UCSF_VPN_FLAVOR}/\${_hook_}.sh"
ucsf_vpn_log "\${_hook_file_} ..."
if [ -f "\${_hook_file_}" ]; then
_hook_status_="done"
# shellcheck disable=SC1090
. "\${_hook_file_}" || _hook_status_="error"
ucsf_vpn_log "\${_hook_file_} ... \${_hook_status_}"
else
ucsf_vpn_log "\${_hook_file_} ... non-existing"
fi
ucsf_vpn_log "\$* ... done"
fi
HOOK_SCRIPT_EOF
}

function install_vpnc() {
local file filename dest hooks_dir dir path

file="$(mktemp -d)/ucsf-vpn-flavors.sh"
ucsf-vpn-flavors_code > "${file}"

find_vpnc-script > /dev/null
hooks_dir=$(find_hooks_dir)

mdebug "install_vpnc() ..."
mdebug " - hooks folder: ${hooks_dir}"
mdebug " - template: ${file}"

assert_sudo "install-vpnc"

sudo mkdir -p "${hooks_dir}"
[[ -d "${hooks_dir}" ]] || merror "Failed to create directory: ${hooks_dir}"

filename=$(basename "${file}")
dest="${hooks_dir}/${filename}"
sudo cp "${file}" "${dest}"
sudo chmod ugo+r "${dest}"
[[ -f "${dest}" ]] || merror "Failed to create file: ${dest}"
mdebug " - copied generic hook script: ${dest}"

for dir in pre-init connect post-connect disconnect post-disconnect attempt-reconnect post-attempt-reconnect reconnect; do
path=${hooks_dir}/${dir}
sudo mkdir -p "${path}"
[[ -d "${path}" ]] || merror "Failed to create directory: ${path}"
dest="${path}/${filename}"
sudo ln -fs "${hooks_dir}/${filename}" "${dest}"
[[ -L "${dest}" ]] || merror "Failed to create symbol link: ${dest} -> ${hooks_dir}/${filename}"
mdebug " - added symbolic link: ${dest} -> ${hooks_dir}/${filename}"
done

rm "${file}"
mdebug "install_vpnc() ... done"
}


function logfile() {
local path file

Expand Down Expand Up @@ -1309,23 +1415,25 @@ while [[ $# -gt 0 ]]; do

## Commands:
if [[ "$1" == "start" ]]; then
action=start
action=$1
elif [[ "$1" == "stop" ]]; then
action=stop
action=$1
elif [[ "$1" == "toggle" ]]; then
action=toggle
action=$1
force=true
elif [[ "$1" == "restart" ]]; then
action=restart
action=$1
force=true
elif [[ "$1" == "status" ]]; then
action=status
action=$1
elif [[ "$1" == "details" ]]; then
action=details
action=$1
elif [[ "$1" == "routing" ]]; then
action=routing
action=$1
elif [[ "$1" == "install-vpnc" ]]; then
action=$1
elif [[ "$1" == "log" ]]; then
action=log
action=$1
elif [[ "$1" == "troubleshoot" ]]; then
pulse_is_defunct
elif [[ "$1" == "open-gui" ]]; then
Expand Down Expand Up @@ -1559,6 +1667,9 @@ elif [[ $action == "details" ]]; then
elif [[ $action == "routing" ]]; then
routing_details
_exit $?
elif [[ $action == "install-vpnc" ]]; then
install_vpnc
_exit $?
elif [[ $action == "start" ]]; then
openconnect_start
res=$?
Expand Down
6 changes: 5 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ grep -q -F 'source "${incl}/' "${tmpl}"
file=$(sed -E 's/source "[$][{](incl)[}][/]([^.]+[.]sh)"/\1\/\2/' <<< "${line}")
cat "src/${file}"
echo
elif ! grep -q -E "^(# shellcheck source=|this=|incl=)" <<< "${line}"; then
elif [[ "${line}" == *'cat "${vpnc}/ucsf-vpn-flavors.sh"'* ]]; then
echo 'cat << HOOK_SCRIPT_EOF'
sed -E 's/[$]/\\$/g' src/vpnc/ucsf-vpn-flavors.sh
echo 'HOOK_SCRIPT_EOF'
elif ! grep -q -E "^(# shellcheck source=|this=|vpnc=|incl=)" <<< "${line}"; then
echo "${line}"
if [[ "${line}" == "#! /usr/bin/env bash" ]]; then
echo "###################################################################"
Expand Down
2 changes: 1 addition & 1 deletion src/incl/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function help() {
local what res

what=$1
res=$(grep "^###" "$0" | grep -vE '^(####|### whatis: )' | cut -b 5- | sed "s/{{pulsesvc_version}}/$(pulsesvc_version)/" | sed "s/{{openconnect_version}}/$(openconnect_version)/")
res=$(grep "^###" "$0" | grep -vE '^(####|### whatis: )' | cut -b 5- | sed "s/{{openconnect_version}}/$(openconnect_version)/")

if [[ $what == "full" ]]; then
res=$(echo "$res" | sed '/^---/d')
Expand Down
2 changes: 1 addition & 1 deletion src/incl/openconnect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function openconnect_start() {

## Assert that --flavor=<flavor> exists, if specified
flavor_home > /dev/null

assert_sudo "start"

## Load user credentials from file?
Expand Down
87 changes: 78 additions & 9 deletions src/ucsf-vpn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
### status Display VPN connection status
### details Display connection details in JSON format
### routing Display IP routing details
### install-vpnc Install 'ucsf-vpn' hook scripts
### log Display log file
###
### Options:
Expand Down Expand Up @@ -105,14 +106,15 @@
### * UCSF Managing Your Passwords:
### - https://it.ucsf.edu/services/managing-your-passwords
###
### Version: 5.8.0-9002
### Version: 5.8.0-9004
### Copyright: Henrik Bengtsson (2016-2024)
### License: GPL (>= 2.1) [https://www.gnu.org/licenses/gpl.html]
### Source: https://github.com/HenrikBengtsson/ucsf-vpn
call="$0 $*"

this="${BASH_SOURCE%/}"; [[ -L "${this}" ]] && this=$(readlink "${this}")
incl="$(dirname "${this}")/incl"
vpnc="$(dirname "${this}")/vpnc"

# shellcheck source=incl/output.sh
source "${incl}/output.sh"
Expand Down Expand Up @@ -349,6 +351,68 @@ function flavor_home() {
}


function find_vpnc-script() {
local file
file=$(openconnect --help | grep -E "vpnc-script" | sed 's/[^"]*"//' | sed 's/".*//')
if [[ -z "${file}" ]]; then
merror "Failed to locate the default 'vpnc-script' script. It appears that openconnect --help does not specify it"
fi
echo "${file}"
}

function find_hooks_dir() {
local file dir
find_vpnc-script > /dev/null
file=$(find_vpnc-script)
dir=$(grep -E "^HOOKS_DIR=" "${file}" | sed 's/[^=]*=//' | sed 's/[[:blank:]]$//')
echo "${dir}"
}


function ucsf-vpn-flavors_code() {
cat "${vpnc}/ucsf-vpn-flavors.sh"
}

function install_vpnc() {
local file filename dest hooks_dir dir path

file="$(mktemp -d)/ucsf-vpn-flavors.sh"
ucsf-vpn-flavors_code > "${file}"

find_vpnc-script > /dev/null
hooks_dir=$(find_hooks_dir)

mdebug "install_vpnc() ..."
mdebug " - hooks folder: ${hooks_dir}"
mdebug " - template: ${file}"

assert_sudo "install-vpnc"

sudo mkdir -p "${hooks_dir}"
[[ -d "${hooks_dir}" ]] || merror "Failed to create directory: ${hooks_dir}"

filename=$(basename "${file}")
dest="${hooks_dir}/${filename}"
sudo cp "${file}" "${dest}"
sudo chmod ugo+r "${dest}"
[[ -f "${dest}" ]] || merror "Failed to create file: ${dest}"
mdebug " - copied generic hook script: ${dest}"

for dir in pre-init connect post-connect disconnect post-disconnect attempt-reconnect post-attempt-reconnect reconnect; do
path=${hooks_dir}/${dir}
sudo mkdir -p "${path}"
[[ -d "${path}" ]] || merror "Failed to create directory: ${path}"
dest="${path}/${filename}"
sudo ln -fs "${hooks_dir}/${filename}" "${dest}"
[[ -L "${dest}" ]] || merror "Failed to create symbol link: ${dest} -> ${hooks_dir}/${filename}"
mdebug " - added symbolic link: ${dest} -> ${hooks_dir}/${filename}"
done

rm "${file}"
mdebug "install_vpnc() ... done"
}


function logfile() {
local path file

Expand Down Expand Up @@ -417,23 +481,25 @@ while [[ $# -gt 0 ]]; do

## Commands:
if [[ "$1" == "start" ]]; then
action=start
action=$1
elif [[ "$1" == "stop" ]]; then
action=stop
action=$1
elif [[ "$1" == "toggle" ]]; then
action=toggle
action=$1
force=true
elif [[ "$1" == "restart" ]]; then
action=restart
action=$1
force=true
elif [[ "$1" == "status" ]]; then
action=status
action=$1
elif [[ "$1" == "details" ]]; then
action=details
action=$1
elif [[ "$1" == "routing" ]]; then
action=routing
action=$1
elif [[ "$1" == "install-vpnc" ]]; then
action=$1
elif [[ "$1" == "log" ]]; then
action=log
action=$1
elif [[ "$1" == "troubleshoot" ]]; then
pulse_is_defunct
elif [[ "$1" == "open-gui" ]]; then
Expand Down Expand Up @@ -667,6 +733,9 @@ elif [[ $action == "details" ]]; then
elif [[ $action == "routing" ]]; then
routing_details
_exit $?
elif [[ $action == "install-vpnc" ]]; then
install_vpnc
_exit $?
elif [[ $action == "start" ]]; then
openconnect_start
res=$?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
# Use user-specific UCSF VPN configurations
#
# Install:
# mkdir -p /etc/vpnc/connect.d/
# cp ucsf-vpn-flavors.sh /etc/vpnc/connect.d/
# ucsf vpn install-vpnc
#
# Requires:
# https://github.com/HenrikBengtsson/ucsf-vpn
Expand Down

0 comments on commit 4d6fb8b

Please sign in to comment.