2007-08-16 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Thu, 16 Aug 2007 12:20:55 +0000 (12:20 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Thu, 16 Aug 2007 12:20:55 +0000 (12:20 -0000)
* RecordProtocol.cs, SslStreamBase.cs: Ensure nothing (even the same
thread) can confuse the record decoding code. Fix bug #82145 (LDAP)
which uses several thread over a single SslClientStream instance.

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

mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs

index 2bada9576c7aed251ba52b3b8195be08b2a5b08d..58e997abc91eebdfe7528a57162b21fd065e89dd 100644 (file)
@@ -1,3 +1,9 @@
+2007-08-16  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * RecordProtocol.cs, SslStreamBase.cs: Ensure nothing (even the same
+       thread) can confuse the record decoding code. Fix bug #82145 (LDAP) 
+       which uses several thread over a single SslClientStream instance.
+
 2007-05-23 Gonzalo Paniagua Javier <gonzalo.mono@gmail.com>
 
        * Context.cs: fix the calculation of the unix time.
index 7806a39bcc0e7013ac5841264227475a66f544da..6ccced66b85d9d50a9a0bf00fe3b58f12e49839b 100644 (file)
@@ -1,6 +1,6 @@
 // Transport Security Layer (TLS)
 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -35,6 +35,8 @@ namespace Mono.Security.Protocol.Tls
        {
                #region Fields
 
+               private static ManualResetEvent record_processing = new ManualResetEvent (true);
+
                protected Stream        innerStream;
                protected Context       context;
 
@@ -316,6 +318,7 @@ namespace Mono.Security.Protocol.Tls
                                        "The session is finished and it's no longer valid.");
                        }
 
+                       record_processing.Reset ();
                        byte[] recordTypeBuffer = new byte[1];
 
                        ReceiveRecordAsyncResult internalResult = new ReceiveRecordAsyncResult(callback, state, recordTypeBuffer, record);
@@ -426,8 +429,10 @@ namespace Mono.Security.Protocol.Tls
 
                        if (internalResult.CompletedWithError)
                                throw internalResult.AsyncException;
-                       else
-                               return internalResult.ResultingBuffer;
+
+                       byte[] result = internalResult.ResultingBuffer;
+                       record_processing.Set ();
+                       return result;
                }
 
                public byte[] ReceiveRecord(Stream record)
index ed43c9d2d7eb919a5dfeaa13324857e3ea3e75e1..988749b005bf68eac60da6a435e631655b49e608 100644 (file)
@@ -1,6 +1,6 @@
 // Transport Security Layer (TLS)
 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -39,6 +39,8 @@ namespace Mono.Security.Protocol.Tls
                
                #region Fields
 
+               static ManualResetEvent record_processing = new ManualResetEvent (true);
+
                private const int WaitTimeOut = 5 * 60 * 1000;
 
                internal Stream innerStream;
@@ -950,6 +952,7 @@ namespace Mono.Security.Protocol.Tls
 
                        lock (this.read) {
                                try {
+                                       record_processing.Reset ();
                                        // do we already have some decrypted data ?
                                        if (this.inputBuffer.Position > 0) {
                                                // or maybe we used all the buffer before ?
@@ -957,8 +960,10 @@ namespace Mono.Security.Protocol.Tls
                                                        this.inputBuffer.SetLength (0);
                                                } else {
                                                        int n = this.inputBuffer.Read (buffer, offset, count);
-                                                       if (n > 0)
+                                                       if (n > 0) {
+                                                               record_processing.Set ();
                                                                return n;
+                                                       }
                                                }
                                        }
 
@@ -969,7 +974,16 @@ namespace Mono.Security.Protocol.Tls
                                                        needMoreData = false;
                                                        // if we loop, then it either means we need more data
                                                        byte[] recbuf = new byte[16384];
-                                                       int n = innerStream.Read (recbuf, 0, recbuf.Length);
+                                                       int n = 0;
+                                                       if (count == 1) {
+                                                               int value = innerStream.ReadByte ();
+                                                               if (value >= 0) {
+                                                                       recbuf[0] = (byte) value;
+                                                                       n = 1;
+                                                               }
+                                                       } else {
+                                                               n = innerStream.Read (recbuf, 0, recbuf.Length);
+                                                       }
                                                        if (n > 0) {
                                                                // Add the new received data to the waiting data
                                                                if ((recordStream.Length > 0) && (recordStream.Position != recordStream.Length))
@@ -977,6 +991,7 @@ namespace Mono.Security.Protocol.Tls
                                                                recordStream.Write (recbuf, 0, n);
                                                        } else {
                                                                // or that the read operation is done (lost connection in the case of a network stream).
+                                                               record_processing.Set ();
                                                                return 0;
                                                        }
                                                }
@@ -1025,7 +1040,9 @@ namespace Mono.Security.Protocol.Tls
                                                        if (dataToReturn) {
                                                                // we have record(s) to return -or- no more available to read from network
                                                                // reset position for further reading
-                                                               return this.inputBuffer.Read (buffer, offset, count);
+                                                               int i = inputBuffer.Read (buffer, offset, count);
+                                                               record_processing.Set ();
+                                                               return i;
                                                        }
                                                }
                                        }