OpenConnect_macOS_Bar/bibVPN.sh

297 lines
15 KiB
Bash
Raw Normal View History

2023-02-10 08:54:11 +01:00
#!/bin/bash
# Get current status of a VPN connection with options to connect/disconnect.
# Working with OpenConnect, but can work with any executable VPN. Commands
# that require admin permissions should be whitelisted with 'visudo', e.g.:
#
#joesmith ALL=(ALL) NOPASSWD: /usr/local/bin/openconnect
#joesmith ALL=(ALL) NOPASSWD: /usr/bin/killall -2 openconnect
# <xbar.title>VPN Status</xbar.title>
2023-05-11 13:08:32 +02:00
# <xbar.version>v1.3</xbar.version>
2023-03-10 01:16:31 +01:00
# <xbar.author>Thomas Schmauder</xbar.author>
# <xbar.author.github>itssct</xbar.author.github>
2023-02-10 08:54:11 +01:00
# <xbar.desc>Displays status of a VPN interface with option to connect/disconnect.</xbar.desc>
# <xbar.image>http://i.imgur.com/RkmptwO.png</xbar.image>
2023-03-10 01:16:31 +01:00
# <xbar.dependencies>openconnect</xbar.dependencies>
# <xbar.about>https://git.bib.de/itssct/OpenFortiVPN_macOS</xbar.about>
# <swiftbar.hideAbout>true</swiftbar.hideAbout>
# <swiftbar.hideRunInTerminal>true</swiftbar.hideRunInTerminal>
# <swiftbar.hideLastUpdated>false</swiftbar.hideLastUpdated>
# <swiftbar.hideDisablePlugin>true</swiftbar.hideDisablePlugin>
# <swiftbar.hideSwiftBar>true</swiftbar.hideSwiftBar>
2023-02-24 15:28:03 +01:00
###################
2023-02-24 15:21:55 +01:00
#### Variables ####
2023-02-24 15:28:03 +01:00
###################
VERSION='1.5.1'
2023-02-24 15:21:55 +01:00
WORKDIR="/Users/$USER/.openconnect"
mkdir -p $WORKDIR
LOG="$WORKDIR/bibVPN.log"
ERRORLOG="$WORKDIR/ERROR.log"
echo -e "\nStart: $(date)" >>$LOG
echo "Run $0 $@" >> $LOG
PATH=$PATH:/usr/local/bin
2023-02-10 08:54:11 +01:00
VPN_EXECUTABLE=$(which openconnect)
2023-02-24 15:21:55 +01:00
OC_PIDFILE="$WORKDIR/vpn.bib.de.pid"
2023-05-12 17:04:06 +02:00
SETTINGSFILE="$WORKDIR/settings.txt"
2023-02-24 15:21:55 +01:00
ACCOUNTFILE="$WORKDIR/accounts.csv"
2023-02-10 08:54:11 +01:00
VPN_USERNAME="$2"
2023-02-24 15:28:03 +01:00
VPN_HOST="$3"
2023-03-10 01:16:31 +01:00
#### Settings ####
2023-05-12 17:04:06 +02:00
SHOW_SETTINGS='true'
SHOW_ICON='true'
SHOW_COLOR='true'
DEBUG_OUTPUT='false'
2023-03-10 01:16:31 +01:00
NET_FILTER='inet 172.[123][0-9].1[67][80].'
2023-02-24 15:28:03 +01:00
###################
2023-02-24 15:21:55 +01:00
#### Functions ####
2023-02-24 15:28:03 +01:00
###################
2023-05-12 17:04:06 +02:00
function saveSettings(){
echo "Speichere die Einstellungen" >> $LOG
2023-05-12 17:04:06 +02:00
echo "SHOW_SETTINGS='$SHOW_SETTINGS'
SHOW_ICON='$SHOW_ICON'
SHOW_COLOR='$SHOW_COLOR'
DEBUG_OUTPUT=$DEBUG_OUTPUT" | tee $SETTINGSFILE
2023-05-12 17:04:06 +02:00
echo "Lade die Einstellungsdatei" >> $LOG
2023-05-12 17:04:06 +02:00
source $SETTINGSFILE
open swiftbar://refreshplugin?name=$(basename $0)
}
2023-02-24 15:21:55 +01:00
function askFor(){
2023-05-11 13:08:32 +02:00
osascript="$1 buttons {\"Cancel\",\"OK\"} default button {\"OK\"} cancel button \"Cancel\" with title \"Neuen User für das VPN anlegen\" with icon caution"
#üecho $osascript >> $LOG
2023-03-15 13:07:44 +01:00
results=$( /usr/bin/osascript -e "$osascript")
2023-05-11 13:08:32 +02:00
if [[ $? != 0 ]]; then
2023-05-12 17:47:14 +02:00
clmsg='display notification "" with title "OpenConnectVPN" subtitle "Beende mich" sound name "Submarine"'
2023-05-11 13:08:32 +02:00
osascript -e "$clmsg"
exit 2
else
#echo $results >> $LOG
2023-05-11 13:08:32 +02:00
theButton=$( echo "$results" | /usr/bin/awk -F "button returned:|," '{print $2}' )
theText=$( echo "$results" | /usr/bin/awk -F "text returned:" '{print $2}' )
2023-02-14 21:31:49 +01:00
2023-05-11 13:08:32 +02:00
if [[ $theButton == "OK" ]] ;then
2023-05-12 17:04:06 +02:00
if [ -z $theText ];then
echo "OK"
else
echo $theText
fi
2023-05-11 13:08:32 +02:00
elif [[ $theButton == "Cancel" ]] ; then
2023-05-12 17:47:14 +02:00
clmsg='display notification "" with title "OpenConnectVPN" subtitle "Beende mich" sound name "Submarine"'
2023-05-11 13:08:32 +02:00
osascript -e "$clmsg"
2023-05-12 17:47:14 +02:00
break
2023-05-11 13:08:32 +02:00
exit 2
fi
2023-02-14 21:31:49 +01:00
fi
}
2023-02-24 15:21:55 +01:00
function showSettings()
2023-05-12 17:04:06 +02:00
{
echo '---'
echo "Neues **VPN** Profil anlegen | shell='$0' param1=newuser terminal=false refresh=true md=true"
if [[ $SHOW_SETTINGS == "true" ]]; then
2023-02-24 15:21:55 +01:00
echo "---"
echo "Settings"
2023-05-12 17:04:06 +02:00
echo "--Icons verwenden | shell='$0' terminal=false param1=toggleIcon tooltip='Icon im Menü anzeigen oder Text' checked=$SHOW_ICON"
echo "--Farbiges Icon/Schrift | shell='$0' terminal=false param1=toggleColor tooltip='Icon oder Schrift einfärben oder eintönig lassen' checked=$SHOW_COLOR"
2023-03-15 13:07:44 +01:00
echo "---"
2023-05-11 13:08:32 +02:00
echo "-- --- INFOS ---"
echo "--**Logfile:** *${LOG}* | shell='$0' param1=openlog terminal=false refresh=true tooltip='Das Logfile öffnen' md=true"
2023-05-11 14:02:24 +02:00
echo "--${SETTINGSFILE} | shell='$0' param1=openDIR terminal=false refresh=true tooltip='Ordner öffnen'"
2023-05-11 13:08:32 +02:00
echo "--Script: $(basename -- "$0") Version: **v$VERSION** | href="https://git.bib.de/itssct/OpenFortiVPN_macOS" terminal=false refresh=true tooltip='Die Projektwebsite im Browser öffnen' md=true"
2023-05-12 17:04:06 +02:00
if [[ $DEBUG_OUTPUT == 'true' ]] ; then
echo "-- --- DEBUG ---"
echo "--SHOW_ICON: $SHOW_ICON"
echo "--SHOW_COLOR: $SHOW_COLOR"
echo "--COLOR_CONNECTED: $COLOR_CONNECTED"
echo "--COLOR_UNCONNECTED: $COLOR_UNCONNECTED"
fi
2023-02-24 15:21:55 +01:00
fi
}
###################
#### Prüfungen ####
###################
if [ -f $SETTINGSFILE ] ; then
echo "Lade die Einstellungsdatei" >> $LOG
source $SETTINGSFILE
else
saveSettings
fi
if [ $SHOW_COLOR == 'true' ] ; then
COLOR_CONNECTED='green'
COLOR_UNCONNECTED='crimson'
else
COLOR_CONNECTED='none'
COLOR_UNCONNECTED='none'
fi
# A command that will result in your VPN password.
2024-10-11 08:52:42 +02:00
GET_VPN_PASSWORD="security find-generic-password -w -l openconnect -a $VPN_USERNAME 2>&1"
# Command to determine if VPN is connected or disconnected
VPN_CONNECTED="ifconfig | egrep -A1 '$NET_FILTER' |cut -d' ' -f2"
# Command to run to disconnect VPN
VPN_DISCONNECT_CMD="sudo killall -2 openconnect"
# Get IP of Current VPN Tunnel
IP=$(ifconfig | egrep -A1 "$NET_FILTER" |cut -d' ' -f2)
2023-02-24 15:28:03 +01:00
###################
###### MAIN #######
###################
2023-02-10 08:54:11 +01:00
case "$1" in
connect)
rm -f $ERRORLOG
echo "$GET_VPN_PASSWORD" >> $LOG
2023-02-10 08:54:11 +01:00
VPN_PASSWORD=$(eval "$GET_VPN_PASSWORD")
2023-02-24 15:28:03 +01:00
# Passwort checken
2023-05-12 17:47:14 +02:00
if [[ $VPN_PASSWORD =~ 'item could not be found in the keychain.' ]] ; then
echo "Es konnte kein Passwort für $VPN_USERNAME gefunden werden" >> $LOG
2023-05-11 13:08:32 +02:00
NEW_VPN_PASSWORD=$(askFor 'display dialog "Es ist kein Passwort im Schlüsselbund vorhanden. Wie lautet das Passwort für '$VPN_USERNAME'? " default answer "Mein Passwort..." with hidden answer')
if [[ $? != 0 ]]; then exit 2 ; fi # Beim Abbruch der Maske, gesamte Script beenden.
#echo $VPN_PASSWORD
2023-05-11 13:08:32 +02:00
VPN_PASSWORD=$NEW_VPN_PASSWORD
#echo "security add-generic-password -a $VPN_USERNAME -s openconnect -w '$VPN_PASSWORD'" >> $LOG
2023-05-12 17:04:06 +02:00
SAVE_PASSWORD=$(askFor 'display dialog "Soll das Passwort, dauerhaft im Schlüsselbund gespeichert werden? "')
if [[ $SAVE_PASSWORD == "OK" ]]; then
security add-generic-password -a $VPN_USERNAME -s openconnect -T /usr/bin/security -w "$NEW_VPN_PASSWORD"
fi
2023-05-11 13:08:32 +02:00
#else
#echo "VPN PASSWORT: $VPN_PASSWORD" >> $LOG
2023-05-11 13:08:32 +02:00
fi
VPN_EXECUTABLE_PARAMS="--passwd-on-stdin --servercert $4 --protocol=fortinet --pid-file=$OC_PIDFILE --background" # Optional
2023-02-24 15:28:03 +01:00
# Verbindung aufbauen
echo "<pseudoPasswort>| sudo $VPN_EXECUTABLE $VPN_EXECUTABLE_PARAMS --user $VPN_USERNAME $VPN_HOST" >> $LOG
echo "$VPN_PASSWORD" | sudo $VPN_EXECUTABLE $VPN_EXECUTABLE_PARAMS --user $VPN_USERNAME $VPN_HOST 2> $ERRORLOG 1>> $LOG
2023-05-11 13:08:32 +02:00
if [[ $? != 0 ]]; then
if [ -f $ERRORLOG ] ; then
cat $ERRORLOG >> $LOG
if grep -q "None of the 1 fingerprint(s) specified via --servercert match server's certificate:" $ERRORLOG ; then
newServerCert=$(grep -o 'pin-.*=$' $ERRORLOG)
echo "Das Servercert ist nicht aktuell. Dieses muss aktualisiert werden. (ALT: $4 | NEU: $newServerCert)" >> $LOG
dialogCert=$(osascript -e "display alert \"Das Servercert ist nicht aktuell. \nSoll dieses aktualisiert werden?\n\nAlt : \n$4\n\nNeu : \n$newServerCert\" buttons {\"Nein\", \"Ja\"}")
theButton=$( echo "$dialogCert" | /usr/bin/awk -F "button returned:|," '{print $2}' )
if [[ $theButton == "Ja" ]] ;then
echo "Ändere das Servercert" >> $LOG
# sed mit | statt / , da im String auch Slashes vorhanden sein können.
echo "sed -i '' -e \"s|$4|$newServerCert|g\" $ACCOUNTFILE" >> $LOG
sed -i '' -e "s|$4|$newServerCert|g" $ACCOUNTFILE
if [[ $? = 0 ]]; then
osascript -e 'display alert "Erfolgreich geändert. Bitte die Verbindung erneut aufbauen."'
fi
else
echo "Wie du willst. Das Servercert wird nicht geändert." >> $LOG
fi
elif grep -q "nodename nor servname provided, or not known" $ERRORLOG; then
echo "Verbindungsaufbau fehlgeschlagen. $VPN_HOST kann nicht aufgelöst werden." >> $LOG
osascript -e "display notification \"Verbindungsaufbau fehlgeschlagen. $VPN_HOST kann nicht aufgelöst werden.\" with title \"OpenConnectVPN\" subtitle \"Schade\" sound name \"Brise\""
fi
else
osascript -e 'display notification "Verbindungsaufbau fehlgeschlagen. Bitte im Log prüfen, was die Ursache ist." with title "OpenConnectVPN" subtitle "Schade" sound name "Brise"'
fi
exit
fi
2023-02-24 15:21:55 +01:00
IP=$(ifconfig | egrep -A1 "$NET_FILTER" |cut -d' ' -f2)
2023-05-11 13:08:32 +02:00
ii=0
while [ -z $IP ] && [[ $ii != 20 ]]; do echo "noch keine IP" ; sleep 0.5 ; IP=$(ifconfig | egrep -A1 "$NET_FILTER"|cut -d' ' -f2) ; ((ii++)) ; done
2023-05-12 17:47:14 +02:00
msg='display notification "Erfolgreich verbunden \nConnected User: '$VPN_USERNAME'" with title "OpenConnectVPN" subtitle "Deine IP lautet: '$IP'" sound name "Brise"'
errmsg='display notification "Verbindungsversuch nicht erfolgreich. Vermutlich ist das Passwort falsch." with title "OpenConnectVPN" subtitle "Schade" sound name "Brise"'
2023-05-12 17:04:06 +02:00
if [[ $IP =~ 172 ]] ; then
osascript -e "$msg" ;
else
osascript -e "$errmsg"
echo "Vermutlich ist das Passwort falsch. Es konnte keine Verbindung hergestellt werden." >> $LOG
2023-05-12 17:04:06 +02:00
exit 5 ;
fi
2023-02-10 08:54:11 +01:00
# Wait for connection so menu item refreshes instantly
until eval "$VPN_CONNECTED"; do sleep 1; done
;;
disconnect)
eval "$VPN_DISCONNECT_CMD"
# Wait for disconnection so menu item refreshes instantly
2023-03-10 01:16:31 +01:00
until [ -z "$(eval "$VPN_CONNECTED")" ]; do sleep 1; eval "$VPN_CONNECTED" ;done
2023-05-12 17:47:14 +02:00
osascript -e 'display notification "VPN Tunnel erfolgreich geschlossen" with title "OpenConnectVPN" subtitle "Mach Feierabend" sound name "Submarine"'
2023-02-10 08:54:11 +01:00
;;
newuser)
2023-05-11 14:02:24 +02:00
#echo "Sie wollen einen weiteren Benutzer für das VPN anlegen. Geben Sie dazu die folgenden Dinge ein."
askFor 'display dialog "Sie wollen einen weiteren Benutzer für das VPN anlegen. Geben Sie dazu die benötigten Daten an."'
2023-05-12 17:47:14 +02:00
NEW_VPN_NAME=$(askFor 'display dialog "Wie soll die neue Verbindung heißen?" default answer "bib | eduUP | FHDW"' ); if [[ $? != 0 ]]; then exit 2 ; fi # Beim Abbruch der Maske, gesamte Script beenden.
NEW_VPN_USERNAME=$(askFor 'display dialog "Wie lautet die E-Mail des Benutzers, der zum Verbinden verwendet werden soll?" default answer "vorname.nachname@bib.de"' ); if [[ $? != 0 ]]; then exit 2 ; fi
NEW_VPN_HOST=$(askFor 'display dialog "Wie lautet der Servername?" default answer "vpn.bib.de"'); if [[ $? != 0 ]]; then exit 2 ; fi
2023-03-15 13:07:44 +01:00
if [[ -z $NEW_VPN_NAME ]] ; then echo -n "Wie lautet der Name der neuen Verbindung? " ; read NEW_VPN_NAME ; fi
if [[ -z $NEW_VPN_HOST ]] ; then echo -n "Wie lautet der VPN-Server? "; read NEW_VPN_HOST ; fi
if [[ -z $NEW_VPN_USERNAME ]] ; then echo -n "Wie lautet die E-Mail des Benutzers? " ; read NEW_VPN_USERNAME ; fi
2023-02-14 21:31:49 +01:00
NEW_VPN_PUBKEY=$(gnutls-cli --print-cert $NEW_VPN_HOST |grep -e 'pin-.*:'|awk '{$1=$1;print}')
NEW_VPN_PASSWORD=$(security find-generic-password -g -a $NEW_VPN_USERNAME 2>&1 ) # >>$LOG) #>/dev/null)
2023-02-14 21:31:49 +01:00
if [[ $NEW_VPN_PASSWORD =~ password ]] ; then
echo "Es ist bereits ein Passwort im Schlüsselbund für $NEW_VPN_USERNAME hinterlegt."
else
2023-05-11 13:08:32 +02:00
echo -n "Es ist noch kein Passwort im Schlüsselbund hinterlegt. Bitte einmal das Passwort angeben : " ;
2023-05-11 14:02:24 +02:00
NEW_VPN_PASSWORD=$(askFor 'display dialog "Es ist kein Passwort im Schlüsselbund vorhanden. Wie lautet das Passwort? " default answer "Mein Passwort..." with hidden answer')
2023-05-12 17:04:06 +02:00
SAVE_PASSWORD=$(askFor 'display dialog "Soll das Passwort, dauerhaft im Schlüsselbund gespeichert werden? "')
if [[ $SAVE_PASSWORD == "OK" ]] ; then
security add-generic-password -a $NEW_VPN_USERNAME -s openconnect -w $NEW_VPN_PASSWORD
fi
2023-02-10 08:54:11 +01:00
fi
echo "$NEW_VPN_NAME,$NEW_VPN_USERNAME,$NEW_VPN_HOST,$NEW_VPN_PUBKEY" >> $LOG >> $ACCOUNTFILE
2023-05-11 14:02:24 +02:00
# Refreshen, damit das Profil direkt angezeigt wird.
2023-05-12 17:04:06 +02:00
open swiftbar://refreshplugin?name=$(basename $0)
osascript -e 'display notification "VPN Profil '$NEW_VPN_NAME' erfolgreich angelegt" with title "OpenVPN" subtitle "'$NEW_VPN_HOST' - '$NEW_VPN_USERNAME'" sound name "Brise"'
2023-05-11 13:08:32 +02:00
;;
openlog)
open -a console $LOG
2023-02-10 08:54:11 +01:00
;;
2023-05-11 14:02:24 +02:00
openDIR)
open ${WORKDIR}
;;
2023-05-12 17:04:06 +02:00
toggleColor)
if [ $SHOW_COLOR == 'false' ];then SHOW_COLOR='true';else SHOW_COLOR='false' ; fi
echo "Switche den Farbmodus ($SHOW_COLOR)" >> $LOG
2023-05-12 17:04:06 +02:00
saveSettings
;;
toggleIcon)
if [ $SHOW_ICON == 'false' ];then SHOW_ICON='true';else SHOW_ICON='false' ; fi
echo "Switche den Iconmodus ($SHOW_ICON)" >> $LOG
2023-05-12 17:04:06 +02:00
saveSettings
;;
2023-02-10 08:54:11 +01:00
esac
if [ -f $OC_PIDFILE ]; then
2023-05-12 17:04:06 +02:00
if [ $SHOW_ICON == 'true' ]; then echo ":firewall.fill:| sfcolor=$COLOR_CONNECTED sfsize=17" ; else echo "VPN ✔ | color=$COLOR_CONNECTED" ; fi
2023-02-10 08:54:11 +01:00
echo '---'
echo "Disconnect VPN | bash='$0' param1=disconnect terminal=false refresh=true"
2023-02-24 15:21:55 +01:00
aUser=$(ps -ef | grep -e '--user\ ' | cut -d' ' -f 32)
if [[ $aUser =~ .*@.* ]]; then echo "User: $aUser" ; fi
2023-02-10 08:54:11 +01:00
echo "IP: $IP"
2024-10-11 08:52:42 +02:00
pidTime=$(stat $OC_PIDFILE | cut -d'"' -f4)
startZeit=$(date -j -f "%b %d %H:%M:%S %Y" "$pidTime" +%s)
now=$(date +%s)
seitZeit="$(( (now-startZeit) ))"
echo "Verbunden seit: $pidTime ($seitZeit Sek ~ $(( seitZeit/60 )) Min) "
2023-02-24 15:21:55 +01:00
showSettings
2023-02-10 08:54:11 +01:00
exit
else
2023-05-12 17:04:06 +02:00
if [ $SHOW_ICON == 'true' ] ; then echo ":firewall:| sfcolor=$COLOR_UNCONNECTED sfsize=17" ; else echo "VPN X | color=$COLOR_UNCONNECTED" ; fi
2023-02-10 08:54:11 +01:00
echo '---'
# Alle User aus der accounts.csv auslesen und dann zur Auswahl anbieten.
cat "$ACCOUNTFILE" | while IFS= read config;
2023-02-24 15:21:55 +01:00
do
[[ $config =~ ^#.* ]] && continue
cfgName=$(echo $config|cut -d',' -f1)
cfgMail=$(echo $config|cut -d',' -f2)
cfgHost=$(echo $config|cut -d',' -f3)
cfgPubKey=$(echo $config|cut -d',' -f4)
2023-02-24 15:21:55 +01:00
echo "Connect $cfgName VPN | shell='$0' param1=connect param2=$cfgMail param3=$cfgHost param4=$cfgPubKey terminal=false refresh=true"
2023-02-10 08:54:11 +01:00
done
2023-02-24 15:21:55 +01:00
showSettings
2023-02-10 08:54:11 +01:00
exit
fi