Assert() private method

private Assert ( bool condition, string messageFormat ) : void
condition bool
messageFormat string
return void
示例#1
0
        internal void PostPop(object newOwner)
        {
            GlobalLog.Assert(!IsEmancipated, "Pooled object not in pool.");
            GlobalLog.Assert(CanBePooled, "Pooled object is not poolable.");


            lock (this) {
                if (null == m_Owner)
                {
                    m_Owner = new WeakReference(newOwner);
                }
                else
                {
                    if (null != m_Owner.Target)
                    {
                        throw new InternalException();        // pooled connection already has an owner!
                    }
                    m_Owner.Target = newOwner;
                }

                m_PooledCount--;

                if (null != Pool)
                {
                    if (0 != m_PooledCount)
                    {
                        throw new InternalException();  // popping object off stack with multiple pooledCount
                    }
                }
                else
                {
                    if (-1 != m_PooledCount)
                    {
                        throw new InternalException();  // popping object off stack with multiple pooledCount
                    }
                }
            }
        }
示例#2
0
        private void ReadFrameCallback(IAsyncResult transportResult)
        {
            if (!(transportResult.AsyncState is WorkerAsyncResult))
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Assert("StreamFramer::ReadFrameCallback|The state expected to be WorkerAsyncResult, received:{0}.", transportResult.GetType().FullName);
                }

                Debug.Fail("StreamFramer::ReadFrameCallback|The state expected to be WorkerAsyncResult, received:" + transportResult.GetType().FullName + ".");
            }

            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            WorkerAsyncResult workerResult = (WorkerAsyncResult)transportResult.AsyncState;

            try
            {
                ReadFrameComplete(transportResult);
            }
            catch (Exception e)
            {
                if (e is OutOfMemoryException)
                {
                    throw;
                }

                if (!(e is IOException))
                {
                    e = new System.IO.IOException(SR.Format(SR.net_io_readfailure, e.Message), e);
                }

                workerResult.InvokeCallback(e);
            }
        }
        internal virtual void ConnectionCallback(object owningObject, Exception e, Socket socket, IPAddress address)
        {
            GlobalLog.Assert(owningObject == Owner || Owner == null, "PooledStream::ConnectionCallback|Owner is not the same as expected.");
            object result = null;

            if (e != null)
            {
                m_Initalizing = false;
                result        = e;
            }
            else
            {
                try {
                    m_NetworkStream.InitNetworkStream(socket, FileAccess.ReadWrite);
                    result = this;
                }
                catch (Exception ex)
                {
                    if (NclUtilities.IsFatal(ex))
                    {
                        throw;
                    }
                    result = ex;
                }
                catch {
                    throw;
                }
                m_ServerAddress = address;
                m_Initalizing   = false;
                m_JustConnected = true;
            }
            if (m_AsyncCallback != null)
            {
                m_AsyncCallback(owningObject, result);
            }
            m_AbortSocket  = null;
            m_AbortSocket6 = null;
        }
示例#4
0
        private static bool IsRecoverableAutoProxyError(int errorCode)
        {
            GlobalLog.Assert(errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER,
                             "WinHttpGetProxyForUrl() call: Error code 'Invalid parameter' should not be returned.");

            // According to WinHttp the following states can be considered "recoverable", i.e.
            // we should continue trying WinHttpGetProxyForUrl() with the provided script-location
            // (if available).
            switch ((UnsafeNclNativeMethods.WinHttp.ErrorCodes)errorCode)
            {
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AutoProxyServiceError:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.AudodetectionFailed:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.BadAutoProxyScript:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.LoginFailure:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.OperationCancelled:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.Timeout:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnableToDownloadScript:
            case UnsafeNclNativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme:
                return(true);
            }

            return(false);
        }
示例#5
0
        //
        //
        //
        private bool CheckCompletionBeforeNextRead(int bytes)
        {
            if (bytes == 0)
            {
                // 0 bytes was requested or EOF in the beginning of a frame, the caller should decide whether it's OK
                if (_TotalRead == 0)
                {
                    _Request.CompleteRequest(0);
                    return(true);
                }
                // EOF in the middle of a frame, bummer!
                throw new IOException(SR.GetString(SR.net_io_eof));
            }

            GlobalLog.Assert(_TotalRead + bytes <= _Request.Count, "FixedSizeReader::CheckCompletion()|State got out of range. Total:{0} Count:{1}", _TotalRead + bytes, _Request.Count);

            if ((_TotalRead += bytes) == _Request.Count)
            {
                _Request.CompleteRequest(_Request.Count);
                return(true);
            }
            return(false);
        }
示例#6
0
 internal unsafe SslConnectionInfo(byte[] nativeBuffer)
 {
     fixed(void *voidPtr = nativeBuffer)
     {
         try
         {
             // TODO (Issue #3114): replace with Marshal.PtrToStructure.
             IntPtr unmanagedAddress = new IntPtr(voidPtr);
             Protocol        = Marshal.ReadInt32(unmanagedAddress);
             DataCipherAlg   = Marshal.ReadInt32(unmanagedAddress, 4);
             DataKeySize     = Marshal.ReadInt32(unmanagedAddress, 8);
             DataHashAlg     = Marshal.ReadInt32(unmanagedAddress, 12);
             DataHashKeySize = Marshal.ReadInt32(unmanagedAddress, 16);
             KeyExchangeAlg  = Marshal.ReadInt32(unmanagedAddress, 20);
             KeyExchKeySize  = Marshal.ReadInt32(unmanagedAddress, 24);
         }
         catch (OverflowException)
         {
             GlobalLog.Assert(false, "SslConnectionInfo::.ctor", "Negative size.");
             throw;
         }
     }
 }
        /// <summary>
        ///    <para>Retrieves a pooled stream from the pool proper
        ///     this work by first attemting to find something in the pool on the New stack
        ///     and then trying the Old stack if something is not there availble </para>
        /// </summary>
        private PooledStream GetFromPool(object owningObject)
        {
            PooledStream res = null;

            GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool");
            res = (PooledStream)m_StackNew.Pop();
            if (null == res)
            {
                res = (PooledStream)m_StackOld.Pop();
            }

            // Shouldn't be null, we could assert here.
            GlobalLog.Assert(res != null, "GetFromPool called with nothing in the pool!");

            if (null != res)
            {
                res.PostPop(owningObject);
                GlobalLog.Print("GetFromGeneralPool pooledStream#" + ValidationHelper.HashString(res));
            }

            GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool", ValidationHelper.HashString(res));
            return(res);
        }
示例#8
0
 protected bool Activate(object owningObject, bool async, GeneralAsyncDelegate asyncCallback)
 {
     GlobalLog.Assert(owningObject == Owner || Owner == null, "PooledStream::Activate|Owner is not the same as expected.");
     try {
         if (m_Initalizing)
         {
             IPAddress address = null;
             m_AsyncCallback = asyncCallback;
             Socket socket = ServicePoint.GetConnection(this, owningObject, async, out address, ref m_AbortSocket, ref m_AbortSocket6);
             if (socket != null)
             {
                 if (Logging.On)
                 {
                     Logging.PrintInfo(Logging.Web, this,
                                       SR.GetString(SR.net_log_socket_connected, socket.LocalEndPoint,
                                                    socket.RemoteEndPoint));
                 }
                 m_NetworkStream.InitNetworkStream(socket, FileAccess.ReadWrite);
                 m_ServerAddress = address;
                 m_Initalizing   = false;
                 m_JustConnected = true;
                 m_AbortSocket   = null;
                 m_AbortSocket6  = null;
                 return(true);
             }
             return(false);
         }
         else if (async && asyncCallback != null)
         {
             asyncCallback(owningObject, this);
         }
         return(true);
     } catch {
         m_Initalizing = false;
         throw;
     }
 }
示例#9
0
        private static void ReadCallback(IAsyncResult transportResult)
        {
            if (GlobalLog.IsEnabled && !(transportResult.AsyncState is FixedSizeReader))
            {
                GlobalLog.Assert("ReadCallback|State type is wrong, expected FixedSizeReader.");
            }

            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            FixedSizeReader      reader  = (FixedSizeReader)transportResult.AsyncState;
            AsyncProtocolRequest request = reader._request;

            // Async completion.
            try
            {
                int bytes = reader._transportAPM.EndRead(transportResult);

                if (reader.CheckCompletionBeforeNextRead(bytes))
                {
                    return;
                }

                reader.StartReading();
            }
            catch (Exception e)
            {
                if (request.IsUserCompleted)
                {
                    throw;
                }

                request.CompleteWithError(e);
            }
        }
示例#10
0
        private static X509Store EnsureStoreOpened(ref X509Store storeField, StoreLocation storeLocation)
        {
            X509Store store = Volatile.Read(ref storeField);

            if (store == null)
            {
                lock (s_lockObject)
                {
                    store = Volatile.Read(ref storeField);

                    if (store == null)
                    {
                        try
                        {
                            store = new X509Store(StoreName.My, storeLocation);
                            store.Open(OpenFlags.ReadOnly);

                            Volatile.Write(ref storeField, store);

                            GlobalLog.Print(
                                "CertModule::EnsureStoreOpened() storeLocation:" + storeLocation +
                                " returned store:" + store.GetHashCode().ToString("x"));
                        }
                        catch (CryptographicException e)
                        {
                            GlobalLog.Assert(
                                "CertModule::EnsureStoreOpened()",
                                "Failed to open cert store, location:" + storeLocation + " exception:" + e);

                            throw;
                        }
                    }
                }
            }

            return(store);
        }
        internal void CloseAsIs()
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
#if DEBUG
                // If this throws it could be very bad.
                try
                {
#endif
                InnerSafeCloseSocket innerSocket = m_InnerSocket == null ? null : Interlocked.Exchange <InnerSafeCloseSocket>(ref m_InnerSocket, null);
                Close();
                if (innerSocket != null)
                {
                    // Wait until it's safe.
                    while (!m_Released)
                    {
                        Thread.SpinWait(1);
                    }

                    // Now free it with blocking.
                    innerSocket.BlockingRelease();
                }
#if DEBUG
            }
            catch (Exception exception)
            {
                if (!NclUtilities.IsFatal(exception))
                {
                    GlobalLog.Assert("SafeCloseSocket::CloseAsIs(handle:" + handle.ToString("x") + ")", exception.Message);
                }
                throw;
            }
#endif
            }
        }
示例#12
0
        public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials)
        {
            GlobalLog.Print("BasicClient::Authenticate(): " + challenge);

            GlobalLog.Assert(credentials != null, "BasicClient::Authenticate()|credentials == null");
#if !FEATURE_PAL
            if (credentials == null || credentials is SystemNetworkCredential)
            {
#else
            if (credentials == null)
            {
#endif // !FEATURE_PAL
                return(null);
            }

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "BasicClient::Authenticate()|httpWebRequest == null");
            if (httpWebRequest == null || httpWebRequest.ChallengedUri == null)
            {
                //
                // there has been no challenge:
                // 1) the request never went on the wire
                // 2) somebody other than us is calling into AuthenticationManager
                //
                return(null);
            }

            int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);
            if (index < 0)
            {
                return(null);
            }

            return(Lookup(httpWebRequest, credentials));
        }
示例#13
0
        private void BeginWriteCallback(IAsyncResult transportResult)
        {
            GlobalLog.Assert(transportResult.AsyncState is WorkerAsyncResult, "StreamFramer::BeginWriteCallback|The state expected to be WorkerAsyncResult, received:{0}.", transportResult.AsyncState.GetType().FullName);
            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            WorkerAsyncResult workerResult = (WorkerAsyncResult)transportResult.AsyncState;

            try
            {
                BeginWriteComplete(transportResult);
            }
            catch (Exception e)
            {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
                {
                    throw;
                }

                workerResult.InvokeCallback(e);
            }
        }
示例#14
0
        internal unsafe SecSizes(byte[] memory)
        {
            fixed(void *voidPtr = memory)
            {
                IntPtr unmanagedAddress = new IntPtr(voidPtr);

                try
                {
                    // TODO (Issue #3114): replace with Marshal.PtrToStructure.
                    MaxToken        = (int)checked ((uint)Marshal.ReadInt32(unmanagedAddress));
                    MaxSignature    = (int)checked ((uint)Marshal.ReadInt32(unmanagedAddress, 4));
                    BlockSize       = (int)checked ((uint)Marshal.ReadInt32(unmanagedAddress, 8));
                    SecurityTrailer = (int)checked ((uint)Marshal.ReadInt32(unmanagedAddress, 12));
                }
                catch (OverflowException)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("SecSizes::.ctor", "Negative size.");
                    }
                    throw;
                }
            }
        }
示例#15
0
            /// <summary>
            /// <para>Creates new timers.  This method is thread-safe.</para>
            /// </summary>
            internal override Timer CreateTimer(Callback callback, object context)
            {
                TimerNode timer = new TimerNode(callback, context, Duration, m_Timers);

                // Add this on the tail.  (Actually, one before the tail - m_Timers is the sentinel tail.)
                bool needProd = false;

                lock (m_Timers)
                {
                    GlobalLog.Assert(m_Timers.Prev.Next == m_Timers, "TimerThread#{0}::CreateTimer()|m_Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString());

                    // If this is the first timer in the list, we need to create a queue handle and prod the timer thread.
                    if (m_Timers.Next == m_Timers)
                    {
                        if (m_ThisHandle == IntPtr.Zero)
                        {
                            m_ThisHandle = (IntPtr)GCHandle.Alloc(this);
                        }
                        needProd = true;
                    }

                    timer.Next         = m_Timers;
                    timer.Prev         = m_Timers.Prev;
                    m_Timers.Prev.Next = timer;
                    m_Timers.Prev      = timer;
                }

                // If, after we add the new tail, there is a chance that the tail is the next
                // node to be processed, we need to wake up the timer thread.
                if (needProd)
                {
                    TimerThread.Prod();
                }

                return(timer);
            }
示例#16
0
        /// <summary>
        ///    <para>Retrieves a pooled stream from the pool proper
        ///     this work by first attemting to find something in the pool on the New stack
        ///     and then trying the Old stack if something is not there availble </para>
        /// </summary>
        private PooledStream GetFromPool(object owningObject)
        {
            PooledStream res = null;

            GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool");
            res = (PooledStream)m_StackNew.Pop();
            if (null == res)
            {
                res = (PooledStream)m_StackOld.Pop();
            }

            // The semaphore guaranteed that a connection was available so if res is
            // null it means that this contract has been violated somewhere
            GlobalLog.Assert(res != null, "GetFromPool called with nothing in the pool!");

            if (null != res)
            {
                res.PostPop(owningObject);
                GlobalLog.Print("GetFromGeneralPool pooledStream#" + ValidationHelper.HashString(res));
            }

            GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool", ValidationHelper.HashString(res));
            return(res);
        }
        /*++
         *
         *  ResponseStream - Return the response stream.
         *
         *  This property returns the response stream for this response. The
         *  response stream will do de-chunking, etc. as needed.
         *
         *  Input: Nothing. Property is readonly.
         *
         *  Returns: Response stream for response.
         *
         * --*/


        /// <devdoc>
        ///    <para>Gets the stream used for reading the body of the response from the
        ///       server.</para>
        /// </devdoc>
        public override Stream GetResponseStream()
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.Web, this, "GetResponseStream", "");
            }
            CheckDisposed();
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, "ContentLength=" + m_ContentLength);
            }

            Stream result;

            if (m_IsWebSocketResponse && m_StatusCode == HttpStatusCode.SwitchingProtocols) // HTTP 101
            {
                if (this.m_WebSocketConnectionStream == null)
                {
                    ConnectStream connectStream = m_ConnectStream as ConnectStream;
                    GlobalLog.Assert(connectStream != null, "HttpWebResponse.m_ConnectStream should always be a ConnectStream in WebSocket cases.");
                    GlobalLog.Assert(connectStream.Connection != null, "HttpWebResponse.m_ConnectStream.Connection should never be null in WebSocket cases.");
                    this.m_WebSocketConnectionStream = new WebSocketConnectionStream(connectStream, this.ConnectionGroupName);
                }
                result = this.m_WebSocketConnectionStream;
            }
            else
            {
                result = m_ConnectStream;
            }

            if (Logging.On)
            {
                Logging.Exit(Logging.Web, this, "GetResponseStream", result);
            }
            return(result);
        }
示例#18
0
        //
        // NextRecord - called typically in Callback
        //  to indicate that we need more bytes from the wire
        //  to be decrypted.  It is called either by a worker
        //  thread or by the Read directly, it reads one chunk
        //  of data, and attempts to decrypt.  As soon as it has
        //  the chunk of unencrypted data, it returns it in
        //  m_ArrivingData and m_ExistingAmount contains,
        //  the amount data that was decrypted.
        //
        // ASSUMES: we have an empty buffer of unencrypted bytes
        // RETURNS: upon error, by either leaving this buffer empty (0),
        //   with an Exception set on this object, or on success,
        //   by updating the global state (m_ArrivingData)
        //   with unencrypted bytes
        //
        // WARNING: Can Throw!
        //
        private void NextRecord(byte[] buffer, int length)
        {
            byte[] packet = null;

            GlobalLog.Assert(
                (m_ExistingAmount == 0),
                "m_ExistingAmount != 0",
                "Has assumed internal SSL buffer would be empty");

            //
            // This LOOP below will keep going until (EITHER):
            //   1) we have ONE succesful chunk of unencrypted data
            //   2) we have an error either from a renegotiate handhake (OR) Read (OR) Decrypt
            //

            do
            {
                packet = ReadFullRecord(buffer, length);

                if (packet == null)
                {
                    return;
                }

                lock (this) {
                    SecureChannel chkSecureChannel = SecureChannel;
                    if (chkSecureChannel == null)
                    {
                        return;
                    }

                    int errorCode = chkSecureChannel.Decrypt(packet, ref m_ArrivingData);

                    if (errorCode == (int)SecurityStatus.OK)
                    {
                        // SUCCESS - we have our decrypted Bytes

                        GlobalLog.Print("TlsStream::NextRecord called (success) Decrypt["
                                        + (m_ArrivingData != null
                                ? (Encoding.ASCII.GetString(m_ArrivingData, 0, Math.Min(m_ArrivingData.Length, 512)))
                                : "null")
                                        + "]");
                        break;
                    }
                    else
                    {
                        // ERROR - examine what kind

                        ProtocolToken message = new ProtocolToken(packet, errorCode);

                        GlobalLog.Print("TlsStream:: Decrypt errorCode = " + errorCode.ToString());

                        if (message.Renegotiate)
                        {
                            // HANDSHAKE - do a handshake between us and server

                            InnerException = Handshake(message);
                            if (InnerException != null)
                            {
                                return; // failure
                            }

                            // CONTINUE - Read On! we pick up from where
                            //  we were before the handshake and try to get
                            //  one block of unencrypted bytes, the earlier block
                            //  of data was control information for the handshake.

                            //  We need to read in the new header.
                            if (ForceRead(buffer, 0, length) < length)
                            {
                                InnerException = new IOException(SR.GetString(SR.net_io_readfailure));
                                return; //failure
                            }
                        }
                        else if (message.CloseConnection)
                        {
                            // CLOSE - server ordered us to shut down

                            Close(); // close down the socket
                            return;
                        }
                        else
                        {
                            // EXCEPTION - throw later on

                            InnerException = message.GetException();
                            return;
                        }
                    }
                }

                // continue here in the case where we had a handshake, and needed
                //  to reget new Data
            } while (true);

            // m_ExistingAmount was 0 on entry!

            if (m_ArrivingData == null)
            {
                return;
            }

            m_ExistingAmount = m_ArrivingData.Length;

            return;
        }
        // If abortState becomes non-zero, the attempt to find a service point has been aborted.
        internal static ServicePoint FindServicePoint(Uri address, IWebProxy proxy, out ProxyChain chain, ref HttpAbortDelegate abortDelegate, ref int abortState)
        {
            if (address == null)
            {
                throw new ArgumentNullException("address");
            }
            GlobalLog.Enter("ServicePointManager::FindServicePoint() address:" + address.ToString());

            bool isProxyServicePoint = false;

            chain = null;

            //
            // find proxy info, and then switch on proxy
            //
            Uri proxyAddress = null;

            if (proxy != null && !address.IsLoopback)
            {
                IAutoWebProxy autoProxy = proxy as IAutoWebProxy;
                if (autoProxy != null)
                {
                    chain = autoProxy.GetProxies(address);

                    // Set up our ability to abort this MoveNext call.  Note that the current implementations of ProxyChain will only
                    // take time on the first call, so this is the only place we do this.  If a new ProxyChain takes time in later
                    // calls, this logic should be copied to other places MoveNext is called.
                    GlobalLog.Assert(abortDelegate == null, "ServicePointManager::FindServicePoint()|AbortDelegate already set.");
                    abortDelegate = chain.HttpAbortDelegate;
                    try
                    {
                        Thread.MemoryBarrier();
                        if (abortState != 0)
                        {
                            Exception exception = new WebException(NetRes.GetWebStatusString(WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled);
                            GlobalLog.LeaveException("ServicePointManager::FindServicePoint() Request aborted before proxy lookup.", exception);
                            throw exception;
                        }

                        if (!chain.Enumerator.MoveNext())
                        {
                            GlobalLog.Assert("ServicePointManager::FindServicePoint()|GetProxies() returned zero proxies.");

/*
 *                          Exception exception = new WebException(NetRes.GetWebStatusString(WebExceptionStatus.RequestProhibitedByProxy), WebExceptionStatus.RequestProhibitedByProxy);
 *                          GlobalLog.LeaveException("ServicePointManager::FindServicePoint() Proxy prevented request.", exception);
 *                          throw exception;
 */
                        }
                        proxyAddress = chain.Enumerator.Current;
                    }
                    finally
                    {
                        abortDelegate = null;
                    }
                }
                else if (!proxy.IsBypassed(address))
                {
                    // use proxy support
                    // rework address
                    proxyAddress = proxy.GetProxy(address);
                }

                // null means DIRECT
                if (proxyAddress != null)
                {
                    address             = proxyAddress;
                    isProxyServicePoint = true;
                }
            }

            ServicePoint servicePoint = FindServicePointHelper(address, isProxyServicePoint);

            GlobalLog.Leave("ServicePointManager::FindServicePoint() servicePoint#" + ValidationHelper.HashString(servicePoint));
            return(servicePoint);
        }
示例#20
0
 internal InternalException()
 {
     GlobalLog.Assert("InternalException thrown.");
 }
示例#21
0
 internal SslStreamContext(SslStream sslStream)
 {
     GlobalLog.Assert(sslStream != null, "SslStreamContext..ctor(): Not expecting a null sslStream!");
     this.sslStream = sslStream;
 }
示例#22
0
        private unsafe SecurityStatus EncryptDecryptHelper(OP op, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
        {
            Interop.Secur32.SecurityBufferDescriptor sdcInOut = new Interop.Secur32.SecurityBufferDescriptor(input.Length);
            var unmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[input.Length];

            fixed(Interop.Secur32.SecurityBufferStruct *unmanagedBufferPtr = unmanagedBuffer)
            {
                sdcInOut.UnmanagedPointer = unmanagedBufferPtr;
                GCHandle[] pinnedBuffers = new GCHandle[input.Length];
                byte[][]   buffers       = new byte[input.Length][];
                try
                {
                    for (int i = 0; i < input.Length; i++)
                    {
                        SecurityBuffer iBuffer = input[i];
                        unmanagedBuffer[i].count = iBuffer.size;
                        unmanagedBuffer[i].type  = iBuffer.type;
                        if (iBuffer.token == null || iBuffer.token.Length == 0)
                        {
                            unmanagedBuffer[i].token = IntPtr.Zero;
                        }
                        else
                        {
                            pinnedBuffers[i]         = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned);
                            unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset);
                            buffers[i] = iBuffer.token;
                        }
                    }

                    // The result is written in the input Buffer passed as type=BufferType.Data.
                    int errorCode;
                    switch (op)
                    {
                    case OP.Encrypt:
                        errorCode = EncryptMessage(context, sdcInOut, sequenceNumber);
                        break;

                    case OP.Decrypt:
                        errorCode = DecryptMessage(context, sdcInOut, sequenceNumber);
                        break;

                    default: throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException);
                    }

                    // Marshalling back returned sizes / data.
                    for (int i = 0; i < input.Length; i++)
                    {
                        SecurityBuffer iBuffer = input[i];
                        iBuffer.size = unmanagedBuffer[i].count;
                        iBuffer.type = unmanagedBuffer[i].type;

                        if (iBuffer.size == 0)
                        {
                            iBuffer.offset = 0;
                            iBuffer.token  = null;
                        }
                        else
                        {
                            checked
                            {
                                // Find the buffer this is inside of.  Usually they all point inside buffer 0.
                                int j;
                                for (j = 0; j < input.Length; j++)
                                {
                                    if (buffers[j] == null)
                                    {
                                        continue;
                                    }

                                    byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0);
                                    if ((byte *)unmanagedBuffer[i].token >= bufferAddress &&
                                        (byte *)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length)
                                    {
                                        iBuffer.offset = (int)((byte *)unmanagedBuffer[i].token - bufferAddress);
                                        iBuffer.token  = buffers[j];
                                        break;
                                    }
                                }

                                if (j >= input.Length)
                                {
                                    GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range.");
                                    iBuffer.size   = 0;
                                    iBuffer.offset = 0;
                                    iBuffer.token  = null;
                                }
                            }
                        }

                        // Backup validate the new sizes.
                        GlobalLog.Assert(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length), "SSPIWrapper::EncryptDecryptHelper|'offset' out of range.  [{0}]", iBuffer.offset);
                        GlobalLog.Assert(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset), "SSPIWrapper::EncryptDecryptHelper|'size' out of range.  [{0}]", iBuffer.size);
                    }

                    if (errorCode != 0 && Logging.On)
                    {
                        if (errorCode == 0x90321)
                        {
                            Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_returned_something, op, "SEC_I_RENEGOTIATE"));
                        }
                        else
                        {
                            Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_failed_with_error, op, String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
                        }
                    }
                    return(MapToSecurityStatus((Interop.SecurityStatus)errorCode));
                }
                finally
                {
                    for (int i = 0; i < pinnedBuffers.Length; ++i)
                    {
                        if (pinnedBuffers[i].IsAllocated)
                        {
                            pinnedBuffers[i].Free();
                        }
                    }
                }
            }
        }
示例#23
0
 //
 private void StartWakeupPendingIO(object nullState)
 {
     // state must be is  null here
     GlobalLog.Assert(nullState == null, "TlsStream::StartWakeupPendingIO|Expected null state but got {0}.", nullState == null ? "null" : (nullState.GetType().FullName));
     WakeupPendingIO(null);
 }
示例#24
0
        internal bool ProcessAuthentication(LazyAsyncResult result)
        {
            bool doHandshake = false;
            bool isSyncCall  = result == null;

            lock (m_PendingIO)
            {
                // do we have handshake as already done before we grabbed a lock?
                if (m_Worker.IsAuthenticated)
                {
                    return(false);
                }

                if (m_PendingIO.Count == 0)
                {
                    doHandshake = true;
                }

                if (isSyncCall)
                {
                    // we will wait on this guy in this method for the handshake to complete
                    result = new LazyAsyncResult(this, null, null);
                }

                m_PendingIO.Add(result);
            }

            try {
                if (doHandshake)
                {
                    bool            success         = true;
                    LazyAsyncResult handshakeResult = null;
                    try
                    {
                        m_Worker.ValidateCreateContext(false,
                                                       m_DestinationHost,
                                                       m_SslProtocols,
                                                       null,
                                                       m_ClientCertificates,
                                                       true,
                                                       m_CheckCertificateRevocationList,
                                                       ServicePointManager.CheckCertificateName);


                        if (!isSyncCall)
                        {
                            // wrap a user async IO/Handshake request into auth request
                            handshakeResult = new LazyAsyncResult(m_Worker, null, new AsyncCallback(WakeupPendingIO));
#if DEBUG
                            result._DebugAsyncChain = handshakeResult;
#endif
                        }

                        //
                        // TlsStream is used by classes that manually control ExecutionContext, so set it here if we need to.
                        //
                        if (_ExecutionContext != null)
                        {
                            ExecutionContext.Run(_ExecutionContext.CreateCopy(), new ContextCallback(CallProcessAuthentication), handshakeResult);
                        }
                        else
                        {
                            m_Worker.ProcessAuthentication(handshakeResult);
                        }
                    }
                    catch
                    {
                        success = false;
                        throw;
                    }
                    finally
                    {
                        if (isSyncCall || !success)
                        {
                            lock (m_PendingIO)
                            {
                                if (m_PendingIO.Count > 1)
                                {
                                    // It was a real sync handshake (now completed) and another IO came in.
                                    // It's now waiting on us so resume.
                                    ThreadPool.QueueUserWorkItem(new WaitCallback(StartWakeupPendingIO), null);
                                }
                                else
                                {
                                    m_PendingIO.Clear();
                                }
                            }
                        }
                    }
                }
                else if (isSyncCall)
                {
                    GlobalLog.Assert(result != null, "TlsStream::ProcessAuthentication() this is a Sync call and it did not started the handshake hence null result must be wrapped into LazyAsyncResult");
                    Exception e = result.InternalWaitForCompletion() as Exception;
                    if (e != null)
                    {
                        throw e;
                    }
                }
            }
            catch {
                if (m_Worker.IsCertValidationFailed)
                {
                    m_ExceptionStatus = WebExceptionStatus.TrustFailure;
                }
                else if (m_Worker.LastSecurityStatus != SecurityStatus.OK)
                {
                    m_ExceptionStatus = WebExceptionStatus.SecureChannelFailure;
                }
                else
                {
                    m_ExceptionStatus = WebExceptionStatus.ReceiveFailure;
                }
                throw;
            }

            // Here in the async case a user IO has been queued (and may be already completed)
            // For sync case it does not matter since the caller will resume IO upon return
            return(true);
        }
示例#25
0
        //
        // Security: We temporarily reset thread token to open the cert store under process account.
        //
        internal override X509Store EnsureStoreOpened(bool isMachineStore)
        {
            X509Store store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx;

            if (store == null)
            {
                lock (s_syncObject)
                {
                    store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx;
                    if (store == null)
                    {
                        // NOTE: that if this call fails we won't keep track and the next time we enter we will try to open the store again.
                        StoreLocation storeLocation = isMachineStore ? StoreLocation.LocalMachine : StoreLocation.CurrentUser;
                        store = new X509Store(StoreName.My, storeLocation);
                        try
                        {
                            // For app-compat We want to ensure the store is opened under the **process** account.
                            try
                            {
                                WindowsIdentity.RunImpersonated(SafeAccessTokenHandle.InvalidHandle, () =>
                                {
                                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                                    GlobalLog.Print("SecureChannel::EnsureStoreOpened() storeLocation:" + storeLocation + " returned store:" + store.GetHashCode().ToString("x"));
                                });
                            }
                            catch
                            {
                                throw;
                            }

                            if (isMachineStore)
                            {
                                s_myMachineCertStoreEx = store;
                            }
                            else
                            {
                                s_myCertStoreEx = store;
                            }

                            return(store);
                        }
                        catch (Exception exception)
                        {
                            if (exception is CryptographicException || exception is SecurityException)
                            {
                                GlobalLog.Assert("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception);
                                return(null);
                            }

                            if (Logging.On)
                            {
                                Logging.PrintError(Logging.Web, SR.Format(SR.net_log_open_store_failed, storeLocation, exception));
                            }

                            throw;
                        }
                    }
                }
            }
            return(store);
        }
示例#26
0
        //
        // ReadFullRecord - reads a block of bytes,
        //  attemps to ascertain, how much to read, by
        //  assuming block encoding of the byte stream.
        //
        // This can be dangerous as these things
        //   tend to change from protocol to protocol
        //
        // WARNING: Can throw!
        //
        public byte[] ReadFullRecord(byte[] buffer, int length)
        {
            // after shutdown/Close throw an exception
            if (m_ShutDown > 0)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            SecureChannel chkSecureChannel = SecureChannel;

            if (chkSecureChannel == null)
            {
                return(null);
            }
            int headerSize = chkSecureChannel.HeaderSize;

            byte[] header = new byte[headerSize];
            int    read   = length;

            if (buffer != null)
            {
                GlobalLog.Assert(length <= headerSize, "length > headerSize", "");
                Buffer.BlockCopy(buffer, 0, header, 0, Math.Min(length, headerSize));
            }
            if (length < headerSize)
            {
                GlobalLog.Print("RecordLayer::ReadFullRecord Reading " + headerSize + " byte header from the stream");
                read += ForceRead(header, length, headerSize - length);
            }
            GlobalLog.Dump(header);
            if (read != headerSize)
            {
                GlobalLog.Print("RecordLayer::ReadFullRecord returning null");
                return(null);
            }

            // if we can't verify, just return what we can find

            if (!verifyRecordFormat(header))
            {
                return(header);
            }

            // WARNING this line, I find worrisome, because it
            //  can differ on new protocols
            int payloadSize = (0x100 * header[3]) + header[4];

            byte[] record = new byte[payloadSize + headerSize];
            Buffer.BlockCopy(header, 0, record, 0, headerSize);

            int received = ForceRead(record, headerSize, payloadSize);

            GlobalLog.Dump(record);

            if (received < payloadSize)
            {
                GlobalLog.Print("RecordLayer::ReadFullRecord returning null");
                return(null);
            }

            return(record);
        }
示例#27
0
        //
        // Handshake - the Handshake is perhaps the most important part of the SSL process,
        //  this is a Handshake protocol between server & client, where we send a
        //  a HELLO message / server responds, we respond back, and after a few round trips,
        //  we have an SSL connection with the server.  But this process may be repeated,
        //  if a higher level of security is required for by the server, therefore,
        //  this function may be called several times in the life of the connection.
        //
        //  returns an Exception on error, containing the error code of the failure
        //

        private Exception Handshake(ProtocolToken message)
        {
            //
            // With some SSPI APIs, the SSPI wrapper may throw
            //  uncaught Win32Exceptions, so we need to add
            //  this try - catch here.
            //

            try {
                int    round    = 0;
                byte[] incoming = null;

                // will be null == message on connection creation/otherwise should be
                //  renegotation

                if (message == null)
                {
                    GlobalLog.Assert(
                        (SecureChannel == null),
                        "had assembed a null SecureChannel at this point",
                        "SecureChannel != null");

                    m_SecureChannel = new SecureChannel(m_DestinationHost, m_ClientCertificates);
                }
                else
                {
                    incoming = message.Payload;
                }

                do
                {
                    GlobalLog.Print("Handshake::Round #" + round);

                    //
                    // this code runs in the constructor, hence there's no
                    // way SecureChannel can become null
                    //
                    message = SecureChannel.NextMessage(incoming);

#if TRAVE
                    GlobalLog.Print("Handshake::generating TLS message(Status:" + SecureChannel.MapSecurityStatus((uint)message.Status) + " Done:" + message.Done.ToString() + ")");
#endif

                    if (message.Failed)
                    {
                        break;
                    }

                    if (message.Payload != null)
                    {
                        GlobalLog.Print("Handshake::Outgoing message size: " + message.Payload.Length);
                        GlobalLog.Dump(message.Payload);
                        base.Write(message.Payload, 0, message.Payload.Length);
                    }
                    else
                    {
                        GlobalLog.Print("Handshake::No message necessary.");
                    }

                    if (message.Done)
                    {
                        break;
                    }

                    //
                    // ReadFullRecord attempts to parse read data
                    //   from the byte stream, this can be dangerous as its not
                    //   always sure about protocols, at this point
                    //

                    incoming = ReadFullRecord(null, 0);

                    if (incoming == null)
                    {
                        //
                        // Handshake failed
                        //
                        GlobalLog.Print("Handshake::ReadFullRecord is null, Handshake failed");

                        GlobalLog.Assert(
                            (!message.Done),
                            "attempted bad return / must always fail",
                            "message.Done");

                        return(message.GetException());
                    }

                    GlobalLog.Print("Handshake::Incoming message size: " + incoming.Length);
                    round++;
                } while (!message.Done);

                if (message.Done)
                {
                    SecureChannel.ProcessHandshakeSuccess();
                    GlobalLog.Print("Handshake::Handshake completed successfully.");
                }
                else
                {
                    // SEC_I_CONTINUE_NEEDED
#if TRAVE
                    GlobalLog.Print("Handshake::FAILED Handshake, last error: " + SecureChannel.MapSecurityStatus((uint)message.Status));
#endif
                }
                return(message.GetException());
            }
            catch (Exception exception) {
                return(exception);
            }
        }
示例#28
0
        //
        // Used only by client SSL code, never returns null.
        //
        internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
        {
            Interop.SspiCli.IssuerListInfoEx issuerList =
                (Interop.SspiCli.IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(
                    GlobalSSPI.SSPISecureChannel,
                    securityContext,
                    Interop.SspiCli.ContextAttribute.IssuerListInfoEx);

            string[] issuers = Array.Empty <string>();

            try
            {
                if (issuerList.cIssuers > 0)
                {
                    unsafe
                    {
                        uint count = issuerList.cIssuers;
                        issuers = new string[issuerList.cIssuers];
                        Interop.SspiCli._CERT_CHAIN_ELEMENT *pIL = (Interop.SspiCli._CERT_CHAIN_ELEMENT *)issuerList.aIssuers.DangerousGetHandle();
                        for (int i = 0; i < count; ++i)
                        {
                            Interop.SspiCli._CERT_CHAIN_ELEMENT *pIL2 = pIL + i;
                            if (pIL2->cbSize <= 0)
                            {
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Assert("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString());
                                }

                                Debug.Fail("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString());
                            }

                            if (pIL2->cbSize > 0)
                            {
                                uint   size = pIL2->cbSize;
                                byte * ptr  = (byte *)(pIL2->pCertContext);
                                byte[] x    = new byte[size];
                                for (int j = 0; j < size; j++)
                                {
                                    x[j] = *(ptr + j);
                                }

                                X500DistinguishedName x500DistinguishedName = new X500DistinguishedName(x);
                                issuers[i] = x500DistinguishedName.Name;
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Print("SecureChannel#" + LoggingHash.HashString(securityContext) + "::GetIssuers() IssuerListEx[" + i + "]:" + issuers[i]);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                if (issuerList.aIssuers != null)
                {
                    issuerList.aIssuers.Dispose();
                }
            }

            return(issuers);
        }
示例#29
0
        //Caution, this will return ipv6 addresses if the OS supports it.  This shouldn't be called by the public apis.
        internal static IPHostEntry InternalResolveFast(string hostName, int timeout, out bool timedOut)
        {
            GlobalLog.Assert(hostName != null, "hostName == null");
            GlobalLog.Print("Dns.InternalResolveFase: " + hostName);

            //
            // the differences between this method and the previous InternalResolve() are:
            //
            // 1) we don't throw any exceptions
            // 2) we don't do a reverse lookup for address strings, we just use them
            //
            // IPv6 Changes: It is not practical to embed the code for GetAddrInfo here, instead
            //               we call it and catch any exceptions.
            //
            // Timeout: Supports a timeout by offloading work to another thread if necessary.
            //

            // We can't abort a DNS lookup so if we think might need to, run it on another thread.
            // According to MSDN the max time is 17 seconds.  Use 18 and say 20.
            // Also: MSDN describes how one lookup can result in a string of queries.  It's unclear whether
            // those would be run in series, extending the possible time this will take, or whether it will always
            // give up after 17 seconds.  For now assume that 17 seconds is the absolute max.
            bool mightTimeOut = 18000 >= (uint)timeout && timeout != Timeout.Infinite;

            timedOut = false;

            if (hostName.Length > 0 && hostName.Length <= MaxHostName)
            {
                // IP Address?
                IPAddress address;
                if (TryParseAsIP(hostName, out address))
                {
                    IPHostEntry ipHostEntry = new IPHostEntry();
                    ipHostEntry.HostName    = address.ToString();
                    ipHostEntry.Aliases     = new string[0];
                    ipHostEntry.AddressList = new IPAddress[] { address };

                    GlobalLog.Print("Dns::InternalResolveFast() returned address:" + address.ToString());
                    return(ipHostEntry);
                }

                // Looks like a hostname (or failed address parsing)
                if (Socket.OSSupportsIPv6)
                {
                    try
                    {
                        // we will no longer offload to a thread, due to the consequence of having a threadpool thread
                        //block on another threadpool thread.  In addition, even w/ the DNS server functioning, we run
                        // the risk of having too many of these queued up, causing requests to fail w/ an unable to resolve
                        //exception.

                        //I'm leaving the code commented out to possibly reuse in our async case.

                        // if (!mightTimeOut)
                        // {
                        return(GetAddrInfo(hostName));
                        // }

                        /* else
                         * {
                         *   AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                         *   dnsContext.Offload(new WaitCallback(OffloadedGetAddrInfo));
                         *   return (IPHostEntry) dnsContext.Wait(timeout, out timedOut);
                         * }
                         */
                    }
                    catch (Exception e)
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() GetAddrInfo() threw: " + e.Message);
                    }
                }
                else
                {
                    //
                    // we duplicate the code in GetHostByName() to avoid
                    // having to catch the thrown exception
                    //
                    IntPtr nativePointer;
                    //if (!mightTimeOut)
                    //{
                    nativePointer = UnsafeNclNativeMethods.OSSOCK.gethostbyname(hostName);
                    //}

                    /*
                     * else
                     * {
                     *  AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                     *  dnsContext.Offload(new WaitCallback(OffloadedGetHostByName));
                     *  object result = dnsContext.Wait(timeout, out timedOut);
                     *  nativePointer = result == null ? IntPtr.Zero : (IntPtr) result;
                     * }
                     */
                    if (nativePointer != IntPtr.Zero)
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() gethostbyname() returned nativePointer:" + nativePointer.ToString());
                        return(NativeToHostEntry(nativePointer));
                    }
                }
            }

            GlobalLog.Print("Dns::InternalResolveFast() returning null");
            if (Logging.On)
            {
                Logging.Exit(Logging.Sockets, "DNS", "InternalResolveFast", null);
            }
            return(null);
        }
示例#30
0
        //
        // Security: We temporarily reset thread token to open the cert store under process account.
        //
        internal static X509Store EnsureStoreOpened(bool isMachineStore)
        {
            X509Store store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx;

            // TODO #3862 Investigate if this can be switched to either the static or Lazy<T> patterns.
            if (Volatile.Read(ref store) == null)
            {
                lock (s_syncObject)
                {
                    store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx;
                    if (Volatile.Read(ref store) == null)
                    {
                        // NOTE: that if this call fails we won't keep track and the next time we enter we will try to open the store again.
                        StoreLocation storeLocation = isMachineStore ? StoreLocation.LocalMachine : StoreLocation.CurrentUser;
                        store = new X509Store(StoreName.My, storeLocation);
                        try
                        {
                            // For app-compat We want to ensure the store is opened under the **process** account.
                            try
                            {
                                WindowsIdentity.RunImpersonated(SafeAccessTokenHandle.InvalidHandle, () =>
                                {
                                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                                    if (GlobalLog.IsEnabled)
                                    {
                                        GlobalLog.Print("SecureChannel::EnsureStoreOpened() storeLocation:" + storeLocation + " returned store:" + store.GetHashCode().ToString("x"));
                                    }
                                });
                            }
                            catch
                            {
                                throw;
                            }

                            if (isMachineStore)
                            {
                                s_myMachineCertStoreEx = store;
                            }
                            else
                            {
                                s_myCertStoreEx = store;
                            }

                            return(store);
                        }
                        catch (Exception exception)
                        {
                            if (exception is CryptographicException || exception is SecurityException)
                            {
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Assert("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception);
                                }

                                Debug.Fail("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception);
                                return(null);
                            }

                            if (NetEventSource.Log.IsEnabled())
                            {
                                NetEventSource.PrintError(NetEventSource.ComponentType.Security, SR.Format(SR.net_log_open_store_failed, storeLocation, exception));
                            }

                            throw;
                        }
                    }
                }
            }

            return(store);
        }