#!/usr/bin/perl -w

# Michael Weinberger, neddix 2007
# See http://wiki.contribs.org/Dirty_Tools for full documentation

use strict;
use Getopt::Long;

my %opts;
my $getRes = GetOptions( 
	"revoke"=>\$opts{'revoke'},
	"port=s"=>\$opts{'keys-port'},
);

die "Usage: dt-send-key [--revoke] [--port=PORT] remotehost\n" if( not $ARGV[0] ) ;

my $ExecCmdOutout='';

my $remotehost=$ARGV[0];
my $port=$opts{'keys-port'} ? $opts{'keys-port'} : 22;

sub trim($)
	{
	my $s=shift;
	$s=~s/^\s+//;
	$s=~s/\s+$//;
	return $s;
	}

sub ExecCmd( \@$ )
	{
	(my $cmdRef, my $forcelog) = @_;
	my @cmd = @$cmdRef;
	my $pipestatus='';
	die "Fork failed: $!\n" unless defined( my $pid=open(RCHILD, "-|"));
	if( $pid )
		{
		$ExecCmdOutout='';
		while(<RCHILD>)
			{
			chomp( $_ );
			next if $_ eq '';
			$ExecCmdOutout.="$_\n";
			$pipestatus=$_;
			}
		close( RCHILD );
		}
	else
		{
		exec( "@cmd 2>&1; echo \${PIPESTATUS}" ) or die "exec failed: $!\n";
		}
	$ExecCmdOutout =~ s/$pipestatus\n$//;
	$pipestatus =  $? if not $pipestatus;
	return $pipestatus;
	}

sub sendKeys()
	{
	my $kf="/root/.ssh/id_dsa.pub";
	my $s;
	my @cmd;

	$remotehost =~ /(.*)/; $remotehost=$1;

	if( not -f $kf or not -f "/root/.ssh/id_dsa" )
		{
		$s="Generating DSA keys...";
		print "$s\n"; 
		@cmd=("/usr/bin/ssh-keygen","-q","-t","dsa","-N ''","-f", "/root/.ssh/id_dsa" );
		not ExecCmd( @cmd, 0 ) or errorExit( 1, "Couldn't generate DSA keys" );
		$s="Successfully created DSA key pair.";
		print "$s\n"; 
		}
	open( PUBK, $kf ) or errorExit( 2, "Could not open $kf" );
	my $pubk=trim(<PUBK>);
	close( PUBK );
	my $ak="/root/.ssh/authorized_keys2";
	@cmd=("/bin/cat", $kf,
		"|/usr/bin/ssh", '-o', "StrictHostKeyChecking=no", '-p', $port, $remotehost,"'/bin/cat - > $ak.\$\$ && /bin/touch $ak && /bin/grep -v \"$pubk\" < $ak >> $ak.\$\$ ; /bin/mv -f $ak.\$\$ $ak'"); 
	ExecCmd( @cmd, 0 );
	if( $ExecCmdOutout )
		{
		print "$ExecCmdOutout";
		errorExit( 3, "$ExecCmdOutout" );
		}
	$s="Public DSA key sent to $remotehost";
	print "$s\n"; 
	}

sub revokeKeys()
	{
	my $kf="/root/.ssh/id_dsa.pub";
	return if not -f $kf;
	my $s;
	my @cmd;

	open( PUBK, $kf ) or errorExit( 4, "Could not open $kf" );
	my $pubk=trim(<PUBK>);
	close( PUBK );

	$remotehost =~ /(.*)/; $remotehost=$1;
	my $ak="/root/.ssh/authorized_keys2";
	@cmd=("/usr/bin/ssh", '-o', "StrictHostKeyChecking=no", '-p', $port, $remotehost, "'/bin/touch $ak && /bin/grep -v \"$pubk\" < $ak > $ak.\$\$ ; /bin/mv -f $ak.\$\$ $ak'");
	ExecCmd( @cmd, 0 );
	if( $ExecCmdOutout )
		{
		print "$ExecCmdOutout";
		errorExit( 5, "$ExecCmdOutout" );
		}
	$s="Public DSA key deleted on $remotehost";
	print "$s\n"; 
	}



sub errorExit( $$ )
	{
	(my $err, my $msg) = @_;
	print( "Error $err: $msg\n" );
	exit -1;
	}


# main
if( $opts{'revoke'} )
	{
	revokeKeys();
	}
else
	{
	sendKeys();
	}
exit 0;
