Skip to content

Instantly share code, notes, and snippets.

@halocaridina
Forked from awhow/anyconnect.scpt
Last active May 19, 2024 22:59
Show Gist options
  • Save halocaridina/99466e4b1d08e57fb9dd to your computer and use it in GitHub Desktop.
Save halocaridina/99466e4b1d08e57fb9dd to your computer and use it in GitHub Desktop.
-- 1. Create a new generic password entry in Keychain Access called "WHATEVER_AnyConnect_VPN" (the name in Keychain access must match that in line 39 below) with your password for the Cisco AnyConnect VPN server.
-- 2. Open this script in Script Editor (both this and the above are in the Applications->Utilities folder) and "Save as.." an Application (.app) with desired name.
-- 3. Open Security & Privacy System Preferences, go to Privacy, Accessibility.
-- 4. Enable the above .app so it can access Accessibility
-- 5. Copy and paste a nice icon on the generic Applescript icon (I used a copy of the default AnyConnect one)
-- 6. Add the new .app to /Users/[yourshortname]/Applications with a shortcut to your Dock
-- 7. Enjoy the fast connection with no need to enter password and increased security of not having a sensitive password stored as plain text
-- 8. Run script again to close connection
-- AnyConnect now refered to as targetApp
set targetApp to "Cisco AnyConnect Secure Mobility Client"
-- Determine if AnyConnect is currently running
tell application "System Events"
set processExists to exists process targetApp
end tell
-- Close connection if running; else start connection and fill in password
if processExists is true then
tell application targetApp
quit
end tell
else
tell application targetApp
activate
end tell
tell application "System Events"
-- Wait for first window to open. Do nothing.
repeat until (window 1 of process targetApp exists)
delay 1
end repeat
-- You may need to uncomment below if your OpenConnect implementation requires a keystroke to accept the default VPN
-- tell process targetApp
-- keystroke return
-- end tell
-- Wait for second window to open and then automatically enter password extracted from your Keychain
repeat until (window 2 of process targetApp exists)
delay 2
end repeat
tell process targetApp
-- This is where the the password in the Keychain is accessed for use as input rather than being hardcoded as plain text in other versions of this script out in the wild
delay 4
set inString to "WHATEVER_AnyConnect_VPN"
set PSWD to do shell script "/usr/bin/security find-generic-password -wl " & quoted form of inString
keystroke PSWD as text
keystroke return
end tell
-- Autoclick on "Accept" of AnyConnect Banner window. If you have no welcome banner that needs acceptance, comment out these lines to the first "end tell" below
repeat until (window "Cisco AnyConnect - Banner" of process targetApp exists)
delay 2
end repeat
tell process targetApp
keystroke return
end tell
end tell
end if
@neilernst
Copy link

I added the lines

tell process targetApp
            keystroke return
end tell

after line 33, because in my version, the first window needs a return to accept the default VPN.

This script is massively helpful btw

@halocaridina
Copy link
Author

@neilernst,

Glad you are finding the script useful. I can't take credit beyond integrating the Keychain functionality.

Also thank you for the info regarding your particular situation. I had a feeling that there wouldn't be a "one-size-fits-all" since OpenConnect implementations seem to vary by quite a bit. I've added your input as commented code in case others need to implement it.

Halocaridina

@Grinderofl
Copy link

Please update the default script to have

	repeat until (window "Cisco AnyConnect - Banner" of process targetApp exists)
		delay 2
	end repeat
	tell process targetApp
		keystroke return
	end tell

commented and

tell process targetApp
keystroke return
end tell

not commented. This is now the default behaviour in Cisco AnyCrapnect.

@horst80
Copy link

horst80 commented Aug 11, 2017

This works great for me, thanks for sharing!

One issue: When starting the app from a dock shortcut, I can't use the dock shortcut again to close the connection. (because the app stays open, I have to force quit it, then run it again).

Does someone have an idea how to fix this? Maybe auto-close the app once the connection has been established?

@Hefeweizen
Copy link

I changed the keystroke return to:

		tell process targetApp
			click button "Connect" of window 1
		end tell

Security lockdown within my company greyed out the network selection in the AnyConnect Client. I suspect that this prevented the keystroke hitting the right place.

@Jonyder
Copy link

Jonyder commented Nov 16, 2017

Works like a charm, no more typing ;-)
Thanks a lot for sharing!

@jmooo
Copy link

jmooo commented Dec 29, 2017

@horst80 I ran into this but all I needed to do was comment out the block as recommended in the script:

  -- Autoclick on "Accept" of AnyConnect Banner window. If you have no welcome banner that needs acceptance, comment out these lines to the first "end tell" below

@djiwondee
Copy link

Thanks for this nice script! it works fine for me and helps to save time in an environment I work with a high level of password strength.

@tuxian0
Copy link

tuxian0 commented Apr 4, 2018

Nice Script!
Hey, is it possible to check if Cisco anyconnect VPN is connected already?
I am trying to write a applescript which automatically mounts the remote server when connected to VPN or some SSID's.
How can I get these details? Can someone help me on this?

Copy link

ghost commented Jun 28, 2018

Brilliant. I'm running 4.5.04029 and in my case, window 1 doesn't contain the connect button. That is in window 2, which seems to be a subwindow of window 1. Window 3 is the username / password.

-- line 35
tell window 2 of process targetApp
click button "Connect"
end tell
-- line 40
repeat until (window 3 of process targetApp exists)

@halocaridina
Copy link
Author

Thanks to everyone for the interest and comments. These are helpful since implementations of Cisco Anyconnect VPN seem to considerably vary, so there is no one-size-fits-all and this script needs to be tweaked on case-by-case instances.

@fouledout443
Copy link

Just when I thought I was going to have to write this from scratch, thanks @halocaridina !!!

@qkp1994
Copy link

qkp1994 commented Jun 18, 2019

This is awesome! Thank you @halocaridina! Is there anyway for the script app to quit after it has successfully launch and login to anyconnect?

@QuantenGhost
Copy link

Version 4.6 passed error -128 which canceled the script.
To reconnect if already connected, I found a try/catch solution from https://apple.stackexchange.com/questions/176139/simple-3-line-applescript-error-128.

--Close while ignoring error -128 from unclean quit
try
	tell application targetApp to quit
on error error_message number error_number
	
	if error_number is equal to -128 then
		--Keep Calm and Carry On
	else
		display dialog error_message
	end if
end try

@QuantenGhost
Copy link

Delays also accept decimal point values now.
So using delay 0.1 sped things up a lot.

@sarnobat
Copy link

The VPN connection failed due to unsuccessful domain name resolution.

What am I doing wrong?

@communikein
Copy link

@halocaridina love the script :D
I forked your code and added a couple of lines to speed up the process and prevent the script from terminating in an error if the internet connection is not fast enough.

Have a look and consider merging it with your solution if you like it :)
https://gist.github.com/communikein/62b253cea6cb31344cd4e88066ea4289

@CrookedGrin
Copy link

CrookedGrin commented Mar 9, 2021

I got this script to work, sort of, except that in the middle of execution, I get a popup window saying "macOS wants to make changes. Enter an administrator's password to allow this. macOS wants to use the "System" keychain." If I put in my username and password, the rest of the script executes properly, but that kind of defeats the purpose. Any ideas on how to allow access for the app permanently?

EDIT: I found the answer for this, adding in case anyone else has this problem. In your Keychain Access app, you need to double-click the keychain entry you made for these credentials ("WHATEVER_AnyConnect") within the System keychain, then go to the "Access Control" tab at the top. You'll have to authenticate to do this. Select "Allow all applications to access this item" and hit "Save changes". You can try explicitly adding the app you just created to the whitelist at the bottom, but that didn't work for me. It would probably be better to allow explicit access, though; maybe someone on here knows what app corresponds to the process that's running the script (what it's calling macOS).

Also: on line 40 of this script, mine didn't work until I changed window 2 to look for the exact title of the second window; it didn't appear to understand window 2. (Maybe there's some other window in the background that is actually window 2). So it's now repeat until (window "Cisco AnyConnect | CompanyName Connect" of process targetApp exists). The title will be the literal title you see at the top of the window.

One more tip: every time you change or move this script after you've granted access in the security settings, you'll need to remove it from the accessibility list and re-add it, even if the name or location hasn't changed.

@CrookedGrin
Copy link

CrookedGrin commented Aug 6, 2021

This script is awesome, but it has a major security flaw: since it's just typing into a field, it will actually type into whatever field happens to be in focus, not specifically AnyConnect. I learned this the hard way when I accidentally broadcast my system password into a Slack channel (and immediately had to go change it.)

I wrote a revision that addresses this by explicitly targeting the window and field, and setting the value rather than just typing keystrokes. You might have to adjust the window numbers, etc. if your config is slightly different. I recommend UI Browser (https://pfiddlesoft.com/uibrowser/) to help figure out how to refer to the various elements.

-- 1. Create a new generic password entry in Keychain Access called "EG_AnyConnect" (the name in Keychain access must match that in line 39 below) with your password for the Cisco AnyConnect VPN server.  
-- 2. Open this script in Script Editor (both this and the above are in the Applications->Utilities folder) and "Save as.." an Application (.app) with desired name.
-- 3. Open Security & Privacy System Preferences, go to Privacy, Accessibility.
-- 4. Add the the above .app so it can access Accessibility. If you modify or move the app, you'll need to remove and re-add it.
-- 5. Copy and paste a nice icon on the generic Applescript icon (I used a copy of the default AnyConnect one)
-- 6. Add the new .app to /Users/[yourshortname]/Applications with a shortcut to your Dock 
-- 7. Enjoy the fast connection with no need to enter password and increased security of not having a sensitive password stored as plain text
-- 8. If the system keeps asking for authentication, you may need to open the EG_AnyConnect entry in Keychain Access and set its Access Control to "Allow all applications to access this item."

-- AnyConnect now refered to as targetApp
set targetApp to "Cisco AnyConnect Secure Mobility Client"

-- Determine if AnyConnect is currently running
tell application "System Events"
	set processExists to exists process targetApp
end tell

tell application targetApp
	activate
	
end tell

tell application "System Events"
	-- Wait for first window to open. Do nothing.
	repeat until (window 1 of process targetApp exists)
		delay 1
	end repeat
	
	-- This block deals with the alert that pops up if you've been disconnected.
        tell process targetApp
		if (exists button "OK" of sheet 1 of window 2) then
			click button "OK" of sheet 1 of window 2 
		end if
	end tell
	
	tell process targetApp
		if (exists button "Connect" of window 2) then
			click button "Connect" of window 2
		end if
	end tell
	
	set authWindow to "Cisco AnyConnect | ExpediaGroup Connect"
	
	-- Wait for second window to open and then automatically enter password extracted from your Keychain
	repeat until (window authWindow of process targetApp exists)
		delay 1
	end repeat
	
	-- This is where the the password in the Keychain is accessed for use as input rather than being hardcoded as plain text in other versions of this script out in the wild 
	tell process targetApp
		set inString to "EG_AnyConnect" -- NOT the password itself
		set username to "whatever" -- Set to your username
		set PSWD to do shell script "/usr/bin/security find-generic-password -wl " & quoted form of inString
		set value of text field 2 of window authWindow to PSWD
		set value of text field 3 of window authWindow to "push" -- In my case, you have to explicitly type the word "push" into the field. Comment this line out if you don't have that in your version. Also, who designed that???
		click button "OK" of window authWindow
	end tell
	
end tell


@bariskalem
Copy link

Nice script! Check out my menubar app that persists credentials and provides a GUI to connect to the VPN.
https://github.com/bariskalem/NowConnect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment