Skip to content

Instantly share code, notes, and snippets.

@karlbaillie
Last active April 3, 2025 18:12
Show Gist options
  • Save karlbaillie/38508fd92669101ec1fca4bea62bcefe to your computer and use it in GitHub Desktop.
Save karlbaillie/38508fd92669101ec1fca4bea62bcefe to your computer and use it in GitHub Desktop.
AnyConnector: Manage Cisco Anyconnect Connections stored in KeePass through CLI
#!/usr/bin/perl
use File::KeePass;
use Term::ReadKey;
use Data::Dumper qw(Dumper);
use Getopt::Long qw(GetOptions);
use Digest::MD5 qw(md5_hex);
use MIME::Base64;
use File::Slurp;
my $file = "/path/to/keepass.kdbx";
GetOptions (
'con|connect=s' => \$connect,
'discon|disconnect' => \$disconnect,
'state' => \$state)
or die(usage());
if ($connect) {
# get current status
open SAVOUT, ">&STDOUT"; # copy of STDOUT
open STDOUT, ">/dev/null";
my $vpn_status = status();
open STDOUT, ">&SAVOUT";
close SAVOUT;
if ($vpn_status eq "Connected") {
disconnect();
};
my $master_pass = prompt_for_password();
my $k = File::KeePass->new;
$k->load_db($file, $master_pass);
$k->unlock;
my $entry = $k->find_entry({title => "$connect-VPN"});
if (!$entry) {
die("You have no KeePass entry named $connect-VPN\n");
}
else {
print "Connecting to $connect...\n";
open SAVOUT, ">&STDOUT"; # copy of STDOUT
open STDOUT, ">/dev/null";
system qq(printf "y\n$entry->{'username'}\n$entry->{'password'}\ny" | /opt/cisco/anyconnect/bin/vpn -s connect $entry->{'url'});
open STDOUT, ">&SAVOUT";
close SAVOUT;
};
status();
sleep 1;
} elsif ($disconnect) {
disconnect();
} elsif ($state) {
status();
} else {
die(usage());
};
sub status {
my $status = `/opt/cisco/anyconnect/bin/vpn status`;
if ($status =~ "Connected") {
print "Connected\n";
return "Connected";
} else {
print "Not Connected\n";
return "Not Today Punk";
}
}
sub disconnect {
open SAVOUT, ">&STDOUT"; # copy of STDOUT
open STDOUT, ">/dev/null";
system qq(/opt/cisco/anyconnect/bin/vpn disconnect);
open STDOUT, ">&SAVOUT";
close SAVOUT;
print "Disconnected!\n"
}
sub prompt_for_password {
# location for password to be stored
my $passfile = md5_hex($file); # use keepass file location as a unique hash
# if password is stored read it
if (-e "/tmp/$passfile") {
my $decode = read_file("/tmp/$passfile");
$password = decode_base64($decode);
$password =~ s/\R\z//;
return $password;
}
else {
# read password from stdin
require Term::ReadKey;
Term::ReadKey::ReadMode('noecho');
print "Enter your KeePass database password: ";
my $password = Term::ReadKey::ReadLine(0);
Term::ReadKey::ReadMode('restore');
print "\n";
$password =~ s/\R\z//;
# encode password Bae64
my $encoded = encode_base64($password);
# write password to a file
open(my $fh, '>', "/tmp/$passfile") or die "Could not find file /tmp/$passfile!";
print $fh "$encoded\n";
close $fh;
return $password;
}
}
sub usage {
die("Usage: $0 -c|connect ENV / -d|disconnect / -s|state\n");
}
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment