Net::Telnet and SMTP

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Hi all,

I'm using Net::Telnet to test an SMTP proxy product and I've run into
an issue with it.

First, I'm trying to send a sequence of commands and then log  both the
commands sent and the response from the server into a log file.  The
responses need to match up EXACTLY to the commands to which they are in
response.  Second, I've tried Net::SMTP and it doesn't quite do what I
need.  Since the product I'm testing may have to deal,
impolite SMTP clients (read: crackers) I want to make sure that if the
SMTP protocol being sent is broken that the proxy reponds in a correct
(read: secure) way.  Unfortunately Net::SMTP doesn't give me the level
of control I need....mostly because it's too polite. ;)

I've included the script and a sample text file (that feeds the scripts
the commands) below.  It's been since sometime in v4 since I last did
anything with PERL (unfortunately) so I apologize in advance for the
mess. :)



#This script reads from a generated smtp test file and writes to a log
file in
#the logs directory, which will be created under the directory from
which the
#test is run.  I recommend that you place the test file in the same dir
as the
#script, if for no other reason than that you won't have to maintain in
#script the location from which you're running the file.
#test file format note:
#The first line of the test file *must* contain the dns name (if you're
# DNS) or the IP address of the server under test, followed by a colon
(:) and
# the port to which you're connecting, typically 25
# You can place comments in the test file by prepending the line with a
#.  Note
# that this can only be placed at the start of the line
# Each test should beging with "***Start test" (without quotes) and end
# "***Stop test"

use strict;
#no strict 'refs';
use Net::Telnet;

#set the test and log file names, and some globals
my $testfilename = "smtptests.txt";
my $t = localtime(time());
my $logfilename = "./logs/smtplog$.txt";
our $testcount = 0;
our $debug = 1;

open TESTFILE, $testfilename or die "Cannot open test file,

#print $logfilename;
if (-e $logfilename) {
    die "Log file $ already exists!";
mkdir 'logs', 0744;

open LOGFILE, ">$" or die "Cannot open log file,
if ($debug) {print "*****Created log file\n";}

#grab the server and port out of the first line of the file
my ($server, $port) = split (/\:/, getline(*TESTFILE));

#create the telnet object and set some initial values
our $telnet = new Net::Telnet (Timeout => 660,
                Telnetmode => 0,
                Host => $server,
                Port => $port,
                Prompt => '//',
                Errmode => 'die');
#need to set the prompt to null, since SMTP doesn't have a prompt,
large timeout is
#for testing our timeout

#timeout exception for debugging the script
$telnet->timeout(30) if ($debug);

if ($debug) {print "*****Telnet object created\n";}

$t = localtime(time());
print LOGFILE "Starting test of server $ at $\n";

#begin processing the main part of the file
processfile(*TESTFILE, *LOGFILE);

close LOGFILE;

#print "$";
#print $port;

#processfile is where the main work of the program is coordinated.  it
#commands from the test file and organizes the starting and stopping of
sub processfile {
    if ($debug) {print "*****Entering processfile\n";}
    my $TF = shift;
    my $LOG = shift;
    my $line = getline($TF);

    if ($line eq eof) {return 0;}

    if ($debug) {print $line;}
    while ($line ne eof) {
        # checks the line and read if it's a command to start a test
        if ($line eq "***Start test\n") {
            print "*****Starting test\n" if ($debug);
            print $LOG "Starting test $\n";
            if (defined(dotest($TF, $LOG))) {
                print $LOG "Test $ finished\n";
            } else {
                print $LOG "Test $ failed\n";
            }#end else
        }#end if
        #We should never encounter a stop test line in processfile
        if ($line eq "***Stop test\n") {die "Error in test file!"}

        $line = getline($TF);
        if ($debug) {print $line;}
    }#end while

    return 0;

#once we've started a test, dotest actually runs the commands,
including opening
#the telnet session
    sub dotest {
        my $TF = shift;
        my $LOG = shift;
        my @response = ();

        print "*****Entered dotest\n" if ($debug);

        my $line = getline($TF);
        print $LOG "Recd: ";
        print "*****Telnet session open\n" if ($debug);

#Try a short delay

        $telnet->get();        #read output for input_log
        #my $firstline = $telnet->getline();
        #print $LOG "Recd: $";

        while($line ne "***Stop test\n"){
            print $LOG "Sent: $";
            print $LOG "Recd: ";
            print $LOG $telnet->cmd(String => $line);

#Try a short delay between sending command and reading output

            #if (substr($line, 0, 4) eq "ehlo") {
            #@response = $telnet->getlines(All => "");
                #} else {@response = $telnet->getline();}

                #print $LOG "Recd: @";
            $line = getline($TF);
        }#end while
        #$telnet->dump_log('') if ($debug);

        $telnet->cmd(String => localtime(time())) if ($debug);

        return 0;
    }#end dotest
}#end processfile

#Small sub to strip out comments in the test file and exit gracefully
if we've
#reached the end of the input file
sub getline {
    my $TF = shift;
    my $gotline = 0;
    my $line = '';

    while (!($gotline)) {
        $line = <$TF>;
        if (eof($TF)) {
            print "*****EOF reached\n" if ($debug);
            print $line if ($debug);
        $gotline = 1;
        my @a = split (//, $line);
        if ($a[0] eq '#') {$gotline = 0;}
    }#end while

    #print "$";
    return $line;
}#end getline

#small sub to insert a variable length time delay
sub delay {
    my $delaytime = shift;

    my $returntime = (time + $delaytime);
    while(1) {
        if (time >= $returntime)
}#end delay

#Test comment
***Start test
mail from:
rcpt to:
To: bob
From: Bill
Subject: test
This is a test email
***Stop test

Site Timeline