SMTP - 503 Bad sequence of commands when using nim's std/smtp - email

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.

Related

Connecting to Gmail SMTP via socket returns different responses per server

I am trying to understand why opening a socket to Gmail's server via SSL provides different responses for different servers. This is stopping me from connecting to Gmail for sending out emails.
Below is a very simple script:
<?php
$smtp_connect = fsockopen('ssl://smtp.googlemail.com', 465,
$errno,
$errstr,
300);
var_dump(fgets($smtp_connect, 512));
?>
On server 1 [no ssl cert installed], the output of the above code is: string(57) "220 smtp.googlemail.com ESMTP s89sm726209qkl.44 - gsmtp
"
On server 2 [ssl cert installed], the output of the above code is: string(71) "220-mycompany.pro.com ESMTP Exim 4.87 #1 Wed, 26 Oct 2016 07:42:49 -0400
"
Can anyone explain why this happens, and how can I make server 2 have the same behavior as server 1?
Update: I have also tried smtp.gmail.com, the output is same as using smtp.googlemail.com.
The line you get the the SMTP welcome message. It is perfectly normal that different servers give a different welcome message. It is even normal that the response to commands you send is different. This means that when communicating with an SMTP server you should not assume fixed strings as response but implement proper parsing of SMTP. See the SMTP standard (RFC 2821) for details about this protocol.

Telnet SMTP send mail timeout

I want to use telnet to send an e-mail with SMTP. It seemed that I had connect to the mail service successfully. And the message had been put in the queue too. But why did the SMTP service failed to send the message to the received address?
When I searched the solution by the internet, someone had said that firewall should paid it. But I have no idea about the relationship between the firewall or antivirus software and telnet.
This is my command:
220 smtp-5-124.smtpsmail.fmail.xd.sinanode.com ESMTP
helo a
250 smtp-5-124.smtpsmail.fmail.xd.sinanode.com
auth login
334 VXNlcd5hbWU6
a25vd215aGV2341241fasYS5jbg==
334 UGFzczdvcmQ6
UmF5V2adfa23adsfZzgyNA==
235 OK Authenticated
mail from: <knowmyheart#sina.cn>
502 unimplemented (#5.5.1)
mail from:<knowmyheart#sina.cn>
553 Envolope sender mismatch with login user..
mail from:<knowmyheart#sina.cn>
250 ok
rcpt to:<517447201#qq.com>
250 ok
data
354 End data with <CR><LF>.<CR><LF>
subject: test
to:<517447201#qq.com>
from:<knowmyheart#sina.cn>
Testttttttttttttt!
.
250 ok queue id 6744281442287
451 Timeout.
By the way, I tried it both on Windows 10 and Ubuntu-15.10. And both of them failed with the same question.
Finally, I found where I was wrong.
In my previous case,I failed to send a e-mail with the above code.I had succeeded in connecting with the SMTP server, and everything worked except the "Timeout" response. Actually, the "Timeout" didn't mean I failed to send a e-mail but lose the TCP connection. Hours Later, I login my e-mail, which was used for sending, finding that I receive a mail. The mail told me the e-mail I sent hours before with telnet was given back, failing to post. So it meant that the reason was hardly because of my telnet client, but in server or something else.
Finally, I found that it was because of my mail format. In my previous code, after I sending keyword -- "data", I immediately send the content.
data
354 End data with <CR><LF>.<CR><LF>
subject: test
to:<517447201#qq.com>
from:<knowmyheart#sina.cn>
Testttttttttttttt!
.
250 ok queue id 6744281442287
When I changed it to this, it worked.
data
354 End data with <CR><LF>.<CR><LF>
subject: test
to:<517447201#qq.com>
from:<knowmyheart#sina.cn>
Testttttttttttttt!
.
250 ok queue id 6744281442287
Notice that the difference between the codes is the empty line before the content in this mail. "subject", "to" and "from" are the headers. Between the header and the content, there must be an empty line.
Similarly, the headers in mail can be ignored. The code is like this:
data
354 End data with <CR><LF>.<CR><LF>
Testttttttttttttt!
.
250 ok queue id 6744281442287
451 Timeout.
Even if there is a "Timeout", it affect nothing but break the tcp connection between localhost and smtp server.

How configure roundcube to work with imaps?

I recently installed Postfix, Dovecot to setup a mail server on my own VPS ( using this tutorial: Email with Postfix, Dovecot, Mysql)
Imaps server uses port 993 for Authentication, and Postfix uses port 25 to send mails.
In this tutorial, users stored in a Database ( so imaps use mysql to authenticate users).
i'm sure every thing works fine with imaps and postfix , because few days ago i installed Kmail client (on my linux) and receive mails from my server. sending mails also works fine, i sent a mail to Gmail and google received it without a problem (in my "Gmail inbox" not spam folder)
So to get to my Emails from a web mail client, i installed Roundcube on /var/www/mail directory.
I configured Roundcube many times. but each time it gives me this Error:
IMAP Error: Login failed for [me#mydomain] from X.x.X.x . Empty
startup greeting (localhost:993) in
/var/www/mm/program/lib/Roundcube/rcube_imap.php on line 184 (POST
/mm/?_task=login?_task=login&_action=login)
When i do log in from roundcube, imap server says ( in /var/log/mail.log ):
May 20 07:05:16 my-server dovecot: imap-login: Disconnected (no auth
attempts): rip=::1, lip=::1, TLS handshaking: Disconnected
Here is my roundcube config file :
$config['db_dsnw'] = 'mysql://roundcubeuser:myPassword#localhost/roundcubemail';
// ----------------------------------
// IMAP
// ----------------------------------
$config['debug_level'] = 13;
$config['default_host'] = 'ssl://127.0.0.1';
$config['default_port'] = 993;
// ----------------------------------
// SMTP
// ----------------------------------
$config['smtp_server'] = 'ssl://localhost';
What's the problem? i really have no idea what is happening !
Thank you.
I'm using postfix + dovecot + roundcube a few months now and it's working for me. In my configuration, postfix rejects plaintext sessions, so roundcube has to connect with ssl - and it's working.
This is from my main.inc.php. I don't remember editing anything here, it's just the initial config created during the installation.
Now that I'm looking at it, default_port doesn't make any sense, I think it's just ignored.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// Supported replacement variables:
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// %s - domain name after the '#' from e-mail address provided at login screen
// For example %n = mail.domain.tld, %d = domain.tld
// TCP port used for IMAP connections
$rcmail_config['default_port'] = 143;
$rcmail_config['default_host'] = array("ssl://localhost:993");
// TCP port used for IMAP connections
$rcmail_config['default_port'] = 143;
In case the other answer does not work, this is what worked for me. My config.inc.php now contains:
$config['default_host'] = 'ssl://localhost';
$config['default_port'] = 993;
NOTE: using tls://localhost did not work for me. I had to specify ssl:// as the URI scheme.
Via PhpMyAdmin, I also ran this SQL command (all my user accounts are on the same machine that runs RoundCube):
UPDATE `rc_users` SET `mail_host`='ssl://localhost'
I got the port number 993 from running sudo netstat -tulnp in order to determine the port on which Dovecot was listening.

SMTP authentication failure while using SendGrid/Gmail

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

SMTP Error <<: 503 AUTH command used when not advertised

I am facing this error in Webmail Lite.
I have Exim installed. Here is a snippet of the auth block:
PLAIN:
driver = plaintext
server_set_id = $auth2
server_prompts = :
.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
.endif
server_condition = “${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{/etc/$domain/passwd}{$value}{*:*}}}}}{1}{0}}”
I have the passwd stored in the following format:
username:{MD5}asddfasdlasdkandlanskfdaf
How do I get AUTH enabled and working ?
Thanks in advance.
One reason for this error message is sending HELO instead of EHLO, or sending EHLO in the wrong order.
But this message can occur even if EHLO is used, when the server is running Exim.
On my server, I found the solution. In WHM > Home > Service Configuration > Exim
Configuration Manager, the option "Require clients to connect with SSL
or issue the STARTTLS command before they are allowed to authenticate
with the server" was set to the default (On). I'm not sure if I did this
or not, and it is ordinarily a great idea for security, but forces the
mailserver to enable (advertise) only the STARTTLS command, not AUTH. So
when my script sends AUTH, the error message the server sends is correct.
Further information is at http://blog.networkpresence.co/?p=8923 .
Someday when I have time I will find out how to change my script to use
TLS, so I can turn that Exim option On for security.
In my case,this error not coming regularly.some time it works but some time it gives this error.(SMTP Error: Could not authenticate.)
I debug this then I found this
SMTP -> get_lines(): $data was ""
SMTP -> get_lines(): $str is "503 AUTH command used when not advertised "
SMTP -> get_lines(): $data is "503 AUTH command used when not advertised "
SMTP -> FROM SERVER:503 AUTH command used when not advertised
SMTP -> ERROR: RSET failed: 503 AUTH command used when not advertised
SMTP Error: Could not authenticate.