Smtp-test

From brokenpoet.org wiki

Script which automates the process of checking smtp using telnet



wget http://scripts.brokenpoet.org/smtp-test.sh



#!/usr/bin/perl -w

use strict;
use warnings;
use IO::Socket;
use IO::Select;
my $version = '1.2';
print "SMTP Test $version by Noah Petherbridge\n\n";

#------------------------------------------------------------------------------#
# Change Log
# ==========
# 1.2 Mar  6 2008
# + Modified it so it will send the next SMTP command after receiving an entire
#   group of lines from the server, instead of sending one on every positive
#   response (was having issues sending stuff too fast before the server even
#   finished sending its 3 line greeting message).
#
# 1.1 Feb  7 2008
# + Added the command-line option --help (alias -h and -?)
# + Doesn't ask for port number anymore; must use full CLI args for port != 25
# + Bugfix to have it NOT send HELO more than once.
#
# 1.0 Feb  7 2008
# + Initial release.
#------------------------------------------------------------------------------#

# Help Information
if (join("",@ARGV) =~ /(\-\-help|\-h|\-\?)/i) {
	my $hostname = `hostname`;
	chomp $hostname;
	print qq~Usage: smtp-test <server> <email_to> [port]

This script is intended to test SMTP servers for clients, in a manner similar
to using telnet. It will connect to the given 'server' on 'port=25', and try to
deliver an e-mail to 'email_to'. It will output all messages sent and received
from the server, so you have all the same feedback as you\'d have with telnet,
but in a fraction of the time.

If you don\'t provide command-line arguments, you will be prompted for each of
"server", "email to", and "port". Port is assumed to be 25.

On the first run, you\'ll need to enter an e-mail address for this and all
following e-mails to be sent as. The default is devnull\@liquidweb.com but you
should preferably change this to your own e-mail. This information is stored in
\~/.smtp-test

The "HELO" command sends your current hostname, as returned by `hostname`. On
your system, the command will be: "HELO $hostname".

If you have any questions, contact Noah P.
~;
	exit(0);
}

################################################################################
## First Run Information                                                      ##
################################################################################

my $home = $ENV{HOME} || $ENV{USERPROFILE};
my $from = 'devnull@liquidweb.com';
my $helo = `hostname`;
chomp $helo;

if (-f "$home/.smtp-test") {
	open (READ, "$home/.smtp-test");
	$from = <READ>;
	close (READ);
}
else {
	print "First Run Information\n";
	print "---------------------\n";
	print "Choose an e-mail address for all test messages to be sent from.\n";
	print "From [devnull\@liquidweb.com]> ";
	chomp ($from = <STDIN>);
	if (length $from == 0) {
		$from = 'devnull@liquidweb.com';
	}

	open (WRITE, ">$home/.smtp-test");
	print WRITE $from;
	close (WRITE);
}

################################################################################
## Collect Variables. Usage:   smtp-test <server> <target_email>              ##
################################################################################

my $server = ;
my $to = ;
my $port = 25;

if (scalar(@ARGV)) {
	$server = shift(@ARGV);
	if (scalar(@ARGV)) {
		$to = shift(@ARGV);
		if (scalar(@ARGV)) {
			$port = shift(@ARGV);
		}
	}
}
else {
	print "Usage: smtp-test <server> <target_email> [port]\n\n";
}

if (length $server == 0) {
	print "   Server> ";
	chomp ($server = <STDIN>);
}
if (length $to == 0) {
	print "       To> ";
	chomp ($to = <STDIN>);
}

################################################################################
## Connect to the Server.                                                     ##
################################################################################

print "\n";
print "Connecting to $server:$port...\n\n";

my $sock = new IO::Socket::INET (
	PeerAddr => $server,
	PeerPort => $port,
	Proto    => 'tcp',
);
if (!defined $sock) {
	die "Couldn't connect to $server:$port: $!";
}
my $select = IO::Select->new ($sock);

# Wait for replies.
my $step = 0;
my $going = 1;
my $helo_timer = time() + 5; # In case we have to speak up first.
my $sentHelo = 0;
while ($going) {
	if ($sentHelo == 0) {
		if (time() > $helo_timer) {
			# Send HELO. Server's not speaking up.
			print "HELO $helo\n";
			$sock->send ("HELO $helo\x0d\x0a");
			$step++;
			$sentHelo = 1;
		}
	}

	my @ready = $select->can_read(.001);
	next unless(@ready);

	my $success = 0;
	foreach my $line (@ready) {
		my $resp;
		$sock->recv ($resp,2048,0);
		my @in = split(/\n/, $resp);

		foreach my $said (@in) {
			$said =~ s/\x0d//ig;
			$said =~ s/\x0a//ig;

			print "$said\n";

			if ($said =~ /^(2|3)/i) { # 2 = Success
				$success = 1;
			}
		}
	}

	if ($success == 1) {
		if ($step == 0) {
			# Send HELO.
			print "HELO $helo\n";
			$sock->send ("HELO $helo\x0d\x0a");
			$sentHelo = 1;
		}
		elsif ($step == 1) {
			# Send MAIL FROM.
			print "MAIL FROM: <$from>\n";
			$sock->send ("MAIL FROM: <$from>\x0d\x0a");
		}
		elsif ($step == 2) {
			# Send RCPT TO.
			print "RCPT TO: <$to>\n";
			$sock->send ("RCPT TO: <$to>\x0d\x0a");
		}
		elsif ($step == 3) {
			print "DATA\n";
			$sock->send ("DATA\x0d\x0a");
		}
		elsif ($step == 4) {
			print "From: $from\n";
			$sock->send ("From: $from\x0d\x0a");
			print "To: $to\n";
			$sock->send ("To: $to\x0d\x0a");
			print "Subject: SMTP Test\n\n";
			$sock->send ("Subject: SMTP Test\x0d\x0a\x0d\x0a");
			print "This is only a test message.\n.\n";
			$sock->send ("This is only a test message.\x0d\x0a.\x0d\x0a");
		}
		elsif ($step == 5) {
			print "QUIT\n";
			$sock->send ("QUIT\x0d\x0a");
			$going = 0;
			$step++;
			last;
		}

		$step++;
	}

	last if $going == 0;
}

print "\n\nSMTP Tests Completed.\n";
exit(0);
Personal tools