Reputation: 6347
My VPN connection drops at regular intervals. I need to be able to programmatically reconnect when that happens.
Software: Endpoint Security VPN
Brand: Check Point
This is the AppleScript that I put together:
on run
log "VPN auto-connect script started - pinging service accessible only on the VPN.."
set shellScript to "if echo \"$(ping -c 1 -W 1 10.123.321.123 ; echo $?)\" | grep -q \"100.0% packet loss\"; then echo \"failure\"; else echo \"success\"; fi"
set pwd to do shell script "openssl enc -base64 -d <<< BaS364Enc0d3dPwdHere=="
repeat while true
try
log "Checking VPN connection pinging GitLab.."
set networkSuccess to do shell script shellScript
if not (networkSuccess = "success") then
log "VPN GOT DISCONNECTED! Reconnecting.."
do shell script "pkill -f \"Endpoint_Security_VPN\""
delay 10
tell application "Endpoint Security VPN" to activate
log "Launching VPN client.."
delay 3
tell application "System Events"
tell process "TextExpander"
keystroke pwd
delay 0.5
keystroke return
end tell
end tell
end if
log "Sleeping 1 min.."
delay 60
on error errMsg number errorNumber
if (errorNumber = -128) then
log "VPN script terminated"
exit repeat
end if
log ("An error occurred! " & errorNumber as text) & " - " & errMsg as text
delay 3
end try
end repeat
end run
Most of the times this does the trick but quite often instead, after killing "Endpoint Security VPN" and programmatically relaunching it, the software is ran only in the background (the icon appears in the MacOS toolbar). The fact that the GUI is not presented means that the AppleScript cannot interact with the GUI to re-enter the credentials and submit. (I can do so clicking on the icon in the toolbar and selecting Show Client).
How can I programmatically force the VPN client to appear?
This script did not work because I don't have /Library/Extensions/cpfw.kext
. Also, I would like to avoid sudo
.
Upvotes: 0
Views: 726
Reputation: 3184
First things first: if you're going to have a constantly running script like this, it is much more efficient (and much more aesthetically pleasing) to create a stay-open script application with an on idle
handler. Using delay
commands aren't bad per se but they freeze the script and clog up Script Editor. so I've rewritten your script with that in mind (note that I've used an external log file because we can't read the logs on a running script application).
Copy the following into Script Editor, then save it, choosing "Application" from the File Format popup, and clicking the "Stay open after run handler" checkbox. Then run the resulting app file like normal. It will sit in the background watching your VPN connection.
Aside from turning this into a script app, I've added loop-checks to ensure that actions are completing. The script waits until the VPN has definitely quit, it waits until it is definitively reopened, it waits until a window exists. If the window doesn't show it will try every 5 seconds to pull the app to the foreground again, but since I don't own this app I don't know that this will automatically open a window. If it doesn't, we may have to modify the script to open a window directly.
property logPath : POSIX path of (path to home folder from user domain) & "logFile.txt"
property shellScript : "if echo \"$(ping -c 1 -W 1 10.123.321.123 ; echo $?)\" | grep -q \"100.0% packet loss\"; then echo \"failure\"; else echo \"success\"; fi"
property pwd : ""
on run
externalLog("VPN auto-connect script started - pinging service accessible only on the VPN..")
set pwd to do shell script "openssl enc -base64 -d <<< BaS364Enc0d3dPwdHere=="
end run
on idle
(*
when you return a number from an idle handler, the app idles for that many seconds.
Thus "return 60" causes the app to idle for one minute
*)
try
externalLog("Checking VPN connection pinging GitLab..")
set networkSuccess to do shell script shellScript
if not (networkSuccess = "success") then
externalLog("VPN GOT DISCONNECTED! Reconnecting..")
-- pushed all these routines into handlers for clarity
my killApp()
my restartApp()
my doConnect()
end if
externalLog("Sleeping 1 min..")
return 60
on error errMsg number errorNumber
if (errorNumber = -128) then
externalLog("VPN script terminated")
quit
end if
externalLog(("An error occurred! " & errorNumber as text) & " - " & errMsg as text)
return 3
end try
return 30
end idle
on killApp()
tell application "System Events"
-- make sure the process has fully quit
tell process "Endpoint Security VPN" to quit
repeat while exists process "Endpoint Security VPN"
delay 0.2
end repeat
end tell
end killApp
on restartApp()
externalLog("Launching VPN client..")
tell application "Endpoint Security VPN" to activate
tell application "System Events"
-- make sure the process has started again
repeat until (exists process "Endpoint Security VPN")
delay 0.5
end repeat
-- make sure the process has a window
set timeCount to 0
tell process "Endpoint Security VPN"
repeat until exists first window
set timeCount to timeCount + 0.5
if timeCount ≥ 20 then
-- no window in 20 seconds, something more serious whent wrong
my quit
else if timeCount mod 5 = 0 then
-- try bringing the process forward every 5 seconds
set its frontmost to true
end if
delay 0.5
end repeat
end tell
end tell
end restartApp
on doConnect()
tell application "System Events"
tell process "TextExpander"
keystroke pwd
delay 0.5
keystroke return
end tell
end tell
end doConnect
on externalLog(t)
try
set fp to open for access logPath with write permission
on error
close access logPath
set fp to open for access logPath with write permission
end try
write return & "--------" & return to fp starting at ((get eof fp) + 1)
write t to fp starting at ((get eof fp) + 1)
close access fp
end externalLog
Last point: you are using an app called "TextExpander" to paste in the password. You could do that directly from AppleScript; I'm not sure what the advantages of TextExpander are. Just so you know you have options, in case it turns out the TextExpander is causing the problem.
Upvotes: 1