示例#1
0
        //
        // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte.
        //
        private int StartReading(byte[] buffer, int offset, int count)
        {
            int result = 0;

            if (GlobalLog.IsEnabled && InternalBufferCount != 0)
            {
                GlobalLog.AssertFormat("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:{0}", InternalBufferCount);
            }

            do
            {
                int copyBytes = _SslState.CheckEnqueueRead(buffer, offset, count, null);
                if (copyBytes == 0)
                {
                    //Queued but not completed!
                    return(0);
                }

                if (copyBytes != -1)
                {
                    return(copyBytes);
                }
            }
            // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping.
            while ((result = StartFrameHeader(buffer, offset, count)) == -1);

            return(result);
        }
示例#2
0
        private void LogBuffer(int size)
        {
            if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled)
            {
                GlobalLog.AssertFormat("OverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this));
            }

            if (size > -1)
            {
                if (_wsaBuffers != null)
                {
                    foreach (WSABuffer wsaBuffer in _wsaBuffers)
                    {
                        SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, wsaBuffer.Pointer, Math.Min(wsaBuffer.Length, size));
                        if ((size -= wsaBuffer.Length) <= 0)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, _singleBuffer.Pointer, Math.Min(_singleBuffer.Length, size));
                }
            }
        }
示例#3
0
 private void LogBuffer(int size)
 {
     if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled)
     {
         GlobalLog.AssertFormat("ReceiveMessageOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this));
     }
     SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, _wsaBuffer->Pointer, Math.Min(_wsaBuffer->Length, size));
 }
示例#4
0
        private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            if (readBytes == 0)
            {
                //EOF
                if (asyncRequest != null)
                {
                    asyncRequest.CompleteUser((object)0);
                }
                return(0);
            }

            if ((readBytes == _ReadHeader.Length) && GlobalLog.IsEnabled)
            {
                GlobalLog.AssertFormat("NegoStream::ProcessHeader()|Frame size must be 4 but received {0} bytes.", readBytes);
            }

            // Replace readBytes with the body size recovered from the header content.
            readBytes = _ReadHeader[3];
            readBytes = (readBytes << 8) | _ReadHeader[2];
            readBytes = (readBytes << 8) | _ReadHeader[1];
            readBytes = (readBytes << 8) | _ReadHeader[0];

            //
            // The body carries 4 bytes for trailer size slot plus trailer, hence <=4 frame size is always an error.
            // Additionally we'd like to restrict the read frame size to 64k.
            //
            if (readBytes <= 4 || readBytes > NegoState.MaxReadFrameSize)
            {
                throw new IOException(SR.net_frame_read_size);
            }

            //
            // Always pass InternalBuffer for SSPI "in place" decryption.
            // A user buffer can be shared by many threads in that case decryption/integrity check may fail cause of data corruption.
            //
            EnsureInternalBufferSize(readBytes);
            if (asyncRequest != null)
            {
                asyncRequest.SetNextRequest(InternalBuffer, 0, readBytes, s_readCallback);

                _FrameReader.AsyncReadPacket(asyncRequest);

                if (!asyncRequest.MustCompleteSynchronously)
                {
                    return(0);
                }

                readBytes = asyncRequest.Result;
            }
            else //Sync
            {
                readBytes = _FrameReader.ReadPacket(InternalBuffer, 0, readBytes);
            }

            return(ProcessFrameBody(readBytes, buffer, offset, count, asyncRequest));
        }
示例#5
0
 private void LogBuffer(int size)
 {
     if (!SocketsEventSource.Log.IsEnabled())
     {
         if (GlobalLog.IsEnabled)
         {
             GlobalLog.AssertFormat("ReceiveMessageOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this));
         }
         Debug.Fail("ReceiveMessageOverlappedAsyncResult#" + LoggingHash.HashString(this) + "::LogBuffer()|Logging is off!");
     }
     SocketsEventSource.Dump(_wsaBuffer->Pointer, Math.Min(_wsaBuffer->Length, size));
 }
示例#6
0
            // This method is implicitly reliable and called from a CER.
            protected override bool ReleaseHandle()
            {
                bool ret = false;

#if DEBUG
                try
                {
#endif
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")");
                }

                SocketError errorCode = InnerReleaseHandle();
                return(ret = errorCode == SocketError.Success);

#if DEBUG
            }

            catch (Exception exception)
            {
                if (!ExceptionCheck.IsFatal(exception))
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")", exception.Message);
                    }
                    Debug.Fail("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")", exception.Message);
                }
                ret = true;      // Avoid a second assert.
                throw;
            }
            finally
            {
                _closeSocketThread = Environment.CurrentManagedThreadId;
                _closeSocketTick   = Environment.TickCount;
                if (!ret)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.AssertFormat("SafeCloseSocket::ReleaseHandle(handle:{0:x})|ReleaseHandle failed.", handle);
                    }
                    Debug.Fail("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")|ReleaseHandle failed.");
                }
            }
#endif
            }
示例#7
0
        //
        // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte.
        //
        private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            int result = 0;

            if (InternalBufferCount != 0)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.AssertFormat("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:{0}", InternalBufferCount);
                }

                Debug.Fail("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:" + InternalBufferCount);
            }

            do
            {
                if (asyncRequest != null)
                {
                    asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncReadCallback);
                }

                int copyBytes = _sslState.CheckEnqueueRead(buffer, offset, count, asyncRequest);
                if (copyBytes == 0)
                {
                    // Queued but not completed!
                    return(0);
                }

                if (copyBytes != -1)
                {
                    if (asyncRequest != null)
                    {
                        asyncRequest.CompleteUser((object)copyBytes);
                    }

                    return(copyBytes);
                }
            }
            // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping.
            while ((result = StartFrameHeader(buffer, offset, count, asyncRequest)) == -1);

            return(result);
        }
示例#8
0
        private Authorization SetContextAndTryAuthenticate(ISmtpAuthenticationModule module, NetworkCredential credential, ContextAwareResult context)
        {
            // We may need to restore user thread token here
            if (ReferenceEquals(credential, CredentialCache.DefaultNetworkCredentials))
            {
#if DEBUG
                if (context != null && !context.IdentityRequested)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.AssertFormat("SmtpConnection#{0}::SetContextAndTryAuthenticate|Authentication required when it wasn't expected.  (Maybe Credentials was changed on another thread?)", LoggingHash.HashString(this));
                    }

                    Debug.Fail("SmtpConnection#" + LoggingHash.HashString(this) + "::SetContextAndTryAuthenticate|Authentication required when it wasn't expected.  (Maybe Credentials was changed on another thread?)");
                }
#endif

                try
                {
                    ExecutionContext x = context == null ? null : context.ContextCopy;
                    if (x != null)
                    {
                        AuthenticateCallbackContext authenticationContext =
                            new AuthenticateCallbackContext(this, module, credential, _client.TargetName, _channelBindingToken);

                        ExecutionContext.Run(x, s_AuthenticateCallback, authenticationContext);
                        return(authenticationContext._result);
                    }
                    else
                    {
                        return(module.Authenticate(null, credential, this, _client.TargetName, _channelBindingToken));
                    }
                }
                catch
                {
                    // Prevent the impersonation from leaking to upstack exception filters.
                    throw;
                }
            }

            return(module.Authenticate(null, credential, this, _client.TargetName, _channelBindingToken));
        }
        private void LogBuffer(long size)
        {
            if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled)
            {
                GlobalLog.AssertFormat("AcceptOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this));
            }
            IntPtr pinnedBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0);

            if (pinnedBuffer != IntPtr.Zero)
            {
                if (size > -1)
                {
                    SocketsEventSource.Dump(pinnedBuffer, (int)Math.Min(size, (long)_buffer.Length));
                }
                else
                {
                    SocketsEventSource.Dump(pinnedBuffer, (int)_buffer.Length);
                }
            }
        }
示例#10
0
        private unsafe static void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
        {
#if DEBUG
            GlobalLog.SetThreadSource(ThreadKinds.CompletionPort);
            using (GlobalLog.SetThreadKind(ThreadKinds.System))
            {
#endif
            BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped);

            object returnObject = null;

            if (asyncResult.InternalPeekCompleted)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|asyncResult.IsCompleted", LoggingHash.HashString(asyncResult));
                }
                Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|asyncResult.IsCompleted");
            }
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print(
                    "BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback" +
                    " errorCode:" + errorCode.ToString() +
                    " numBytes:" + numBytes.ToString() +
                    " pOverlapped:" + ((int)nativeOverlapped).ToString());
            }

            // Complete the IO and invoke the user's callback.
            SocketError socketError = (SocketError)errorCode;

            if (socketError != SocketError.Success && socketError != SocketError.OperationAborted)
            {
                // There are cases where passed errorCode does not reflect the details of the underlined socket error.
                // "So as of today, the key is the difference between WSAECONNRESET and ConnectionAborted,
                //  .e.g remote party or network causing the connection reset or something on the local host (e.g. closesocket
                // or receiving data after shutdown (SD_RECV)).  With Winsock/TCP stack rewrite in longhorn, there may
                // be other differences as well."

                Socket socket = asyncResult.AsyncObject as Socket;
                if (socket == null)
                {
                    socketError = SocketError.NotSocket;
                }
                else if (socket.CleanedUp)
                {
                    socketError = SocketError.OperationAborted;
                }
                else
                {
                    try
                    {
                        // The async IO completed with a failure.
                        // Here we need to call WSAGetOverlappedResult() just so Marshal.GetLastWin32Error() will return the correct error.
                        SocketFlags ignore;
                        bool        success = Interop.Winsock.WSAGetOverlappedResult(
                            socket.SafeHandle,
                            asyncResult.NativeOverlapped,
                            out numBytes,
                            false,
                            out ignore);
                        if (!success)
                        {
                            socketError = (SocketError)Marshal.GetLastWin32Error();
                            if (socketError == 0)
                            {
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|socketError:0 numBytes:{1}", LoggingHash.HashString(asyncResult), numBytes);
                                }
                                Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|socketError:0 numBytes:" + numBytes);
                            }
                        }

                        if (success)
                        {
                            if (GlobalLog.IsEnabled)
                            {
                                GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|Unexpectedly succeeded. errorCode:{1} numBytes:{2}", LoggingHash.HashString(asyncResult), errorCode, numBytes);
                            }
                            Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|Unexpectedly succeeded. errorCode:" + errorCode + " numBytes: " + numBytes);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        // CleanedUp check above does not always work since this code is subject to race conditions
                        socketError = SocketError.OperationAborted;
                    }
                }
            }
            asyncResult.ErrorCode = (int)socketError;
            returnObject          = asyncResult.PostCompletion((int)numBytes);
            asyncResult.ReleaseUnmanagedStructures();
            asyncResult.InvokeCallback(returnObject);
#if DEBUG
        }
#endif
        }