On DigitalOcean I've got a vps running MIAB ("Mail-in-aBox") at box.emailserver.com and a web app server on another vps at appserver.com.
I want to send emails from the web app using a Perl script.
I'm using the MIAB DNS server for both domain names. With the MIAB server I can send and receive email using my Mac Mini "Mail" app so that's working great.
I've edited a perl script I found on CPAN that attempts to authenticate a user and send a simple email from appserver.com but it is not passing the auth stage. I get this error:
Error sending email: failed AUTH: Command unknown: 'AUTH'
Anyone have any ideas on what I'm doing wrong?
Here's the script on the web app server, the mail.log from the MIAB, and what the script outputs when run:
#!/usr/bin/perl
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTPS;
use Try::Tiny;
my $transport = Email::Sender::Transport::SMTPS->new(
host => 'box.emailserver.com',
ssl => 'starttls',
sasl_username => 'hostmaster#emailserver.com',
sasl_password => 'xxxx',
debug => 1, # or 1
);
use Email::Simple::Creator; # or other Email::
my $message = Email::Simple->create(
header => [
From => 'hostmaster#emailserver.com',
To => 'bill#my.com',
Subject => 'appserver.com perl test',
],
body => 'This is the test.',
);
try {
sendmail($message, { transport => $transport });
} catch {
die "Error sending email: $_";
};
MIAB mail.log:
Apr 16 13:17:10 box postfix/submission/smtpd[31729]: connect from appserver.com[45.55.229.99]
Apr 16 13:17:10 box postfix/submission/smtpd[31729]: lost connection after EHLO from appserver.com[45.55.229.99]
Apr 16 13:17:10 box postfix/submission/smtpd[31729]: disconnect from appserver.com[45.55.229.99]
appserver.com perl script output
root#appserver:/usr/lib/cgi-bin# perl test6.pl
Net::SMTPS>>> Net::SMTPS(0.06)
Net::SMTPS>>> IO::Socket::IP(0.37)
Net::SMTPS>>> IO::Socket(1.38)
Net::SMTPS>>> IO::Handle(1.35)
Net::SMTPS>>> Exporter(5.72)
Net::SMTPS>>> Net::SMTP(3.10)
Net::SMTPS>>> Net::Cmd(3.10)
Net::SMTPS=GLOB(0x33b7958)<<< 220 box.emailserver.com ESMTP Hi, I'm a Mail-in-a-Box (Ubuntu/Postfix; see https://mailinabox.email/)
Net::SMTPS=GLOB(0x33b7958)>>> EHLO localhost.localdomain
Net::SMTPS=GLOB(0x33b7958)<<< 250-box.emailserver.com
Net::SMTPS=GLOB(0x33b7958)<<< 250-PIPELINING
Net::SMTPS=GLOB(0x33b7958)<<< 250-SIZE 134217728
Net::SMTPS=GLOB(0x33b7958)<<< 250-VRFY
Net::SMTPS=GLOB(0x33b7958)<<< 250-ETRN
Net::SMTPS=GLOB(0x33b7958)<<< 250-STARTTLS
Net::SMTPS=GLOB(0x33b7958)<<< 250-ENHANCEDSTATUSCODES
Net::SMTPS=GLOB(0x33b7958)<<< 250-8BITMIME
Net::SMTPS=GLOB(0x33b7958)<<< 250 DSN
Error sending email: failed AUTH: Command unknown: 'AUTH'
Trace begun at /usr/local/share/perl/5.22.1/Email/Sender/Transport/SMTPS.pm line 98
Email::Sender::Transport::SMTPS::_throw('Email::Sender::Transport::SMTPS=HASH(0x24d8b80)', 'failed AUTH', 'Net::SMTPS=GLOB(0x33b7958)') called at /usr/local/share/perl/5.22.1/Email/Sender/Transport/SMTPS.pm line 71
Email::Sender::Transport::SMTPS::smtpclient('Email::Sender::Transport::SMTPS=HASH(0x24d8b80)') called at /usr/local/share/perl/5.22.1/Email/Sender/Transport/SMTPS.pm line 107
Email::Sender::Transport::SMTPS::send_email('Email::Sender::Transport::SMTPS=HASH(0x24d8b80)', 'Email::Abstract=ARRAY(0x3023ae0)', 'HASH(0x3023ca8)') called at /usr/local/share/perl/5.22.1/Email/Sender/Role/CommonSending.pm line 45
Email::Sender::Role::CommonSending::try {...} at /usr/share/perl5/Try/Tiny.pm line 92
eval {...} at /usr/share/perl5/Try/Tiny.pm line 83
Try::Tiny::try('CODE(0x307b370)', 'Try::Tiny::Catch=REF(0x3023d38)') called at /usr/local/share/perl/5.22.1/Email/Sender/Role/CommonSending.pm line 58
Email::Sender::Role::CommonSending::send('Email::Sender::Transport::SMTPS=HASH(0x24d8b80)', 'Email::Abstract=ARRAY(0x3023ae0)', 'HASH(0x3069a30)') called at /usr/local/share/perl/5.22.1/Email/Sender/Simple.pm line 119
Email::Sender::Simple::send_email('Email::Sender::Simple', 'Email::Abstract=ARRAY(0x3023ae0)', 'HASH(0x3023cf0)') called at /usr/local/share/perl/5.22.1/Email/Sender/Role/CommonSending.pm line 45
Email::Sender::Role::CommonSending::try {...} at /usr/share/perl5/Try/Tiny.pm line 92
eval {...} at /usr/share/perl5/Try/Tiny.pm line 83
Try::Tiny::try('CODE(0x3023b58)', 'Try::Tiny::Catch=REF(0x3005228)') called at /usr/local/share/perl/5.22.1/Email/Sender/Role/CommonSending.pm line 58
Email::Sender::Role::CommonSending::send('Email::Sender::Simple', 'Email::Simple=HASH(0x3004f88)', 'HASH(0x3004ee0)') called at /usr/share/perl5/Sub/Exporter/Util.pm line 18
Sub::Exporter::Util::ANON('Email::Simple=HASH(0x3004f88)', 'HASH(0x3004ee0)') called at test6.pl line 26
main::try {...} at /usr/share/perl5/Try/Tiny.pm line 92
eval {...} at /usr/share/perl5/Try/Tiny.pm line 83
Try::Tiny::try('CODE(0x2fd50b0)', 'Try::Tiny::Catch=REF(0x2f96d08)') called at test6.pl line 29
Net::SMTPS=GLOB(0x33b7958)<<< 220 box.emailserver.com ESMTP Hi, I'm a Mail-in-a-Box (Ubuntu/Postfix; see https://mailinabox.email/)
Net::SMTPS=GLOB(0x33b7958)>>> EHLO localhost.localdomain
Net::SMTPS=GLOB(0x33b7958)<<< 250-box.emailserver.com
Net::SMTPS=GLOB(0x33b7958)<<< 250-PIPELINING
Net::SMTPS=GLOB(0x33b7958)<<< 250-SIZE 134217728
Net::SMTPS=GLOB(0x33b7958)<<< 250-VRFY
Net::SMTPS=GLOB(0x33b7958)<<< 250-ETRN
Net::SMTPS=GLOB(0x33b7958)<<< 250-STARTTLS
Net::SMTPS=GLOB(0x33b7958)<<< 250-ENHANCEDSTATUSCODES
Net::SMTPS=GLOB(0x33b7958)<<< 250-8BITMIME
Net::SMTPS=GLOB(0x33b7958)<<< 250 DSN
Based on this output from the EHLO command the server does not support any kind of authentication. If it would there would be a line like 250-AUTH LOGIN PLAIN ..., i.e. a line which declares support for the AUTH command and shows which authentication methods are supported. But since there is no such line the server does not support authentication.
If you want to use authentication you need to fix this at the server setup. While I can find no information about it in the setup guid of MIAB it uses Postfix underneath which support authentication and there are various tutorials online which describe the process. But, any questions for this server setup are probably more on-topic at serverfault.com.
None of the instructions here or elsewhere worked for me, so I crafted my own solution using Net::SMTP. I have Mail-In-A-Box working successfully on Namecheap with full STARTTLS support using a Perl script. The e-mails pass Gmail's spam folder, passing all their authenticity tests. Once you have your mailinabox server fully configured, this script can be used to send e-mails via SMTP.
#!/usr/bin/perl
use warnings;
use strict;
use Net::SMTP;
use Authen::SASL;
my $host = 'box.yoursite.com'; #server1.yoursite.com if on namecheap
my $port = 587;
my $username = 'you#yoursite.com';
my $password = 'yourpassword';
my $sendto = 'your#friend.com';
my $smtp = Net::SMTP->new(
$host,
Port => $port,
SSL => 0, #No SSL on initial handshake.
Timeout => 10,
Debug => 1
);
#Postfix has no AUTH option until STARTTLS.
$smtp->starttls();
$smtp->auth($username, $password);
$smtp->mail($username);
if ($smtp->to($sendto)) {
$smtp->data();
$smtp->datasend("From: $username\n");
$smtp->datasend("To: $sendto\n");
$smtp->datasend("Subject: Test message\n");
$smtp->datasend("\n");
$smtp->datasend("The test works!\n");
$smtp->dataend();
} else {
print "Error: ", $smtp->message();
}
$smtp->quit;
A few notes:
The first EHLO handshake needs to be performed without SSL (SSL=>0), and once initiated, a STARTTLS connection can then be established. Hence, this initial EHLO handshake fails to return a 250-AUTH response from the mailinabox server, but upgrading the SMTP connection constructor to STARTTLS ($smtp->starttls()) succeeds in returning 250-AUTH PLAIN LOGIN, at which point, you can proceed to authenticate with the SMTP server in the normal way.
Make sure both the Net::SMTP and Authen::SASL cpan modules are both installed/upgraded.
I added the server IP address to mynetworks as described by Bill Stephenson, but did not find it to be necessary.
Related
I am building a web application in the nim programming language and recently wanted to start implementing features regarding sending mails.
Nim has a library std/smtp for this that comes with some pretty simple examples for using both starttls and ssl.
For that purpose I created a dummy mail address on a local mail service provider to play around a bit and can't get it to work, despite following the examples as closely as I could.
Here the code I used:
import std/[smtp]
let smtpServerName = "smtp.web.de"
let startTlsportNumber = 587
let un = "dummymail" # replace with actual username
let pw = "dummypw" # replace with actual pw
let target = "bla#mailinator.com"
#StartTLS code block - Have either this or the SSL code block commented in, not both
let smtpConn = newSmtp(debug=true)
smtpConn.connect(smtpServerName, Port startTlsportNumber)
smtpConn.startTls()
#SSL code block - Have either this or the startTLS code block commented in, not both
# let sslPortNumber = 465
# let smtpConn = newSmtp(useSsl = true, debug=true)
# smtpConn.connect(smtpServerName, Port sslPortNumber)
var msg = createMessage(mSubject = "Hello from Nim's SMTP",
mBody = "Hello!.\n Is this awesome or what?",
mTo = #[target])
smtpConn.auth(un, pw)
smtpConn.sendmail(un, #[target], $msg)
With startTLS this causes a runtime error as the server sends back a 503 response on smtpConn.startTls:
S:220 web.de (mrweb105) Nemesis ESMTP Service ready
C:HELO smtp.web.de
S:250 web.de Hello smtp.web.de [46.183.103.17]
C:STARTTLS
S:503 Bad sequence of commands
C:QUIT
/home/philipp/dev/playground/src/playground.nim(11) playground
/usr/lib/nim/pure/smtp.nim(246) startTls
/usr/lib/nim/pure/smtp.nim(226) checkReply
/usr/lib/nim/pure/smtp.nim(110) quitExcpt
Error: unhandled exception: Expected 220 reply, got: 503 Bad sequence of commands [ReplyError]
With SSL this causes a runtime error as the server sends back a 503 response on smtpConn.connect:
S:220 web.de (mrweb005) Nemesis ESMTP Service ready
C:HELO smtp.web.de
S:503 Bad sequence of commands
C:QUIT
/home/philipp/dev/playground/src/playground.nim(15) playground
/usr/lib/nim/pure/smtp.nim(240) connect
/usr/lib/nim/pure/smtp.nim(231) helo
/usr/lib/nim/pure/smtp.nim(226) checkReply
/usr/lib/nim/pure/smtp.nim(110) quitExcpt
Error: unhandled exception: Expected 250 reply, got: 503 Bad sequence of commands [ReplyError]
I've triple checked the ports, the service provider states explicitly that 587 is the port for startTls and 465 for SSL. I compile on Arch Linux with -d:ssl in both cases, so that shouldn't be an issue either.
Trying the same with google-mail it all worked out, but I am slightly annoyed that this didn't work with my original mail provider.
Googling the error for a bit and looking at other questions of other programming languages, the error seems to be related to authentication? Which is weird, because I thought authentication starts after I made the connection secure with startTls. This looks to me like I'm using the std/smtp library wrong, but I don't quite see where. Does anyone here see the issue?
The server doesn't like the HELO that std/smtp uses, it needs EHLO:
$ telnet smtp.web.de 587
[ ... ]
220 web.de (mrweb105) Nemesis ESMTP Service ready
HELO smtp.web.de
250 web.de Hello smtp.web.de [92.191.80.254]
STARTTLS
503 Bad sequence of commands
$ telnet smtp.web.de 587
[ ... ]
220 web.de (mrweb006) Nemesis ESMTP Service ready
EHLO smtp.web.de
250-web.de Hello smtp.web.de [92.191.80.254]
250-8BITMIME
250-SIZE 141557760
250 STARTTLS
STARTTLS
220 OK
So you can get the Nim dev version with this patch, or copy-paste the patch code into your program while it doesn't reach the stable:
import std / [net, strutils, asyncnet, asyncdispatch]
proc recvEhlo(smtp: Smtp | AsyncSmtp): Future[bool] {.multisync.} =
## Skips "250-" lines, read until "250 " found.
## Return `true` if server supports `EHLO`, false otherwise.
while true:
var line = await smtp.sock.recvLine()
echo("S:" & line) # Comment out this if you aren't debugging
if line.startsWith("250-"): continue
elif line.startsWith("250 "): return true # last line
else: return false
proc ehlo*(smtp: Smtp | AsyncSmtp): Future[bool] {.multisync.} =
# Sends the EHLO request
await smtp.debugSend("EHLO " & smtp.address & "\c\L")
return await smtp.recvEhlo()
proc connect*(smtp: Smtp | AsyncSmtp, address: string, port: Port) {.multisync.} =
smtp.address = address
await smtp.sock.connect(address, port)
await smtp.checkReply("220")
let speaksEsmtp = await smtp.ehlo()
if speaksEsmtp:
await smtp.debugSend("STARTTLS\c\L")
await smtp.checkReply("220")
let smtpConn = newSmtp(debug=true)
smtpConn.connect("smtp.web.de", Port 587)
Notice that you need to avoid the call to startTls because the unpatched version does a HELO that would raise another 503, so we send the STARTTLS at the end of our modified connect.
I've noticed that you need to modify your local smtp.nim file to make sock field for SmtpBase object public for this to work. The file is at nim-1.6.6/lib/pure/smtp.nim and you need to change:
62 sock: SocketType
to
62 sock*: SocketType
So it might be better to just patch the whole smtp.nim local file with the code linked above.
I want to submit email on port 465 of my smtp server using the Net::SMTP module(without using Net::SMTP::SSL) in a perl script from client. On Port 465 of my SMTP server, "submissions" service runs, which understands SMTPS.
I have tried to find the way to do this on google. Then used the Net::SMTP::SSL module to make request on port 465. It works fine.
But the documentation for Net::SMTP::SSL recommends using latest version Net::SMTP instead of using Net::SMTP::SSL.
The document clearly states that
Since Net::SMTP v1.28 (2014-10-08), Net::SMTP itself has support for
SMTP over SSL, and also for STARTTLS. Use Net::SMTP, not
Net::SMTP::SSL.
I have updated Net::SMTP module to the latest version 3.11.
Also the document for Net::SMTP also stated clearly that
With IO::Socket::SSL installed it also provides support for implicit
and explicit TLS encryption, i.e. SMTPS or SMTP+STARTTLS.
The part of my perl script code on client ,relevant to the problem mentioned looks like so:
$smtp = Net::SMTP::SSL->new("$mailserver",
Hello => "$localhostname",
Timeout => 60,
Port => "$port", //Port value is 465
Debug => 1);
$smtp->auth($username, $password);
...Remaining script which sets sender, receiver body etc
This works fine. The email gets submitted.
Replacing the above code with :
$smtp = Net::SMTP->new("$mailserver",
Hello => "$localhostname",
Timeout => 60,
Port => "$port", //Port value is 465
Debug => 1);
$smtp->auth($username, $password);
...Remaining script which sets sender, receiver body etc
This fails. The debug logs look like this:
Net::SMTP>>> Net::SMTP(3.11)
Net::SMTP>>> Net::Cmd(3.11)
Net::SMTP>>> Exporter(5.73)
Net::SMTP>>> IO::Socket::INET(1.39)
Net::SMTP>>> IO::Socket(1.39)
Net::SMTP>>> IO::Handle(1.39)
Net::SMTP: Net::Cmd::getline(): unexpected EOF on command channel: at fescommon/mailsend-new.pl line 67.
Can't call method "auth" on an undefined value at fescommon/mailsend-new.pl line 74.
Note: Modules like Net::SMTP, Net::SMTP::SSL, IO::Socket::SSL and others are all updated to the latest version.
Expected Result is that request on "submissions" service listening on port 465 on SMTP server can be made using latest Net::SMTP module, without using Net::SMTP::SSL (because the document claims)
If you want to use smtps (i.e. TLS from start instead TLS after the STARTTLS command) you have to explicitly say so. Net::SMTP does not magically derive this requirement from the port number. From the documentation:
new ( [ HOST ] [, OPTIONS ] )
SSL - If the connection should be done from start with SSL, contrary to later upgrade with starttls. You can use SSL arguments as documented in IO::Socket::SSL, but it will usually use the right arguments already.
Thus, the proper code should be:
$smtp = Net::SMTP->new($mailserver,
SSL => 1, # <<<<<<<<<<<<<<<<<<<<<<<< THIS IS IMPORTANT
Hello => $localhostname,
Timeout => 60,
Port => $port, # Port value is 465
Debug => 1
);
I am getting SMTP Authentication Failure on the server and the mail is getting send via the server SMTP only...
It appears to be a server configuration or related problem, but I am not sure.
This is the debug details:
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-AUTH PLAIN LOGIN
250-STARTTLS
250 HELP
Failed to authenticate password. Error: 535 Incorrect authentication data
from: 250 OK
to: 250 Accepted
data: 354 Enter message, ending with "." on a line by itself
250 OK id=1U8Pjp-0002As-FB
quit: 221 ************** closing connection
Your message has been successfully sent using the following protocol: smtp
While testing from my local system, this works and the email is being sent via sendgrid.me
Again, This may not be a SendGrid Problem, but if you have faced similar issue, Can you please tell me what is the problem here?
I am using CentOs and I have cPanel in the server. I believe we are using EXIM for mail server.
For anyone that comes across this in future and are using cpanel/whm, you need to 'disable' this option under 'SMTP Restrictions' in WHM.
I was able to resolve this.
The issue was my server was not allowing the use of external SMTP and using its own SMTP server. I changed the settings and now it works fine.
I am using centos 7 Finally it works!
I was getting this issue(tail -f /var/log/mailog):
to=<usmanali#example.com>, relay=smtp.sendgrid.net[169.45.113.201]:587, delay=0.3, delays=0.05/0.07/0.16/0.02, dsn=5.0.0, status=bounced (host smtp.sendgrid.net[169.45.113.201] said: 550 Unauthenticated senders not allowed (in reply to MAIL FROM command))
Then i changed file /etc/postfix/main.cf in this way that added following lines into end of file
mtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
mailbox_size_limit = 256000000
# Sendgrid Settings
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:apikey:SG.YOUR_SENDGRID_KEY
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may
header_size_limit = 4096000
relayhost = [smtp.sendgrid.net]:587
Then Installing postfix missing module dependency using:
sudo yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain
Then restarting postfix
sudo systemctl restart postfix.service
i created this code(to send an email from gmail to gmail):
use MIME::Lite;
use Net::SMTP::SSL;
my $smtps = Net::SMTP::SSL->new ("www.gmail.com", Port=> 465);
$msg = MIME::Lite->new(
From =>'testeotest1234#gmail.com',
To =>'xxx',
# Cc =>'some#other.com, some#more.com',
Encoding => 'base64',
Subject =>'Helloooooo, nurse!',
Data =>"How's it goin', eh?"
);
MIME::Lite->send('smtp','smtp.gmail.com', Port=> 465, Debug=>1, Hello =>'www.gmail.com',AuthUser=>'testeotest1234', AuthPass=>'xxx');
$msg->send();
but i get this error:
Port=> 465MIME::Lite::SMTP>>> MIME::Lite::SMTP
MIME::Lite::SMTP>>> Net::SMTP(2.31)
MIME::Lite::SMTP>>> Net::Cmd(2.29)
MIME::Lite::SMTP>>> Exporter(5.65)
MIME::Lite::SMTP>>> IO::Socket::INET(1.31)
MIME::Lite::SMTP>>> IO::Socket(1.32)
MIME::Lite::SMTP>>> IO::Handle(1.31)
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 220 mx.google.com ESMTP kn18sm4777324veb.5 -
gsmtp
MIME::Lite::SMTP=GLOB(0x244c0d4)>>> EHLO www.gmail.com
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250-mx.google.com at your service, [12.226.1
28.130]
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250-SIZE 35882577
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250-8BITMIME
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250-STARTTLS
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250-ENHANCEDSTATUSCODES
MIME::Lite::SMTP=GLOB(0x244c0d4)<<< 250 PIPELINING
SMTP auth() command not supported on smtp.gmail.com
i tried using mail::sender:easy (cant install it, gives me an error when i try), i try to use the SSL line to create a conection before (due to how gmail conection works, but to no avail
Try Email::Sender with Email::Simple. They are relatively new modules, and much nicer than most others.
For educational purposes, I need to send an email through an SMTP server, using SMTP's fundamental and simple rules.
I was able to do that using smtp4dev. I telnet localhost 25 and and commands are:
I want to do the same thing, using Gmail SMTP server. However, it requires authentication and TLS. I can't figure out how to do that for Gmail. Here's a screenshot of telnet smtp.gmail.com 587:
I searched and found many links including Wikipedia's article about STARTTLS command. But I'm not able to use TLS and authenticate to Gmail's SMTP server using command line (or sending commands myself in programming languages). Can anyone help?
to send over gmail, you need to use an encrypted connection. this is not possible with telnet alone, but you can use tools like openssl
either connect using the starttls option in openssl to convert the plain connection to encrypted...
openssl s_client -starttls smtp -connect smtp.gmail.com:587 -crlf -ign_eof
or connect to a ssl sockect directly...
openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof
EHLO localhost
after that, authenticate to the server using the base64 encoded username/password
AUTH PLAIN AG15ZW1haWxAZ21haWwuY29tAG15cGFzc3dvcmQ=
to get this from the commandline:
echo -ne '\00user#gmail.com\00password' | base64
AHVzZXJAZ21haWwuY29tAHBhc3N3b3Jk
then continue with "mail from:" like in your example
example session:
openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof
[... lots of openssl output ...]
220 mx.google.com ESMTP m46sm11546481eeh.9
EHLO localhost
250-mx.google.com at your service, [1.2.3.4]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH
250 ENHANCEDSTATUSCODES
AUTH PLAIN AG5pY2UudHJ5QGdtYWlsLmNvbQBub2l0c25vdG15cGFzc3dvcmQ=
235 2.7.0 Accepted
MAIL FROM: <gryphius-demo#gmail.com>
250 2.1.0 OK m46sm11546481eeh.9
rcpt to: <somepoorguy#example.com>
250 2.1.5 OK m46sm11546481eeh.9
DATA
354 Go ahead m46sm11546481eeh.9
Subject: it works
yay!
.
250 2.0.0 OK 1339757532 m46sm11546481eeh.9
quit
221 2.0.0 closing connection m46sm11546481eeh.9
read:errno=0
Unfortunately as I am forced to use a windows server I have been unable to get openssl working in the way the above answer suggests.
However I was able to get a similar program called stunnel (which can be downloaded from here) to work. I got the idea from www.tech-and-dev.com but I had to change the instructions slightly. Here is what I did:
Install telnet client on the windows box.
Download stunnel. (I downloaded and installed a file called stunnel-4.56-installer.exe).
Once installed you then needed to locate the stunnel.conf config file, which in my case I installed to C:\Program Files (x86)\stunnel
Then, you need to open this file in a text viewer such as notepad. Look for [gmail-smtp] and remove the semicolon on the client line below (in the stunnel.conf file, every line that starts with a semicolon is a comment). You should end up with something like:
[gmail-smtp]
client = yes
accept = 127.0.0.1:25
connect = smtp.gmail.com:465
Once you have done this save the stunnel.conf file and reload the config (to do this use the stunnel GUI program, and click on configuration=>Reload).
Now you should be ready to send email in the windows telnet client!
Go to Start=>run=>cmd.
Once cmd is open type in the following and press Enter:
telnet localhost 25
You should then see something similar to the following:
220 mx.google.com ESMTP f14sm1400408wbe.2
You will then need to reply by typing the following and pressing enter:
helo google
This should give you the following response:
250 mx.google.com at your service
If you get this you then need to type the following and press enter:
ehlo google
This should then give you the following response:
250-mx.google.com at your service, [212.28.228.49]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH
250 ENHANCEDSTATUSCODES
Now you should be ready to authenticate with your Gmail details. To do this type the following and press enter:
AUTH LOGIN
This should then give you the following response:
334 VXNlcm5hbWU6
This means that we are ready to authenticate by using our gmail address and password.
However since this is an encrypted session, we're going to have to send the email and password encoded in base64. To encode your email and password, you can use a converter program or an online website to encode it (for example base64 or search on google for ’base64 online encoding’). I reccomend you do not touch the cmd/telnet session again until you have done this.
For example test#gmail.com would become dGVzdEBnbWFpbC5jb20= and password would become cGFzc3dvcmQ=
Once you have done this copy and paste your converted base64 username into the cmd/telnet session and press enter. This should give you following response:
334 UGFzc3dvcmQ6
Now copy and paste your converted base64 password into the cmd/telnet session and press enter. This should give you following response if both login credentials are correct:
235 2.7.0 Accepted
You should now enter the sender email (should be the same as the username) in the following format and press enter:
MAIL FROM:<test#gmail.com>
This should give you the following response:
250 2.1.0 OK x23sm1104292weq.10
You can now enter the recipient email address in a similar format and press enter:
RCPT TO:<recipient#gmail.com>
This should give you the following response:
250 2.1.5 OK x23sm1104292weq.10
Now you will need to type the following and press enter:
DATA
Which should give you the following response:
354 Go ahead x23sm1104292weq.10
Now we can start to compose the message! To do this enter your message in the following format (Tip: do this in notepad and copy the entire message into the cmd/telnet session):
From: Test <test#gmail.com>
To: Me <recipient#gmail.com>
Subject: Testing email from telnet
This is the body
Adding more lines to the body message.
When you have finished the email enter a dot:
.
This should give you the following response:
250 2.0.0 OK 1288307376 x23sm1104292weq.10
And now you need to end your session by typing the following and pressing enter:
QUIT
This should give you the following response:
221 2.0.0 closing connection x23sm1104292weq.10
Connection to host lost.
And your email should now be in the recipient’s mailbox!
As no one has mentioned - I would suggest to use great tool for such purpose - swaks
# yum info swaks
Installed Packages
Name : swaks
Arch : noarch
Version : 20130209.0
Release : 3.el6
Size : 287 k
Repo : installed
From repo : epel
Summary : Command-line SMTP transaction tester
URL : http://www.jetmore.org/john/code/swaks
License : GPLv2+
Description : Swiss Army Knife SMTP: A command line SMTP tester. Swaks can test
: various aspects of your SMTP server, including TLS and AUTH.
It has a lot of options and can do almost everything you want.
GMAIL: STARTTLS, SSLv3 (and yes, in 2016 gmail still support sslv3)
$ echo "Hello world" | swaks -4 --server smtp.gmail.com:587 --from user#gmail.com --to user#example.net -tls --tls-protocol sslv3 --auth PLAIN --auth-user user#gmail.com --auth-password 7654321 --h-Subject "Test message" --body -
=== Trying smtp.gmail.com:587...
=== Connected to smtp.gmail.com.
<- 220 smtp.gmail.com ESMTP h8sm76342lbd.48 - gsmtp
-> EHLO www.example.net
<- 250-smtp.gmail.com at your service, [193.243.156.26]
<- 250-SIZE 35882577
<- 250-8BITMIME
<- 250-STARTTLS
<- 250-ENHANCEDSTATUSCODES
<- 250-PIPELINING
<- 250-CHUNKING
<- 250 SMTPUTF8
-> STARTTLS
<- 220 2.0.0 Ready to start TLS
=== TLS started with cipher SSLv3:RC4-SHA:128
=== TLS no local certificate set
=== TLS peer DN="/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com"
~> EHLO www.example.net
<~ 250-smtp.gmail.com at your service, [193.243.156.26]
<~ 250-SIZE 35882577
<~ 250-8BITMIME
<~ 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
<~ 250-ENHANCEDSTATUSCODES
<~ 250-PIPELINING
<~ 250-CHUNKING
<~ 250 SMTPUTF8
~> AUTH PLAIN AGFhQxsZXguaGhMGdATGV4X2hoYtYWlsLmNvbQBS9TU1MjQ=
<~ 235 2.7.0 Accepted
~> MAIL FROM:<user#gmail.com>
<~ 250 2.1.0 OK h8sm76342lbd.48 - gsmtp
~> RCPT TO:<user#example.net>
<~ 250 2.1.5 OK h8sm76342lbd.48 - gsmtp
~> DATA
<~ 354 Go ahead h8sm76342lbd.48 - gsmtp
~> Date: Wed, 17 Feb 2016 09:49:03 +0000
~> To: user#example.net
~> From: user#gmail.com
~> Subject: Test message
~> X-Mailer: swaks v20130209.0 jetmore.org/john/code/swaks/
~>
~> Hello world
~>
~>
~> .
<~ 250 2.0.0 OK 1455702544 h8sm76342lbd.48 - gsmtp
~> QUIT
<~ 221 2.0.0 closing connection h8sm76342lbd.48 - gsmtp
=== Connection closed with remote host.
YAHOO: TLS aka SMTPS, tlsv1.2
$ echo "Hello world" | swaks -4 --server smtp.mail.yahoo.com:465 --from user#yahoo.com --to user#gmail.com --tlsc --tls-protocol tlsv1_2 --auth PLAIN --auth-user user#yahoo.com --auth-password 7654321 --h-Subject "Test message" --body -
=== Trying smtp.mail.yahoo.com:465...
=== Connected to smtp.mail.yahoo.com.
=== TLS started with cipher TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128
=== TLS no local certificate set
=== TLS peer DN="/C=US/ST=California/L=Sunnyvale/O=Yahoo Inc./OU=Information Technology/CN=smtp.mail.yahoo.com"
<~ 220 smtp.mail.yahoo.com ESMTP ready
~> EHLO www.example.net
<~ 250-smtp.mail.yahoo.com
<~ 250-PIPELINING
<~ 250-SIZE 41697280
<~ 250-8 BITMIME
<~ 250 AUTH PLAIN LOGIN XOAUTH2 XYMCOOKIE
~> AUTH PLAIN AGFhQxsZXguaGhMGdATGV4X2hoYtYWlsLmNvbQBS9TU1MjQ=
<~ 235 2.0.0 OK
~> MAIL FROM:<user#yahoo.com>
<~ 250 OK , completed
~> RCPT TO:<user#gmail.com>
<~ 250 OK , completed
~> DATA
<~ 354 Start Mail. End with CRLF.CRLF
~> Date: Wed, 17 Feb 2016 10:08:28 +0000
~> To: user#gmail.com
~> From: user#yahoo.com
~> Subject: Test message
~> X-Mailer: swaks v20130209.0 jetmore.org/john/code/swaks/
~>
~> Hello world
~>
~>
~> .
<~ 250 OK , completed
~> QUIT
<~ 221 Service Closing transmission
=== Connection closed with remote host.
I have been using swaks to send email notifications from nagios via gmail for last 5 years without any problem.
Based on the existing answers, here's a step-by-step guide to sending automated e-mails over SMTP, using a GMail account, from the command line, without disclosing the password.
Requirements
First, install the following software packages:
Expect
OpenSSL
Core Utils (base64)
These instructions assume a Linux operating system, but should be reasonably easy to port to Windows (via Cygwin or native equivalents), or other operating system.
Authentication
Save the following shell script as authentication.sh:
#!/bin/bash
# Asks for a username and password, then spits out the encoded value for
# use with authentication against SMTP servers.
echo -n "Email (shown): "
read email
echo -n "Password (hidden): "
read -s password
echo
TEXT="\0$email\0$password"
echo -ne $TEXT | base64
Make it executable and run it as follows:
chmod +x authentication.sh
./authentication.sh
When prompted, provide your e-mail address and password. This will look something like:
Email (shown): bob#gmail.com
Password (hidden):
AGJvYkBnbWFpbC5jb20AYm9iaXN0aGViZXN0cGVyc29uZXZlcg==
Copy the last line (AGJ...==), as this will be used for authentication.
Notification
Save the following expect script as notify.sh (note the first line refers to the expect program):
#!/usr/bin/expect
set address "[lindex $argv 0]"
set subject "[lindex $argv 1]"
set ts_date "[lindex $argv 2]"
set ts_time "[lindex $argv 3]"
set timeout 10
spawn openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof
expect "220" {
send "EHLO localhost\n"
expect "250" {
send "AUTH PLAIN YOUR_AUTHENTICATION_CODE\n"
expect "235" {
send "MAIL FROM: <YOUR_EMAIL_ADDRESS>\n"
expect "250" {
send "RCPT TO: <$address>\n"
expect "250" {
send "DATA\n"
expect "354" {
send "Subject: $subject\n\n"
send "Email sent on $ts_date at $ts_time.\n"
send "\n.\n"
expect "250" {
send "quit\n"
}
}
}
}
}
}
}
Make the following changes:
Paste over YOUR_AUTHENTICATION_CODE with the authentication code generated by the authentication script.
Change YOUR_EMAIL_ADDRESS with the e-mail address used to generate the authentication code.
Save the file.
For example (note the angle brackets are retained for the e-mail address):
send "AUTH PLAIN AGJvYkBnbWFpbC5jb20AYm9iaXN0aGViZXN0cGVyc29uZXZlcg==\n"
send "MAIL FROM: <bob#gmail.com>\n"
Lastly, make the notify script executable as follows:
chmod +x notify.sh
Send E-mail
Send an e-mail from the command line as follows:
./notify.sh recipient#domain.com "Command Line" "March 14" "15:52"