smtp-cli — command line SMTP client

smtp-cli is a powerful SMTP command line client with a support for advanced features, such as STARTTLS, SMTP-AUTH, or IPv6 and with a scriptable message composition capabilities supporting anything from simple plain-text messages right up to building complex HTML emails with alternative plain-text part, attachments and inline images. The MIME-Type of the attachments can either be guessed automatically or alternatively set on the command line, separately for each attachment if required.

It's also a convenient tool for testing and debugging SMTP servers' setups. Even the hardcore mail admins used to typing the SMTP protocol over telnet need a specialised tool when it comes to verifying encryption settings of their TLS enabled server with a subsequent user authentication. Such things are pretty hard to type into a telnet session by hand :-)

The name smtp-cli stands for:

  1. smtp-client
  2. smtp-command line interface

Use the script for checking given server's capabilities, test you server's setup or create and send mails. Command line interface is intuitive, everything is scriptable and can run in a completely non-interactive mode from various scripts or cron jobs. It is also ideal for shipping log files from remote machines, running periodical mail delivery test loops, etc. Also if you ever needed to send a complex email with attachments from a command line, this script is all you need.

Releases
Download the latest version
Optional dependencies

Some features of smtp-cli are optional and available only when the appropriate perl modules are installed:

Users of other Linux distributions will have to find the appropriate packages by themselves, or install the modules directly from CPAN.

Make it executable
$ chmod +x smtp-cli
Test on your localhost:
$ ./smtp-cli --verbose --host=localhost
[220] 'server.domain.top ESMTP Postfix'
> EHLO localhost
[250] 'server.domain.top'
[250] 'PIPELINING'
[250] 'SIZE 20480000'
[250] 'ETRN'
[250] '8BITMIME'
> QUIT
[221] 'Bye'
Send an e-mail through a host which requires authentication after an encryption takes place:
 ./smtp-cli --verbose --host=relayhost.domain.top --enable-auth --user test \
--from test@domain.com --to user@another.domain.org --data message-body.txt
[220] 'server.domain.top ESMTP Postfix'
> EHLO localhost
[250] 'server.domain.top'
[250] 'PIPELINING'
[250] 'SIZE 10240000'
[250] 'VRFY'
[250] 'ETRN'
[250] 'STARTTLS'
[250] 'XVERP'
[250] '8BITMIME'
Starting TLS...
> STARTTLS
[220] 'Ready to start TLS'
Using cipher: EDH-RSA-DES-CBC3-SHA
Subject Name: /C=XX/CN=server.domain.top/Email=info@domain.top
Issuer  Name: /C=XX/CN=Domain.TOP Root CA/Email=ca@domain.top
> EHLO localhost
[250] 'server.domain.top'
[250] 'PIPELINING'
[250] 'SIZE 10240000'
[250] 'VRFY'
[250] 'ETRN'
[250] 'AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5'
[250] 'AUTH=PLAIN LOGIN DIGEST-MD5 CRAM-MD5'
[250] 'XVERP'
[250] '8BITMIME'
AUTH method (PLAIN LOGIN DIGEST-MD5 CRAM-MD5): using CRAM-MD5
> AUTH CRAM-MD5
[334] 'PDE0OTQyOTcxOC4yNjAwOTYwQHNlcnZlci5kb21haW4udG9wPg=='
> dGVzdCBmOTUyY2RkM2VlODBiMzk1YjYxNDI4NjBlYzg2Y2ExZnJvb3Q=
[235] 'Authentication successful'
Authentication of test@localhost succeeded
> MAIL FROM: <test@domain.com>
[250] 'Ok'
> RCPT TO: <user@another.domain.org>
[250] 'Ok'
> DATA
[354] 'End data with <CR><LF>.<CR><LF>'
[250] 'Ok: queued as C5C3A299D7'
> QUIT
[221] 'Bye'
Compose a plain text email with attachments

For composing emails you're gonna need an optional MIME::Lite perl module. See the download section above for details.

./smtp-cli --from test@domain.com --to user@another.domain.org \
                 --subject "Simple test with attachments" \
		 --body-plain "Log files are attached." \
                 --attach /var/log/some.log@text/plain \
		 --attach /var/log/other.log

Pretty self-explanatory, isn't it? Standard plain text email with attachments. The only interesting bit is the syntax used for enforcing MIME-Type of the second attachment. The syntax some.log@text/plain will make some.log attached as text/plain part, while the MIME-Type of other.log will be guessed by the script and eventually default to application/octet-stream.

Attachment as an email body
./smtp-cli --from test@domain.com --to user@another.domain.org \
                 --subject "Image as a mail body" \
                 --attach /path/to/tux.png

If there is only one text or image file to be sent, the file itself could be the message body. At the same time it will be accessible as an attachment with a file name for easy saving. Best to show a screenshot I guess...

There is no Text or HTML body part and the email is not multipart/mixed. All that is in the email is Tux the Penguin image. You can immediately see it in your mailer but also can easily save it with its provided name tux.png. The same way it works with text files (or files forced to be text/plain, to be precise).

Compose a multipart/alternative email with both HTML and Plain text part and inline images

Sending HTML emails is popular, especially among non-technical people. They like to change font colours, backgrounds, embed images and apply all sorts of other useless effects to their one short line of text. Indeed, me and you are more than happy with plain text and we both know that some mail readers can't even display colours and graphics at all (our office manager wouldn't believe!). And therefore it is a good practice for HTML messages to use multipart/alternative MIME format with both HTML and TEXT parts. In this example we're going to go wild and even embed an inlined image or two into the HTML part.

However first of all prepare the message body. Or bodies, actually. First one is body.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head></head>
<body bgcolor="#ffffff" text="#000000">
<div align="center">
Here comes embedded <font color="#006600"><b>Mr Tux</b></font><br>
<img src="cid:tux.png"><br>
<i>Nice, isn't it?</i><br>
<img src="cid:smiley.png"><br>
</div>
</body>
</html>

Note the <img> tags with cid:filename.xyz source — that's the way to refer inlined attachments from inside the message. We will obviously have to inline-attach tux.png and smiley.png to the message to make it work.

Anyway, the second body file is a plain text representation of the above, call it body.txt:

Here comes embedded Mr Tux
... actually it doesn't ... 
Not in a text-only mail reader.
Sorry

That's it. Here comes the magic command line that puts it all together:

./smtp-cli --from test@domain.com --to user@another.domain.org \
                 --subject "HTML with embedded image" \
		 --body-html body.html --body-plain body.txt \
		 --attach-inline tux.png --attach-inline smiley.png

And this is what we get:

Screenshot of inlined images

Donations

Have you found this script useful? Do you use it in production? Support its author by a PayPal or CreditCard donation.


 

Place for your feedback...
Cornelinux
3rd March 2004 at 17:21
Looked for such a sw ever!
Always asked, why such a commandline tool wouldn't exist. Nearly started to code it on my own. But that is even better! :-)

9th March 2004 at 16:42
Thanks, thanks, and once more thanks!
I owe you a beer!
Jacob Smith
1st August 2004 at 16:26
Your Perl smtp script
Hello Michal,

Just a brief note of thanks for the excellant Perl script you offer
publically for automating sending mail.

I, like many, have a dynamic IP here at home, but need a way to be able to
"dial in" to my home Linux server from anywhere. I use an expect script
which telnets my modem to determine my current public IP, and then compare
this to the last IP. This script is called by cron every 15 minutes.

I was using a mail server to send a mail to various web accessable
addresses when the IP changed to inform of the change. This was unwieldy,
and really alot of "expense" for such a small job.

Your Perl script fit the bill perfectly! Once I found all the necessary
Perl modules and added them to my system I found your script to function
properly for all the various login methods!

The only modification I made was to remove the interactive prompting for a
password if none is specified on the command line, as this won't work in a
cron job which has no term.

Thnaks again!

Best Regards,

Jacob Smith
23rd November 2004 at 16:20
GREAT!
Good script.
I will use it next time!
Thanks!
27th January 2005 at 18:34
Problem with Hang at end of Data Command
Michal

Great Script!
I did experience some deadlocks on connection with some SMTP Server.
On closer inspection I realised that it occured where the data file did not end with a blank line.

I think the correct fix is to end the DATA section with
$sock->printf ("\r\n.\r\n");

rather than
$sock->printf (".\r\n");

regards
Dave
9th March 2005 at 6:41
Nicely Done
Was looking for something to do this, and here it is. With TLS and AUTH no less. Also like your no 'e-patents' graphic.
9th March 2005 at 7:52
Re: Nicely Done
A couple of notes. The script does not convert \n to \r\n in the data file. This is a problem if you are editing this file on an OS that uses \n (only) to terminate lines.

The fix is to add:
$line =~ s/\n/\r\n/;
after line 293.

The data file is sent with-or-without headers. It is probably useful to put at least Date and Subject fields in your data file.

Neither of these are bugs, just notes.

Once again, good job.
6th May 2005 at 13:22
Can i get Smtp-Server.pl
Greetings,
I am working on honeypot technology and for this purpose i need SMTP server simulation ..... if any one can help me then please tell me that can i get Smtp Server script with complete functionality written in PERL.Thanks
Regards,
Fadiebia
9th May 2005 at 1:24
Re: Can i get Smtp-Server.pl
The script here is just a client. Server must be more "sophisticated", e.g. at least reply that the recipient doesn't exist, but better accept and deliver the e-mail.

Write it yourself and share ;-)
Eberhard Mattes
21st May 2005 at 11:20
LF vs. CRLF
smtp-client.pl doesn't work with the SMTP server
of my ISP because that SMTP server insinsts on
receiving CRLF at the end of each line whereas
smtp-client.pl sends only a LF.

Eberhard
22nd May 2005 at 21:33
Re: LF vs. CRLF
Could you tell me your ISP's mailserver vendor/version? I'd like to test against it.
Eberhard Mattes
29th May 2005 at 16:28
Re: Re: LF vs. CRLF
smtp.1und1.com shows this greeting:
220 Welcome to Nemesis ESMTP server on mrelayeu

Eberhard
Edgard Pevidor
16th June 2006 at 20:55
Re: Re: Re: LF vs. CRLF
qmail program doesn't accept bare LF (It violates 822bis)
See http://cr.yp.to/docs/smtplf.html

To correct this, I've added the line:
$line =~ s/[\r\n]+$/$CRLF/;
above line
$sock->print ($line);

George
8th July 2006 at 19:43
Re: Re: Re: Re: LF vs. CRLF
When I add that line there, qmail tells me:

> DATA
[354] 'go ahead'
[451] 'qq internal bug (#4.3.0)'
DATA not send: '451 qq internal bug (#4.3.0)'


Anybody have any ideas?
George
8th July 2006 at 19:50
Re: Re: Re: Re: LF vs. CRLF
However, that line did make it work with an SBC (Yahoo, who runs qmail) server.
I guess my own installation of qmail is just messed up somehow.
Thanks
21st June 2005 at 15:27
Adding SUBJECT
Is it possible to add a SUBJECT or CC address to the emails send with smtp-client.pl?
Excellent by the way
21st June 2005 at 22:44
Re: Adding SUBJECT
No, sorry. smtp-client.pl works on the SMTP level and isn't at all aware of the RFC822 message headers. The e-mail messages provided with --data= option must have complete headers including Subject, etc. But note that From:/To:/Cc: are not taken into account when sending the e-mail, instead you must provide the SMTP from/to addresses with --from/--to options.
(this may look stupid but is perfectly consistent with the fact that smtp-client.pl only supports SMTP, not RFC822).
3rd April 2007 at 18:39
Re: Re: Adding SUBJECT
Anybody know an easy way to create such a message on linux? I tried using mutt and mail but can't find a way. I also tried putting this at the top of the file:

From: "me"
To: somebody@yyy.com
Subject: Test using smtp-client.pl

It nearly works but I get some headers after the text in my file (I use --data=somefile), also I noticed if I send the message to Outlook the message "Sent" field says "none" and
10th April 2007 at 0:21
Re: Re: Re: Adding SUBJECT
In From should be your email address, not just name. And your headers are missing Date field in RFC2822 format (e.g. 'Date: Fri, 21 Nov 1997 09:55:06 -0600').

You'll always get extra headers - each server on the way adds at least one, plus some more may be generated on delivery, etc. You can't avoid that.
15th November 2007 at 11:30
qwerfty
it is great!
MoH
20th July 2007 at 22:30
Re: Re: Re: Adding SUBJECT
You can use echo
echo -e "Subject: foobar\nFrom: Me@myself.and.i\nTo: sombody@yyy.com\n\nvery much content"

and then pipe that to smtp-client --data=-
3rd September 2007 at 0:08
Unknown

[url=][/url]
28th November 2009 at 23:05
Subject not working
--subject is not working in my case it just say: "(no subject)" in all mails sended with smtp-cli
But I see the header and it is present in the MIME part. Why it is not present just in the header itself??
26th July 2005 at 16:33
force_auth patch
Sometime SMTP servers needs authentication, but not say about this.
smtp.tom.com is an example of such antisocial behaviour.
This patch allows to use explicitly selected authentication method
ignoring information received from server.
26 Jul 2005, Ilya Evseev
--- smtp-client.pl.orig 2005-07-25 15:10:23 +0400
+++ smtp-client.pl 2005-07-25 16:31:36 +0400
@@ -37,6 +37,8 @@
$auth_ok = 0;
$ehlo_ok = 1;

+my $force_auth;
+
# Get command line options.
GetOptions ('host=s' => \$host, 'port=i' => \$port,
'user=s' => \$user, 'password=s' => \$pass,
@@ -47,6 +49,7 @@
'disable-ehlo' => sub { $ehlo_ok = 0; },
'hello-host|ehlo-host|helo-host=s' => \$hello_host,
'enable-auth' => \$auth_ok,
+ 'force-auth=s' => \$force_auth,
'disable-starttls|disable-tls|disable-ssl' =>
sub { $starttls_ok = 0; },
'from|mail-from=s' => \$from,
@@ -61,6 +64,12 @@
$port = $2;
}

+if (defined $force_auth) {
+ $use_login = 1 if $force_auth =~ /LOGIN/i;
+ $use_plain = 1 if $force_auth =~ /PLAIN/i;
+ $use_cram_md5 = 1 if $force_auth =~ /CRAM-MD5/i;
+}
+
# If at least one --auth-* option was given, enable AUTH.
if ($use_login + $use_plain + $use_cram_md5 + $use_digest_md5 > 0)
{ $auth_ok = 1; }
@@ -375,6 +384,9 @@
$featref->{$feat} = $param;
}

+ $featref->{'AUTH'} = $force_auth
+ if defined $force_auth;
+
return 1;
}

@@ -400,6 +412,9 @@
host offers it.

--enable-auth Enable all methods of SMTP authentication.
+ --force-auth= Use AUTH method even if server
+ does not requests that. Possible strings are:
+ LOGIN, PLAIN, CRAM-MD5
--auth-login Enable only AUTH LOGIN method.
--auth-plain Enable only AUTH PLAIN method.
--auth-cram-md5 Enable only AUTH CRAM-MD5 method.
28th July 2005 at 4:16
Re: force_auth patch
Thanks for the patch. The problem with smtp.tom.com is, however, that the server offers only SMTP, not ESMTP. My client then chooses to use HELO instead of EHLO which makes the server to not offer any SMTP extensions like AUTH. The obvious solution is to force using EHLO even if not detected as being supported by the server. I added a new --force-ehlo switch for this purpose and tested with smtp.tom.com. Voila, now it works!
26th July 2005 at 16:36
bug: message should not contain zero timestamp
Messages generated by smtp-client are displayed in e-mail client on receiver side with 1-Jan-1970 date. Is it a bug or it is a feature?;-)
28th July 2005 at 4:26
Re: bug: message should not contain zero timestamp
It is neither bug nor a feature, it's a misunderstanding of the purpose of the script. The script takes the _whole_ RFC822 message, including *headers* and sends it to the server of your choice. These headers should contain the Date field, as well as any Subject/To/From or other fields. That's why there is no --subject option either. Simply prepare the _whole_ message and then send it. See RFC2822 for details. FYI the script does _only_ what RFC2821 says, nothing more.
1st September 2005 at 13:53
Not able to use the script with qmail MTA's
Hi,

Thanks for writing this script.

I am trying to use this to send mails using a Qmail MTA. I am getting the following error.

> DATA
'354] 'go ahead punk, make my day
'451] 'See http://pobox.com/~djb/docs/smtplf.html.
'ATA not send: '451 See http://pobox.com/~djb/docs/smtplf.html.
> QUIT

Having checked this I tried to add the "\r" in the line 282 in the script which should read like " &send_line ($sock, "DATA\n");" Even if I add the "\r" I am getting the following error.

> DATA
'502] 'unimplemented (#5.5.1)
'ATA failed: '502 unimplemented (#5.5.1)
> QUIT

Could you kindly let us know how we can rectify this.

Rgds

M.Velu

30th September 2005 at 17:29
Re: Not able to use the script with qmail MTA's
I, too, would like to thank Michal for such an excellent script.

Regarding your qmail issue. It appears that there might be a slight problem in the way the script handles CRLF character sequences. RFC 821 (SMTP) and RFC 2822 (mail format) both require the use of CRLF combinations, not bare linefeeds.

The following document covers the issue under the secion 'Newlines':

http://search.cpan.org/dist/perl/pod/perlport.pod

This means that when I generate the message headers and body (passed via --data), I use "$crlf" instead of "\n", with my $crlf = "\015\012". This means that a couple of tweaks to the script are needed:

replace:
$line =~ s/^\.$/\. /;
with:
$line =~ s/^\.\015\012/\. \015\012/;
$line =~ s/^\.$/\. /;
and replace:
$sock->printf ("\r\n.\r\n");
with:
$sock->printf ("\015\012.\015\012");

Other tweaks are probably necessary to get the SMTP portion into compliance, but at least this gets the 2822 portion right.
18th January 2006 at 16:28
HOW TO INPUT DATA FROM STDIN?
Hello Michal:

Great script!

I have been using shuntmail for the same purpose.



However, shuntmail is very basic and has no authentication of any kind. Nevertheless, I do use it in scripts because it does accept data from stdin.

Not being versed in Perl, I have come up with a gross hack to smtp-client.pl that seems to allow it to accept data from stdin, as follows:

Configure "$datasrc" by adding a "$datasrc = '[PATH_TO_ANY_TEXT_FILE]';" line after the "$ehlo_ok =" line; and

replace "while ()" with "while ()".

As I said, this is a gross hack but seems works.

What would be a more refined, gentle and Perl specific way to accomplish the same purpose?

Mile grazie!

--
Casco
21st December 2006 at 23:09
Re: HOW TO INPUT DATA FROM STDIN?
hi there,
We have been testing this script to use (which by the way is a great script). I have found the best way for STDIN is to add $datasrc = '-'; and that is it. thanks , cg
21st December 2006 at 23:17
Re: Re: HOW TO INPUT DATA FROM STDIN?
Quote from the output of --help:


With "--data=-" the script will read
standard input (useful e.g. for pipes).
22nd December 2006 at 0:29
Re: Re: Re: HOW TO INPUT DATA FROM STDIN?
Hi there, we started that way, but we ran into a situation where we had to put the -to and -from at the very end which would have come after the --data, so had to figure out how without the --data option. Thanks for the reply ... Cg
14th February 2006 at 14:07
Can I use it as delivering agent instead of sendmail?
Postfix filters are constructed from pipelines like "spamc | drwebdc | sendmail -f $1 -- $2", but this has one disadvantage: /usr/sbin/sendmail helper posts filtered message back to incoming mail queue on localhost:25 port, and filtered message is processed by filter twice. I need something that can deliver STDIN to localhost:10025. Can smtp-client.pl be used for this purpose?
12th March 2006 at 4:04
Command line SMTP client
I have tried the script but my only question is, my host does not enable smtp forwarding so I need to add a userid and password to be able to send mail through my server. How can I do that to this script.

Thanks,
5th April 2006 at 14:57
bug: returncode to shell
Hi,
GREAT piece of software. While working on a bash wrapper around your perl client, and trying to trap all error conditions, I found this light bug. If I send wrong credentials to the server the function run_smtp gets it and returns 0. But in the main around line 120 there's only: "&run_smtp ();" The return code is not trapped, therefore smtp-client.pl always exits with 0 in case of troubles in run_smtp. I fixed it with:
&run_smtp () or $smtp_result=1; and some if-then-else when exiting back to shell.
29th May 2006 at 19:14
smtp-client.pl and smtp.gmail.com?
Hallo all!
Is it possible to use smtp-client for sending emails via smtp.gmail.com? It seems that no other perl mail package supports TLS.

Regards,
Jiri Rosicky
30th May 2006 at 0:45
Re: smtp-client.pl and smtp.gmail.com?
Sure it is:
smtp-client.pl --verbose --host smtp.gmail.com \
--user {gmail-user-name} --auth-plain \
--from {gmail-user-name}@gmail.com \
--to {the@recipient.com} \
--data /path/to/file.eml
14th June 2006 at 20:20
Re: Re: smtp-client.pl and smtp.gmail.com?
When I try smtp-client.pl with smtp.google.com, I get the following at the end:

> QUIT
[0] ''
Unknown QUIT response ''.
15th June 2006 at 0:53
Re: Re: Re: smtp-client.pl and smtp.gmail.com?
Yes I noticed. Google violates the SMTP protocol - they should respond with code "221", not "0". I can't do much about it. In theory I could accept 0 as a valid return code but that's against the rules so I won't.

Anyway, it's at the very end of SMTP session and doesn't affect the other operations, just ignore it.
20th October 2006 at 0:04
Re: Re: smtp-client.pl and smtp.gmail.com?

It does not work well for me (in my gmail account).

When I use your command line, I get:
MAIL FROM failed: '530 5.7.0 Must issue a STARTTLS command first'

What went wrong ??
20th October 2006 at 21:59
Re: Re: Re: smtp-client.pl and smtp.gmail.com?
Hi.

I tried smtp.runbox.com .
The authentication is ok.

BUT:
I have problem with the recepient.
after RCPT TO: blabla@intel.com

I get
[550] 'Administrative prohibition'

I tried various recepient addresses and the problem remains.
16th August 2007 at 1:37
Re: Re: Re: Re: smtp-client.pl and smtp.gmail.com?
got the same error, I think the smtp sever I was
loging into thinks my ip address is a spamer !!

works for other ip's I have tryed !!
27th August 2007 at 22:38
Re: Re: Re: Re: smtp-client.pl and smtp.gmail.com?
yes got the same problem..
I can send email to the same address using thunderbird.. but not this script
found out mailsend http://www.muquit.com/muquit/software/mailsend/mailsend.html

works better for me.. also dos cc and subject..

Lachlan
Shantanu Gadgil
5th August 2009 at 6:07
Re: Re: smtp-client.pl and smtp.gmail.com? [SOLVED]
I solved the following error:

[530] '5.7.0 Must issue a STARTTLS command first.

by doing the following ...

$> smtp-cli --verbose --host smtp.gmail.com \
--port 587 --user {gmail-user-name} --auth-plain \
--from {gmail-user-name}@gmail.com \
--to {the@recipient.com}

Ref: http://mail.google.com/support/bin/answer.py?hl=en&answer=13287
18th July 2006 at 6:34
Just GREAT dude!
So simple.
Perfect for testing your Server.

I had a little inconvenient with this line:
use Digest::HMAC_MD5 qw(hmac_md5_hex);

But I just commented it, and it works great.
16th January 2007 at 12:44
Good script
Many thanks for your script.
I've started coding a script like that, but your programm is very good :)
1st June 2007 at 0:40
awesome perl smtp client
Great script man. Talk about a bunch of code I didn't have to do myself.

I've been putting it to great use :)
29th June 2007 at 11:13
FR: Multiple "To:" field
So that I can send one mail to Multiple person.
Thanks.
26th December 2007 at 9:10
Re: FR: Multiple receiver
How can I send one mail to Multiple receiverH
tks.
5th January 2009 at 16:02
Re: FR: Multiple
this is possible by specifying many --to fields:
ex: --to x@comp.org --to y@comp.org
20th September 2007 at 15:58
Fix work with ssmtp(port 465)
Before:
$smtp-client.pl --port=465 -host=localhost --from=spam@rm-rf.kiev.ua --to=spam@rm-rf.kiev.ua --data=/etc/group --verbose=2
^C

After:
$smtp-client.pl --port=465 -host=localhost --from=spam@rm-rf.kiev.ua --to=spam@rm-rf.kiev.ua --data=/etc/group --verbose=2
Starting SSMTP...
Using cipher: AES256-SHA
Subject Name: /C=US/ST=Berkshire/L=Newbury/O=Magic, Inc/OU=Unknown/CN=localhost/emailAddress=spam@rm-rf.kiev.ua
Issuer Name: /C=US/ST=Berkshire/L=Newbury/O=Magic, Inc/OU=Unknown/CN=localhost/emailAddress=spam@rm-rf.kiev.ua
[220] 'localhost ESMTP Exim 4.58'
> EHLO localhost
[250] 'localhost Hello localhost [127.0.0.1]'
[250] 'SIZE 20971520'
[250] '8BITMIME'
[250] 'PIPELINING'
[250] 'AUTH PLAIN LOGIN'
[250] 'HELP'
> MAIL FROM:
[250] 'OK'
> RCPT TO:
[250] 'Accepted'
> DATA
[354] 'Enter message, ending with "." on a line by itself'
[250] 'OK id=1IYMMq-000MLG-C2'
> QUIT
[221] 'localhost closing connection'

patch:
Index: smtp-client.pl
@@ -110,12 +110,18 @@
my (%features);

# Wait for the welcome message of the server.
-($code, $text) = &get_line ($sock);
-die ("Unknown welcome string: '$code $text'\n") if ($code != 220);
-$ehlo_ok-- if ($text !~ /ESMTP/);
+if ($port != 465)
+{
+ ($code, $text) = &get_line ($sock);
+ die ("Unknown welcome string: '$code $text'\n") if ($code != 220);
+ $ehlo_ok-- if ($text !~ /ESMTP/);
+};

# Send EHLO
-&say_hello ($sock, $ehlo_ok, $hello_host, \%features) or exit (1);
+if ($port != 465)
+{
+ &say_hello ($sock, $ehlo_ok, $hello_host, \%features) or exit (1);
+};

# Run the SMTP session
&run_smtp ();
@@ -131,18 +137,22 @@
sub run_smtp
{
# See if we could start encryption
- if ((defined ($features{'STARTTLS'}) || defined ($features{'TLS'})) && $starttls_ok)
+ if ((defined ($features{'STARTTLS'}) || defined ($features{'TLS'}) || $port == 465 ) && $starttl
{
- printf ("Starting TLS...\n") if ($verbose >= 1);
+ printf ("Starting TLS...\n") if ($verbose >= 1 && $port != 465);
+ printf ("Starting SSMTP...\n") if ($verbose >= 1 && $port == 465);

# Do Net::SSLeay initialization
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

- &send_line ($sock, "STARTTLS\n");
- ($code, $text) = &get_line ($sock);
- die ("Unknown STARTTLS response '$code'.\n") if ($code != 220);
+ if ($port != 465)
+ {
+ &send_line ($sock, "STARTTLS\n");
+ ($code, $text) = &get_line ($sock);
+ die ("Unknown STARTTLS response '$code'.\n") if ($code != 220);
+ };

if (! IO::Socket::SSL::socket_to_SSL($sock,
SSL_version => 'SSLv3 TLSv1'))
@@ -156,6 +166,14 @@
printf ("%s", $sock->dump_peer_certificate());
}

+ # Wait for the welcome message of the server (for sstmp).
+ if ($port == 465)
+ {
+ ($code, $text, $more) = &get_line ($sock);
+ die ("Unknown welcome string: '$code $text'\n") if ($code != 220);
+ $ehlo_ok-- if ($text !~ /ESMTP/);
+ };
+
# Send EHLO again (required by the SMTP standard).
&say_hello ($sock, $ehlo_ok, $hello_host, \%features) or return 0;
}
NightKid
4th July 2008 at 1:42
magnificient
I'm a mail server admin and have always tested new installations via telnet. Man, your script is just wonderful! Thanks for the great job! I'll save 10% of my time just by using it!
3rd December 2008 at 2:38
hey hats off to the pl script
It taught me how to specify the input parameters for the response of auth cram-md5 command. verr much thanks.
8th January 2009 at 7:48
Fine work - little correction necessary
Hi, just what I was looking for. No unneccessary stuff. Thanks!

I had to apply a little correction though on my system:
I got an error regarding "ReadMode" which went away after I added a "use Term::ReadKey;" line.
21st January 2009 at 9:06
Footer text
Great script! However, when I use it, my email body has footer text like so: "From: root@xxx Bcc: Return-Path: root@xxx Message-ID: X-OriginalArrivalTime: 21 Jan 2009 16:36:28.0278 (UTC) FILETIME=[68817960:01C97BE6] Date: 21 Jan 2009 11:36:28 -0500"

Is there any way to suppress this?

-Randy
14th March 2009 at 2:53
Re: Footer text
I'm also seeing the same footer. I'm testing by sending to my Corporate Microsoft Exchange Server
12th April 2009 at 12:11
Thank you for this awesome user-friendly script
I have been working on trying to figure out how to send emails from a Gmail account to a Gmail account. Your script works great. Thank you very much!
21st April 2009 at 6:16
Great Script!
Thanks a lot Michal.

Sure this Great Script will helps many people.HATS OFF!

It reduces my scripting time and got a Perl script with lot of added command line options.

Once again thanks...

Rajiv
7th May 2009 at 5:07
Support for cc and bcc ?
Is there a way to send emails with cc and bcc?

Thanks for your great program.

10th September 2009 at 23:36
Re: Support for cc and bcc ?
Yes, thanks for your great program. But I need that bcc feature too. How can we do that?
Arda
23rd September 2009 at 6:19
Re: Re: Support for cc and bcc ?
I would like to have this implemented too
15th October 2009 at 5:46
Re: Re: Re: Support for cc and bcc ?
Hi
I'm also interested in support for cc and bcc
Thanks in advance
23rd June 2009 at 10:31
Thanks, very nice
I was needing something to remotely test our STARTTLS config at $WORK, and this did the trick. I needed to edit only two things to get an interactive prompt (once I'd installed Term:ReadKey)

ReadMode(2) became Term::ReadKey::ReadMode(2)

and likewise on the reset to ReadMode(0);

Not sure exactly why my perl wasn't picking up the module, but I expect it has to do with the require in an eval you do.

Anyway, well done. Thanks!

Malcolm
22nd July 2009 at 22:03
smtp-cli: Digest/HMAC_MD5.pm error
Hi, I got myself a copy of smtp-cli latest version (2.5 I guess). Tried to run

"./smtp-cli --verbose --host=localhost"

to see if the script works on my machine. It generated this error message:

Can't locate Digest/HMAC_MD5.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.8.8 /usr/local/share/perl/5.8.8 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .) at ./smtp-cli line 42.
BEGIN failed--compilation aborted at ./smtp-cli line 42.

I don't have a clue how to rectify this. I'm running Ubuntu Hardy.
23rd July 2009 at 0:01
Re: smtp-cli: Digest/HMAC_MD5.pm error
You need to install the perl modules that the script requires.

On Ubuntu or Debian run this command:

aptitude install libterm-readkey-perl libio-socket-ssl-perl \
libdigest-hmac-perl libio-socket-inet6-perl \
libmime-lite-perl libfile-type-perl
5th August 2009 at 15:36
nice script
thanks.
15th August 2009 at 21:08
Great script! Extension for "--from"
Hello Michal,

thanks for this program. I am looking for a new job and want to send my c.v. to many people.

If i succeed i send you a donation!

i make an extension for the from argument, maybe other people need too. (sorry for my english)

i tried something like this: --from '"First Last" "' but t-online dont recognized my alias email address

Here is the code:
if ($from=~/".*"\s*<(.*)>/) {
&send_line ($sock, "MAIL FROM: <%s>\n", $1);
}
else {
&send_line ($sock, "MAIL FROM: <%s>\n", $from);
}

Original code was:
&send_line ($sock, "MAIL FROM: <%s>\n", $from);

good luck for all
kalaha
14th December 2009 at 12:57
Re: Great script! Extension for
You mean:
&send_line ($sock, "MAIL FROM: %s\n", $from);
,
not
&send_line ($sock, "MAIL FROM: <%s>\n", $1);

in the first if, right?
17th December 2009 at 21:27
Re: Re: Great script! Extension for
I was wrong - The change suggested by kalaha chaot works correctly.
P.S. the feedback system of this site does not work in Chrome 4.0.266.0 - the form is not shown.
18th August 2009 at 13:57
Socket Errors when trying to connect
I am attempting to use this script, but when it attempts to make a connection to my SMTP server, it bombs with the following:

Connect failed: IO::Socket::INET: connect: Unknown error

Is there a way to get the error message back from the socket to where I can troubleshoot it? I am running it with ActivePerl 5.10 on Win32.
27th August 2009 at 15:00
yeaaaah, that's the kinda shit I was looking for !
Great job !!!
1st September 2009 at 14:33
smtp-cli
Thanks a lot for this very useful script. Why don't you place it on cpan ? and why not building a module which could be called from the command line ?

Any way it saved me a lot of telnet test and head scratching !

Francois
4th December 2009 at 6:11
Load attacments from file
It would be nice to load attachments in a comma list form a file..
28th December 2009 at 19:49
Arm-Linux
Hi,
I'm looking to integrate this cli with arm linux. Could someone help me out finding the concerned libraries.
Best Regards,
Rahul
7th April 2010 at 12:35
Fantastic software... $$$ on the way
I use this for troubleshooting SMTP issues all the time, and it's probably saved me more time than I'm donating money for.
7th October 2010 at 11:19
Great little script
I was looking for a Linux version of the Blat mailer to allow me to send HTML email with a plain text part and found this. It's a wonderfully useful script which does exactly what is needed without adding loads of fluff.

Brilliant
31st December 2010 at 1:22
GOVNO EBANOE
GOVNO EBANOE
5th January 2011 at 18:26
SMTP over SSL
I recently switched to AT&T Uverse and their SMTP server apparently uses SMTP over SSL as opposed to STARTTLS. Are there any plans to support SMTP of SSL?
6th January 2011 at 0:32
Re: SMTP over SSL
Hi Nick,

sure, grab smtp-cli 2.8 -- just released, fresh from the oven ;-)

With --port=465 (or --server smtp.blahblah.com:465) will enable SSL automatically. Or use --ssl to run on a non-standard port.

Michal
11th January 2011 at 2:00
Re: Re: SMTP over SSL
Awesome! Thanks a lot. This is a great tool!
Jiri Hlusi
12th February 2011 at 5:20
Saved my day by not having to fiddle with sendmail through the night
Seriously, there are moments when spending hours tuning sendmail (or alike) with all of its complexities, just to get one thing done, is not worth it. I'm glad I came across this site. Many thanks, Michal!
30th March 2011 at 2:36
Header present inside mail body
Dear all,

I have experienced a bug with smtp-cli with Exchange like SMTP server. The bug consists in the presence of some header lines into the mail body, mail that was generated with text/plain MIME type on a Linux machine and transferred by means of an Microsoft Exchange 2003. After some investigation I have found that the problem was the line termination of the data part of the mail. I have fixed these bug with the following modification (vers. 2.8):

--- smtp-cli-2.8.orig 2011-03-29 15:28:09.372642133 +0200
+++ smtp-cli-2.8 2011-03-29 15:33:41.716308584 +0200
@@ -494,8 +494,10 @@
while ()
{
my $line = $_;
+ chomp $line;
+ $line = sprintf("%s$CRLF", $line);
$line =~ s/^\.$CRLF$/\. $CRLF/;
- $line =~ s/^\.\n$/\. $CRLF/;
+ #$line =~ s/^\.\n$/\. $CRLF/;
$sock->print ($line);
}

The problem was not experienced if the MTA was Sendmail or Qmail. Due to chomp(), the last substitution will never be applied and than can be removed.

Best regards
8th June 2011 at 18:45
Thanks just what I needed.
Just what I was looking for and works great!
Mar 3   17:21 Looked for such a sw ever! (by Cornelinux)
Mar 9   16:42 Thanks, thanks, and once more thanks! (by Paolo Cravero)
Aug 1   16:26 Your Perl smtp script (by Jacob Smith)
Nov 23   16:20 GREAT! (by Daniel Siebert)
Jan 27   18:34 Problem with Hang at end of Data Command (by Dave Carey)
Mar 9   6:41 Nicely Done (by Caleb)
Mar 9   7:52 Re: Nicely Done (by Caleb)
May 6   13:22 Can i get Smtp-Server.pl (by Fadiebia)
May 9   1:24 Re: Can i get Smtp-Server.pl (by Michal Ludvig)
May 21   11:20 LF vs. CRLF (by Eberhard Mattes)
May 22   21:33 Re: LF vs. CRLF (by Michal Ludvig)
May 29   16:28 Re: Re: LF vs. CRLF (by Eberhard Mattes)
Jun 16   20:55 Re: Re: Re: LF vs. CRLF (by Edgard Pevidor)
Jul 8   19:43 Re: Re: Re: Re: LF vs. CRLF (by George)
Jul 8   19:50 Re: Re: Re: Re: LF vs. CRLF (by George)
Jun 21   15:27 Adding SUBJECT (by Carlos Ferriol)
Jun 21   22:44 Re: Adding SUBJECT (by Michal Ludvig)
Apr 3   18:39 Re: Re: Adding SUBJECT (by Mark Delahunty)
Apr 10   0:21 Re: Re: Re: Adding SUBJECT (by Michal)
Nov 15   11:30 qwerfty (by qwerfty)
Jul 20   22:30 Re: Re: Re: Adding SUBJECT (by MoH)
Sep 3   0:08 Unknown (by Unknown)
Nov 28   23:05 Subject not working (by Anyeos)
Jul 26   16:33 force_auth patch (by Ilya Evseev)
Jul 28   4:16 Re: force_auth patch (by Michal Ludvig)
Jul 26   16:36 bug: message should not contain zero timestamp (by Ilya Evseev)
Jul 28   4:26 Re: bug: message should not contain zero timestamp (by Michal Ludvig)
Sep 1   13:53 Not able to use the script with qmail MTA's (by Muthuvelu.T.J)
Sep 30   17:29 Re: Not able to use the script with qmail MTA's (by Todd Lucas)
Jan 18   16:28 HOW TO INPUT DATA FROM STDIN? (by Casco Bucci)
Dec 21   23:09 Re: HOW TO INPUT DATA FROM STDIN? (by Chris G)
Dec 21   23:17 Re: Re: HOW TO INPUT DATA FROM STDIN? (by Michal Ludvig)
Dec 22   0:29 Re: Re: Re: HOW TO INPUT DATA FROM STDIN? (by Chris G)
Mar 12   4:04 Command line SMTP client (by Donovan Berthoud)
Apr 5   14:57 bug: returncode to shell (by Paolo)
May 29   19:14 smtp-client.pl and smtp.gmail.com? (by Jiri Rosicky)
May 30   0:45 Re: smtp-client.pl and smtp.gmail.com? (by Michal Ludvig)
Jun 14   20:20 Re: Re: smtp-client.pl and smtp.gmail.com? (by Hans)
Jun 15   0:53 Re: Re: Re: smtp-client.pl and smtp.gmail.com? (by Michal Ludvig)
Oct 20   0:04 Re: Re: smtp-client.pl and smtp.gmail.com? (by Nahum Barnea)
Oct 20   21:59 Re: Re: Re: smtp-client.pl and smtp.gmail.com? (by Nahum Barnea)
Aug 16   1:37 Re: Re: Re: Re: smtp-client.pl and smtp.gmail.com? (by Lachlan Audas)
Aug 27   22:38 Re: Re: Re: Re: smtp-client.pl and smtp.gmail.com? (by Lachlan Audas)
Aug 5   6:07 Re: Re: smtp-client.pl and smtp.gmail.com? [SOLVED] (by Shantanu Gadgil)
Jul 18   6:34 Just GREAT dude! (by Daniel Gamez)
Jan 16   12:44 Good script (by Binh Nguyen)
Jun 1   0:40 awesome perl smtp client (by Cormander)
Jun 29   11:13 FR: Multiple "To:" field (by Roy Tam)
Dec 26   9:10 Re: FR: Multiple receiver (by eagle)
Jan 5   16:02 Re: FR: Multiple (by thushara wijeratna)
Sep 20   15:58 Fix work with ssmtp(port 465) (by Alex Kozlov)
Jul 4   1:42 magnificient (by NightKid)
Dec 3   2:38 hey hats off to the pl script (by vinayaka a)
Jan 8   7:48 Fine work - little correction necessary (by Josh)
Jan 21   9:06 Footer text (by Randy Monnin)
Mar 14   2:53 Re: Footer text (by Contact)
Apr 21   6:16 Great Script! (by Rajiv Durai Pandian)
May 7   5:07 Support for cc and bcc ? (by Damien Challet)
Sep 10   23:36 Re: Support for cc and bcc ? (by Ali)
Sep 23   6:19 Re: Re: Support for cc and bcc ? (by Arda)
Oct 15   5:46 Re: Re: Re: Support for cc and bcc ? (by Nizar)
Jun 23   10:31 Thanks, very nice (by Malcolm)
Jul 22   22:03 smtp-cli: Digest/HMAC_MD5.pm error (by Martin)
Jul 23   0:01 Re: smtp-cli: Digest/HMAC_MD5.pm error (by Michal)
Aug 5   15:36 nice script (by chris lo)
Aug 15   21:08 Great script! Extension for "--from" (by kalaha chaot)
Dec 14   12:57 Re: Great script! Extension for (by Ran)
Dec 17   21:27 Re: Re: Great script! Extension for (by Ran)
Aug 18   13:57 Socket Errors when trying to connect (by eellis)
Sep 1   14:33 smtp-cli (by Francois)
Dec 4   6:11 Load attacments from file (by joseph philbert)
Dec 28   19:49 Arm-Linux (by Rahul)
Apr 7   12:35 Fantastic software... $$$ on the way (by Arun)
Oct 7   11:19 Great little script (by Robin Patenall)
Dec 31   1:22 GOVNO EBANOE (by GOVNO EBANOE)
Jan 5   18:26 SMTP over SSL (by Nick)
Jan 6   0:32 Re: SMTP over SSL (by Michal)
Jan 11   2:00 Re: Re: SMTP over SSL (by Nick)
Mar 30   2:36 Header present inside mail body (by Massimiliano Ottimo)
Jun 8   18:45 Thanks just what I needed. (by Simon)