perl script to telnet an eagle stp device - perl

I need to a script that telnet to eagle STP device and run commands there.
When I try to telnet a eagle STP device from command prompt,
I am getting the below output :
[root#localhost tmp]# telnet hostname port
Trying hostname...
Connected to hostname hostname).
Escape character is '^]'.
I am not getting any prompt here to match in the perl script. We need to press control+a inorder to get the prompt.If we press control+a, it will give the below output
[root#localhost tmp]# telnet hostname port
Trying...
Connected to hostname.
Escape character is '^]'.
>
Then we need to enter login:uid at this prompt
> login:uid=dumps
Then it prompts for a password
Enter password : password
then again we need to press control+a again to execute the commands.
> rtrv-dstn.
I am struck here , I am unable to pass control+a command after telnet command.
I wrote the script in the below way. But it is not working. Can ANY ONE HELP ME !!!!
#!/usr/bin/perl
use Net::Telnet;
my $host='hostname';
my $port='port';
my $telnet = new Net::Telnet(Host => $host, Port => $port, Timeout => 20)
or die "connect failed: $!";
$telnet->open($host);
print"Hi iii";
$telnet->waitfor('+$/i');');
print"Hello";
$telnet->print("^]");
$telnet->waitfor('/>$/i');
$telnet->print("login:uid=username");
$telnet->waitfor('/Enter Password :\s+$/i');
$telnet->print("password");
$telnet->waitfor('/>$/i');
#res1=$telnet->print("rtrv-dstn");
print"#res1";
Exit;

From Net::Telnet:
print - write to object
This method writes #list followed by the output record separator to the open object and returns 1 if all data was successfully written. On time-out or other failures, the error mode action is performed. See errmode().
You can set the output_record_separtor via $telnet->ors("\x01"); or by using:
$telnet->cmd("\x01");
to send a Ctrl-A when you need it. Don't have an Eagle STP for testing, but I hope this helps.
By the way, you should always check the output of each method call to make sure it works.

I dont have your device to try out, but you could try to use the metasymbols and send "\cA" for CTRL-A:
$telnet->print("\cA");
Also ^] is used by the local telnet client to escape sequences not sending them directly to the server, so i suppose it has no use here.

$telnet->print("\cA") will not likely work as it also sends a trailing newline. Use put() to send chars without the trailing newline e.g. $telnet->put("\cA");

Related

Output results of telnet and nmap to powershell/cmd session

So I have a serious fundamental gap in my knowledge that I'm sure has an easy answer, but after googling and looking on here, I can't find what I'm looking for:
I use nmap and telnet on an almost daily basis for checking ports and logging into IP codecs and I use them through either the powershell or cmd consoles, but when I tried to script something and run that script with either a .bat or .ps1 suffix, either will give me the classic not recognized... message. But, if you're able to run it in the console, you should be able to script it, right? How can one go about that?
Sample code for telnet (that works in when inputting to either console, but not in script form):
telnet 192.168.87.21
Sample code for nmap (again, works when inputting to either console, but not in script form):
nmap -p 9999 192.168.87.101
Add a '&' symbol before 'telnet' like that: & telnet 127.0.0.1
For more information how to run executables from Powershell look there: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

unable to take user input in perl

I am having a strange issue. I have written a script which is basically running a perl script in remote server using ssh.
This script is working fine but after completion of the above operation it will ask user to choose the next operation.
it is showing the options in the command prompt but while I am giving any input it is not showing in the screen even after hitting enter also it remain same.
I am not getting what is the exact issue, but it seems there is some issue with the ssh command because if I am commenting out the ssh command it is working fine.
OPERATION:
print "1: run the script in remote server \n2: Exit\n\nEnter your choice:";
my $input=<STDIN>;
chomp($input);
..........
sub run_script()
{
my $com="sshg3.exe server -q --user=user --password=pass -exec script >/dev/null";
system("$com");
goto OPERATION;
}
after completing this ssh script it is showing in screen:
1: run remote script
2: exit
Enter your choice:
but while I am giving any input it is not displaying in the screen until and unless I am exiting it using crtl C.
Please can anyone help what might be the issue here ?
One of the classic gotchas with ssh is this - that it normally runs interactively, and as such will attach STDIN by default.
This can result in STDIN being consumed by ssh rather than your script.
Try it with ssh -n instead.
You can redirect the output in command prompt if -n option is not available for you.
try this one it might work for you.
system("$com />null");
As per https://support.ssh.com/manuals/client-user/62/sshg3.html there is an option for redirecting input use --dev-null (*nix) or --null (Windows).
-n, --dev-null (Unix), -n, --null (Windows)
Redirects input from /dev/null (Unix) and from NUL (Windows).

Perl Debugger: Filehandle as Input

I have this problem:
I need to control the perl-debugger from an external script.
By research I found out about various solutions, but I don't understand them.
I failed to properly set up the RemotePort option (editing ".perldb"), which was the first I tried, and found no useful information on providing a filehandle from which the debugger would get its input (by somehow setting #cmdfhs)
I found both options over here: http://search.cpan.org/~nwclark/perl-5.8.6/lib/perl5db.pl
It would be nice if you could tell me how to provide the filehandle from which the debugger gets its input, or if you know a link where this is explained?
Here's a simple example setting it up using RemotePort, which seemed easier to me:
The trick to using RemotePort is that you have to have someone listening on the remote end BEFORE you launch the script to be debugged.
As soon as you launch your script with -d Perl will attempt to connect to RemotePort. So you have to make sure the initial connection succeeds by having someone listening there beforehand.
Here I assume some Linux/Unix variant, which has the netcat utility installed. We use netcat to wait for incoming connections in this example, but you can use anything else you wish too which is able to create a service port and shuffle data between that and the current TTY:
In terminal 1:
# Use netcat to listen for incoming connections on port 9999
> nc -l -p 9999
In terminal 2:
# Start perl with -d and request a RemotePort connection
> PERLDB_OPTS=RemotePort=127.0.0.1:9999 perl -d my_script.pl
As soon as you do that in terminal 1 you will see something like this:
Loading DB routines from perl5db.pl version 1.39_10
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(my_script.pl:4):
DB<1>
There you go..debug away.
Devel::Trepan is a gdb-like debugger. Although it has remote control, you can also run it at the outset with the option --command which will "source" (in the gdb-sense) or run a series of debugger commands.
To go into remote control, either start the debugger using the --server option or inside the debugger use the "server" command once inside the debugger.
See Options for a list of options you can give at the outset.

Get the output of a command executed via $self->send() on a remote host in Perl Expect module

I am using Expect module in Perl to do an interactive activity and execute a command on a remote machine. Request your help on this
Here are the steps I used
Do a switch user to another account.
Sends the password to login.
Once I get the shell for the new user, execute a ssh command to connect to a remote machine.
Then I want to execute a command in that remote machine and get its response.
I am able to execute the command on the remote machine. I am seeing the output on my terminal too.
But I am not able to capture it in a variable so that I can compare it against a value.
use Expect;
my $exp = Expect->new;
$exp->raw_pty(1);
$exp->spawn('su - crazy_user') or die "Cannot spawn switch user cmd: $!\n"
$exp->expect($timeout,
[ qr/Password:/i,
sub { my $self = shift;
$self->send("$passwd\n");
exp_continue;
}],
[ qr/\-bash\-4.1\$/i,
sub { my $self = shift;
$self->send("ssh $REMOTE_MACHINE\n");
$self->send("$COMMAND1\n");
exp_continue;
}]
);
$exp->soft_close();
How can I get the result of the $COMMAND1 that I executed on the remote machine via $self->send("$COMMAND1\n") ?
I am by no means an expert on this but as noone else has answered so far, let me attempt it.
Your expect command is the su and as such, normal expecting will only work on whatever that command answers back to your original shell. That however is only the password prompt and maybe some error messages. You can still send commands, but their responses show up on the shell of the new user, not the shell the expect command has been executed in. That is why they show up on screen but not in the stream available to your expect object. Note that you would likely encounter the very same problem if you where to ssh directly (i am not sure why you would su and then ssh anyways, could you not directly ssh crazy-user#remote_machine?).
The solution is probably to get rid of the su and ssh directly into the user you need on the remote machine employing Net::SSH::Expect instead of plain Expect as it gives you everything written to the remote console in its output stream. But be careful, if i remember correctly, the syntax for inspecting the stream is slightly different.

automating FTP session

I have the following excerpt from a perl script to automate an FTP session, I'm hoping someone can explain how it works.
system("rsh some_server ftp -in ftp.something.com << !
user anonymous someone\#somewhere.org
some ftp commands
bye");
The background. This perl script runs on a Linux machine, it remotes into a Solaris machine. The FTP session must be executed from the Solaris machine because the FTP site performs IP address checking.
Formerly this script ran on the Solaris machine directly (i.e. it didn't use rsh) I hacked it around and came up with this which seems to work. However I have little idea how, in particular I don't understand the << ! bit at the end of the first line. It looks a little like a here-document but I'm not really sure.
Any explanations welcome.
You are right, << is a heredoc, which is made clear by the following warning (which I get when I take out the rsh command):
sh: line 2: warning: here-document at line 0 delimited by end-of-file (wanted `!')
The construct
<< HEREDOC
reads as standard input everything from HEREDOC up to a line containing only HEREDOC or up to an end-of-file character. When you put this after a command, it is equivalent to
command < file
where file contains the text in the heredoc. In your case, instead of HEREDOC the delimiter is !, so the ! is not passed to ftp but everything after ! is. This is equivalent to
$ cat file
user anonymous someone\#somewhere.org
some ftp commands
bye
$ ftp -in ftp.something.com < file
rsh takes that entire command and runs it on your remote host.
As illustrated by user1146334's answer, this command does not act on the principal of least surprise. At the very least, make it less confusing by changing it to
system("rsh some_server ftp -in ftp.something.com << HEREDOC
user anonymous someone\#somewhere.org
some ftp commands
bye
HEREDOC");
Or even better, as mpapec mentioned in the comments, use Net::FTP and Net::SSH2.
Did you look at the man page?
-i Turns off interactive prompting during multiple file transfers.
-n Restrains ftp from attempting “auto-login” upon initial connection. If auto-login is enabled, ftp will check the .netrc (see netrc(5)) file in the user's
home directory for an entry describing an account on the remote machine. If no entry exists, ftp will prompt for the remote machine login name (default is
the user identity on the local machine), and, if necessary, prompt for a password and an account with which to login.
The client host and an optional port number with which ftp is to communicate may be specified on the command line. If this is done, ftp will immediately attempt
to establish a connection to an FTP server on that host; otherwise, ftp will enter its command interpreter and await instructions from the user. When ftp is
awaiting commands from the user the prompt ‘ftp>’ is provided to the user. The following commands are recognized by ftp:
! [command [args]]
Invoke an interactive shell on the local machine. If there are arguments, the first is taken to be a command to execute directly, with the rest of
the arguments as its arguments.
So essentially you're ftp'ing in and providing a new command per line in-line instead of from a file.