Merge pull request #1896 from meum/patch-1
[mono.git] / mcs / class / System / System.Net.Mail / SmtpClient.cs
index ab1bde4ff7fd86789d37c22aa278abeb7f8cd0c1..bb6f93a048400ae68242ed19ca98aa64892b7946 100644 (file)
 //
 
 #if SECURITY_DEP
+#if MONO_SECURITY_ALIAS
+extern alias MonoSecurity;
+#endif
+#if MONO_X509_ALIAS
+extern alias PrebuiltSystem;
+#endif
 
-#if MONOTOUCH || MONODROID
-using System.Security.Cryptography.X509Certificates;
+#if MONO_SECURITY_ALIAS
+using MSI = MonoSecurity::Mono.Security.Interface;
 #else
-extern alias PrebuiltSystem;
+using MSI = Mono.Security.Interface;
+#endif
+#if MONO_X509_ALIAS
 using X509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
-using System.Security.Cryptography.X509Certificates;
+#else
+using X509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
 #endif
-
+using System.Security.Cryptography.X509Certificates;
 #endif
 
 using System;
@@ -50,14 +59,15 @@ using System.Net.Mime;
 using System.Net.Sockets;
 using System.Text;
 using System.Threading;
-using System.Reflection;
 using System.Net.Configuration;
 using System.Configuration;
 using System.Net.Security;
 using System.Security.Authentication;
 using System.Threading.Tasks;
+using Mono.Net.Security;
 
 namespace System.Net.Mail {
+       [Obsolete ("SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead")]
        public class SmtpClient
        : IDisposable
        {
@@ -581,10 +591,13 @@ namespace System.Net.Mail {
                        
                        // FIXME: parse the list of extensions so we don't bother wasting
                        // our time trying commands if they aren't supported.
-                       status = SendCommand ("EHLO " + Dns.GetHostName ());
+                       
+                       // Get the FQDN of the local machine
+                       string fqdn = Dns.GetHostEntry (Dns.GetHostName ()).HostName;
+                       status = SendCommand ("EHLO " + fqdn);
                        
                        if (IsError (status)) {
-                               status = SendCommand ("HELO " + Dns.GetHostName ());
+                               status = SendCommand ("HELO " + fqdn);
                                
                                if (IsError (status))
                                        throw new SmtpException (status.StatusCode, status.Description);
@@ -601,10 +614,10 @@ namespace System.Net.Mail {
                                ResetExtensions();
                                writer = new StreamWriter (stream);
                                reader = new StreamReader (stream);
-                               status = SendCommand ("EHLO " + Dns.GetHostName ());
+                               status = SendCommand ("EHLO " + fqdn);
                        
                                if (IsError (status)) {
-                                       status = SendCommand ("HELO " + Dns.GetHostName ());
+                                       status = SendCommand ("HELO " + fqdn);
                                
                                        if (IsError (status))
                                                throw new SmtpException (status.StatusCode, status.Description);
@@ -742,7 +755,7 @@ namespace System.Net.Mail {
 
                static void SendMailAsyncCompletedHandler (TaskCompletionSource<object> source, AsyncCompletedEventArgs e, SendCompletedEventHandler handler, SmtpClient client)
                {
-                       if ((object) handler != e.UserState)
+                       if (source != e.UserState)
                                return;
 
                        client.SendCompleted -= handler;
@@ -1134,21 +1147,6 @@ try {
                        return "unknown";
                }
 
-#if SECURITY_DEP
-               RemoteCertificateValidationCallback callback = delegate (object sender,
-                                                                        X509Certificate certificate,
-                                                                        X509Chain chain,
-                                                                        SslPolicyErrors sslPolicyErrors) {
-                       // honor any exciting callback defined on ServicePointManager
-                       if (ServicePointManager.ServerCertificateValidationCallback != null)
-                               return ServicePointManager.ServerCertificateValidationCallback (sender, certificate, chain, sslPolicyErrors);
-                       // otherwise provide our own
-                       if (sslPolicyErrors != SslPolicyErrors.None)
-                               throw new InvalidOperationException ("SSL authentication error: " + sslPolicyErrors);
-                       return true;
-                       };
-#endif
-
                private void InitiateSecureConnection () {
                        SmtpResponse response = SendCommand ("STARTTLS");
 
@@ -1156,11 +1154,14 @@ try {
                                throw new SmtpException (SmtpStatusCode.GeneralFailure, "Server does not support secure connections.");
                        }
 
-#if   SECURITY_DEP
-                       SslStream sslStream = new SslStream (stream, false, callback, null);
+#if SECURITY_DEP
+                       var tlsProvider = MonoTlsProviderFactory.GetProviderInternal ();
+                       var settings = MSI.MonoTlsSettings.CopyDefaultSettings ();
+                       settings.UseServicePointManagerCallback = true;
+                       var sslStream = tlsProvider.CreateSslStream (stream, false, settings);
                        CheckCancellation ();
                        sslStream.AuthenticateAsClient (Host, this.ClientCertificates, SslProtocols.Default, false);
-                       stream = sslStream;
+                       stream = sslStream.AuthenticatedStream;
 
 #else
                        throw new SystemException ("You are using an incomplete System.dll build");