Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Using Perl to simulate Telnet from a Program

News See also Telnet Protocol Recommended Links Expect Perl Expect.pm

Telnet Windows Clients

Perl Monitoring Scripts Filesystem free space monitoring Programming Monitors in Perl Humor Etc

If you are running a monitoring application it is often useful to simulate a telnet connection from your program to a remote machine using telnet, then issues one or a couple of commands and process output to generate alerts or status report. 

The simplest way to accomplish this is to use Expect (or Perl Expect.pm) but you can use the CPAN module Net::Telnet too:

use Net::Telnet;

$t = Net::Telnet->new( Timeout => 10,
                       Prompt  => '/%/',
                       Host    => $hostname );

$t->login($username, $password);
@files = $t->cmd("ls");
$t->print("top");
(undef, $process_string) = $t->waitfor('/\d+ processes/');
$t->close;

Net::Telnet provides an interface to the telnet protocol. It has object-oriented flavor (which is unnnessary in case of a single connection, but beneficial for multiple connections)

You first need to create a connection with Net::Telnet->new, and then interact with the remote machine using method calls on the resulting object.

The new method requires passing several parameters in form of a hash.  The most important is Host, the machine you're telnetting to. The default host is localhost. If you want to telnet to a port other than one telnet normally uses, specify this in the Port option. Error handling is done through the function whose reference is specified in the Errmode parameter.

Another important option is Prompt. When you log in or run a command, Net::Telnet uses the Prompt pattern to determine when the login or command has completed. The default Prompt is:

/[\$%#>] $/

which matches the common shell prompts. If the prompt on the remote machine doesn't match the default pattern, you have to specify your own. Remember to include the slashes.

Timeout lets you control how long (in seconds) network operations wait before they give up. The default is 10 seconds.

If an error or timeout occurs in the Net::Telnet module, the default behavior is to raise an exception, which, if uncaught, prints a message to STDERR and exits. To change this, pass a subroutine reference to new in the Errmode argument. If instead of a code subroutine, you specify the string "return" as the Errmode, methods return undef (in scalar context) or an empty list (in list context) on error, with the error message available via the errmsg method:

$telnet = Net::Telnet->new( Errmode => sub { main::log(@_) }, ... );

The login method is used to send a username and password to the remote machine. It uses the Prompt to decide when the login is complete and times out if the machine doesn't reply with a prompt:

$telnet->login($username, $password)or die "Login failed: @{[ $telnet->errmsg() ]}\n";

To run a program and gather its output, use the cmd method. Pass it the string to send, and it returns the output of the command. In list context, it returns one line per list element. In scalar context, it returns one long line. It waits for the before returning.

You can separate the sending of the command from the reception of its output with the and methods. This is somewhat similar to Expect. The method takes either a single string containing a Perl regular expression match operator:

$telnet->waitfor('/--more--/');

or named arguments. Timeout lets you specify a timeout to override the default, Match is a string containing a match operator as above, and String is a literal string to find:

$telnet->waitfor(String => 'greasy smoke', Timeout => 30);

In scalar context, returns true if the pattern or string was found. If it is not found before timeout occures, the Errmode action is performed. In list context, it returns two strings: all the text before the match, and the text that matched.

See also the documentation for the Net::Telnet module from CPAN; RFCs 854-856, as amended by later RFCs


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[Jan 03, 2012] [SOLVED] Perl Telnet login script [Archive]

Ubuntu Forums

View Full Version : [SOLVED] Perl Telnet login script


PastorTaz

August 1st, 2007, 01:00 AMI'm new to programming in Perl and I'm trying to get a script to automate a login to a FTP server using Telnet. I've searched the net and everything I see does not work for me for some reason. Here is my code

#!/usr/bin/perl -w
use strict;
use Net::Telnet;
my ($host, $port, $user, $pass, $command);

##### get host info
print 'Enter host: ';
chop($host = <STDIN>);
##### get port info
print 'Enter port: ';
chop($port = <STDIN>);
##### get user info
print 'Enter user: ';
chop($user = <STDIN>);
##### get user info & hide input
print 'Enter password: ';
system 'stty -echo';
chop($pass = <STDIN>);
system 'stty echo';
print "\n";

my $tn = new Net::Telnet(Host => $host, Port => $port, Timeout => 20)
or die "connect failed: $!";
$tn->open ($host);
$tn->login($user, $pass)
or die "login failed: $!";

print 'Hostname: ';
print $tn->cmd('/bin/hostname'), "\n";
my @who = $tn->cmd('/usr/bin/who');
print "Here's who:\n", @who, "\n";
print "\nWhat is your command: ";
chop($command = <STDIN>);
print $tn->cmd($command), "\n";
$tn->close or die "close fail: $!";

This is where it dies
$tn->login($user, $pass)

And here is the error:
timed-out waiting for login prompt at ./test2.pl line 26

The FTP server I'm trying to get into is FileCOPA.

Thanks for any help you can give a noobie.


Mr. C.

August 1st, 2007, 02:37 AMThe login method in Net::Telnet will timeout when the prompts do not match what is expected. The login method expects the remote server to prompt with a login prompt that matches either:
/login[: ]*$/i
/username[: ]*$/i

and the password prompt must match:

/password[: ]*$/i

Use print() and watifor() to connect instead of login() if the remote FTP server does not prompt with those patterns.

Be sure the command prompt is also set.

See:

perldoc Net::Telnet

If your goal is to automate an FTP login and transfer, you can use wget or curl.

MrC


PastorTaz

August 3rd, 2007, 01:29 AMThanks Mr. C... I'm getting closer, this FTP server just wants to be a pain to automate. Here is what I have for code...

#!/usr/bin/perl -w
use strict;
use Net::Telnet;
my ($host, $port, $user, $pass, $command);

##### get host info
print 'Enter host: ';
chop($host = <STDIN>);
##### get port info
print 'Enter port: ';
chop($port = <STDIN>);
##### get user info
print 'Enter user: ';
chop($user = <STDIN>);
##### get user info & hide input
print 'Enter password: ';
system 'stty -echo';
chop($pass = <STDIN>);
system 'stty echo';
print "\n";

print "user ", + $user, + "\r\n";
print "pass ", + $pass, + "\r\n";

my $tn = new Net::Telnet(Host => $host, Port => $port, Timeout => 20)
or die "connect failed: $!";
$tn->open ($host);
#$tn->login($user, $pass)
# or die "login failed: $!";
$tn->waitfor('/remaining/i');
#$tn->waitfor('/remaining: $/i');
print 'user ', + $user;
$tn->waitfor('/./i');
print 'pass ', + $pass;
$tn->waitfor ('/logged in./i');
print 'Hostname: ';
print $tn->cmd('/bin/hostname'), "\n";
my @who = $tn->cmd('/usr/bin/who');
print "Here's who:\n", @who, "\n";
print "\nWhat is your command: ";
chop($command = <STDIN>);
print $tn->cmd($command), "\n";
$tn->close or die "close fail: $!";

Here is what my log in to the FTP server looks like

220-InterVations FileCOPA FTP Server Version 1.01 21st November 2005
220 Trial Version. 19 days remaining
user test
331 Password required for test.
pass test
230 User test logged in.


And here is my error...
pattern match timed-out at ./test2.pl line 33
user testroot@vm-ubuntu:/lpt/scripts/perl#

Line 33 is $tn->waitfor('/./i'); what's wierd is that the script is reading and executing line 34 before it times out. Any suggestions as to why the waitfor() is not working for me?

Thanks,


Mr. C.

August 3rd, 2007, 01:51 AMThe /./ pattern matches any single character. Is this what you want ?

MrC


PastorTaz

August 4th, 2007, 12:30 AMNot really sure to be honest. What I'm trying to do is automate a login to a FTP server with a Perl script. Here is what the server answers with when I do a manual login...

[Trying 192.168.1.235...
Connected to 192.168.1.235.
Escape character is '^]'.
220-InterVations FileCOPA FTP Server Version 1.01 21st November 2005
220 Trial Version. 19 days remaining
user test
331 Password required for test.
pass test
230 User test logged in.
/QUOTE]

This is the code that I have so far for the login...

$tn->open ($host);
$tn->waitfor('/remaining/i');
print 'user ', + $user;
$tn->waitfor('/required for test/i');
print 'pass ', + $pass;
$tn->waitfor ('/logged in./i');

The "waitfor('/remaining/i'); seems to be working fine as the "print 'user' line runs. The hang up is with the "waitfor('/required for test/i')" line (which was the "waitfor('/./i')" line in the previous post).

Here is the error being returned

[QUOTE]pattern match timed-out at ./test2.pl line 33


My ultimate goal is to be prompted for the host, port, user, and password and then have the script run and complete the login.

Thanks for the help. I haven't programmed since college 8 years ago.


Mr. C.

August 4th, 2007, 12:37 AMSince you are trying to match:

331 Password required for test.

try:

$tn->waitfor('/required for test\.$/i');

A dot (.) means any single character, so you have to escape it to match a literal dot.

MrC


PastorTaz

August 4th, 2007, 01:32 AMSomeone else helped me do this with a socket instead of Telnet... However, my curiosity has been sparked and I want to get to the bottom of this. I'm still getting the same error on the same line even with the adjusted code.

expect spawns telnet -- screen height

Hi,

I'm trying to login to a router using telnet and EXPECT, to backup the
router config.

When I'm connecting to the device via telnet, everything is ok, but when I'm
using a perl/expect-Script to connect, the router asks "Press any key to
continue", even before the login prompt.

*** via telnet commandline:

# telnet 1.2.3.4
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.


One200

Username:


*** via script

# ./save-cpe.pl
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.


One200

Press any key to continue (Q to quit)

This is the perl code I spawn telnet with:

$telnet = Expect->spawn('telnet', $ipaddr)
or error_exit(11, "....");

Looks like the router thinks the screen height is just a few lines?

Any ideas?

Thanks,

Re: "expect" spawns telnet -- screen height> This is the perl code I spawn telnet with:
>
> $telnet = Expect->spawn('telnet', $ipaddr)
> or error_exit(11, "....");
>
> Looks like the router thinks the screen height is just a few lines?

OK, I've found out that the following code works ok when run from a bash
shell:

my $telnet = new Expect;
$telnet->raw_pty(1);
if (defined ($telnet->slave)) {
$telnet->slave->clone_winsize_from(\*STDIN);
}

$telnet->spawn('telnet', $ipaddr)
or error_exit(11, ".....");

Unfortunately, I'm running this script from a PHP Page, NOT from a bash
shell... perl teminates without any hint when reaching the line
"$telnet->slave->clone_winsize_from(\*STDIN);".

Any Idea how to set the winsize to e.g. 80x25 without cloning it or where to
clone it from when run from a PHP script?

Re: "expect" spawns telnet -- screen heightMy solution, based on Jens script, is not very elegant, but it works
from crontab (for example) :

open TTY,"/dev/console" or die "not connected to a terminal\n";
$telnet->slave->clone_winsize_from(\*TTY);
close TTY;

Daniel


--
dpratlong

Using perl to connect to remote hosts via telnet.

>Suppose you needed to open a connection to a remote host from within your perl program. One thing you would probably think of doing at first is the following:

open TELNET "|telnet $hostname"; print TELNET "$username\n"; print TELNET "$password\n"; ...

Unfortunately, if you try this, you'll find it doesn't work. The telnet program connects to the remote host but it completely ignores any commands you pipe to it. That's because the telnet program reads its input only from the terminal and not from standard input.

The most cunning among you might then think a workaround for this: Open a socket to port 23 (the default telnet port) of the remote machine and write directly to it, thus, bypassing the telnet program altogether. Well, although that might sound like a neat idea, it's not. And that's because the telnet protocol requires that certain control data be exchanged between the two machines by sending them along through the same socket connection.

So, it turns out that the problem is much more complicated than it seemed at first. We don't just need to write code to perform socket I/O, but also we need to write code that speaks the TELNET protocol. This is the bad news. The good news is that this code has already been written, and that its author was kind enough to bundle it in a useful module, Net::Telnet, available at CPAN.

Net::Telnet

Using Net::Telnet is pretty straightforward and simple. Let's first see a no-thrills example:

use Net::Telnet; $telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die'); $telnet->open('camel.perlfect.com'); $telnet->waitfor('/login: $/i'); $telnet->print('bilbo'); $telnet->waitfor('/password: $/i'); $telnet->print('baggins'); $telnet->waitfor('/\$ $/i'); $telnet->print('who'); $output = $telnet->waitfor('/\$ $/i'); print $output;

This simple program connects to camel.perlfect.com with username and password, 'bilbo' and 'baggins' respectively, and the issues the command 'who' to get a list of logged in users. It then retrieves and prints the output. Although the code is self explanatory, here are a few things worth of noting:

Shortcuts

You might notice that issuing commands involves repeating print() and waitfor() calls in a very much similar manner. We print a command and then we try to match a shell prompt. Net::Telnet provides a very nice mode of operation that rids you of some of the repetitive tt. All you need to do is to specify the regular expression that matches a prompt as a parameter in the object's constructor and then use the cmd() method to issue commands. Similarly to command issuing, Net::Telnet provides a handy method to simplify the login process, namely login(). The following example demonstrates these shortcuts.

use Net::Telnet; $telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die' Prompt => '/\$ $/i'); $telnet->open('camel.perlfect.com'); $telnet->login('bilbo', 'baggins'); print $telnet->cmd('who');

This does the same as the previous example, but with much less typing. Note that the login() method matches the login and password prompts with the regular expressions /(login|username)[: ]*$/i and /password[: ]*$/i respectively.

So far we have covered the basics of the Net::Telnet module, enough to get you going with your first telnetting scripts. The module is rich with other features, so make sure you take the time to have a look at the documentation.

Happy TELNETing!

Recommended Links

Simple Telnet Automation Using Expect

Using perl to connect to remote hosts via telnet.

Perl Cookbook Solutions and ... - Google Book Search

O'Reilly - Safari Books Online - 1565922433 - Perl Cookbook



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: March 12, 2019