Last active
February 14, 2023 14:20
-
-
Save toonetown/b45ccff51065cc33d982c10989c85590 to your computer and use it in GitHub Desktop.
Leverages ssh and openconnect to connect Shimo to PulseSecure hosts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
: ${NUM_FAILURES_ALLOWED:=10} | |
: ${SLEEP_PING_TIME:=10} | |
if [ "${1}" == "-c" -a -n "${2}" ]; then SHIMO_SCRIPT_CFG="${2}"; shift 2; fi | |
if [ -n "${SHIMO_SCRIPT_CFG}" ]; then | |
: ${SHIMO_HOME:="${HOME}/Library/Application Support/Shimo"} | |
: ${SHIMO_SCRIPT_HOME:="${SHIMO_HOME}/Scripts"} | |
: ${SHIMO_CONFIG_DIR:="${SHIMO_SCRIPT_HOME}/${SHIMO_SCRIPT_CFG}"} | |
: ${PULSE_VPN_CONF:="${SHIMO_CONFIG_DIR}/openconnect.conf"} | |
[ -f "${PULSE_VPN_CONF}" ] && export PULSE_VPN_CONF || echo "${PULSE_VPN_CONF} not found" >&2; | |
fi | |
if [ "${1}" == "env" ]; then | |
[[ $0 != "$BASH_SOURCE" ]] || { echo "Usage: source ${0} env [msg]" >&2; exit 1; } | |
[ -f "${HOME}/.bashrc" ] && source "${HOME}/.bashrc" | |
[ -n "${SHIMO_CONFIG_DIR}" ] || { echo "Requires SHIMO_CONFIG_DIR to be set" >&2; return 1; } | |
[[ ${SHIMO_CONFIG_DIR} != /* ]] && SHIMO_CONFIG_DIR="$(dirname "${0}")/${SHIMO_CONFIG_DIR}" | |
[ -d "${SHIMO_CONFIG_DIR}" ] || { echo "Configuration directory ${SHIMO_CONFIG_DIR} does not exist" >&2; return 1; } | |
: ${PULSE_VPN_CONF:="${SHIMO_CONFIG_DIR}/openconnect.conf"} | |
[ -f "${PULSE_VPN_CONF}" ] || { echo "${PULSE_VPN_CONF} not found" >&2; return 1; } | |
export PULSE_VPN_CONF | |
VPNC_SCRIPT="$(cat "${PULSE_VPN_CONF}" | grep '^script=' | cut -d'=' -f2 | sed -e 's/"//g')" | |
grep -q "env-only" "${VPNC_SCRIPT}" && source "${VPNC_SCRIPT}" env-only | |
[ -n "${SHIMO_ACCOUNT}" ] || { echo "Requires SHIMO_ACCOUNT to be set" >&2; return 1; } | |
SHIMO_INFO="$(sqlite3 "${HOME}/Library/Application Support/Shimo/Shimo4Profiles.sqlite" \ | |
"select zusername, zremotehost from zbaseaccount where zaccountname='${SHIMO_ACCOUNT}';")" | |
[ -n "${SHIMO_INFO}" ] || { echo "Could not find info for '${SHIMO_ACCOUNT}'" >&2; return 1; } | |
export PULSE_KEYCHAIN_ITEM="Shimo: ${SHIMO_ACCOUNT}" | |
export PULSE_VPN_USER="$(echo "${SHIMO_INFO}" | cut -d'|' -f1)" | |
export PULSE_VPN_HOST="$(echo "${SHIMO_INFO}" | cut -d'|' -f2)" | |
[ -x "${SHIMO_CONFIG_DIR}/env" ] && source "${SHIMO_CONFIG_DIR}/env" | |
[ -n "${2}" ] && echo "${SHIMO_ACCOUNT} ${2}" | |
return 0 | |
fi | |
if [ "$(id -u)" != "0" ]; then sudo "${0}" "$@"; exit $?; fi | |
if [ "${1}" == "setup" ]; then | |
[ -n "${PULSE_KEYCHAIN_ITEM}" ] || { echo "Requires PULSE_KEYCHAIN_ITEM to be set" >&2; exit 1; } | |
[ -f "${HOME}/.pulse-keychain" ] && { /usr/bin/security unlock-keychain -p "$(cat "${HOME}/.pulse-keychain")"; } | |
/usr/bin/security find-generic-password -s "${PULSE_KEYCHAIN_ITEM}" -w &>/dev/null && exit $? | |
/usr/bin/security delete-generic-password -s "TMP-${PULSE_KEYCHAIN_ITEM}" &>/dev/null | |
while [ -z "${_PW}" ]; do | |
_PW="$(osascript -e "set t to text returned of (display dialog \"Enter password for ${PULSE_KEYCHAIN_ITEM}\" \ | |
with title \"${PULSE_KEYCHAIN_ITEM} Password\" \ | |
default answer \"\" \ | |
buttons {\"Cancel\", \"Continue\"} \ | |
default button 2 \ | |
hidden answer true)")" || exit $? | |
done | |
/usr/bin/security add-generic-password -a "TMP-${PULSE_KEYCHAIN_ITEM}" \ | |
-s "TMP-${PULSE_KEYCHAIN_ITEM}" \ | |
-w "${_PW}" &>/dev/null | |
exit $? | |
fi | |
case "${1}" in | |
"ssh-vpn") | |
NC_HOST="${2}" | |
NC_PORT="${3}" | |
[ -n "${NC_HOST}" -a -n "${NC_PORT}" ] || { echo "Usage: ${0} ssh-vpn <NC_HOST> <NC_PORT> [wait]" >&2; exit 1; } | |
"${0}" wait start "${4:-60}" &>/dev/null && /usr/bin/nc "${NC_HOST}" "${NC_PORT}" | |
;; | |
"start") | |
[ "$("${0}" status)" == "Stopped" ] || { echo "Already running" >&2; exit 1; } | |
[ -n "${PULSE_KEYCHAIN_ITEM}" ] || { echo "Requires PULSE_KEYCHAIN_ITEM to be set" >&2; exit 1; } | |
[ -n "${PULSE_VPN_CONF}" ] || { echo "Requires PULSE_VPN_CONF to be set" >&2; exit 1; } | |
[ -n "${PULSE_VPN_HOST}" ] || { echo "Requires PULSE_VPN_HOST to be set" >&2; exit 1; } | |
[ -n "${PULSE_VPN_USER}" ] || { echo "Requires PULSE_VPN_USER to be set" >&2; exit 1; } | |
PIDFILE_STARTING="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2).start" | |
echo "$$" > "${PIDFILE_STARTING}" | |
[ -f "${HOME}/.pulse-keychain" ] && { /usr/bin/security unlock-keychain -p "$(cat "${HOME}/.pulse-keychain")"; } | |
echo -n "$( | |
/usr/bin/security find-generic-password -s "${PULSE_KEYCHAIN_ITEM}" -w 2>/dev/null || \ | |
/usr/bin/security find-generic-password -s "TMP-${PULSE_KEYCHAIN_ITEM}" -w 2>/dev/null \ | |
)" \ | |
| /usr/local/bin/openconnect --user="${PULSE_VPN_USER}" --passwd-on-stdin \ | |
--config="${PULSE_VPN_CONF}" \ | |
"${PULSE_VPN_HOST}" \ | |
>>/var/log/shimo-pulse-vpnc-conn.log \ | |
2>>/var/log/shimo-pulse-vpnc-conn.err || { | |
rm -f "${PIDFILE_STARTING}" | |
exit 1 | |
} | |
rm -f "${PIDFILE_STARTING}" | |
;; | |
"stop") | |
[ "$("${0}" status)" == "Starting" ] && { | |
PIDFILE_STARTING="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2).start" | |
rm -rf "${PIDFILE_STARTING}" | |
exit 0 | |
} | |
[ "$("${0}" status)" == "Running" ] || { echo "Already stopped" >&2; exit 1; } | |
[ -n "${PULSE_VPN_CONF}" ] || { echo "Requires PULSE_VPN_CONF to be set" >&2; exit 1; } | |
PIDFILE="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2)" | |
kill -SIGINT $(cat "${PIDFILE}") | |
;; | |
"reconnect") | |
[ "$("${0}" status)" == "Running" ] || { echo "Not running" >&2; exit 1; } | |
[ -n "${PULSE_VPN_CONF}" ] || { echo "Requires PULSE_VPN_CONF to be set" >&2; exit 1; } | |
PIDFILE="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2)" | |
kill -SIGUSR2 $(cat "${PIDFILE}") | |
;; | |
"restart") | |
"${0}" stop &>/dev/null; "${0}" start || exit $? | |
;; | |
"status") | |
[ -n "${PULSE_VPN_CONF}" ] || { echo "Requires PULSE_VPN_CONF to be set" >&2; exit 1; } | |
PIDFILE="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2)" | |
PIDFILE_STARTING="$(cat "${PULSE_VPN_CONF}" | grep '^pid-file=' | cut -d'=' -f2).start" | |
[ -d "$(dirname "${PIDFILE}")" ] || mkdir -p "$(dirname "${PIDFILE}")" | |
[ -f "${PIDFILE}" ] && { | |
rm -f "${PIDFILE_STARTING}"; echo "Running" | |
} || { | |
[ -f "${PIDFILE_STARTING}" ] && echo "Starting" || echo "Stopped" | |
} | |
;; | |
"wait") | |
[ -n "${PULSE_VPN_CONF}" ] || { echo "Requires PULSE_VPN_CONF to be set" >&2; exit 1; } | |
x=0; t=${3:-10}0; s=0 | |
case "${2}" in | |
"start") | |
while [ "$("${0}" status)" != "Running" -a ${x} -lt ${t} ]; do | |
[ "$("${0}" status)" == "Stopped" -a ${s} -eq 1 ] && { echo "Cancelled"; exit 1; } | |
[ "$("${0}" status)" == "Starting" ] && s=1 | |
x=$((x+1)); sleep .1 | |
done | |
;; | |
"stop") while [ "$("${0}" status)" != "Stopped" -a ${x} -lt ${t} ]; do x=$((x+1)); sleep .1; done ;; | |
*) echo "Invalid wait action '${2}'. Choose one of 'start', or 'stop'"; exit 1 ;; | |
esac | |
[ ${x} -lt ${t} ] && exit 0 || { echo "Timed out"; exit 1; } | |
;; | |
*) | |
echo "Invalid action '${1}'. Choose one of 'start', 'stop', 'reconnect', 'restart', 'status', 'setup' 'env'" | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment