2007-10-22 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Mon, 22 Oct 2007 13:54:23 +0000 (13:54 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Mon, 22 Oct 2007 13:54:23 +0000 (13:54 -0000)
* AttachmentCollection.cs : remove TODO.
* Attachment.cs : guess NameEncoding when set_Name().
* MailMessage.cs : moved encoding guess impl to ContentType.
* SmtpClient.cs : moved RFC 2047 encoding impl to ContentType.
  Support attachment Name encoding. Added some SSL changes (it's not
  working yet).

svn path=/trunk/mcs/; revision=87907

mcs/class/System/System.Net.Mail/Attachment.cs
mcs/class/System/System.Net.Mail/AttachmentCollection.cs
mcs/class/System/System.Net.Mail/ChangeLog
mcs/class/System/System.Net.Mail/MailMessage.cs
mcs/class/System/System.Net.Mail/SmtpClient.cs

index f3b8d6c422c5ca79c6362a2fa2e02f502602233d..2053103a58cb9b9964923c1ee7e495bdd6b12824 100644 (file)
@@ -87,10 +87,13 @@ namespace System.Net.Mail {
 
                public string Name {
                        get { return ContentType.Name; }
-                       set { ContentType.Name = value; }
+                       set {
+                               if (value != null && nameEncoding == null)
+                                       nameEncoding = ContentType.GuessEncoding (value);
+                               ContentType.Name = value;
+                       }
                }
 
-               [MonoTODO]
                public Encoding NameEncoding {
                        get { return nameEncoding; }
                        set { nameEncoding = value; }
index d7f1216440b5800560af3370601ab38ff87b8d80..24e11430adae18b103f673a92b40e8ed596c525e 100644 (file)
@@ -41,7 +41,6 @@ namespace System.Net.Mail {
                {
                }
                
-               [MonoTODO]
                public void Dispose ()
                {
                        for (int i = 0; i < Count; i += 1)
index 9e3881f14363fd4f81ebf8539bdcd99bcf40e97a..e33250b1d568b41f5de02870fcc57e239d84198f 100644 (file)
@@ -1,3 +1,12 @@
+2007-10-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * AttachmentCollection.cs : remove TODO.
+       * Attachment.cs : guess NameEncoding when set_Name().
+       * MailMessage.cs : moved encoding guess impl to ContentType.
+       * SmtpClient.cs : moved RFC 2047 encoding impl to ContentType.
+         Support attachment Name encoding. Added some SSL changes (it's not
+         working yet).
+
 2007-10-22  Atsushi Enomoto  <atsushi@ximian.com>
 
        * SmtpClient.cs : attachment refactory. First, determine whether we
index c96f3c1e35aea01efde10fa278a3e7170fc091d0..c8132d816a30e6522a8bcf532388339909a0fe19 100644 (file)
@@ -235,10 +235,7 @@ namespace System.Net.Mail {
 
                private Encoding GuessEncoding (string s)
                {
-                       for (int i = 0; i < s.Length; i++)
-                               if (s [i] >= '\u0080')
-                                       return Encoding.UTF8;
-                       return Encoding.ASCII;
+                       return ContentType.GuessEncoding (s);
                }
 
                #endregion // Methods
index 94b7c794ddca9f63878b275796d16f351b57e64c..74f57fad97bde79ec785c0f4a96038c480c6d9fb 100644 (file)
 
 #if NET_2_0
 
+#if SECURITY_DEP
+extern alias PrebuiltSystem;
+#endif
+
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
@@ -44,6 +48,13 @@ using System.Threading;
 using System.Reflection;
 using System.Net.Configuration;
 using System.Configuration;
+using System.Net.Security;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+#if SECURITY_DEP
+using X509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
+#endif
 
 namespace System.Net.Mail {
        public class SmtpClient
@@ -58,10 +69,10 @@ namespace System.Net.Mail {
                string pickupDirectoryLocation;
                SmtpDeliveryMethod deliveryMethod;
                bool enableSsl;
-               //X509CertificateCollection clientCertificates;
+               X509CertificateCollection clientCertificates;
 
                TcpClient client;
-               NetworkStream stream;
+               Stream stream;
                StreamWriter writer;
                StreamReader reader;
                int boundaryIndex;
@@ -131,13 +142,16 @@ namespace System.Net.Mail {
 
                #region Properties
 
-               [MonoTODO("Client certificates are not supported")]
+#if SECURITY_DEP
+               [MonoTODO("STARTTLS is not supported yet")]
                public X509CertificateCollection ClientCertificates {
                        get {
-                               throw new NotImplementedException ("Client certificates are not supported");
-                               //return clientCertificates;
+                               if (clientCertificates == null)
+                                       clientCertificates = new X509CertificateCollection ();
+                               return clientCertificates;
                        }
                }
+#endif
 
                public ICredentialsByHost Credentials {
                        get { return credentials; }
@@ -155,7 +169,7 @@ namespace System.Net.Mail {
                        }
                }
 
-               [MonoTODO]
+               [MonoTODO("STARTTLS is not supported yet")]
                public bool EnableSsl {
                        // FIXME: So... is this supposed to enable SSL port functionality? or STARTTLS? Or both?
                        get { return enableSsl; }
@@ -234,10 +248,7 @@ namespace System.Net.Mail {
 
                private string EncodeSubjectRFC2047 (MailMessage message)
                {
-                       if (message.SubjectEncoding == null || Encoding.ASCII.Equals (message.SubjectEncoding))
-                               return message.Subject;
-                       string b64 = Convert.ToBase64String (message.SubjectEncoding.GetBytes (message.Subject));
-                       return String.Concat ("=?", message.SubjectEncoding.HeaderName, "?B?", b64, "?=");
+                       return ContentType.EncodeSubjectRFC2047 (message.Subject, message.SubjectEncoding);
                }
 
                private string EncodeBody (MailMessage message)
@@ -396,6 +407,9 @@ namespace System.Net.Mail {
 
                        client = new TcpClient (host, port);
                        stream = client.GetStream ();
+                       // FIXME: this StreamWriter creation is bogus.
+                       // It expects as if a Stream were able to switch to SSL
+                       // mode (such behavior is only in Mainsoft Socket API).
                        writer = new StreamWriter (stream);
                        reader = new StreamReader (stream);
 
@@ -423,6 +437,7 @@ namespace System.Net.Mail {
                        }
                        
                        if (enableSsl) {
+#if old_comment
                                // FIXME: I get the feeling from the docs that EnableSsl is meant
                                // for using the SSL-port and not STARTTLS (or, if it includes
                                // STARTTLS... only use STARTTLS if the SSL-type in the certificate
@@ -431,6 +446,9 @@ namespace System.Net.Mail {
                                // FIXME: even tho we have a canStartTLS flag... ignore it for now
                                // so that the STARTTLS command can throw the appropriate
                                // SmtpException if STARTTLS is unavailable
+#else
+                               // SmtpClient implements STARTTLS support.
+#endif
                                InitiateSecureConnection ();
                                
                                // FIXME: re-EHLO?
@@ -723,7 +741,12 @@ try {
                private void SendAttachments (MailMessage message, Attachment body, string boundary) {
                        foreach (Attachment att in message.Attachments) {
                                ContentType contentType = new ContentType (att.ContentType.ToString ());
-                               att.ContentDisposition.FileName = att.Name;
+                               if (att.Name != null) {
+                                       contentType.Name = att.Name;
+                                       if (att.NameEncoding != null)
+                                               contentType.CharSet = att.NameEncoding.HeaderName;
+                                       att.ContentDisposition.FileName = att.Name;
+                               }
                                StartSection (boundary, contentType, att.TransferEncoding, att == body ? null : att.ContentDisposition);
 
                                switch (att.TransferEncoding) {
@@ -819,6 +842,15 @@ try {
                        return "unknown";
                }
 
+               RemoteCertificateValidationCallback callback = delegate (object sender,
+                                                                        X509Certificate certificate,
+                                                                        X509Chain chain,
+                                                                        SslPolicyErrors sslPolicyErrors) {
+                       if (sslPolicyErrors != SslPolicyErrors.None)
+                               throw new InvalidOperationException ("SSL authentication error: " + sslPolicyErrors);
+                       return true;
+                       };
+
                private void InitiateSecureConnection () {
                        SmtpResponse response = SendCommand ("STARTTLS");
 
@@ -826,16 +858,16 @@ try {
                                throw new SmtpException (SmtpStatusCode.GeneralFailure, "Server does not support secure connections.");
                        }
 
-                       ChangeToSSLSocket ();
-               }
-
-               private bool ChangeToSSLSocket () {
 #if TARGET_JVM
-                       stream.ChangeToSSLSocket ();
+                       ((NetworkStream) stream).ChangeToSSLSocket ();
+#elif SECURITY_DEP
+                       SslStream sslStream = new SslStream (stream, false, callback, null);
+                       sslStream.AuthenticateAsClient (Host, this.ClientCertificates, SslProtocols.Default, false);
+                       stream = sslStream;
 
-                       return true;
-#else
                        throw new NotImplementedException ();
+#else
+                       throw new SystemException ("You are using an incomplete System.dll build");
 #endif
                }