I am working on a bash script that uses openconnect to connect a VPN with a smartcard or RSA token using Zenity (end user friendly) which prompts users for the required variable(s) before calling the expect spawn process. It works great unless RSA token gets out of sync, requiring the user to enter the next tokencode.
Does anyone know how to successfully call zenity after starting the spawn process? I need to define a new variable ($token) with zenity and apply it to expect script that is in process. Since it is requesting the next token code, I can't predefine the variable before calling the spawn process. Below is part of the bash script. Also, this script runs in the background. The user does not see the script running in a terminal.
function rsa() {
while [ -z "$user" ]; do
user
if [[ $? -eq 1 ]]; then
exit 1
fi
done
while [ -z "$pin" ]; do
pin
if [[ $? -eq 1 ]]; then
exit 1
elif [ -n "$pin" ]; then
notify-send -t 10000 "Starting VPN" "Attempting connection to the network."
expect -c "
spawn sudo openconnect https://***removed*** -g ***removed*** -u $user --no-dtls --no-cert-check --no-xmlpost
expect {
\"Failed to obtain WebVPN cookie\" {
puts [exec notify-send -t 10000 \"Connection Unsuccessful\" \"Connection attempt halted.\"]
exit
}
\"Password:\" {
send $pin\r
expect {
\"TOKENCODE:\" {
***need to call zenity and define $token here***
send $token\r
interact
}
\"Login failed\" {
puts [exec notify-send -t 10000 \"Incorrect PIN\" \"Connection attempt halted.\"]
exit
}
\"Failed to obtain WebVPN cookie\" {
puts [exec notify-send -t 10000 \"Connection Unsuccessful\" \"Connection attempt halted.\"]
exit
}
\"Connected tun0\" {
puts [exec notify-send -t 10000 \"Connection Successful\" \"VPN Connected\"]
interact
}
}
}
}"
fi
done
exit
}
You don't need to use spawn
: since expect is built on Tcl, you can use exec
to call zenity:
# the quoting for the --text option looks funny, but Tcl requires that
# the quote appear at the start of a word
# (otherwise a quote is just a regular character)
set status [catch {exec zenity --entry "--text=Enter the current RSA token"} token]
If the user clicked OK, the entered text will be in $token and $status will be 0.
If the user clicked Cancel or hit Esc, then the $status will be 1 and $token holds the string "child process exited abnormally". Presumably, the user does not want to continue, so you can do:
if {$status != 0} exit