2012-04-02 13:41:37 +00:00
|
|
|
package xCAT::SSHInteract;
|
2012-03-29 20:10:50 +00:00
|
|
|
use Exporter;
|
|
|
|
use Net::Telnet;
|
2012-05-18 15:44:42 +00:00
|
|
|
BEGIN {
|
|
|
|
our @ISA = qw/Exporter Net::Telnet/;
|
|
|
|
};
|
2012-03-29 20:10:50 +00:00
|
|
|
use strict;
|
|
|
|
our @EXPORT_OK = ();
|
|
|
|
use IO::Pty;
|
|
|
|
use POSIX;
|
|
|
|
|
|
|
|
sub _startssh {
|
2012-04-02 19:27:34 +00:00
|
|
|
my $self = shift;
|
2012-03-29 20:10:50 +00:00
|
|
|
my $pty = shift;
|
|
|
|
my $name = shift;
|
|
|
|
my $dest = shift;
|
2012-04-02 19:27:34 +00:00
|
|
|
my %args=@_;
|
2012-03-29 20:10:50 +00:00
|
|
|
my $tty;
|
|
|
|
my $tty_fd;
|
|
|
|
my $pid = fork();
|
|
|
|
if ($pid) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#in child
|
|
|
|
$tty = $pty->slave or die "$!";
|
2012-05-18 15:44:42 +00:00
|
|
|
$pty->make_slave_controlling_terminal();
|
2012-03-29 20:10:50 +00:00
|
|
|
$tty_fd = $tty->fileno or die "$!";
|
|
|
|
close($pty);
|
|
|
|
open STDIN, "<&", $tty_fd;
|
|
|
|
open STDOUT,">&",$tty_fd;
|
2012-06-18 08:38:30 +00:00
|
|
|
open STDERR, ">&", STDOUT;
|
2012-03-29 20:10:50 +00:00
|
|
|
close($tty);
|
2012-04-02 19:27:34 +00:00
|
|
|
my @cmd = ("ssh","-o","StrictHostKeyChecking=no");
|
|
|
|
if ($args{"-nokeycheck"}) {
|
|
|
|
push @cmd,("-o","UserKnownHostsFile=/dev/null");
|
|
|
|
}
|
|
|
|
push @cmd,("-l",$name,$dest);
|
|
|
|
exec @cmd;
|
2012-03-29 20:10:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub new {
|
2012-11-13 22:03:57 +00:00
|
|
|
my $class = shift;
|
|
|
|
my %args = @_;
|
|
|
|
my $pty = IO::Pty->new or die "Unable to perform ssh: $!";
|
|
|
|
$args{"-fhopen"} = $pty;
|
|
|
|
$args{"-telnetmode"} = 0;
|
|
|
|
$args{"-telnetmode"} = 0;
|
|
|
|
$args{"-cmd_remove_mode"} = 1;
|
|
|
|
my $username = $args{"-username"};
|
|
|
|
my $host = $args{"-host"};
|
|
|
|
my $password = $args{"-password"};
|
|
|
|
delete $args{"-host"};
|
|
|
|
delete $args{"-username"};
|
|
|
|
delete $args{"-password"};
|
|
|
|
my $nokeycheck = $args{"-nokeycheck"};
|
|
|
|
delete $args{"-nokeycheck"};
|
|
|
|
my $self = $class->Net::Telnet::new(%args);
|
|
|
|
_startssh($self,$pty,$username,$host,"-nokeycheck"=>$nokeycheck);
|
|
|
|
my $promptex = $args{Prompt};
|
|
|
|
$promptex =~ s!^/!!;
|
|
|
|
$promptex =~ s!/\z!!;
|
2012-06-18 08:38:30 +00:00
|
|
|
my ($prematch,$match) = $self->waitfor(Match => $args{Prompt},Match=>'/password:/i',Match=>'/REMOTE HOST IDENTIFICATION HAS CHANGED/') or die "Login Failed:", $self->lastline;
|
2012-11-13 22:03:57 +00:00
|
|
|
#print "prematch=$prematch, match=$match\n";
|
2012-04-13 03:10:34 +00:00
|
|
|
if ($match =~ /password:/i) {
|
2012-11-13 22:03:57 +00:00
|
|
|
#$self->waitfor("-match" => '/password:/i', -errmode => "return") or die "Unable to reach host ",$self->lastline;
|
|
|
|
$self->print($password);
|
|
|
|
my $nextline = $self->getline();
|
|
|
|
chomp($nextline);
|
2013-09-25 01:04:02 +00:00
|
|
|
while ($nextline =~ /^\s*$/) {
|
2012-11-13 22:03:57 +00:00
|
|
|
$nextline = $self->get();
|
|
|
|
chomp($nextline);
|
|
|
|
}
|
|
|
|
if ($nextline =~ /password:/i or $nextline =~ /Permission denied, please try again/ or $nextline =~ /disconnect from/) {
|
|
|
|
die "Incorrect Password";
|
2013-09-25 01:04:02 +00:00
|
|
|
} elsif ($nextline =~ /$promptex/) {
|
|
|
|
*$self->{_xcatsshinteract}->{_atprompt}=1;
|
2012-11-13 22:03:57 +00:00
|
|
|
}
|
2012-05-18 15:44:42 +00:00
|
|
|
} elsif ($match =~ /$promptex/) {
|
|
|
|
*$self->{_xcatsshinteract}->{_atprompt}=1;
|
2012-06-18 08:38:30 +00:00
|
|
|
} elsif ($match =~ /REMOTE HOST IDENTIFICATION HAS CHANGED/){
|
2012-11-13 22:03:57 +00:00
|
|
|
die "Known_hosts issue";
|
|
|
|
}
|
|
|
|
return bless($self,$class);
|
2012-03-29 20:10:50 +00:00
|
|
|
}
|
2012-05-18 15:44:42 +00:00
|
|
|
sub atprompt {
|
|
|
|
my $self=shift;
|
|
|
|
return *$self->{_xcatsshinteract}->{_atprompt};
|
|
|
|
}
|
2012-03-29 20:10:50 +00:00
|
|
|
1;
|