SmtpClient不会通过SSL / TLS进行身份验证(不指向gmail)

时间:2011-08-16 17:24:48

标签: c# .net-4.0 smtp ssl

我有一个ssl / tls服务器(nodejs),它充当postfix / sendmail的代理,以对外发邮件执行一些预处理/数据获取。

从C#,我可以使用以下代码手动连接和验证:

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);

但是,我无法连接SmtpClient。顶级错误是超时,但我已调试到SmtpClient / SmtpConnection,并且潜在的错误是流不可读,大概是因为它从未经过身份验证(我无法在我的ssl / tls代理服务器中遇到断点) SmtpClient代码,但上面的手动sslConnection工作得很好。

如果有一种方法可以手动将底层通信流提供给SmtpClient,那将会很棒,但我找不到办法。

任何人都知道为什么下面的代码不会进行身份验证?

以下是我尝试与SmtpClient连接但未成功的测试应用程序:

    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);

1 个答案:

答案 0 :(得分:6)

解决了一会儿,忘了发布答案。

.NET smtp客户端以及大多数smtp客户端库不支持通过ssl / tls进行启动通信。它要求smtp服务器支持启动未加密的通信,然后使用“upgrade”命令转换到加密连接(这几乎总是由SMTP客户端库在幕后处理)。

当时,我正在连接到代理postfix的半自定义smtp服务器,而这个自定义解决方案最初只支持通过ssl / tls连接。此后开始使用Haraka作为我的SMTP服务器,它支持所有SMTP标准,并为我提供了所需的插件功能。