SmtpServer icon indicating copy to clipboard operation
SmtpServer copied to clipboard

IOException replying to QUIT when receiving mail from outlook.com

Open ppaschedag opened this issue 3 years ago • 2 comments

It seems that outlook.com is not behaving very nicely when relaying mail, after it sends quit it looks like it is closing the connection before the response can be send, resulting in the exception below. This happens every time when receiving mail from Outlook. When mail is relayed/received from Gmail everything works as expected and if get "Command Executed" for QUIT followed by "SessionCompleted".

Is is possible to implement some checking when replying to QUIT if the connection is still active to prevent these exceptions?

SessionCreated: 40.107.22.44:8032 on port 25 Command Executing EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executed EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executing STARTTLS Command Executed STARTTLS Command Executing EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executed EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executing MAIL: Address=[REDACTED]@[REDACTED].[REDACTED] Parameters=SIZE=23964289,AUTH=<> Command Executed MAIL: Address=[REDACTED]@[REDACTED].[REDACTED] Parameters=SIZE=23964289,AUTH=<> Command Executing RCPT: Address=[REDACTED]@[REDACTED].[REDACTED] Command Executed RCPT: Address=[REDACTED]@[REDACTED].[REDACTED] Command Executing DATA Command Executed DATA Command Executing QUIT SessionFaulted: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.. ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host. --- End of inner exception stack trace --- at System.Net.Security.SslStream.<WriteSingleChunk>g__CompleteAsync|210_1[TWriteAdapter](ValueTask writeTask, Byte[] bufferToReturn) at System.Net.Security.SslStream.WriteAsyncInternal[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer) at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken) at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken) at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken) at SmtpServer.SmtpSession.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken) at SmtpServer.SmtpSession.RunAsync(CancellationToken cancellationToken) at SmtpServer.SmtpSessionManager.RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToken)

ppaschedag avatar Jun 23 '21 08:06 ppaschedag

I will look into this.

The specification is pretty clear that the client needs to wait for the response after initiating the QUIT command so I am surprised that Outlook would be doing it wrong, however, most servers are usually pretty lenient.

cosullivan avatar Jun 28 '21 07:06 cosullivan

Yeah, it seems Microsoft is ignoring the specs. Thanks for looking into this! If you have something, I'll be happy to test it out!

ppaschedag avatar Jul 01 '21 10:07 ppaschedag

I've published 10.0.0-beta1 for now which includes a fix to handle this.

cosullivan avatar Oct 26 '23 13:10 cosullivan

Hi,

This should now be fixed in v10.0.0 which is now published.

Please note that there is a breaking change to the mailbox filter API but its a very easy modification for implementations.

cosullivan avatar Nov 02 '23 13:11 cosullivan