◎软件环境:
macOS Mojave 10.14
Alfred 3
Cisco AnyConnect Secure Mobility Client.app(4.5.01044)
go version go1.12.7 darwin/amd64
◎功能描述:
打开alfred输入 ccv
触发alfred workflow调用AppleScripts脚本登陆Cisco VPN客户端,自动输入通过本地脚本获取的密码+动态验证码登陆vpn。使用前请先安装配置好必要软件,把脚本里的secret改成自己的token,然后替换workflow里的脚本绝对路径。脚本使用golang编写打成二进制文件,防止敏感信息泄漏。
◎实现思路:
on alfred_script(q) tell application "Cisco AnyConnect Secure Mobility Client" to activate tell application "Cisco AnyConnect Secure Mobility Client" to reopen delay 0.5 # get password + dynamic_code set dynamic_code to do shell script "/usr/local/bin/get_pass" tell application "System Events" tell process "Cisco AnyConnect Secure Mobility Client" tell window 1 click button "Connect" of window 2 of application process "Cisco AnyConnect Secure Mobility Client" of application "System Events" delay 0.5 set value of text field 2 of window 2 of application process "Cisco AnyConnect Secure Mobility Client" of application "System Events" to dynamic_code click button "OK" of window 2 of application process "Cisco AnyConnect Secure Mobility Client" of application "System Events" end tell end tell end tell end alfred_script
脚本如下 get_pass.go:
package main import ( "encoding/base32" "flag" "fmt" "github.com/hgfischer/go-otp" "strings" ) const ( SECRET = "xxxx" //此处修改为google auth token ) var ( secret = flag.String("secret", "password", "Secret key") isBase32 = flag.Bool("base32", true, "If true, the secret is interpreted as a Base32 string") length = flag.Uint("length", otp.DefaultLength, "OTP length") period = flag.Uint("period", otp.DefaultPeriod, "Period in seconds") counter = flag.Uint64("counter", 0, "Counter") auth = flag.String("auth", "relay", "login platform [relay|vpn]") ) func isGoogleAuthenticatorCompatible(base32Secret string) bool { cleaned := strings.Replace(base32Secret, "=", "", -1) cleaned = strings.Replace(cleaned, " ", "", -1) return len(cleaned) == 16 } func GetToken(secret *string) string { key := *secret if !*isBase32 { key = base32.StdEncoding.EncodeToString([]byte(*secret)) } key = strings.ToUpper(key) if !isGoogleAuthenticatorCompatible(key) { } totp := &otp.TOTP{ Secret: key, Length: uint8(*length), Period: uint8(*period), IsBase32Secret: true, } return fmt.Sprintf("%v", totp.Get()) } func main() { flag.Parse() *secret = SECRET //fmt.Printf("Code: ") fmt.Println(GetToken(secret)) }
◎查看效果:
◎下载地址:https://github.com/anzhihe/Efficient-office/tree/master/connect-cisco-vpn