MailKit.Net.Smtp.SmtpClient.Send无法在Linux上运行

时间:2018-12-13 01:47:04

标签: linux ssl smtpclient mailkit

以下用.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

1 个答案:

答案 0 :(得分:0)

这似乎是DotNet Core CLR中的错误,因为该错误发生在CoreCLR的OpenSSL可移植性抽象层(这就是PAL)之内。

我建议将错误报告提交给https://github.com/dotnet/coreclr/issues