Merge pull request #637 from LogosBible/enetdown
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / SslStreamBase.cs
index 34f8ceaa73e36c80bad808e87ba03a26063608f1..7462702d9a421a34c64d5c5ff717c429fd35c133 100644 (file)
@@ -33,15 +33,18 @@ using System.Threading;
 
 namespace Mono.Security.Protocol.Tls
 {
-       public abstract class SslStreamBase: Stream, IDisposable
+#if INSIDE_SYSTEM
+       internal
+#else
+       public
+#endif
+       abstract class SslStreamBase: Stream, IDisposable
        {
                private delegate void AsyncHandshakeDelegate(InternalAsyncResult asyncResult, bool fromWrite);
                
                #region Fields
 
-               static ManualResetEvent record_processing = new ManualResetEvent (true);
-
-               private const int WaitTimeOut = 5 * 60 * 1000;
+               static ManualResetEvent record_processing = new ManualResetEvent (true);        
 
                internal Stream innerStream;
                internal MemoryStream inputBuffer;
@@ -185,6 +188,8 @@ namespace Mono.Security.Protocol.Tls
                                                                                                                        X509CertificateCollection serverRequestedCertificates);
 
                internal abstract bool OnRemoteCertificateValidation(X509Certificate certificate, int[] errors);
+               internal abstract ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection);
+               internal abstract bool HaveRemoteValidation2Callback { get; }
 
                internal abstract AsymmetricAlgorithm OnLocalPrivateKeySelection(X509Certificate certificate, string targetHost);
 
@@ -205,6 +210,11 @@ namespace Mono.Security.Protocol.Tls
                        return OnRemoteCertificateValidation(certificate, errors);
                }
 
+               internal ValidationResult RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       return OnRemoteCertificateValidation2 (collection);
+               }
+
                internal AsymmetricAlgorithm RaiseLocalPrivateKeySelection(
                        X509Certificate certificate,
                        string targetHost)
@@ -605,7 +615,7 @@ namespace Mono.Security.Protocol.Tls
                                {
                                        asyncResult.SetComplete(preReadSize);
                                }
-                               else if (!this.context.ConnectionEnd)
+                               else if (!this.context.ReceivedConnectionEnd)
                                {
                                        // this will read data from the network until we have (at least) one
                                        // record to send back to the caller
@@ -724,11 +734,15 @@ namespace Mono.Security.Protocol.Tls
 
                                if (!dataToReturn && (n > 0))
                                {
-                                       // there is no record to return to caller and (possibly) more data waiting
-                                       // so continue reading from network (and appending to stream)
-                                       recordStream.Position = recordStream.Length;
-                                       this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
-                                               new AsyncCallback(InternalReadCallback), state);
+                                       if (context.ReceivedConnectionEnd) {
+                                               internalResult.SetComplete (0);
+                                       } else {
+                                               // there is no record to return to caller and (possibly) more data waiting
+                                               // so continue reading from network (and appending to stream)
+                                               recordStream.Position = recordStream.Length;
+                                               this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
+                                                       new AsyncCallback(InternalReadCallback), state);
+                                       }
                                }
                                else
                                {
@@ -864,7 +878,7 @@ namespace Mono.Security.Protocol.Tls
                        // Always wait until the read is complete
                        if (!asyncResult.IsCompleted)
                        {
-                               if (!asyncResult.AsyncWaitHandle.WaitOne (WaitTimeOut, false))
+                               if (!asyncResult.AsyncWaitHandle.WaitOne ())
                                        throw new TlsException (AlertDescription.InternalError, "Couldn't complete EndRead");
                        }
 
@@ -889,7 +903,7 @@ namespace Mono.Security.Protocol.Tls
 
                        if (!asyncResult.IsCompleted)
                        {
-                               if (!internalResult.AsyncWaitHandle.WaitOne (WaitTimeOut, false))
+                               if (!internalResult.AsyncWaitHandle.WaitOne ())
                                        throw new TlsException (AlertDescription.InternalError, "Couldn't complete EndWrite");
                        }
 
@@ -1169,10 +1183,13 @@ namespace Mono.Security.Protocol.Tls
                                        if (this.innerStream != null)
                                        {
                                                if (this.context.HandshakeState == HandshakeState.Finished &&
-                                                       !this.context.ConnectionEnd)
+                                                       !this.context.SentConnectionEnd)
                                                {
-                                                       // Write close notify                                                   
-                                                       this.protocol.SendAlert(AlertDescription.CloseNotify);
+                                                       // Write close notify
+                                                       try {
+                                                               this.protocol.SendAlert(AlertDescription.CloseNotify);
+                                                       } catch {
+                                                       }
                                                }
 
                                                if (this.ownsStream)