private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate)
        {
            if (credentials == null)
            {
                return(null);
            }
            HttpWebRequest   request         = webRequest as HttpWebRequest;
            NTAuthentication securityContext = null;
            string           incomingBlob    = null;

            if (!preAuthenticate)
            {
                int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);
                if (index < 0)
                {
                    return(null);
                }
                int startIndex = index + SignatureSize;
                if ((challenge.Length > startIndex) && (challenge[startIndex] != ','))
                {
                    startIndex++;
                }
                else
                {
                    index = -1;
                }
                if ((index >= 0) && (challenge.Length > startIndex))
                {
                    index = challenge.IndexOf(',', startIndex);
                    if (index != -1)
                    {
                        incomingBlob = challenge.Substring(startIndex, index - startIndex);
                    }
                    else
                    {
                        incomingBlob = challenge.Substring(startIndex);
                    }
                }
                securityContext = request.CurrentAuthenticationState.GetSecurityContext(this);
            }
            if (securityContext == null)
            {
                NetworkCredential credential = credentials.GetCredential(request.ChallengedUri, Signature);
                string            str2       = string.Empty;
                if ((credential == null) || (!(credential is SystemNetworkCredential) && ((str2 = credential.InternalGetUserName()).Length == 0)))
                {
                    return(null);
                }
                if (((str2.Length + credential.InternalGetPassword().Length) + credential.InternalGetDomain().Length) > 0x20f)
                {
                    return(null);
                }
                ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy;
                if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(request.ChallengedUri, request, credential, this))
                {
                    return(null);
                }
                string         computeSpn     = request.CurrentAuthenticationState.GetComputeSpn(request);
                ChannelBinding channelBinding = null;
                if (request.CurrentAuthenticationState.TransportContext != null)
                {
                    channelBinding = request.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint);
                }
                securityContext = new NTAuthentication("NTLM", credential, computeSpn, request, channelBinding);
                request.CurrentAuthenticationState.SetSecurityContext(securityContext, this);
            }
            string outgoingBlob = securityContext.GetOutgoingBlob(incomingBlob);

            if (outgoingBlob == null)
            {
                return(null);
            }
            bool unsafeOrProxyAuthenticatedConnectionSharing = request.UnsafeOrProxyAuthenticatedConnectionSharing;

            if (unsafeOrProxyAuthenticatedConnectionSharing)
            {
                request.LockConnection = true;
            }
            request.NtlmKeepAlive = incomingBlob == null;
            return(AuthenticationManager.GetGroupAuthorization(this, "NTLM " + outgoingBlob, securityContext.IsCompleted, securityContext, unsafeOrProxyAuthenticatedConnectionSharing, false));
        }
예제 #2
0
        private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate)
        {
            GlobalLog.Print("NegotiateClient::DoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString());

            GlobalLog.Assert(credentials != null, "NegotiateClient::DoAuthenticate()|credentials == null");
            if (credentials == null)
            {
                return(null);
            }

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::DoAuthenticate()|httpWebRequest == null");
            GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NegotiateClient::DoAuthenticate()|httpWebRequest.ChallengedUri == null");

            NTAuthentication authSession = null;
            string           incoming    = null;
            bool             useNego2    = false; // In case of pre-auth we always use "Negotiate", never "Nego2".

            if (!preAuthenticate)
            {
                int index = GetSignatureIndex(challenge, out useNego2);
                if (index < 0)
                {
                    return(null);
                }

                int blobBegin = index + (useNego2 ? nego2Signature.Length : negotiateSignature.Length);

                //
                // 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)
                {
                    // Strip other modules information in case of multiple challenges
                    // i.e do not take ", NTLM" as part of the following Negotiate blob
                    // Negotiate TlRMTVNTUAACAAAADgAOADgAAAA1wo ... MAbwBmAHQALgBjAG8AbQAAAAAA,NTLM
                    index = challenge.IndexOf(',', blobBegin);
                    if (index != -1)
                    {
                        incoming = challenge.Substring(blobBegin, index - blobBegin);
                    }
                    else
                    {
                        incoming = challenge.Substring(blobBegin);
                    }
                }

                authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);
                GlobalLog.Print("NegotiateClient::DoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));
            }

            if (authSession == null)
            {
                // Credentials are always set for "Negotiate", never for "Nego2". A customer shouldn't even know
                // about "Nego2".
                NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, negotiateSignature);
                GlobalLog.Print("NegotiateClient::DoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC));

                string username = string.Empty;
                if (NC == null || (!(NC is SystemNetworkCredential) && (username = NC.InternalGetUserName()).Length == 0))
                {
                    return(null);
                }

                ICredentialPolicy policy = AuthenticationManager.CredentialPolicy;
                if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this))
                {
                    return(null);
                }

                SpnToken spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest);
                GlobalLog.Print("NegotiateClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn));

                ChannelBinding binding = null;
                if (httpWebRequest.CurrentAuthenticationState.TransportContext != null)
                {
                    binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint);
                }

                authSession =
                    new NTAuthentication(
                        AuthType,
                        NC,
                        spn,
                        httpWebRequest,
                        binding);

                GlobalLog.Print("NegotiateClient::DoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession));
                httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this);
            }

            string clientResponse = authSession.GetOutgoingBlob(incoming);

            if (clientResponse == null)
            {
                return(null);
            }

            bool canShareConnection = httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing;

            if (canShareConnection)
            {
                httpWebRequest.LockConnection = true;
            }

            // this is the first leg of an NTLM handshake,
            // set the NtlmKeepAlive override *STRICTLY* only in this case.
            httpWebRequest.NtlmKeepAlive = incoming == null && authSession.IsValidContext && !authSession.IsKerberos;

            // If we received a "Nego2" header value from the server, we'll respond with "Nego2" in the "Authorization"
            // header. If the server sent a "Negotiate" header value or if pre-authenticate is used (i.e. the auth blob
            // is sent with the first request), we send "Negotiate" in the "Authorization" header.
            return(AuthenticationManager.GetGroupAuthorization(this, (useNego2 ? nego2Header : negotiateHeader) +
                                                               " " + clientResponse, authSession.IsCompleted, authSession, canShareConnection, authSession.IsKerberos));
        }
예제 #3
0
        public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials)
        {
            GlobalLog.Print("NegotiateClient::Authenticate(): " + challenge);

            GlobalLog.Assert(credentials != null, "NegotiateClient::Authenticate() credentials==null", "");
            if (credentials == null)
            {
                return(null);
            }

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "NegotiateClient::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.ToLower(CultureInfo.InvariantCulture), Signature);

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

            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);
            }

            NTAuthentication authSession = sessions[httpWebRequest.CurrentAuthenticationState] as NTAuthentication;

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

            if (authSession == null)
            {
                NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature);
                GlobalLog.Print("NegotiateClient::Authenticate() GetCredential() returns:" + ValidationHelper.ToString(NC));

                if (NC == null)
                {
                    return(null);
                }
                string username = NC.UserName;
                if (username == null || (username.Length == 0 && !(NC is SystemNetworkCredential)))
                {
                    return(null);
                }
                //
                // here we cover a hole in the SSPI layer. longer credentials
                // might corrupt the process and cause a reboot.
                //
                if (username.Length + NC.Password.Length + NC.Domain.Length > NtlmClient.MaxNtlmCredentialSize)
                {
                    //
                    // rather then throwing an exception here we return null so other packages can be used.
                    // this is questionable, hence:
                    // Consider: make this throw a NotSupportedException so it is discoverable
                    //
                    return(null);
                }

                if (httpWebRequest.ChallengedSpn == null)
                {
                    string host = httpWebRequest.ChallengedUri.Host;
                    if (httpWebRequest.ChallengedUri.HostNameType != UriHostNameType.IPv6 && httpWebRequest.ChallengedUri.HostNameType != UriHostNameType.IPv4 && host.IndexOf('.') == -1)
                    {
                        // only do the DNS lookup for short names, no form of IP addess
                        (new DnsPermission(PermissionState.Unrestricted)).Assert();
                        try {
                            host = Dns.GetHostByName(host).HostName;
                            GlobalLog.Print("NegotiateClient::Authenticate() Dns returned host:" + ValidationHelper.ToString(host));
                        }
                        catch (Exception exception) {
                            GlobalLog.Print("NegotiateClient::Authenticate() GetHostByName(host) failed:" + ValidationHelper.ToString(exception));
                        }
                        finally {
                            DnsPermission.RevertAssert();
                        }
                    }
                    // CONSIDER V.NEXT
                    // for now avoid appending the non default port to the
                    // SPN, sometime in the future we'll have to do this.
                    // httpWebRequest.ChallengedSpn = httpWebRequest.ChallengedUri.IsDefaultPort ? host : host + ":" + httpWebRequest.ChallengedUri.Port;
                    httpWebRequest.ChallengedSpn = host;
                }
                GlobalLog.Print("NegotiateClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(httpWebRequest.ChallengedSpn));

                authSession =
                    new NTAuthentication(
                        AuthType,
                        NC,
                        "HTTP/" + httpWebRequest.ChallengedSpn,
                        httpWebRequest.DelegationFix);

                GlobalLog.Print("NegotiateClient::Authenticate() adding authSession:" + ValidationHelper.HashString(authSession) + " for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState));
                sessions.Add(httpWebRequest.CurrentAuthenticationState, authSession);
            }

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

            if (clientResponse == null)
            {
                return(null);
            }

            if (httpWebRequest.UnsafeAuthenticatedConnectionSharing)
            {
                httpWebRequest.LockConnection = true;
            }

            return(AuthenticationManager.GetGroupAuthorization(this, AuthType + " " + clientResponse, false, authSession, httpWebRequest.UnsafeAuthenticatedConnectionSharing));
        }
        private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate)
        {
            if (credentials == null)
            {
                return(null);
            }
            HttpWebRequest   request         = webRequest as HttpWebRequest;
            NTAuthentication securityContext = null;
            string           incomingBlob    = null;
            bool             flag            = false;

            if (!preAuthenticate)
            {
                int signatureIndex = GetSignatureIndex(challenge, out flag);
                if (signatureIndex < 0)
                {
                    return(null);
                }
                int startIndex = signatureIndex + (flag ? "nego2".Length : "negotiate".Length);
                if ((challenge.Length > startIndex) && (challenge[startIndex] != ','))
                {
                    startIndex++;
                }
                else
                {
                    signatureIndex = -1;
                }
                if ((signatureIndex >= 0) && (challenge.Length > startIndex))
                {
                    signatureIndex = challenge.IndexOf(',', startIndex);
                    if (signatureIndex != -1)
                    {
                        incomingBlob = challenge.Substring(startIndex, signatureIndex - startIndex);
                    }
                    else
                    {
                        incomingBlob = challenge.Substring(startIndex);
                    }
                }
                securityContext = request.CurrentAuthenticationState.GetSecurityContext(this);
            }
            if (securityContext == null)
            {
                NetworkCredential credential = credentials.GetCredential(request.ChallengedUri, "negotiate");
                if ((credential == null) || (!(credential is SystemNetworkCredential) && (credential.InternalGetUserName().Length == 0)))
                {
                    return(null);
                }
                ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy;
                if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(request.ChallengedUri, request, credential, this))
                {
                    return(null);
                }
                string         computeSpn     = request.CurrentAuthenticationState.GetComputeSpn(request);
                ChannelBinding channelBinding = null;
                if (request.CurrentAuthenticationState.TransportContext != null)
                {
                    channelBinding = request.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint);
                }
                securityContext = new NTAuthentication("Negotiate", credential, computeSpn, request, channelBinding);
                request.CurrentAuthenticationState.SetSecurityContext(securityContext, this);
            }
            string outgoingBlob = securityContext.GetOutgoingBlob(incomingBlob);

            if (outgoingBlob == null)
            {
                return(null);
            }
            bool unsafeOrProxyAuthenticatedConnectionSharing = request.UnsafeOrProxyAuthenticatedConnectionSharing;

            if (unsafeOrProxyAuthenticatedConnectionSharing)
            {
                request.LockConnection = true;
            }
            request.NtlmKeepAlive = ((incomingBlob == null) && securityContext.IsValidContext) && !securityContext.IsKerberos;
            return(AuthenticationManager.GetGroupAuthorization(this, (flag ? "Nego2" : "Negotiate") + " " + outgoingBlob, securityContext.IsCompleted, securityContext, unsafeOrProxyAuthenticatedConnectionSharing, securityContext.IsKerberos));
        }
예제 #5
0
        public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials)
        {
            GlobalLog.Print("NtlmClient::Authenticate(): " + challenge);

            GlobalLog.Assert(credentials != null, "NtlmClient::Authenticate() credentials==null", "");
            if (credentials == null)
            {
                return(null);
            }

            HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

            GlobalLog.Assert(httpWebRequest != null, "NtlmClient::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.ToLower(CultureInfo.InvariantCulture), Signature);

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

            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);
            }

            NTAuthentication authSession = sessions[httpWebRequest.CurrentAuthenticationState] as NTAuthentication;

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

            if (authSession == null)
            {
                NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature);
                GlobalLog.Print("NtlmClient::Authenticate() GetCredential() returns:" + ValidationHelper.ToString(NC));

                if (NC == null)
                {
                    return(null);
                }
                string username = NC.UserName;
                if (username == null || (username.Length == 0 && !(NC is SystemNetworkCredential)))
                {
                    return(null);
                }
                //
                // here we cover a hole in the SSPI layer. longer credentials
                // might corrupt the process and cause a reboot.
                //
                if (username.Length + NC.Password.Length + NC.Domain.Length > NtlmClient.MaxNtlmCredentialSize)
                {
                    //
                    // rather then throwing an exception here we return null so other packages can be used.
                    // this is questionable, hence:
                    // Consider: make this throw a NotSupportedException so it is discoverable
                    //
                    return(null);
                }

                authSession =
                    new NTAuthentication(
                        AuthType,
                        NC,
                        null,
                        httpWebRequest.DelegationFix);

                GlobalLog.Print("NtlmClient::Authenticate() adding authSession:" + ValidationHelper.HashString(authSession) + " for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState));
                sessions.Add(httpWebRequest.CurrentAuthenticationState, authSession);
            }

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

            if (clientResponse == null)
            {
                return(null);
            }

            if (httpWebRequest.UnsafeAuthenticatedConnectionSharing)
            {
                httpWebRequest.LockConnection = true;
            }

            return(AuthenticationManager.GetGroupAuthorization(this, AuthType + " " + clientResponse, false, authSession, httpWebRequest.UnsafeAuthenticatedConnectionSharing));
        }