开发者

SmtpClient wont authenticate over SSL/TLS (not pointing to gmail)

开发者 https://www.devze.com 2023-03-28 17:47 出处:网络
I have an ssl/tls server (nodejs) that acts as a proxy to postfix/sendmail to perform some pre-processing/data aquisition on outgoing mail.

I have an ssl/tls server (nodejs) that acts as a proxy to postfix/sendmail to perform some pre-processing/data aquisition on outgoing mail.

From C#, I can manually connect and authenticate with the following code:

var sslStream = new SslStream(tcpClient.GetStream(), false,
                 开发者_运维问答        new RemoteCertificateValidationCallback(CertificateValidation),
                         new LocalCertificateSelectionCallback(CertificateSelectionCallback));

                string fn = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cert.pem");
                X509Certificate c = X509Certificate.CreateFromCertFile(fn);
                var certs = new X509CertificateCollection();
                certs.Add(c);
                sslStream.AuthenticateAsClient(System.Environment.MachineName, certs , SslProtocols.Default, false);

However, I can not get the SmtpClient to connect. The top level error is a timeout, but I have debugged into SmtpClient/SmtpConnection and the underlying error is that the stream is not readable, presumably because it never authenticated (I cant hit a break-point in my ssl/tls proxy server with the SmtpClient code, but the manual sslConnection above works just fine).

It would be great if there was a way to manually supply the underlying communication stream to SmtpClient but I cant find a way to do it.

Anyone have an idea as to why the code below wont authenticate?

Here is the test app I have been using to try and connect with SmtpClient without success:

    ServicePointManager.ServerCertificateValidationCallback = CertificateValidation;
    // Using Ssl3 rather than Tls here makes no difference
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
    var client = new SmtpClient {
                                  Timeout = 10000,
                                  DeliveryMethod = SmtpDeliveryMethod.Network,
                                  EnableSsl = true,
                                  UseDefaultCredentials = false,
                                  Host = "192.168.15.71",
                                  Port = 10126
                                };
    client.ClientCertificates.Add(c);
    client.Credentials = new NetworkCredential("username", "password");

    //times out here, except the real exception that doesn't bubble up is the stream
    //isnt readable because it never authenticated (when it trys to read the status
    //returned by the smtp server, eg: "220 smtp2.example.com ESMTP Postfix")
    client.send(email);


Solved a while back, forgot to post the answer.

The .NET smtp client, along with most smtp client libraries, does not support initiating communications via ssl/tls. It requires that the smtp server support initiating communications unencrypted, and then transitioning to an encrypted connection using the "upgrade" command (this is almost always handled behind the scenes by the SMTP client library).

At the time, I was connecting to a semi-custom smtp server that was proxying postfix, and this custom solution only supported connecting initially via ssl/tls. Have since started using Haraka for my SMTP server, which supports all SMTP standards as well as providing me with the plugin capability I needed.

0

精彩评论

暂无评论...
验证码 换一张
取 消