#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Getopt::Long;

my $opt;
$opt->{key_type} = 'dsa';
Getopt::Long::Configure ("gnu_getopt");
GetOptions(
	'help|h'     => \$opt->{help},
	'passphrase|p=s'   => \$opt->{passphrase},
	'type|t=s' => \$opt->{key_type},
	'keyname|k=s' => \$opt->{key_name},
	'verbose|v+' => \$opt->{verbose},
	'dryrun|n' => \$opt->{dryrun},
) || help();

help() if $opt->{help};

if(not $opt->{key_type})
{
	if($ARGV[0] =~ /^(rsa|dsa)$/)
	{
		$opt->{key_type} = shift(@ARGV);
	}
	elsif($opt->{key_name} and -f -f $ENV{HOME} . "/.ssh/$opt->{key_name}.pub")
	{
		$opt->{key_type} = 'dsa';
	}
	elsif(-f -f $ENV{HOME} . '/.ssh/id_dsa.pub')
	{
		$opt->{key_type} = 'dsa';
	}
	elsif(-f -f $ENV{HOME} . '/.ssh/id_rsa.pub')
	{
		$opt->{key_type} = 'rsa';
	}
}

if($opt->{key_type} !~ /^(rsa|dsa)$/)
{
	help("Invalid key type: $opt->{key_type}");
}

$opt->{passphrase} ||= '';
$opt->{key_name}   ||= 'id_'.$opt->{key_type};

if(scalar(@ARGV) == 0)
{
	help("Grant passwordless logins from this account to '<host>' using RSA/DSA keys\n");
}

for my $domain (@ARGV)
{
	if( not -f $ENV{HOME}."/.ssh/$opt->{key_name}.pub")
	{
		$opt->{passphrase}=~s/"/\\"/g;
		$opt->{passphrase}=~s/\$/\\\$/g;
		
		my $gen_cmd = 'ssh-keygen ';
		$gen_cmd .= ' -t ' . $opt->{key_type};
		$gen_cmd .= ' -N "' . $opt->{passphrase} . '"';
		$gen_cmd .= ' -f ~/.ssh/' . $opt->{key_name};
		run($gen_cmd);
	}

	my $remote_cmd = <<CMD
		cat ~/.ssh/$opt->{key_name}.pub|ssh $domain "
		if [ ! -d ~/.ssh ];then mkdir ~/.ssh; fi;
		chmod 700 ~/.ssh/;cat>>~/.ssh/authorized_keys2
		chmod 600 ~/.ssh/authorized_keys2
#		if [ ! -f ~/.ssh/$opt->{key_name} ];then
			# ssh-keygen -t $opt->{key_type} -N '' -f ~/.ssh/$opt->{key_name}
		# fi
	"
CMD
;
	
	run($remote_cmd);
	if(scalar(@ARGV) > 1)
	{
		print "Granted on $domain\n";
	}
}

sub run
{
	my $cmd = shift;
	
	if($opt->{dryrun} or $opt->{verbose})
	{
		print $cmd."\n";
	}
	
	if(not $opt->{dryrun})
	{
		system($cmd);
	}
}
	
	
sub help
{
	if($_[0])
	{
		warn $_[0] . "\n";
	}
	warn <<"END"
Usage: $0 [options] <server(s)>
  --help, -h                  This message
  --passphrase <s>, -p <s>    Passphrase for the key (default: '')
  --type <type>, -t <type>    Setup rsa or dsa key type (valid: rsa, dsa)
  --keyname <name>, -k <name> Alternate name for key (default: id_$opt->{key_type})
  --dryrun, -n                Dryrun
  --verbose, -v               Verbose.  Show more output (can be repeated for
                              even more output)
END
;
	exit 1;
}

