cosullivan / SmtpServer

A SMTP Server component written in C#
MIT License
692 stars 163 forks source link

502 Unrecognized command #165

Closed ISV-Kran closed 3 years ago

ISV-Kran commented 3 years ago

Hi, and first of all thank you for this valuable smtp server ❤

I'm having some problems sending commands. I tried various tools, including socketlabs smtp console (https://www.socketlabs.com/smtp-server-connection-diagnostics-tool/). The command is sent correctly from the tool, in fact decoding the buffer in string on method ReadCommandAsync look fine. Despite this, the server return error "502 Unrecognized command, X retry(ies) remaining.". It seems the problem is in TryMakeDomain or TryMakeAddressLiteral, but I didn't understand exactly where.

cosullivan commented 3 years ago

Hi, what command is it failing with? Can you share anymore information for me to test with?

ISV-Kran commented 3 years ago

Sure, here's more info:

Net core version: 3.1 SMTP server version: 9.0.1 Configuration: var options = new SmtpServerOptionsBuilder() .ServerName("mydomain.com") .MaxMessageSize(52428800) .Endpoint(builder => builder.Port(25).ReadTimeout(TimeSpan.FromSeconds(60))) .Endpoint(builder => builder.Port(465, true).IsSecure(true) .ReadTimeout(TimeSpan.FromSeconds(60)) .Certificate(GetCertificateInSpecifiedStore("mydomain.com", StoreName.My, StoreLocation.LocalMachine)) .SupportedSslProtocols(SslProtocols.Tls13 | SslProtocols.Tls12)) .Build();

I connect to the smtp server port 25. Mainly I would like to perform a starttls, so:

  1. By sending the "HELO test" command, the server welcomes me
  2. I try to do "EHLO" (same with "EHLO test"), the answer is "502 Unrecognized command, 4 retry (ies) remaining."
  3. I still try to do starttls and get "501 expected NOOP/RSET/QUIT/PROXY/HELO/EHLO, 3 retry(ies) remaining."

If I connect with the SmtpClient (SampleMailClient) directly on port 465 it works perfectly and connection is encrypted.

Therefore, I can't understand why I don't get a reply from ehlo and why I can't run the starttls.

Adding on ReadCommandAsync the code string result = System.Text.Encoding.UTF8.GetString(buffer.ToArray()); if (result == "EHLO") { command = new EhloCommand("test"); return Task.CompletedTask; } ehlo return fine.

Thanks

ISV-Kran commented 3 years ago

-- UPDATE --

while HELO work case insensitive, EHLO is recognized only uppercase. I don't know, maybe that's correct. My fault.

So my problem remains on the STARTTLS. Using openssl s_client -starttls smtp -connect mydomain.com:25 -debug Response is:

CONNECTED(00000220)

220 mydomain.com v9.0.1.0 ESMTP ready..

EHLO openssl.cli ent.net..

read from 0x5738568 [0x8bd840] (4096 bytes => 137 (0x89)) 250-mydomain.com Hello op enssl.client.net , haven't we met before?..250-PI PELINING..250-8B ITMIME..250-SMTP UTF8..250 SIZE 5 2428800..

STARTTLS.. read from 0x5738568 [0x3739058] (8192 bytes => 69 (0x45)) 501 expected NOO P/RSET/QUIT/HELO /EHLO/MAIL, 4 re try(ies) remaini ng...

Maybe I wrong options configuration?

cosullivan commented 3 years ago

How are you trying to connect to the server to issue the commands?

I configured a server with your settings and then did

telnet localhost 25

220 mydomain.com v9.0.1.0 ESMTP ready
HELO test
250 mydomain.com Hello test, haven't we met before?
EHLO test
250-mydomain.com Hello test, haven't we met before?
250-PIPELINING
250-8BITMIME
250-SMTPUTF8
250 SIZE 52428800
quit
221 bye

so that worked. Can you try it through a telnet session and manually issue the commands?

Also note that in your case you wont be able to issue the STARTTLS command on Port 25 as that is not secure. STARTTLS will only be advertised on port 465. However, the other caveat here is that you have

Port(465, true).IsSecure(true)

You don't need true for both of these, the Port(465, true) is just a shortcut for Port(465).IsSecure(true) and by setting it to secure it actually means that the upgrade to TLS will occur when the connection is made, not when the STARTTLS command is issued. If you want to manually issue the STARTTLS command set the IsSecure(false) and then you can see that STARTTLS is advertised.

telnet localhost 465

220 mydomain.com v9.0.1.0 ESMTP ready
HELO test
250 mydomain.com Hello test, haven't we met before?
EHLO test
250-mydomain.com Hello test, haven't we met before?
250-PIPELINING
250-8BITMIME
250-SMTPUTF8
250-STARTTLS
250 SIZE 52428800
quit
221 bye
cosullivan commented 3 years ago

No, the commands should all be case insensitive.

220 SmtpServer SampleApp v9.0.1.0 ESMTP ready
ehlo test
250-SmtpServer SampleApp Hello test, haven't we met before?
250-PIPELINING
250-8BITMIME
250-SMTPUTF8
250 STARTTLS
ISV-Kran commented 3 years ago

You're right it works insensitive. About setting IsSecure(false) now I can manually start starttls.

Thank you so much, next time i'll check better before opening a report, have a nice day!