SDB:SSHK

Jump to: navigation, search

SSHK is a perl script for using USB stick (aka. pen drive) like a ssh token - it needs to contain a private ssh key.

For usage of this script you have to install pmount and add yourself to it's group. You also need to disable automounting of that particular stick.

The core script (sshk):

#!/usr/bin/perl
# author MichaƂ "Fogel" Fogelman
# fogel@nocnemarki.net

use strict;

my $PATH = "/dev/disk/by-uuid";
my $UUID = "";
my $NAME = "";
my $FILE = "";
my $CONFIG = $ENV{HOME} . "/.sshk";

sub saveconfig {

	open FILE, ">", $CONFIG;

	print FILE "UUID=$UUID\n";
	print FILE "NAME=$NAME\n";
	print FILE "FILE=$FILE\n";

	close FILE;
}

sub configure {

	print "Disk UUID: ";
	chop ($UUID = <STDIN>);

	print "Disk NAME: ";
	chop ($NAME = <STDIN>);

	print "Key FILE: ";
	chop ($FILE = <STDIN>);

	saveconfig();
}

sub read_val {

	my $line = shift;
	my @line = split(/=/, $line);
	
	$UUID = $line[1] if ($line[0] =~ /^UUID$/);
	$NAME = $line[1] if ($line[0] =~ /^NAME$/);
	$FILE = $line[1] if ($line[0] =~ /^FILE$/);
}

sub read_cfg {

	return 0 if not -e $CONFIG;

	open FILE, '<', $CONFIG;

	while (my $x = <FILE>) { 
	
		chop($x);
		read_val($x);
	};

	close FILE;
	return 1;
}

sub execute {

	die "$NAME is not present in system" if not -e "$PATH/$UUID";

	system "pmount $PATH/$UUID $NAME";
	system "ssh_watcher 'pumount $NAME'>/dev/null&";
	sleep 1;
	system "ssh $ARGV[0] -i /media/$NAME/$FILE";
}

configure() if not read_cfg();
execute();

And "helper" - ssh_watcher - it detects if connection is made or not and umounts drive after that

#!/usr/bin/perl
# author MichaƂ "Fogel" Fogelman
# fogel@nocnemarki.net

use strict;

sub umount {

	system("$ARGV[0] > /dev/null");
}

my @stat = `netstat -n | grep ":22"`;

my $grep = "";

foreach my $st(@stat) {

	if ($st =~ /^tcp\s+\d+\s+\d+\s+\d+\.\d+\.\d+\.\d+:(\d+)\s+/) {

		$grep .= "$1|";
	}
}
chop($grep);
print "$grep\n";

while (`netstat -n | grep ":22" | grep -Pv "$grep" | wc -l` == 0) {}

my $stat = `netstat -n | grep ":22" | grep -Pv "$grep"`;

if ($stat =~ /^tcp\s+\d+\s+\d+\s+\d+\.\d+\.\d+\.\d+:(\d+)\s+/) {

	$grep = $1;
}

my $cnt = 0;

$stat = `netstat -n | grep ":22" | grep $grep`;

if ($stat =~ /^tcp\s+\d+\s+0/) {

	$stat = `netstat -n | grep ":22" | grep $grep`;
	while ($stat =~ /^tcp\s+\d+\s+0/) {
	
		$stat = `netstat -n | grep ":22" | grep $grep`;
	}

}
$stat = `netstat -n | grep ":22" | grep $grep`;

while ($stat =~ /^tcp\s+\d+\s+[1-9]/) {

	$stat = `netstat -n | grep ":22" | grep $grep`;
}

$stat = `netstat -n | grep ":22" | grep $grep`;



while ($cnt < 3) {

	$cnt++ if ($stat =~ /^tcp\s+\d+\s+0/);
	$stat = `netstat -n | grep ":22" | grep $grep`;
}

$cnt = 0;
while ($cnt < 3) {

	$stat = `netstat -n | grep ":22" | grep $grep`;
	$cnt = 3 if ($stat =~ /TIME_WAIT/);
	$cnt++ if ($stat =~ /^tcp\s+\d+\s+[1-9]/);
}
umount();

Place both scripts in the directory that exists in your PATH environment variable.

USAGE: just run script - it will ask you for config lines to suit your needs. ssh command will be executed with args given as a first argument to sshk and path to private key