GetOutgoingBlob() private method

private GetOutgoingBlob ( byte incomingBlob, bool thrownOnError ) : byte[]
incomingBlob byte
thrownOnError bool
return byte[]
        public bool Update(string challenge, WebRequest webRequest)
        {
            HttpWebRequest   request         = webRequest as HttpWebRequest;
            NTAuthentication securityContext = request.CurrentAuthenticationState.GetSecurityContext(this);

            if (securityContext != null)
            {
                if (!securityContext.IsCompleted && (request.CurrentAuthenticationState.StatusCodeMatch == request.ResponseStatusCode))
                {
                    return(false);
                }
                if (!request.UnsafeOrProxyAuthenticatedConnectionSharing)
                {
                    request.ServicePoint.ReleaseConnectionGroup(request.GetConnectionGroupLine());
                }
                bool flag = true;
                int  num  = (challenge == null) ? -1 : GetSignatureIndex(challenge, out flag);
                if (num >= 0)
                {
                    int    startIndex   = num + (flag ? "nego2".Length : "negotiate".Length);
                    string incomingBlob = null;
                    if ((challenge.Length > startIndex) && (challenge[startIndex] != ','))
                    {
                        startIndex++;
                    }
                    else
                    {
                        num = -1;
                    }
                    if ((num >= 0) && (challenge.Length > startIndex))
                    {
                        incomingBlob = challenge.Substring(startIndex);
                    }
                    securityContext.GetOutgoingBlob(incomingBlob);
                    request.CurrentAuthenticationState.Authorization.MutuallyAuthenticated = securityContext.IsMutualAuthFlag;
                }
                request.ServicePoint.SetCachedChannelBinding(request.ChallengedUri, securityContext.ChannelBinding);
                this.ClearSession(request);
            }
            return(true);
        }
Beispiel #2
0
        public bool Update(string challenge, WebRequest webRequest)
        {
            HttpWebRequest   request         = webRequest as HttpWebRequest;
            NTAuthentication securityContext = request.CurrentAuthenticationState.GetSecurityContext(this);

            if (securityContext != null)
            {
                if (request.CurrentAuthenticationState.StatusCodeMatch == request.ResponseStatusCode)
                {
                    return(false);
                }
                int num = (challenge == null) ? -1 : AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);
                if (num >= 0)
                {
                    int    startIndex   = num + SignatureSize;
                    string incomingBlob = null;
                    if ((challenge.Length > startIndex) && (challenge[startIndex] != ','))
                    {
                        startIndex++;
                    }
                    else
                    {
                        num = -1;
                    }
                    if ((num >= 0) && (challenge.Length > startIndex))
                    {
                        incomingBlob = challenge.Substring(startIndex);
                    }
                    securityContext.GetOutgoingBlob(incomingBlob);
                    request.CurrentAuthenticationState.Authorization.MutuallyAuthenticated = securityContext.IsMutualAuthFlag;
                }
                request.ServicePoint.SetCachedChannelBinding(request.ChallengedUri, securityContext.ChannelBinding);
                this.ClearSession(request);
            }
            return(true);
        }
        //
        // called when getting the final blob on the 200 OK from the server
        //
        public bool Update(string challenge, WebRequest webRequest)
        {
            GlobalLog.Print("KerberosClient::Update(): " + challenge);

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "KerberosClient::Update() httpWebRequest==null", "");
            GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "KerberosClient::Update() httpWebRequest.ChallengedUri==null", "");

            //
            // try to retrieve the state of the ongoing handshake
            //
            NTAuthentication authSession = sessions[httpWebRequest.CurrentAuthenticationState] as NTAuthentication;

            GlobalLog.Print("KerberosClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));

            if (authSession == null)
            {
                GlobalLog.Print("KerberosClient::Update() null session returning true");
                return(true);
            }

            GlobalLog.Print("KerberosClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString());

            if (httpWebRequest.CurrentAuthenticationState.StatusCodeMatch == httpWebRequest.ResponseStatusCode)
            {
                GlobalLog.Print("KerberosClient::Update() still handshaking (based on status code) returning false");
                return(false);
            }

            //
            // the whole point here is to remove the session, so do it right away, and then try
            // to close the Security Context (this will complete the authentication handshake
            // with server authentication for schemese that support it such as Kerberos)
            //
            GlobalLog.Print("KerberosClient::Update() removing authSession:" + ValidationHelper.HashString(authSession) + " from:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState));
            sessions.Remove(httpWebRequest.CurrentAuthenticationState);

            int index = challenge == null ? -1 : AuthenticationManager.FindSubstringNotInQuotes(challenge.ToLower(CultureInfo.InvariantCulture), Signature);

            if (index < 0)
            {
                return(true);
            }

            int    blobBegin = index + SignatureSize;
            string incoming  = null;

            //
            // there may be multiple challenges. If the next character after the
            // package name is not a comma then it is challenge data
            //
            if (challenge.Length > blobBegin && challenge[blobBegin] != ',')
            {
                ++blobBegin;
            }
            else
            {
                index = -1;
            }
            if (index >= 0 && challenge.Length > blobBegin)
            {
                incoming = challenge.Substring(blobBegin);
            }

            GlobalLog.Print("KerberosClient::Update() closing security context using last incoming blob:[" + ValidationHelper.ToString(incoming) + "]");

            bool   handshakeComplete;
            string clientResponse = authSession.GetOutgoingBlob(incoming, out handshakeComplete);

            GlobalLog.Print("KerberosClient::Update() GetOutgoingBlob() returns clientResponse:[" + ValidationHelper.ToString(clientResponse) + "] handshakeComplete:" + handshakeComplete.ToString());
            return(true);
        }
        internal unsafe HttpListenerContext HandleAuthentication(RequestContextBase memoryBlob, out bool stoleBlob)
        {
            string challenge = null;
            HttpListenerContext context3;
            stoleBlob = false;
            string verb = UnsafeNclNativeMethods.HttpApi.GetVerb(memoryBlob.RequestBlob);
            string knownHeader = UnsafeNclNativeMethods.HttpApi.GetKnownHeader(memoryBlob.RequestBlob, 0x18);
            ulong connectionId = memoryBlob.RequestBlob.ConnectionId;
            ulong requestId = memoryBlob.RequestBlob.RequestId;
            bool isSecureConnection = memoryBlob.RequestBlob.pSslInfo != null;
            DisconnectAsyncResult disconnectResult = (DisconnectAsyncResult) this.DisconnectResults[connectionId];
            if (this.UnsafeConnectionNtlmAuthentication)
            {
                if (knownHeader == null)
                {
                    WindowsPrincipal principal = (disconnectResult == null) ? null : disconnectResult.AuthenticatedConnection;
                    if (principal != null)
                    {
                        stoleBlob = true;
                        HttpListenerContext context = new HttpListenerContext(this, memoryBlob);
                        context.SetIdentity(principal, null);
                        context.Request.ReleasePins();
                        return context;
                    }
                }
                else if (disconnectResult != null)
                {
                    disconnectResult.AuthenticatedConnection = null;
                }
            }
            stoleBlob = true;
            HttpListenerContext context2 = null;
            NTAuthentication digestContext = null;
            NTAuthentication newContext = null;
            NTAuthentication authentication3 = null;
            System.Net.AuthenticationSchemes none = System.Net.AuthenticationSchemes.None;
            System.Net.AuthenticationSchemes authenticationSchemes = this.AuthenticationSchemes;
            System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy extendedProtectionPolicy = this.m_ExtendedProtectionPolicy;
            try
            {
                ExtendedProtectionSelector selector;
                SecurityStatus invalidToken;
                ChannelBinding binding;
                string str6;
                ArrayList list;
                if ((disconnectResult != null) && !disconnectResult.StartOwningDisconnectHandling())
                {
                    disconnectResult = null;
                }
                if (disconnectResult != null)
                {
                    digestContext = disconnectResult.Session;
                }
                context2 = new HttpListenerContext(this, memoryBlob);
                AuthenticationSelectorInfo authenticationDelegate = this.m_AuthenticationDelegate;
                if (authenticationDelegate != null)
                {
                    try
                    {
                        context2.Request.ReleasePins();
                        authenticationSchemes = authenticationDelegate.Delegate(context2.Request);
                        if (!authenticationDelegate.AdvancedAuth && ((authenticationSchemes & (System.Net.AuthenticationSchemes.IntegratedWindowsAuthentication | System.Net.AuthenticationSchemes.Digest)) != System.Net.AuthenticationSchemes.None))
                        {
                            throw this.m_SecurityException;
                        }
                        goto Label_01A2;
                    }
                    catch (Exception exception)
                    {
                        if (NclUtilities.IsFatal(exception))
                        {
                            throw;
                        }
                        if (Logging.On)
                        {
                            Logging.PrintError(Logging.HttpListener, this, "HandleAuthentication", SR.GetString("net_log_listener_delegate_exception", new object[] { exception }));
                        }
                        this.SendError(requestId, HttpStatusCode.InternalServerError, null);
                        context2.Close();
                        return null;
                    }
                }
                stoleBlob = false;
            Label_01A2:
                selector = this.m_ExtendedProtectionSelectorDelegate;
                if (selector != null)
                {
                    extendedProtectionPolicy = selector(context2.Request);
                    if (extendedProtectionPolicy == null)
                    {
                        extendedProtectionPolicy = new System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy(PolicyEnforcement.Never);
                    }
                }
                int length = -1;
                if ((knownHeader != null) && ((authenticationSchemes & ~System.Net.AuthenticationSchemes.Anonymous) != System.Net.AuthenticationSchemes.None))
                {
                    length = 0;
                    while (length < knownHeader.Length)
                    {
                        if (((knownHeader[length] == ' ') || (knownHeader[length] == '\t')) || ((knownHeader[length] == '\r') || (knownHeader[length] == '\n')))
                        {
                            break;
                        }
                        length++;
                    }
                    if (length < knownHeader.Length)
                    {
                        if (((authenticationSchemes & System.Net.AuthenticationSchemes.Negotiate) != System.Net.AuthenticationSchemes.None) && (string.Compare(knownHeader, 0, "Negotiate", 0, length, StringComparison.OrdinalIgnoreCase) == 0))
                        {
                            none = System.Net.AuthenticationSchemes.Negotiate;
                        }
                        else if (((authenticationSchemes & System.Net.AuthenticationSchemes.Ntlm) != System.Net.AuthenticationSchemes.None) && (string.Compare(knownHeader, 0, "NTLM", 0, length, StringComparison.OrdinalIgnoreCase) == 0))
                        {
                            none = System.Net.AuthenticationSchemes.Ntlm;
                        }
                        else if (((authenticationSchemes & System.Net.AuthenticationSchemes.Digest) != System.Net.AuthenticationSchemes.None) && (string.Compare(knownHeader, 0, "Digest", 0, length, StringComparison.OrdinalIgnoreCase) == 0))
                        {
                            none = System.Net.AuthenticationSchemes.Digest;
                        }
                        else if (((authenticationSchemes & System.Net.AuthenticationSchemes.Basic) != System.Net.AuthenticationSchemes.None) && (string.Compare(knownHeader, 0, "Basic", 0, length, StringComparison.OrdinalIgnoreCase) == 0))
                        {
                            none = System.Net.AuthenticationSchemes.Basic;
                        }
                        else if (Logging.On)
                        {
                            Logging.PrintWarning(Logging.HttpListener, this, "HandleAuthentication", SR.GetString("net_log_listener_unsupported_authentication_scheme", new object[] { knownHeader, authenticationSchemes }));
                        }
                    }
                }
                HttpStatusCode internalServerError = HttpStatusCode.InternalServerError;
                bool flag2 = false;
                if (none == System.Net.AuthenticationSchemes.None)
                {
                    if (Logging.On)
                    {
                        Logging.PrintWarning(Logging.HttpListener, this, "HandleAuthentication", SR.GetString("net_log_listener_unmatched_authentication_scheme", new object[] { ValidationHelper.ToString(authenticationSchemes), (knownHeader == null) ? "<null>" : knownHeader }));
                    }
                    if ((authenticationSchemes & System.Net.AuthenticationSchemes.Anonymous) != System.Net.AuthenticationSchemes.None)
                    {
                        if (!stoleBlob)
                        {
                            stoleBlob = true;
                            context2.Request.ReleasePins();
                        }
                        return context2;
                    }
                    internalServerError = HttpStatusCode.Unauthorized;
                    context2.Request.DetachBlob(memoryBlob);
                    context2.Close();
                    context2 = null;
                    goto Label_07AA;
                }
                byte[] bytes = null;
                byte[] inArray = null;
                string str4 = null;
                length++;
                while (length < knownHeader.Length)
                {
                    if (((knownHeader[length] != ' ') && (knownHeader[length] != '\t')) && ((knownHeader[length] != '\r') && (knownHeader[length] != '\n')))
                    {
                        break;
                    }
                    length++;
                }
                string incomingBlob = (length < knownHeader.Length) ? knownHeader.Substring(length) : "";
                IPrincipal principal2 = null;
                switch (none)
                {
                    case System.Net.AuthenticationSchemes.Digest:
                    {
                        binding = this.GetChannelBinding(connectionId, isSecureConnection, extendedProtectionPolicy);
                        authentication3 = new NTAuthentication(true, "WDigest", null, this.GetContextFlags(extendedProtectionPolicy, isSecureConnection), binding);
                        str4 = authentication3.GetOutgoingDigestBlob(incomingBlob, verb, null, this.Realm, false, false, out invalidToken);
                        if (invalidToken == SecurityStatus.OK)
                        {
                            str4 = null;
                        }
                        if (!authentication3.IsValidContext)
                        {
                            break;
                        }
                        SafeCloseHandle contextToken = null;
                        try
                        {
                            if (!this.CheckSpn(authentication3, isSecureConnection, extendedProtectionPolicy))
                            {
                                internalServerError = HttpStatusCode.Unauthorized;
                            }
                            else
                            {
                                context2.Request.ServiceName = authentication3.ClientSpecifiedSpn;
                                contextToken = authentication3.GetContextToken(out invalidToken);
                                if (invalidToken != SecurityStatus.OK)
                                {
                                    internalServerError = this.HttpStatusFromSecurityStatus(invalidToken);
                                }
                                else if (contextToken == null)
                                {
                                    internalServerError = HttpStatusCode.Unauthorized;
                                }
                                else
                                {
                                    principal2 = new WindowsPrincipal(this.CreateWindowsIdentity(contextToken.DangerousGetHandle(), "Digest", WindowsAccountType.Normal, true));
                                }
                            }
                        }
                        finally
                        {
                            if (contextToken != null)
                            {
                                contextToken.Close();
                            }
                        }
                        newContext = authentication3;
                        if (str4 != null)
                        {
                            challenge = "Digest " + str4;
                        }
                        goto Label_0761;
                    }
                    case System.Net.AuthenticationSchemes.Negotiate:
                    case System.Net.AuthenticationSchemes.Ntlm:
                        str6 = (none == System.Net.AuthenticationSchemes.Ntlm) ? "NTLM" : "Negotiate";
                        if ((digestContext == null) || !(digestContext.Package == str6))
                        {
                            goto Label_0549;
                        }
                        authentication3 = digestContext;
                        goto Label_056D;

                    case System.Net.AuthenticationSchemes.Basic:
                        try
                        {
                            bytes = Convert.FromBase64String(incomingBlob);
                            incomingBlob = WebHeaderCollection.HeaderEncoding.GetString(bytes, 0, bytes.Length);
                            length = incomingBlob.IndexOf(':');
                            if (length != -1)
                            {
                                string username = incomingBlob.Substring(0, length);
                                string password = incomingBlob.Substring(length + 1);
                                principal2 = new GenericPrincipal(new HttpListenerBasicIdentity(username, password), null);
                            }
                            else
                            {
                                internalServerError = HttpStatusCode.BadRequest;
                            }
                        }
                        catch (FormatException)
                        {
                        }
                        goto Label_0761;

                    default:
                        goto Label_0761;
                }
                internalServerError = this.HttpStatusFromSecurityStatus(invalidToken);
                goto Label_0761;
            Label_0549:
                binding = this.GetChannelBinding(connectionId, isSecureConnection, extendedProtectionPolicy);
                authentication3 = new NTAuthentication(true, str6, null, this.GetContextFlags(extendedProtectionPolicy, isSecureConnection), binding);
            Label_056D:
                try
                {
                    bytes = Convert.FromBase64String(incomingBlob);
                }
                catch (FormatException)
                {
                    internalServerError = HttpStatusCode.BadRequest;
                    flag2 = true;
                }
                if (!flag2)
                {
                    inArray = authentication3.GetOutgoingBlob(bytes, false, out invalidToken);
                    flag2 = !authentication3.IsValidContext;
                    if (flag2)
                    {
                        if (((invalidToken == SecurityStatus.InvalidHandle) && (digestContext == null)) && ((bytes != null) && (bytes.Length > 0)))
                        {
                            invalidToken = SecurityStatus.InvalidToken;
                        }
                        internalServerError = this.HttpStatusFromSecurityStatus(invalidToken);
                    }
                }
                if (inArray != null)
                {
                    str4 = Convert.ToBase64String(inArray);
                }
                if (!flag2)
                {
                    if (authentication3.IsCompleted)
                    {
                        SafeCloseHandle handle2 = null;
                        try
                        {
                            if (!this.CheckSpn(authentication3, isSecureConnection, extendedProtectionPolicy))
                            {
                                internalServerError = HttpStatusCode.Unauthorized;
                            }
                            else
                            {
                                context2.Request.ServiceName = authentication3.ClientSpecifiedSpn;
                                handle2 = authentication3.GetContextToken(out invalidToken);
                                if (invalidToken != SecurityStatus.OK)
                                {
                                    internalServerError = this.HttpStatusFromSecurityStatus(invalidToken);
                                }
                                else
                                {
                                    WindowsPrincipal principal3 = new WindowsPrincipal(this.CreateWindowsIdentity(handle2.DangerousGetHandle(), authentication3.ProtocolName, WindowsAccountType.Normal, true));
                                    principal2 = principal3;
                                    if (this.UnsafeConnectionNtlmAuthentication && (authentication3.ProtocolName == "NTLM"))
                                    {
                                        if (disconnectResult == null)
                                        {
                                            this.RegisterForDisconnectNotification(connectionId, ref disconnectResult);
                                        }
                                        if (disconnectResult != null)
                                        {
                                            lock (this.DisconnectResults.SyncRoot)
                                            {
                                                if (this.UnsafeConnectionNtlmAuthentication)
                                                {
                                                    disconnectResult.AuthenticatedConnection = principal3;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            goto Label_0761;
                        }
                        finally
                        {
                            if (handle2 != null)
                            {
                                handle2.Close();
                            }
                        }
                    }
                    newContext = authentication3;
                    challenge = (none == System.Net.AuthenticationSchemes.Ntlm) ? "NTLM" : "Negotiate";
                    if (!string.IsNullOrEmpty(str4))
                    {
                        challenge = challenge + " " + str4;
                    }
                }
            Label_0761:
                if (principal2 != null)
                {
                    context2.SetIdentity(principal2, str4);
                }
                else
                {
                    if (Logging.On)
                    {
                        Logging.PrintWarning(Logging.HttpListener, this, "HandleAuthentication", SR.GetString("net_log_listener_create_valid_identity_failed"));
                    }
                    context2.Request.DetachBlob(memoryBlob);
                    context2.Close();
                    context2 = null;
                }
            Label_07AA:
                list = null;
                if (context2 == null)
                {
                    if (challenge != null)
                    {
                        AddChallenge(ref list, challenge);
                    }
                    else
                    {
                        if (newContext != null)
                        {
                            if (newContext == authentication3)
                            {
                                authentication3 = null;
                            }
                            if (newContext != digestContext)
                            {
                                NTAuthentication authentication4 = newContext;
                                newContext = null;
                                authentication4.CloseContext();
                            }
                            else
                            {
                                newContext = null;
                            }
                        }
                        if (internalServerError != HttpStatusCode.Unauthorized)
                        {
                            this.SendError(requestId, internalServerError, null);
                            return null;
                        }
                        list = this.BuildChallenge(authenticationSchemes, connectionId, out newContext, extendedProtectionPolicy, isSecureConnection);
                    }
                }
                if ((disconnectResult == null) && (newContext != null))
                {
                    this.RegisterForDisconnectNotification(connectionId, ref disconnectResult);
                    if (disconnectResult == null)
                    {
                        if (newContext != null)
                        {
                            if (newContext == authentication3)
                            {
                                authentication3 = null;
                            }
                            if (newContext != digestContext)
                            {
                                NTAuthentication authentication5 = newContext;
                                newContext = null;
                                authentication5.CloseContext();
                            }
                            else
                            {
                                newContext = null;
                            }
                        }
                        this.SendError(requestId, HttpStatusCode.InternalServerError, null);
                        context2.Request.DetachBlob(memoryBlob);
                        context2.Close();
                        return null;
                    }
                }
                if (digestContext != newContext)
                {
                    if (digestContext == authentication3)
                    {
                        authentication3 = null;
                    }
                    NTAuthentication authentication6 = digestContext;
                    digestContext = newContext;
                    disconnectResult.Session = newContext;
                    if (authentication6 != null)
                    {
                        if ((authenticationSchemes & System.Net.AuthenticationSchemes.Digest) != System.Net.AuthenticationSchemes.None)
                        {
                            this.SaveDigestContext(authentication6);
                        }
                        else
                        {
                            authentication6.CloseContext();
                        }
                    }
                }
                if (context2 == null)
                {
                    this.SendError(requestId, ((list != null) && (list.Count > 0)) ? HttpStatusCode.Unauthorized : HttpStatusCode.Forbidden, list);
                    return null;
                }
                if (!stoleBlob)
                {
                    stoleBlob = true;
                    context2.Request.ReleasePins();
                }
                context3 = context2;
            }
            catch
            {
                if (context2 != null)
                {
                    context2.Request.DetachBlob(memoryBlob);
                    context2.Close();
                }
                if (newContext != null)
                {
                    if (newContext == authentication3)
                    {
                        authentication3 = null;
                    }
                    if (newContext != digestContext)
                    {
                        NTAuthentication authentication7 = newContext;
                        newContext = null;
                        authentication7.CloseContext();
                    }
                    else
                    {
                        newContext = null;
                    }
                }
                throw;
            }
            finally
            {
                try
                {
                    if ((digestContext != null) && (digestContext != newContext))
                    {
                        if ((newContext == null) && (disconnectResult != null))
                        {
                            disconnectResult.Session = null;
                        }
                        if ((authenticationSchemes & System.Net.AuthenticationSchemes.Digest) != System.Net.AuthenticationSchemes.None)
                        {
                            this.SaveDigestContext(digestContext);
                        }
                        else
                        {
                            digestContext.CloseContext();
                        }
                    }
                    if (((authentication3 != null) && (digestContext != authentication3)) && (newContext != authentication3))
                    {
                        authentication3.CloseContext();
                    }
                }
                finally
                {
                    if (disconnectResult != null)
                    {
                        disconnectResult.FinishOwningDisconnectHandling();
                    }
                }
            }
            return context3;
        }
        //
        // called when getting the final blob on the 200 OK from the server
        //
        public bool Update(string challenge, WebRequest webRequest)
        {
            GlobalLog.Print("KerberosClient::Update(): " + challenge);

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "KerberosClient::Update()|httpWebRequest == null");
            GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "KerberosClient::Update()|httpWebRequest.ChallengedUri == null");

            //
            // try to retrieve the state of the ongoing handshake
            //
            NTAuthentication authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);

            GlobalLog.Print("KerberosClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));

            if (authSession == null)
            {
                GlobalLog.Print("KerberosClient::Update() null session returning true");
                return(true);
            }

            GlobalLog.Print("KerberosClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString());

            if (httpWebRequest.CurrentAuthenticationState.StatusCodeMatch == httpWebRequest.ResponseStatusCode)
            {
                GlobalLog.Print("KerberosClient::Update() still handshaking (based on status code) returning false");
                return(false);
            }

            //
            // the whole point here is to to close the Security Context (this will complete the authentication handshake
            // with server authentication for schemese that support it such as Kerberos)
            //
            int index = challenge == null ? -1 : AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);

            if (index >= 0)
            {
                int    blobBegin = index + SignatureSize;
                string incoming  = null;

                //
                // there may be multiple challenges. If the next character after the
                // package name is not a comma then it is challenge data
                //
                if (challenge.Length > blobBegin && challenge[blobBegin] != ',')
                {
                    ++blobBegin;
                }
                else
                {
                    index = -1;
                }
                if (index >= 0 && challenge.Length > blobBegin)
                {
                    incoming = challenge.Substring(blobBegin);
                }
                GlobalLog.Print("KerberosClient::Update() closing security context using last incoming blob:[" + ValidationHelper.ToString(incoming) + "]");
                string clientResponse = authSession.GetOutgoingBlob(incoming);
                httpWebRequest.CurrentAuthenticationState.Authorization.MutuallyAuthenticated = authSession.IsMutualAuthFlag;
                GlobalLog.Print("KerberosClient::Update() GetOutgoingBlob() returns clientResponse:[" + ValidationHelper.ToString(clientResponse) + "] IsCompleted:" + authSession.IsCompleted.ToString());
            }

            // Extract the CBT we used and cache it for future requests that want to do preauth
            httpWebRequest.ServicePoint.SetCachedChannelBinding(httpWebRequest.ChallengedUri, authSession.ChannelBinding);

            GlobalLog.Print("KerberosClient::Update() session removed and ConnectionGroup released returning true");
            ClearSession(httpWebRequest);
            return(true);
        }