Implementing One-Click OpenConnect VPN Login with Alfred
·
2 min read
I frequently need to connect to the company VPN and have been using scripts for login, but it’s still not efficient enough. To save time, I decided to use Alfred to implement one-click VPN connection.
Workflow
The key points in the workflow include the following steps:
- Use keyword to get user input for mobile verification code
- Temporarily store keyword in a variable, because users need to further select server nodes
- For list filter’s keyword, just enter any value that’s different from the first step’s keyword
- The script uses expect, so final execution requires terminal command - cannot use
Run Script
- Since system password and VPN account use workflow environment variables and command doesn’t support environment variable parsing, I added Run Script to parse variables
Shell Script
Run Script
echo "/Users/qhe/Documents/Shell/vpn.sh $code {query} $mac_password $username $password"
Variable Explanation
- query is the verification code
mac_password
is the Mac laptop passwordusername
is the VPN login usernamepassword
is the VPN user password
Notes
- Variables and environment variables in workflow are parsed using $name in shell
- As shown above, this prints the final command that terminal wants to execute, including variables
- Note that if shell script doesn’t have execution permission, you need to add
+x
Terminal Command
Just need to parse query, {query}, which is the result printed from the previous step
#!/usr/bin/expect
set code [lindex $argv 0]
set url [lindex $argv 1]
set macPassword [lindex $argv 2]
set username [lindex $argv 3]
set password [lindex $argv 4]
spawn sudo openconnect "$url"
expect "Password" {send "$macPassword\r"}
expect "Enter 'yes' to accept" {send "yes\r"}
expect "Username:" {send "$username\r"}
expect "Password" {send "$password\r"}
expect "Password" {send "$code\r"}
interact
~
Final Thoughts
I previously didn’t understand how to allow users to perform multiple input operations in Alfred. Now I understand that using keyword plus listFilter as shown above can achieve this. To save values after each user operation, use var and arg for storage.