◎软件环境:
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
