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