以下用.net核心2编写的代码在Windows环境中可用,但在linux中不可用。端口25在linux中可用,但端口465在linux中不可用。
using MailKit.Net.Smtp;
using MimeKit;
using System;
public class MailTest
{
public static void Send()
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("from", "from@xx.cn"));
message.To.Add(new MailboxAddress("me", "me@xx.cn"));
message.Subject = string.Format("mailtest {0}", DateTime.Now.ToLongTimeString());
message.Body = new TextPart("plain") { Text = "I want to send a ssl mail" };
try
{
var client = new SmtpClient();
Console.WriteLine("new SmtpClient()");
// For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
Console.WriteLine(client.SslProtocols);
client.ServerCertificateValidationCallback = (s, c, h, e) =>
{
Console.WriteLine("--------\n");
return true;
};
Console.WriteLine("begin Connect");
client.Connect("smtp.exmail.qq.com", 465, true);
Console.WriteLine("end Connect");
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
Console.WriteLine("Encoding.Default:{0}", System.Text.Encoding.Default.BodyName);
// Note: only needed if the SMTP server requires authentication
client.Authenticate("from@mallcoo.cn", "xxxxxx");
client.Send(message);
client.Disconnect(true);
client.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("ex:{0}", ex);
}
}
}
它在client.Connect(“ smtp.exmail.qq.com”,465,true)上引发异常;似乎没有调用client.ServerCertificateValidationCallback。下面的日志:
new SmtpClient()
Tls, Tls11, Tls12
begin Connect
ex:System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation.
at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.MapVerifyErrorToChainStatus(X509VerifyStatusCode code)
at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.AddElementStatus(X509VerifyStatusCode errorCode, List`1 elementStatus, List`1 overallStatus)
at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.AddElementStatus(List`1 errorCodes, List`1 elementStatus, List`1 overallStatus)
at Internal.Cryptography.Pal.OpenSslX509ChainProcessor.BuildChain(X509Certificate2 leaf, HashSet`1 candidates, HashSet`1 systemTrusted, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan& remainingDownloadTime)
at Internal.Cryptography.Pal.ChainPal.BuildChain(Boolean useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout)
at System.Security.Cryptography.X509Certificates.X509Chain.Build(X509Certificate2 certificate, Boolean throwOnException)
at System.Security.Cryptography.X509Certificates.X509Chain.Build(X509Certificate2 certificate)
at System.Net.Security.CertificateValidation.BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificate, Boolean checkCertName, String hostName)
at System.Net.Security.SecureChannel.VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback, ProtocolToken& alertToken)
at System.Net.Security.SslState.CompleteHandshake(ProtocolToken& alertToken)
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.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.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.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MailKit.Net.Smtp.SmtpClient.Connect(String host, Int32 port, SecureSocketOptions options, CancellationToken cancellationToken)
at MailKit.MailService.Connect(String host, Int32 port, Boolean useSsl, CancellationToken cancellationToken)
at Tom.MailTest.Send() in C:\git\Tom\src\Tom\MailTest.cs:line 45
答案 0 :(得分:0)
这似乎是DotNet Core CLR中的错误,因为该错误发生在CoreCLR的OpenSSL可移植性抽象层(这就是PAL)之内。
我建议将错误报告提交给https://github.com/dotnet/coreclr/issues