Created
November 1, 2023 22:19
-
-
Save anshdivu/264aab8521b47cde15de05a38fd3346a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local MAC_USER_ID = "db880u" | |
local AUTH_METHOD = "2" -- code 2 is for push notification | |
local SHORTCUT_HOTKEY = "F1" | |
-- command => osascript -e 'id of app "Cisco AnyConnect Secure Mobility Client"' | |
-- local CISCO_BUNDLE_ID = 'com.cisco.Cisco-AnyConnect-Secure-Mobility-Client' -- vpn version <=4.6 | |
local CISCO_BUNDLE_ID = 'com.cisco.anyconnect.gui' -- vpn version >=4.9 | |
local function fetchPassword(userId) | |
-- when you run this command the first time it will require your admin password to read keychain | |
return hs.execute("security find-generic-password -w -g -a " .. userId) | |
end | |
local function restartApp(bundleId, runAfterStartFn) | |
local appTerminated = hs.application.watcher.terminated | |
local app = hs.application.get(bundleId) | |
if not app then | |
local newApp = hs.application.open(bundleId, 0, true) | |
return runAfterStartFn(newApp) | |
end | |
local appPid = app:pid() | |
print("**** Killing running app: ", appPid, app) | |
app:kill() | |
hs.application.watcher.new(function(appName, eventType, app) | |
if (eventType == appTerminated and app:pid() == appPid) then | |
local newApp = hs.application.open(bundleId, 0, true) | |
runAfterStartFn(newApp) | |
end | |
end):start() | |
end | |
local function trackCiscoDialogs(ciscoDialogs) | |
local dialogNum = 0 | |
return function(dialog) | |
if ciscoDialogs[dialog] then | |
return | |
end | |
dialogNum = dialogNum + 1 | |
if dialogNum == 1 then | |
print("**** Found password dialog: ", dialogNum, dialog) | |
ciscoDialogs[dialog] = "password" | |
elseif dialogNum == 2 then | |
print("**** Found mfa dialog: ", dialogNum, dialog) | |
ciscoDialogs[dialog] = "mfa" | |
elseif dialogNum == 3 then | |
print("**** Found Accept dialog: ", dialogNum, dialog) | |
ciscoDialogs[dialog] = "accept" | |
else | |
print("**** Found UNKNOWN dialog: ", dialogNum, dialog) | |
ciscoDialogs[dialog] = "UNKNOWN_" .. dialogNum | |
end | |
end | |
end | |
local function vpnSignInFlow(userId, ciscoDialogs) | |
return function(dialog) | |
local type = ciscoDialogs[dialog] | |
if type == "password" then | |
print("**** Focused on password dialog") | |
local password = fetchPassword(userId) | |
hs.eventtap.keyStrokes(password) | |
elseif type == "mfa" then | |
print("**** Focused on mfa dialog") | |
hs.eventtap.keyStrokes(AUTH_METHOD) | |
hs.eventtap.keyStroke({}, "return") | |
elseif type == "accept" then | |
print("**** Focused on accept dialog") | |
hs.eventtap.keyStroke({}, "return") | |
else | |
print("**** Correct Dialog Not Found: ", type, dialog) | |
end | |
end | |
end | |
hs.hotkey.bind({}, SHORTCUT_HOTKEY, function() | |
restartApp(CISCO_BUNDLE_ID, function(ciscoApp) | |
print("**** Started Cisco App: ", ciscoApp:pid(), ciscoApp) | |
local filter = hs.window.filter.new { | |
[ciscoApp:name()] = { | |
allowRoles = 'AXDialog' | |
} | |
} | |
local ciscoDialogs = {} | |
filter:subscribe(hs.window.filter.windowCreated, trackCiscoDialogs(ciscoDialogs)) | |
filter:subscribe(hs.window.filter.windowFocused, vpnSignInFlow(MAC_USER_ID, ciscoDialogs)) | |
end) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment