SmtpClient不会验证通过SSL / TLS(不指向Gmail的)SSL、SmtpClient、Gmail、TLS

2023-09-09 21:05:02 作者:烟花、礼烟花、雨

我有一个SSL / TLS服务器(nodejs)充当代理后缀/ sendmail来对发送的邮件进行一些pre-处理/数据AQUISITION。

从C#,我可以手动连接,并具有以下code认证:

  VAR sslStream =新的SslStream(tcpClient.GetStream(),假的,
                         新RemoteCertificateValidationCallback(CertificateValidation)
                         新LocalCertificateSelectionCallback(CertificateSelectionCallback));

                串FN = Path.Combine(AppDomain.CurrentDomain.BaseDirectorycert.pem);
                x509证书C = X509Certificate.CreateFromCertFile(FN);
                VAR证书=新X509CertificateCollection();
                certs.Add(C);
                sslStream.AuthenticateAsClient(System.Environment.MachineName,证书,SslProtocols.Default,假);
 

不过,我不能让SmtpClient进行连接。顶层错误是超时,但我已经调试到SmtpClient / SmtpConnection和底层的错误是流无法读取,presumably,因为它从来没有验证的(我不能打了一个破发点,在我的SSL / TLS代理服务器与SmtpClient code,但高于手动sslConnection工作得很好)。

如果有一种方法来手动提供底层通信流SmtpClient这将是巨大的,但我不能找到一个方法来做到这一点。

任何人都有一个想法,为什么code以下不会验证?

谁能帮帮我 苹果手机上面的邮件 我添加了QQ邮箱和网易邮箱 但是感觉用不起来

下面是测试应用程序,我一直用它来尝试并与SmtpClient没有成功:

  ServicePointManager.ServerCertificateValidationCallback = CertificateValidation;
    //使用SSL3而不是TLS这里没有什么区别
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
    VAR的客户=新SmtpClient {
                                  超时= 10000,
                                  DeliveryMethod = SmtpDeliveryMethod.Network,
                                  EnableSsl = TRUE,
                                  UseDefaultCredentials =假,
                                  主机=192.168.15.71
                                  端口= 10126
                                };
    client.ClientCertificates.Add(C);
    client.Credentials =新的NetworkCredential(用户名,密码);

    //超时这里,但不能上升真正的例外是流
    //心不是可读的,因为它从来没有认证(当它改掉读取状态
    //返回SMTP服务器,例如:220 smtp2.example.com ESMTP后缀)
    client.send(电子邮件);
 

解决方案

解决而回,忘了张贴的答案。

在.NET SMTP客户端,以及大多数SMTP客户端库,不通过SSL / TLS支持的发起的通信。它要求SMTP服务器支持发起的通信加密,然后使用升级命令(这几乎总是在幕后通过SMTP客户端库处理)过渡到一个加密的连接。

当时,我是连接到已进行代理后缀一个半定制的SMTP服务器,而这个定制的解决方案仅支持通过SSL / TLS开始连接。自从开始使用 Haraka 我的SMTP服务器,它支持所有的SMTP标准,以及为我提供的插件能力我需要的。

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.