Dump() private method

private Dump ( IntPtr buffer, int offset, int length ) : void
buffer IntPtr
offset int
length int
return void
Beispiel #1
0
        /// <devdoc>
        ///    <para> Reads data from the stream. </para>
        /// </devdoc>
        public override int Read(byte[] buffer, int offset, int size)
        {
            int result = m_NetworkStream.Read(buffer, offset, size);

            GlobalLog.Dump(buffer, offset, result);
            return(result);
        }
Beispiel #2
0
        internal static byte[] EncodingRightGetBytes(string rawString)
        {
            GlobalLog.Enter("BasicClient::EncodingRightGetBytes", "[" + rawString.Length.ToString() + ":" + rawString + "]");
            //
            // in order to know if there will not be any '?' translations (which means
            // we should use the Default Encoding) we need to attempt encoding and then decoding.
            //
            GlobalLog.Print("BasicClient::EncodingRightGetBytes(): Default Encoding is:" + Encoding.Default.EncodingName);

            byte[] bytes   = Encoding.Default.GetBytes(rawString);
            string rawCopy = Encoding.Default.GetString(bytes);
            bool   canMapToCurrentCodePage = string.Compare(rawString, rawCopy, false, CultureInfo.InvariantCulture) == 0;

            GlobalLog.Print("BasicClient::EncodingRightGetBytes(): canMapToCurrentCodePage:" + canMapToCurrentCodePage.ToString());

            if (!canMapToCurrentCodePage)
            {
                throw ExceptionHelper.MethodNotSupportedException;

                /*
                 * GlobalLog.Print("BasicClient::EncodingRightGetBytes(): using:" + Encoding.UTF8.EncodingName);
                 * bytes = Encoding.UTF8.GetBytes(rawString);
                 *
                 * string blob = "=?utf-8?B?" + Convert.ToBase64String(bytes) + "?=";
                 * bytes = Encoding.ASCII.GetBytes(blob);
                 */
            }

            GlobalLog.Dump(bytes);
            GlobalLog.Leave("BasicClient::EncodingRightGetBytes", bytes.Length.ToString());

            return(bytes);
        }
Beispiel #3
0
        /// <devdoc>
        ///    <para>Writes data to the stream.</para>
        /// </devdoc>
        public override void Write(byte[] buffer, int offset, int size)
        {
            GlobalLog.Dump(buffer, offset, size);
            try {
                if (ServicePointManager.UseSafeSynchronousClose)
                {
                    int newValue = Interlocked.Increment(ref m_SynchronousIOClosingState);
                    if ((newValue & (ClosedFlag | ClosingFlag)) != 0)
                    {
                        // We don't want new IO after we started cleanup.
                        throw new ObjectDisposedException(GetType().FullName);
                    }
                }

                m_NetworkStream.Write(buffer, offset, size);
            }
            finally {
                if (ServicePointManager.UseSafeSynchronousClose && ClosingFlag == Interlocked.Decrement(ref m_SynchronousIOClosingState))
                {
                    // Close was attempted while in Write() call and no other IO is pending.
                    // Do deferred Close() now.
                    try {
                        // Attempt to close m_NetworkStream - it may not happen on this thread if another call to Read/Write
                        // increased m_SynchronousIOClosingState from another thread in the meantime
                        TryCloseNetworkStream(false, 0);
                    }
                    catch { }
                }
            }
        }
Beispiel #4
0
        internal IAsyncResult BeginMultipleWrite(BufferOffsetSize[] buffers, AsyncCallback callback, object state)
        {
#if TRAVE
            for (int i = 0; i < buffers.Length; ++i)
            {
                GlobalLog.Dump(buffers[i].Buffer, buffers[i].Offset, buffers[i].Size);
            }
#endif
            return(m_NetworkStream.BeginMultipleWrite(buffers, callback, state));
        }
Beispiel #5
0
        /// <devdoc>
        ///    <para>Writes multiple buffers at once</para>
        /// </devdoc>
        internal void MultipleWrite(BufferOffsetSize[] buffers)
        {
#if TRAVE
            for (int i = 0; i < buffers.Length; ++i)
            {
                GlobalLog.Dump(buffers[i].Buffer, buffers[i].Offset, buffers[i].Size);
            }
#endif
            m_NetworkStream.MultipleWrite(buffers);
        }
Beispiel #6
0
 private void AsyncReceiveComplete(IAsyncResult result)
 {
     GlobalLog.Enter("TlsStream#" + ValidationHelper.HashString(this) + "::AsyncReceiveComplete");
     try {
         int bytesRead = base.EndRead(result);
         GlobalLog.Print("TlsStream#" + ValidationHelper.HashString(this) + "::AsyncReceiveComplete: received " + bytesRead + " bytes");
         GlobalLog.Dump(m_AsyncResponseBuffer, bytesRead);
         NextRecord(m_AsyncResponseBuffer, bytesRead);
     } catch (Exception exception) {
         InnerException = new IOException(SR.GetString(SR.net_io_readfailure), exception);
     }
     ((NestedSingleAsyncResult)result.AsyncState).InvokeCallback(false);
     GlobalLog.Leave("TlsStream#" + ValidationHelper.HashString(this) + "::AsyncReceiveComplete");
 }
        internal static byte[] EncodingRightGetBytes(string rawString)
        {
            GlobalLog.Enter("BasicClient::EncodingRightGetBytes", "[" + rawString.Length.ToString() + ":" + rawString + "]");
            //
            // in order to know if there will not be any '?' translations (which means
            // we should use the Default Encoding) we need to attempt encoding and then decoding.
            // <STRIP>this is a limitation only on win9x, if we ever drop support for this platform there might be
            // a more efficient way of doing this.</STRIP>
            //
            GlobalLog.Print("BasicClient::EncodingRightGetBytes(): Default Encoding is:" + Encoding.Default.EncodingName);

            byte[] bytes   = Encoding.Default.GetBytes(rawString);
            string rawCopy = Encoding.Default.GetString(bytes);
            bool   canMapToCurrentCodePage = string.Compare(rawString, rawCopy, StringComparison.Ordinal) == 0;

            GlobalLog.Print("BasicClient::EncodingRightGetBytes(): canMapToCurrentCodePage:" + canMapToCurrentCodePage.ToString());

            //<STRIP>
            // if mapping to the current code page leaves characters out of the
            // [0x00, 0xFF] range, then we need to use the new encoding that IIS6.0
            // will support. do it when they decide it's good enough.
            // </STRIP>
            if (!canMapToCurrentCodePage)
            {
                //<STRIP>
                // for now throw. when IIS 6.0 adds support test it.
                //</STRIP>
                GlobalLog.LeaveException("BasicClient::EncodingRightGetBytes", ExceptionHelper.MethodNotSupportedException);
                throw ExceptionHelper.MethodNotSupportedException;

                /*
                 * GlobalLog.Print("BasicClient::EncodingRightGetBytes(): using:" + Encoding.UTF8.EncodingName);
                 * bytes = Encoding.UTF8.GetBytes(rawString);
                 *
                 * string blob = "=?utf-8?B?" + Convert.ToBase64String(bytes) + "?=";
                 * bytes = Encoding.ASCII.GetBytes(blob);
                 */
            }

            GlobalLog.Dump(bytes);
            GlobalLog.Leave("BasicClient::EncodingRightGetBytes", bytes.Length.ToString());

            return(bytes);
        }
Beispiel #8
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);
            }
        }
Beispiel #9
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);
        }
Beispiel #10
0
        private List <GCHandle> SerializeHeaders(ref UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_HEADERS headers,
                                                 bool isWebSocketHandshake)
        {
            UnsafeNclNativeMethods.HttpApi.HTTP_UNKNOWN_HEADER[] unknownHeaders = null;
            List <GCHandle> pinnedHeaders;
            GCHandle        gcHandle;

            /*
             * // here we would check for BoundaryType.Raw, in this case we wouldn't need to do anything
             * if (m_BoundaryType==BoundaryType.Raw) {
             *  return null;
             * }
             */
            GlobalLog.Print("HttpListenerResponse#" + ValidationHelper.HashString(this) + "::SerializeHeaders(HTTP_RESPONSE_HEADERS)");
            if (Headers.Count == 0)
            {
                return(null);
            }
            string headerName;
            string headerValue;
            int    lookup;

            byte[] bytes = null;
            pinnedHeaders = new List <GCHandle>();

            //---------------------------------------------------
            // DTS Issue: 609383:
            // The Set-Cookie headers are being merged into one.
            // There are two issues here.
            // 1. When Set-Cookie headers are set through SetCookie method on the ListenerResponse,
            // there is code in the SetCookie method and the methods it calls to flatten the Set-Cookie
            // values. This blindly concatenates the cookies with a comma delimiter. There could be
            // a cookie value that contains comma, but we don't escape it with %XX value
            //
            // As an alternative users can add the Set-Cookie header through the AddHeader method
            // like ListenerResponse.Headers.Add("name", "value")
            // That way they can add multiple headers - AND They can format the value like they want it.
            //
            // 2. Now that the header collection contains multiple Set-Cookie name, value pairs
            // you would think the problem would go away. However here is an interesting thing.
            // For NameValueCollection, when you add
            // "Set-Cookie", "value1"
            // "Set-Cookie", "value2"
            //  The NameValueCollection.Count == 1. Because there is only one key
            //  NameValueCollection.Get("Set-Cookie") would conviniently take these two valuess
            //  concatenate them with a comma like
            //  value1,value2.
            //  In order to get individual values, you need to use
            //  string[] values = NameValueCollection.GetValues("Set-Cookie");
            //
            //  -------------------------------------------------------------
            //  So here is the proposed fix here.
            //  We must first to loop through all the NameValueCollection keys
            //  and if the name is a unknown header, we must compute the number of
            //  values it has. Then, we should allocate that many unknown header array
            //  elements.
            //
            //  Note that a part of the fix here is to treat Set-Cookie as an unknown header
            //
            //
            //-----------------------------------------------------------
            int numUnknownHeaders = 0;

            for (int index = 0; index < Headers.Count; index++)
            {
                headerName = Headers.GetKey(index) as string;

                //See if this is an unknown header
                lookup = UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerName);

                //Treat Set-Cookie as well as Connection header in Websocket mode as unknown
                if (lookup == (int)HttpResponseHeader.SetCookie ||
                    isWebSocketHandshake && lookup == (int)HttpResponseHeader.Connection)
                {
                    lookup = -1;
                }

                if (lookup == -1)
                {
                    string[] headerValues = Headers.GetValues(index);
                    numUnknownHeaders += headerValues.Length;
                }
            }

            try
            {
                fixed(UnsafeNclNativeMethods.HttpApi.HTTP_KNOWN_HEADER *pKnownHeaders = &headers.KnownHeaders)
                {
                    for (int index = 0; index < Headers.Count; index++)
                    {
                        headerName  = Headers.GetKey(index) as string;
                        headerValue = Headers.Get(index) as string;
                        lookup      = UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerName);
                        if (lookup == (int)HttpResponseHeader.SetCookie ||
                            isWebSocketHandshake && lookup == (int)HttpResponseHeader.Connection)
                        {
                            lookup = -1;
                        }
                        GlobalLog.Print("HttpListenerResponse#" + ValidationHelper.HashString(this) + "::SerializeHeaders(" + index + "/" + Headers.Count + ") headerName:" + ValidationHelper.ToString(headerName) + " lookup:" + lookup + " headerValue:" + ValidationHelper.ToString(headerValue));
                        if (lookup == -1)
                        {
                            if (unknownHeaders == null)
                            {
                                //----------------------------------------
                                //*** This following comment is no longer true ***
                                // we waste some memory here (up to 32*41=1312 bytes) but we gain speed
                                //unknownHeaders = new UnsafeNclNativeMethods.HttpApi.HTTP_UNKNOWN_HEADER[Headers.Count-index];
                                //--------------------------------------------
                                unknownHeaders = new UnsafeNclNativeMethods.HttpApi.HTTP_UNKNOWN_HEADER[numUnknownHeaders];
                                gcHandle       = GCHandle.Alloc(unknownHeaders, GCHandleType.Pinned);
                                pinnedHeaders.Add(gcHandle);
                                headers.pUnknownHeaders = (UnsafeNclNativeMethods.HttpApi.HTTP_UNKNOWN_HEADER *)gcHandle.AddrOfPinnedObject();
                            }

                            //----------------------------------------
                            //FOR UNKNOWN HEADERS
                            //ALLOW MULTIPLE HEADERS to be added
                            //---------------------------------------
                            string[] headerValues = Headers.GetValues(index);
                            for (int headerValueIndex = 0; headerValueIndex < headerValues.Length; headerValueIndex++)
                            {
                                //Add Name
                                bytes = new byte[WebHeaderCollection.HeaderEncoding.GetByteCount(headerName)];
                                unknownHeaders[headers.UnknownHeaderCount].NameLength = (ushort)bytes.Length;
                                WebHeaderCollection.HeaderEncoding.GetBytes(headerName, 0, bytes.Length, bytes, 0);
                                gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                                pinnedHeaders.Add(gcHandle);
                                unknownHeaders[headers.UnknownHeaderCount].pName = (sbyte *)gcHandle.AddrOfPinnedObject();

                                //Add Value
                                headerValue = headerValues[headerValueIndex];
                                bytes       = new byte[WebHeaderCollection.HeaderEncoding.GetByteCount(headerValue)];
                                unknownHeaders[headers.UnknownHeaderCount].RawValueLength = (ushort)bytes.Length;
                                WebHeaderCollection.HeaderEncoding.GetBytes(headerValue, 0, bytes.Length, bytes, 0);
                                gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                                pinnedHeaders.Add(gcHandle);
                                unknownHeaders[headers.UnknownHeaderCount].pRawValue = (sbyte *)gcHandle.AddrOfPinnedObject();
                                headers.UnknownHeaderCount++;
                                GlobalLog.Print("HttpListenerResponse#" + ValidationHelper.HashString(this) + "::SerializeHeaders(Unknown) UnknownHeaderCount:" + headers.UnknownHeaderCount);
                            }
                        }
                        else
                        {
                            GlobalLog.Print("HttpListenerResponse#" + ValidationHelper.HashString(this) + "::SerializeHeaders(Known) HttpResponseHeader[" + lookup + "]:" + ((HttpResponseHeader)lookup) + " headerValue:" + ValidationHelper.ToString(headerValue));
                            if (headerValue != null)
                            {
                                bytes = new byte[WebHeaderCollection.HeaderEncoding.GetByteCount(headerValue)];
                                pKnownHeaders[lookup].RawValueLength = (ushort)bytes.Length;
                                WebHeaderCollection.HeaderEncoding.GetBytes(headerValue, 0, bytes.Length, bytes, 0);
                                gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                                pinnedHeaders.Add(gcHandle);
                                pKnownHeaders[lookup].pRawValue = (sbyte *)gcHandle.AddrOfPinnedObject();
                                GlobalLog.Print("HttpListenerResponse#" + ValidationHelper.HashString(this) + "::SerializeHeaders(Known) pRawValue:" + ValidationHelper.ToString((IntPtr)(pKnownHeaders[lookup].pRawValue)) + " RawValueLength:" + pKnownHeaders[lookup].RawValueLength + " lookup:" + lookup);
                                GlobalLog.Dump((IntPtr)pKnownHeaders[lookup].pRawValue, 0, pKnownHeaders[lookup].RawValueLength);
                            }
                        }
                    }
                }
            }
            catch {
                FreePinnedHeaders(pinnedHeaders);
                throw;
            }
            return(pinnedHeaders);
        }
Beispiel #11
0
 internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state)
 {
     GlobalLog.Dump(buffer, offset, size);
     return(m_NetworkStream.UnsafeBeginWrite(buffer, offset, size, callback, state));
 }
Beispiel #12
0
 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state)
 {
     GlobalLog.Dump(buffer, offset, size);
     return(m_NetworkStream.BeginWrite(buffer, offset, size, callback, state));
 }
Beispiel #13
0
 /// <devdoc>
 ///    <para>Writes data to the stream.</para>
 /// </devdoc>
 public override void Write(byte[] buffer, int offset, int size)
 {
     GlobalLog.Dump(buffer, offset, size);
     m_NetworkStream.Write(buffer, offset, size);
 }
        //
        // for Digest, the server will send us the blob immediately, so we need to make sure we
        // call InitializeSecurityContext() a first time with a null input buffer, otherwise
        // the next call will fail. do so here:
        // WDigest.dll requires us to pass in 3 security buffers here
        // 1) BufferType: SECBUFFER_TOKEN, Content: server's challenge (incoming)
        // 2) BufferType: SECBUFFER_PKG_PARAMS, Content: request's HTTP Method
        // 3) BufferType: SECBUFFER_PKG_PARAMS, Content: the HEntity (this would be the MD5 footprint of the request entity
        //                                                             body, we can pass in NULL as this is not required)
        //
        public string GetOutgoingDigestBlob(string incomingBlob, string requestMethod, out bool handshakeComplete)
        {
            GlobalLog.Enter("NTAuthentication::GetOutgoingDigestBlob", incomingBlob);
            //
            // first time call with null incoming buffer to initialize.
            // we should get back a 0x90312 and a null outgoingBlob.
            //
            byte[] decodedOutgoingBlob = GetOutgoingBlob(null, out handshakeComplete);
            GlobalLog.Assert(!handshakeComplete, "NTAuthentication::GetOutgoingDigestBlob() handshakeComplete==true", "");
            GlobalLog.Assert(decodedOutgoingBlob == null, "NTAuthentication::GetOutgoingDigestBlob() decodedOutgoingBlob!=null", "");
            //
            // second time call with 3 incoming buffers to select HTTP client.
            // we should get back a SecurityStatus.OK and a non null outgoingBlob.
            //
            byte[] decodedIncomingBlob  = Encoding.Default.GetBytes(incomingBlob);
            byte[] decodedRequestMethod = Encoding.Default.GetBytes(requestMethod);

            int requestedFlags =
                (int)ContextFlags.Delegate |
                (int)ContextFlags.MutualAuth |
                (int)ContextFlags.ReplayDetect |
                (int)ContextFlags.SequenceDetect |
                // (int)ContextFlags.Confidentiality | // this would only work if the server provided a qop="auth-conf" directive
                // (int)ContextFlags.ClientIntegrity | // this would only work if the server provided a qop="auth-int" directive
                (int)ContextFlags.Connection;

            SecurityBufferClass[] inSecurityBuffers = new SecurityBufferClass[] {
                new SecurityBufferClass(decodedIncomingBlob, BufferType.Token),
                new SecurityBufferClass(decodedRequestMethod, BufferType.Parameters),
                new SecurityBufferClass(null, BufferType.Parameters),
            };

            SecurityBufferClass[] outSecurityBuffers = new SecurityBufferClass[] {
                new SecurityBufferClass(m_TokenSize, BufferType.Token),
            };

            SecurityContext newSecurityContext = new SecurityContext(GlobalSSPI.SSPIAuth);

            //
            // this call is still returning an error. fix together with Kevin Damour
            //
            int status =
                SSPIWrapper.InitializeSecurityContext(
                    GlobalSSPI.SSPIAuth,
                    m_CredentialsHandle.Handle,
                    m_SecurityContext.Handle,
                    m_RemotePeerId, // this must match the Uri in the HTTP status line for the current request
                    requestedFlags,
                    m_Endianness,
                    inSecurityBuffers,
                    ref newSecurityContext.Handle,
                    outSecurityBuffers,
                    ref m_ContextFlags,
                    ref newSecurityContext.TimeStamp);

            GlobalLog.Print("NTAuthentication::GetOutgoingDigestBlob() SSPIWrapper.InitializeSecurityContext() returns 0x" + string.Format("{0:x}", status));

            int errorCode = status & unchecked ((int)0x80000000);

            if (errorCode != 0)
            {
                throw new Win32Exception(status);
            }

            //
            // the return value from SSPI will tell us correctly if the
            // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
            // we also have to consider the case in which SSPI formed a new context, in this case we're done as well.
            //
            IsCompleted = (status == (int)SecurityStatus.OK) || (m_SecurityContext.Handle != -1 && m_SecurityContext.Handle != newSecurityContext.Handle);
            if (IsCompleted)
            {
                // ... if we're done, clean the handle up or the call to UpdateHandle() might leak it.
                SSPIWrapper.DeleteSecurityContext(m_SecurityContext.m_SecModule, m_SecurityContext.Handle);
            }
            handshakeComplete = IsCompleted;
            m_Authenticated   = m_SecurityContext.Handle != -1;
            m_SecurityContext.UpdateHandle(newSecurityContext);

#if TRAVE
            if (handshakeComplete)
            {
                //
                // Kevin Damour says:
                // You should not query the securitycontext until you have actually formed one (
                // with a success return form ISC).  It is only a partially formed context and
                // no info is available to user applications (at least for digest).
                //
                SecurityPackageInfoClass securityPackageInfo = (SecurityPackageInfoClass)SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, m_SecurityContext, ContextAttribute.PackageInfo);
                GlobalLog.Print("SecurityPackageInfoClass: using:[" + ((securityPackageInfo == null)?"null":securityPackageInfo.ToString()) + "]");
            }
#endif // #if TRAVE

            GlobalLog.Assert(outSecurityBuffers.Length == 1, "NTAuthentication::GetOutgoingDigestBlob() outSecurityBuffers.Length==" + outSecurityBuffers.Length.ToString(), "");

            GlobalLog.Print("out token = " + m_TokenSize.ToString() + " size = " + outSecurityBuffers[0].size.ToString());
            GlobalLog.Dump(outSecurityBuffers[0].token);

            GlobalLog.Print("NTAuthentication::GetOutgoingDigestBlob() handshakeComplete:" + handshakeComplete.ToString());

            decodedOutgoingBlob = outSecurityBuffers[0].token;

            string outgoingBlob = null;
            if (decodedOutgoingBlob != null && decodedOutgoingBlob.Length > 0)
            {
                // CONSIDER V.NEXT
                // review Encoding.Default.GetString usage here because it might
                // end up creating non ANSI characters in the string
                outgoingBlob = Encoding.Default.GetString(decodedOutgoingBlob, 0, outSecurityBuffers[0].size);
            }

            GlobalLog.Leave("NTAuthentication::GetOutgoingDigestBlob", outgoingBlob);

            return(outgoingBlob);
        }
        //
        // NTAuth::GetOutgoingBlob()
        // Created:   12-01-1999: L.M.
        // Description:
        // Accepts an incoming binary security blob  and returns
        // an outgoing binary security blob
        //
        private byte[] GetOutgoingBlob(byte[] incomingBlob, out bool handshakeComplete)
        {
            GlobalLog.Enter("NTAuthentication::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString()) + " bytes");

            // default to true in case of failure
            handshakeComplete = true;

            if (m_SecurityContext.Handle != -1 && incomingBlob == null)
            {
                // we tried auth previously, now we got a null blob, we're done. this happens
                // with Kerberos & valid credentials on the domain but no ACLs on the resource
                // the handle for m_SecurityContext will be collected at GC time.
                GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() null blob AND m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]");
                m_SecurityContext.Close();
                IsCompleted = true;
                return(null);
            }

            int requestedFlags =
                (int)ContextFlags.Delegate |
                (int)ContextFlags.MutualAuth |
                (int)ContextFlags.ReplayDetect |
                (int)ContextFlags.SequenceDetect |
                (int)ContextFlags.Confidentiality |
                (int)ContextFlags.Connection;

            SecurityBufferClass inSecurityBuffer = null;

            if (incomingBlob != null)
            {
                GlobalLog.Print("in blob = ");
                GlobalLog.Dump(incomingBlob);
                inSecurityBuffer = new SecurityBufferClass(incomingBlob, BufferType.Token);
            }

            SecurityBufferClass outSecurityBuffer = new SecurityBufferClass(m_TokenSize, BufferType.Token);

            int status;

#if SERVER_SIDE_SSPI
            if (m_SecureSessionType == SecureSessionType.ClientSession)
            {
#endif
            //
            // client session
            //
            requestedFlags |= (int)ContextFlags.ClientIntegrity;

            status = SSPIWrapper.InitializeSecurityContext(
                GlobalSSPI.SSPIAuth,
                m_CredentialsHandle.Handle,
                m_SecurityContext.Handle,
                m_RemotePeerId,
                requestedFlags,
                m_Endianness,
                inSecurityBuffer,
                ref m_SecurityContext.Handle,
                outSecurityBuffer,
                ref m_ContextFlags,
                ref m_SecurityContext.TimeStamp
                );

            GlobalLog.Print("SSPIWrapper.InitializeSecurityContext() returns 0x" + string.Format("{0:x}", status));
#if SERVER_SIDE_SSPI
        }

        else
        {
            //
            // server session
            //
            requestedFlags |= (int)ContextFlags.ServerIntegrity;

            status = SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPIAuth,
                m_CredentialsHandle.Handle,
                m_SecurityContext.Handle,
                requestedFlags,
                m_Endianness,
                inSecurityBuffer,
                ref m_SecurityContext.Handle,
                outSecurityBuffer,
                out m_ContextFlags,
                out m_SecurityContext.TimeStamp
                );

            GlobalLog.Print("SSPIWrapper.AcceptSecurityContext() returns 0x" + string.Format("{0:x}", status));
        }
#endif // SERVER_SIDE_SSPI

            int errorCode = status & unchecked ((int)0x80000000);
            if (errorCode != 0)
            {
                throw new Win32Exception(status);
            }

            //
            // the return value from SSPI will tell us correctly if the
            // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
            // we also have to consider the case in which SSPI formed a new context, in this case we're done as well.
            //
            if (status != (int)SecurityStatus.OK && m_SecurityContext.Handle != -1)
            {
                // we need to continue
                GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() need continue status:[0x" + status.ToString("x8") + "] m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]");
                handshakeComplete = false;
            }
            else
            {
                // we're done, cleanup
                GlobalLog.Assert(status == (int)SecurityStatus.OK, "NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() status:[0x" + status.ToString("x8") + "] m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]", "[STATUS != OK]");
                m_SecurityContext.Close();
                IsCompleted = true;
            }

#if TRAVE
            if (handshakeComplete)
            {
                //
                // Kevin Damour says:
                // You should not query the securitycontext until you have actually formed one (
                // with a success return form ISC).  It is only a partially formed context and
                // no info is available to user applications (at least for digest).
                //
                SecurityPackageInfoClass securityPackageInfo = (SecurityPackageInfoClass)SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, m_SecurityContext, ContextAttribute.PackageInfo);
                GlobalLog.Print("SecurityPackageInfoClass: using:[" + ((securityPackageInfo == null)?"null":securityPackageInfo.ToString()) + "]");
            }
#endif // #if TRAVE

            GlobalLog.Print("out token = " + m_TokenSize.ToString());
            GlobalLog.Dump(outSecurityBuffer.token);

            GlobalLog.Leave("NTAuthentication::GetOutgoingBlob", "handshakeComplete:" + handshakeComplete.ToString());

            return(outSecurityBuffer.token);
        }