cfg
7/27/2011 - 7:30 PM

Generate a SecurID token and automatically connect to a Cisco VPN

Generate a SecurID token and automatically connect to a Cisco VPN

-- See: http://coreygilmore.com/blog/2010/02/04/applescript-to-generate-a-securid-token-and-automatically-connect-to-a-cisco-vpn/
-----------------------------------------------
-- Automated token generation and VPN logins
-- Copyright 2010, Corey Gilmore
-- http://coreygilmore.com/
-- Last Modified: 2010-02-04
------------------------------------------------
 
set theConnection to "My VPN" -- the name of your VPN connection
set thePin to "" -- set to "" to prompt every time (recommended)
set theApp to "UserNotificationCenter" -- shouldn't have to change this
set theText to "VPN Connection" -- static text to search for in the VPN dialog, likely locale specific
set tokenAppName to "SecurID" -- The name (sans .app) of the SecurID application, possibly locale specific
 
-- Generate your passcode and open the VPN connection
vpn_connect(thePin, theConnection, theApp, theText, tokenAppName)
 
--------------------------------------
-- Helper functions below
--------------------------------------
 
-- the actual connection - retrieve the token, initiate the connection and enter the password
on vpn_connect(thePin, theConnection, theApp, theText, tokenAppName)
	set thePin to get_user_pin(thePin)
	if thePin is false then
		display alert "Invalid PIN."
		return
	end if
	--display alert "PIN: " & thePin
	--return
 
	set theToken to get_token(thePin, tokenAppName)
	log "gettoken returned: " & theToken
 
	if theToken is not null then
		open_vpn_connection(theConnection, theToken, theApp, theText)
	else
		display alert "Could not retrieve token, please try again."
	end if
end vpn_connect
 
 
-- helper method to retrieve the user's PIN if it's not stored
on get_user_pin(thePin)
	if thePin is not null and thePin is not "" then return thePin
 
	set dialogResult to display dialog "Enter your PIN:" default answer "" with title "PIN" with hidden answer
 
	if button returned of dialogResult is "OK" then
		set thePin to text returned of dialogResult
		if thePin is null or thePin = "" then
			return false
		end if
	end if
 
 
	return thePin
 
end get_user_pin
 
 
-- launch the SecurID application and retrieve the current token
on get_token(userPin, tokenAppName)
	set theToken to null
 
	-- quit the app if it's running
	tell application "System Events" to set allApps to (get name of every application process)
 
	if allApps contains tokenAppName then
		tell application tokenAppName to quit
		log "telling " & tokenAppName & " to quit"
		delay 0.5 -- arbitrary delay, give the app time to exit
	end if
 
	tell application tokenAppName
		activate
		copy (get the clipboard) to origClip
		tell application "System Events"
			delay 0.2
			keystroke userPin
			key code 36
			repeat with x from 1 to 20
				delay 0.1
				keystroke "c" using command down
				keystroke "c" using command down -- copy twice because it didn't always work the first time
				copy (get the clipboard as string) to theToken
				if theToken is origClip then -- if the clipboard hasn't changed, the token hasn't been generated (edge case: clipboard at launch matches the generated token)
					-- do nothing
				else
					log "Token is: " & theToken
					--keystroke "q" using command down
					set the clipboard to origClip -- reset the clipboard to what it was before
					--return (theToken as string) -- return the token we retrieved
					exit repeat
				end if
			end repeat
		end tell
	end tell
	log "tell quit"
	tell application tokenAppName to quit
	log "after quit"
	return (theToken as string) -- return the token we retrieved
end get_token
 
 
-- Find a window containing specific static text, in a given application
on find_window_by_static_text(appname, staticText)
	log "Searching " & appname & " for " & staticText
	tell application "System Events"
		set allApps to (get name of every application process) -- get all apps
		if allApps contains appname then -- find the app if it's running
			set allWin to (get every window of application process appname) -- get all the windows for our app
			set numWin to count allWin -- count the number of windows
			repeat with winNum from 1 to numWin
				set aWin to window winNum of application process appname
				set allText to (get value of every static text of aWin)
				if allText contains staticText then
					log "fwbst winnum: " & winNum
					return winNum
				end if
			end repeat
		end if
	end tell
	return null
end find_window_by_static_text
 
 
-- Open a given VPN connection and enter the password
on open_vpn_connection(theService, thePassword, theApp, theText)
	tell application "System Events"
		tell network preferences
			connect service theService
		end tell
	end tell
	--delay 2
	repeat with x from 1 to 20
		log "vc loop " & x
		delay 0.1
		set winNum to find_window_by_static_text(theApp, theText)
		log "winNum is: " & winNum
		if winNum is not null then
			exit repeat
		end if
	end repeat
	if winNum is null then
		log "Could not find the VPN Connection window"
		return null
	end if
	tell application theApp to activate
	tell application "System Events"
		perform action "AXRaise" of item winNum of (get every window of application process theApp)
		keystroke thePassword
		key code 36
	end tell
end open_vpn_connection