cosullivan / SmtpServer

A SMTP Server component written in C#
MIT License
676 stars 160 forks source link

Service stopping due to SSL exception ! #156

Closed romeosan closed 8 months ago

romeosan commented 3 years ago

Hi,

I am running the newest nuget package v8.0.5 within .NET Core 2.1, dockerized within an Azure Container Instance.

Now after some time I am getting the following exception and the service is stopping. Any idea how to fix that? Any help is appreciated!!!

Authentication failed, see inner exception. at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception) at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, Object asyncState) at System.Net.Security.SslStream.BeginAuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation, AsyncCallback asyncCallback, Object asyncState) at System.Net.Security.SslStream.<>c.b__50_0(X509Certificate arg1, Boolean arg2, SslProtocols arg3, AsyncCallback callback, Object state) at System.Threading.Tasks.TaskFactory1.FromAsyncImpl[TArg1,TArg2,TArg3](Func6 beginMethod, Func2 endFunction, Action1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2,TArg3](Func6 beginMethod, Action1 endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state) at System.Net.Security.SslStream.AuthenticateAsServerAsync(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) at SmtpServer.IO.SecurableDuplexPipe.UpgradeAsync(X509Certificate certificate, SslProtocols protocols, CancellationToken cancellationToken) at SmtpServer.SmtpServer.GetPipeAsync(IEndpointListener endpointListener, SmtpSessionContext sessionContext, CancellationToken cancellationToken) at SmtpServer.SmtpServer.ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken cancellationToken) at SmtpServer.SmtpServer.StartAsync(CancellationToken cancellationToken) at MySmtpService.Program.Main(String[] args) in /src/MySmtpService/Program.cs:line 161


My code looks like this: ` public static async Task Main(string[] args) { try {

            IWebHost webHost = CreateWebHostBuilder(args).Build();

           // placeholder for some other code for reading pfx file

            var cert = new X509Certificate2(certFileByteArray, certPwd, X509KeyStorageFlags.PersistKeySet);

            // Create a new scope
            using (var scope = webHost.Services.CreateScope())
            {

                var options = new SmtpServerOptionsBuilder()
                .ServerName("mysmtp") // display name
                //.Port(25, 587)
                .Endpoint(builder =>
                builder
                .Port(465)
                .IsSecure(true)
                .AuthenticationRequired())
                //.Port(465, isSecure: true)
                .Certificate(cert)
                .SupportedSslProtocols(SslProtocols.Tls12)
                .Build();

                var serviceProvider = new ServiceProvider();
                serviceProvider.Add(new SampleMessageStore());
                serviceProvider.Add(new SampleMailboxFilter());
                serviceProvider.Add(new SampleUserAuthenticator());

                var smtpServer = new SmtpServer.SmtpServer(options, serviceProvider);

                await smtpServer.StartAsync(CancellationToken.None);
            }

            // run the WebHost
            await webHost.RunAsync();
        }
        catch (Exception ex)
        {
            Debug.Write("Exception in main: " + ex.Message + ex.StackTrace);

        }

    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();

`

Thank you!

romeosan commented 3 years ago

@cosullivan - just let me know in case you need more information. appreciate your support!

cosullivan commented 3 years ago

Hi, does this happen with all connections, or only after a period of time?

romeosan commented 3 years ago

thanks for the response @cosullivan, it is happening after some time and the docker instance is stopping as it seems that the above exception is not handled properly. the connections I am creating to tcp/465 are accepted without any issues, I assume the listener is receiving some packets (from random hosts) which he doesn´t like.

cosullivan commented 3 years ago

Ok, I think I know what the issue might be.

If you have configured .IsSecure(true) then it means that the server will attempt to upgrade the client connection to SSL when the connection is first established. However, if that upgrade throws an exception (perhaps the client connects with an invalid certificate) then that exception is bubbling up and causing the server to stop, whereas in v7 it used to handle it and raise the SessionFaulted event and continue on.

Your options at the moment are either catching when the server fails and recreate & restart it, or switch back to v7.

I will look to fix this in the next few days.

romeosan commented 3 years ago

thank you @cosullivan for pinning down the problem that fast. ok, right now I went back to v7 and testing with it. but v8 with such a fix would be awesome!!! ;) thank you in advance.

cosullivan commented 3 years ago

Hi @romeosan ,

This should be resolved in version 9 which I have just published.

Thanks, Cain.