当前位置:   article > 正文

c# 在mono上的移植 系列之一 邮件发送不工作了

c# 在mono上的移植 系列之一 邮件发送不工作了

 IIS环境下的System.Net.Mail.SmtpClient,通过gmail account发送邮件,工作很正常,但是移植到linux Mono上后,出现了无法发送的问题,错误信息如下:

(原文链接 http://ddbiz.com/?p=242)

EmailException: Unable to send email ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateChainErrors
  at System.Net.Mail.SmtpClient.<SmtpClient>m__3 (System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) [0x00000]
  at System.Net.Security.SslStream+<BeginAuthenticateAsClient>c__AnonStorey12.<>m__9 (System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Int32[] certErrors) [0x00000]
  at Mono.Security.Protocol.Tls.SslClientStream.OnRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000]
  at Mono.Security.Protocol.Tls.SslStreamBase.RaiseRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000]
  at Mono.Security.Protocol.Tls.SslClientStream.RaiseServerCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] certificateErrors) [0x00000]
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000]
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000]
  at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000]
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
  at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000]
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000]
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000]
  --- End of inner exception stack trace ---

 

居然出现 System.InvalidOperationException: SSL authentication error: RemoteCertificateChainErrors 的错误,真是莫名其妙。毕竟是头一次对项目进行mono的移植,没有深入了解过她,起初怀疑是mono的这个类对ssl的支持没有实现,但是翻看其SmtpClient.cs源代码,是有X509Certificates.X509Certificate 的实现的。

去mono-project的论坛上问问看(源文见 http://go-mono.com/forums/#nabble%2Bmailing_list%2FSubscribeDefaults.jtp%3Fforum%3D1378%26k%3Duta6lrpm),Sebastien 得回复似乎切中要害。查看了mono的文档知道,mono本身在发行的时候是不带任何证书的,这和windows平台似乎恰恰相反。不过mono提供了两款工具,允许我们自行安装证书。

因为系统是运行在apache+mono的环境下,没有测试以apache的运行帐号导入证书,而是直接把证书安装到了全局范围,下面是安装过程,有3个步骤,其中第2个步骤是不是一定需要,没时间测试了。有兴趣的朋友可以测试后告诉我答案

1. 安装根证书,这由 mozroots 来完成

    mozroots --import /               ##导入证书

                    --ask-remove  /       ##仅删除时确认

                    --machine               ##保存在全局环境

   ...

   ...

Importing certificates into machine store...
124 new root certificates were added to your trust store.
Import process completed.

  mozroots 把证书保存在了 /usr/share/.mono/certs/Trust/

 

2. 保存smtp.gmail.com的证书

因为smtp.gmail.com是要求对连接进行ssl加密的,所以我们在此先把其保存在本地。印象中在开发环境下(windows xp/iis),配置有个人的Outlook Express账户,第一次设置账户信息时确实是自动保存过一个证书;但是在IIS的服务器运营平台上(win200/iis),并没有设置过这个账户信息也可以成功发送,似乎这一步步是必须的。

  mono下工具certmgr 可以导入证书
certmgr -ssl -m smtps://smtp.gmail.com:465

certmgr把证书保存在了/usr/share/.mono/certs/AddressBook/

 

3.配置一下gmail帐号的发送参数:
   Host : smtp.gmail.com
   Port : 587
   SSL  : true

 

好了,可以发送了  

这个问题可以说是windows平台和linux平台的差异造成的。我们的开发和应用多跑在windows平台上,好处是这个平台为我们作了很多幕后工作,坏处是我们清楚她做了些什么,看来后面的移植过程中出现的问题,第一要考虑的就是时不时平台差异造成的:-)

(原文链接 http://ddbiz.com/?p=242)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/127094
推荐阅读
相关标签
  

闽ICP备14008679号