我有一个 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);
最佳答案
解决了一段时间,忘了发布答案。
.NET smtp 客户端以及大多数 smtp 客户端库不支持通过 ssl/tls 发起通信。它要求 smtp 服务器支持发起未加密的通信,然后使用“升级”命令转换到加密连接(这几乎总是由 SMTP 客户端库在幕后处理)。
当时,我连接到一个代理 postfix 的半自定义 smtp 服务器,而这个自定义解决方案最初只支持通过 ssl/tls 连接。从那以后开始使用 Haraka 作为我的 SMTP 服务器,它支持所有 SMTP 标准并为我提供我需要的插件功能。
关于c# - SmtpClient 不会通过 SSL/TLS 进行身份验证(不指向 gmail),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7082315/