#!/usr/bin/perl
use strict;
use warnings;
use api::Telnet;
use Data::Dumper;
my $host_prompt = '/[\$%#>] $/';
my $owner = &open_pty (
user_name => "root",
user_pswd => "a",
ip_addr => "127.0.0.1",
prompt => $host_prompt,
log_file => 'Log/Owner',
dump_log => 'Log/dump_log',
# input_log => 'Log/input_log',
);
my @output = $owner->cmd ( String => "date", Prompt => $host_prompt );
print "Output is @output\n";
####
package api::Telnet;
use strict;
use warnings;
use Net::Telnet;
use Exporter;
use Carp;
our @ISA = qw (Exporter);
our @EXPORT = qw (
&open_pty
&close_pty
);
# Constant global variables
use constant SSH_TIMEOUT => 1800;
sub spwan_pty
{
my (@cmd) = @_;
my ($pid, $tty, $tty_fd);
# Create a new pseudo terminal
use IO::Pty ();
my $pty = new IO::Pty or die $!;
# Execute the program in another process
# Child process
unless ($pid = fork) {
die "problem spawning program: $!\n" unless defined $pid;
# Disassociate process from existing controlling terminal
use POSIX ();
POSIX::setsid
or die "setsid failed: $!";
# Associate process with new controlling terminal
$pty->make_slave_controlling_terminal;
$pty->set_raw();
$tty = $pty->slave();
$tty_fd = $tty->fileno;
close $pty;
# Make stdio use the new controlling terminal
open STDIN, "<&$tty_fd" or die $!;
open STDOUT, ">&$tty_fd" or die $!;
open STDERR, ">&STDOUT" or die $!;
close $tty;
exec @cmd
or die "problem executing $cmd[0]\n";
} # end child process
$pty;
}
sub open_pty
{
my (%args) = @_;
# Start ssh program.
my $pty = &spwan_pty("ssh",
"-l", $args{user_name},
"-e", "none",
"-F", "/dev/null",
"-o", "PreferredAuthentications=password",
"-o", "NumberOfPasswordPrompts=1",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
$args{ip_addr}
);
# Create a Net::Telnet object to perform I/0 on ssh's tty
my $ssh = new Net::Telnet (
-fhopen => $pty,
-prompt => $args{prompt},
-telnetmode => 0,
-cmd_remove_mode => 1,
-timeout => SSH_TIMEOUT,
-output_record_separator => "\r",
#-errmode => sub { print "Telnet FAIL\n"; }
);
# Wait for the password prompt and send password.
$ssh->waitfor(-match => '/password: ?$/i', -errmode => "return")
or die "problem connecting to \"$args{ip_addr}\": ", $ssh->lastline;
$ssh->print($args{user_pswd});
# Wait for the shell prompt.
my (undef, $match) = $ssh->waitfor(
-match => $ssh->prompt,
-match => '/^Permission denied/m',
-errmode => "return"
) or return $ssh->error("login failed: expected shell prompt ", "doesn't match actual\n");
return $ssh->error("login failed: bad login-name or password\n") if $match =~ /^Permission denied/m;
# logging
$ssh->input_log($args{log_file});
$ssh->cmd("ifconfig");
$ssh->cmd("date");
return $ssh;
}
sub close_pty
{
my ($tty) = shift;
$tty->close();
}
1;
####
[root@n3fips-346 ~]# date
Wed Jul 3 14:33:03 IST 2019
####
< 0x00000: 5b 72 6f 6f 74 40 6e 33 66 69 70 73 2d 33 34 36 [root@n3fips-346
< 0x00010: 20 7e 5d 23 20 ~]#
> 0x00000: 64 61 74 65 0d date.
< 0x00000: 64 61 74 65 0d 0a date..
< 0x00000: 57 65 64 20 4a 75 6c 20 20 33 20 31 34 3a 33 33 Wed Jul 3 14:33
< 0x00010: 3a 30 33 20 49 53 54 20 32 30 31 39 0d 0a :03 IST 2019..
< 0x00000: 1b 5d 30 3b 72 6f 6f 74 40 6e 33 66 69 70 73 2d .]0;root@n3fips-
< 0x00010: 33 34 36 3a 7e 07 346:~.
< 0x00000: 5b 72 6f 6f 74 40 6e 33 66 69 70 73 2d 33 34 36 [root@n3fips-346
< 0x00010: 20 7e 5d 23 20 ~]#
####
[root@hyd1658 ~]# Wed Jul 3 14:39:47 IST 2019
####
< 0x00000: 5b 72 6f 6f 74 40 68 79 64 31 36 35 38 20 7e 5d [root@hyd1658 ~]
< 0x00010: 23 20 #
> 0x00000: 64 61 74 65 0d date.
< 0x00000: 57 65 64 20 4a 75 6c 20 20 33 20 31 34 3a 33 39 Wed Jul 3 14:39
< 0x00010: 3a 34 37 20 49 53 54 20 32 30 31 39 0a :47 IST 2019.
< 0x00000: 1b 5d 30 3b 72 6f 6f 74 40 68 79 64 31 36 35 38 .]0;root@hyd1658
< 0x00010: 3a 7e 07 :~.
< 0x00000: 5b 72 6f 6f 74 40 68 79 64 31 36 35 38 20 7e 5d [root@hyd1658 ~]
< 0x00010: 23 20 #