// // we need to do this to handle proxies in the correct way before // calling into the AuthenticationManager APIs // private void PrepareState(HttpWebRequest httpWebRequest) { Uri newUri = IsProxyAuth ? httpWebRequest.ServicePoint.InternalAddress : httpWebRequest.GetRemoteResourceUri(); if ((object)ChallengedUri != (object)newUri) { if ((object)ChallengedUri == null || (object)ChallengedUri.Scheme != (object)newUri.Scheme || ChallengedUri.Host != newUri.Host || ChallengedUri.Port != newUri.Port) { // // must be a new server/port/scheme for this auth state, can happen on a redirect // ChallengedSpn = null; } ChallengedUri = newUri; } httpWebRequest.CurrentAuthenticationState = this; }
private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { NTAuthentication securityContext = null; string incomingBlob = null; SecurityStatus status; if (!preAuthenticate) { int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return null; } securityContext = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); incomingBlob = RefineDigestChallenge(challenge, index); } else { HttpDigestChallenge challenge2 = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (challenge2 == null) { return null; } challenge2 = challenge2.CopyAndIncrementNonce(); challenge2.SetFromRequest(httpWebRequest); incomingBlob = challenge2.ToBlob(); } UriComponents uriParts = 0; if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; } else if (httpWebRequest.UsesProxySemantics) { uriParts = UriComponents.HttpRequestUrl; } else { uriParts = UriComponents.PathAndQuery; } string parts = httpWebRequest.GetRemoteResourceUri().GetParts(uriParts, UriFormat.UriEscaped); if (securityContext == null) { NetworkCredential credential = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); if ((credential == null) || (!(credential is SystemNetworkCredential) && (credential.InternalGetUserName().Length == 0))) { return null; } ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy; if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, credential, this)) { return null; } string computeSpn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); ChannelBinding channelBinding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { channelBinding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } securityContext = new NTAuthentication("WDigest", credential, computeSpn, httpWebRequest, channelBinding); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(securityContext, this); } string str4 = securityContext.GetOutgoingDigestBlob(incomingBlob, httpWebRequest.CurrentMethod.Name, parts, null, false, false, out status); if (str4 == null) { return null; } Authorization authorization = new Authorization("Digest " + str4, securityContext.IsCompleted, string.Empty, securityContext.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { HttpDigestChallenge challenge3 = HttpDigest.Interpret(incomingBlob, -1, httpWebRequest); string[] strArray = (challenge3.Domain == null) ? new string[] { httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped) } : challenge3.Domain.Split(singleSpaceArray); authorization.ProtectionRealm = (challenge3.Domain == null) ? null : strArray; for (int i = 0; i < strArray.Length; i++) { challengeCache.Add(strArray[i], challenge3); } } return authorization; }
private void CompleteConnection(bool async, HttpWebRequest request) { GlobalLog.Enter("Connection#" + ValidationHelper.HashString(this) + "::CompleteConnection", "async:" + async.ToString() + " request:" + ValidationHelper.HashString(request)); GlobalLog.ThreadContract(ThreadKinds.Unknown, "Connection#" + ValidationHelper.HashString(this) + "::CompleteConnection"); WebExceptionStatus ws = WebExceptionStatus.ConnectFailure; // // From now on the request.SetRequestSubmitDone must be called or it may hang // For a [....] request the write side reponse windowwas opened in HttpWebRequest.SubmitRequest if (request.Async) request.OpenWriteSideResponseWindow(); try { try { #if !FEATURE_PAL if (request.Address.Scheme == Uri.UriSchemeHttps) { TlsStream tlsStream = new TlsStream(request.GetRemoteResourceUri().IdnHost, NetworkStream, request.ClientCertificates, ServicePoint, request, request.Async ? request.GetConnectingContext().ContextCopy : null); NetworkStream = tlsStream; } #endif ws = WebExceptionStatus.Success; } catch { // The TLS stream could not be created. Close the current non-TLS stream immediately // to prevent any future use of it. Due to race conditions, the error handling will sometimes // try to write (flush) out some of the HTTP headers to the stream as it is closing down the failed // HttpWebRequest. This would cause plain text to go on the wire even though the stream should // have been TLS encrypted. NetworkStream.Close(); throw; } finally { // // There is a ---- with Abort so TlsStream ctor may throw. // SetRequestSubmitDone will deal with this kind of errors. // m_ReadState = ReadState.Start; ClearReaderState(); request.SetRequestSubmitDone(new ConnectStream(this, request)); } } catch (Exception exception) { if (m_InnerException == null) m_InnerException = exception; WebException webException = exception as WebException; if (webException != null) { ws = webException.Status; } } if (ws != WebExceptionStatus.Success) { ConnectionReturnResult returnResult = null; HandleError(false, false, ws, ref returnResult); ConnectionReturnResult.SetResponses(returnResult); if (Logging.On) Logging.PrintError(Logging.Web, this, "CompleteConnection", "on error"); GlobalLog.Leave("Connection#" + ValidationHelper.HashString(this) + "::CompleteConnection", "on error"); } else { GlobalLog.Leave("Connection#" + ValidationHelper.HashString(this) + "::CompleteConnection"); } }
internal void SetFromRequest(HttpWebRequest httpWebRequest) { this.HostName = httpWebRequest.ChallengedUri.Host; this.Method = httpWebRequest.CurrentMethod.Name; if (httpWebRequest.CurrentMethod.ConnectRequest) { // Use the orriginal request Uri, not the proxy Uri this.Uri = httpWebRequest.RequestUri.GetParts(UriComponents.HostAndPort, UriFormat.UriEscaped); } else { // Don't use PathAndQuery, it breaks IIS6 // GetParts(Path) doesn't return the initial slash this.Uri = "/" + httpWebRequest.GetRemoteResourceUri().GetParts(UriComponents.Path, UriFormat.UriEscaped); } this.ChallengedUri = httpWebRequest.ChallengedUri; }
// On Windows XP and up, WDigest.dll supports the Digest authentication scheme (in addition to // support for HTTP client sides, it also supports HTTP server side and SASL) through SSPI. private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { GlobalLog.Print("DigestClient::XPDoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString()); NTAuthentication authSession = null; string incoming = null; int index; if (!preAuthenticate) { index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return null; } authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("DigestClient::XPDoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); incoming = RefineDigestChallenge(challenge, index); } else { #if WDIGEST_PREAUTH GlobalLog.Print("DigestClient::XPDoAuthenticate() looking up digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); authSession = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as NTAuthentication; if (authSession==null) { return null; } #else GlobalLog.Print("DigestClient::XPDoAuthenticate() looking up digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); HttpDigestChallenge digestChallenge = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (digestChallenge==null) { return null; } GlobalLog.Print("DigestClient::XPDoAuthenticate() retrieved digestChallenge#" + ValidationHelper.HashString(digestChallenge) + " digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); digestChallenge = digestChallenge.CopyAndIncrementNonce(); digestChallenge.SetFromRequest(httpWebRequest); incoming = digestChallenge.ToBlob(); #endif } UriComponents uriParts = 0; Uri remoteUri = httpWebRequest.GetRemoteResourceUri(); if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; // Use the orriginal request Uri, not the proxy Uri remoteUri = httpWebRequest.RequestUri; } else { uriParts = UriComponents.PathAndQuery; } // here we use Address instead of ChallengedUri. This is because the // Digest hash is generated using the uri as it is present on the wire string rawUri = remoteUri.GetParts(uriParts, UriFormat.UriEscaped); GlobalLog.Print("DigestClient::XPDoAuthenticate() rawUri:" + ValidationHelper.ToString(rawUri)); if (authSession==null) { NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); GlobalLog.Print("DigestClient::XPDoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); if (NC == null || (!(NC is SystemNetworkCredential) && 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("NtlmClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( NegotiationInfoClass.WDigest, NC, spn, httpWebRequest, binding); GlobalLog.Print("DigestClient::XPDoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession)); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this); } SecurityStatus statusCode; string clientResponse; GlobalLog.Print("DigestClient::XPDoAuthenticate() incoming:" + ValidationHelper.ToString(incoming)); #if WDIGEST_PREAUTH clientResponse = authSession.GetOutgoingDigestBlob(incoming, httpWebRequest.CurrentMethod.Name, rawUri, null, preAuthenticate, true, out statusCode); #else clientResponse = authSession.GetOutgoingDigestBlob(incoming, httpWebRequest.CurrentMethod.Name, rawUri, null, false, false, out statusCode); #endif if (clientResponse == null) return null; GlobalLog.Print("DigestClient::XPDoAuthenticate() GetOutgoingDigestBlob(" + incoming + ") returns:" + ValidationHelper.ToString(clientResponse)); Authorization digestResponse = new Authorization(AuthType + " " + clientResponse, authSession.IsCompleted, string.Empty, authSession.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { // add this to the cache of challenges so we can preauthenticate // use this DCR when avaialble to do this without calling HttpDigest.Interpret(): // 762115 3 WDigest should allow an application to retrieve the parsed domain directive HttpDigestChallenge digestChallenge = HttpDigest.Interpret(incoming, -1, httpWebRequest); string[] prefixes = digestChallenge.Domain==null ? new string[]{httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped)} : digestChallenge.Domain.Split(singleSpaceArray); // If Domain property is not set we associate Digest only with the server Uri namespace (used to do with whole server) digestResponse.ProtectionRealm = digestChallenge.Domain==null ? null: prefixes; for (int i=0; i<prefixes.Length; i++) { GlobalLog.Print("DigestClient::XPDoAuthenticate() adding authSession#" + ValidationHelper.HashString(authSession) + " for prefix:" + prefixes[i]); #if WDIGEST_PREAUTH challengeCache.Add(prefixes[i], authSession); #else challengeCache.Add(prefixes[i], digestChallenge); #endif } } return digestResponse; }
private void PrepareState(HttpWebRequest httpWebRequest) { Uri uri = this.IsProxyAuth ? httpWebRequest.ServicePoint.InternalAddress : httpWebRequest.GetRemoteResourceUri(); if (this.ChallengedUri != uri) { if (((this.ChallengedUri == null) || (this.ChallengedUri.Scheme != uri.Scheme)) || ((this.ChallengedUri.Host != uri.Host) || (this.ChallengedUri.Port != uri.Port))) { this.ChallengedSpn = null; } this.ChallengedUri = uri; } httpWebRequest.CurrentAuthenticationState = this; }
private void CompleteConnection(bool async, HttpWebRequest request) { WebExceptionStatus connectFailure = WebExceptionStatus.ConnectFailure; if (request.Async) { request.OpenWriteSideResponseWindow(); } try { try { if (request.Address.Scheme == Uri.UriSchemeHttps) { TlsStream stream = new TlsStream(request.GetRemoteResourceUri().Host, base.NetworkStream, request.ClientCertificates, this.ServicePoint, request, request.Async ? request.GetConnectingContext().ContextCopy : null); base.NetworkStream = stream; } } finally { this.m_ReadState = ReadState.Start; this.ClearReaderState(); request.SetRequestSubmitDone(new ConnectStream(this, request)); connectFailure = WebExceptionStatus.Success; } } catch (Exception exception) { if (this.m_InnerException == null) { this.m_InnerException = exception; } WebException exception2 = exception as WebException; if (exception2 != null) { connectFailure = exception2.Status; } } if (connectFailure != WebExceptionStatus.Success) { ConnectionReturnResult returnResult = null; this.HandleError(false, false, connectFailure, ref returnResult); ConnectionReturnResult.SetResponses(returnResult); } }
internal static void OnSendingHeaders(HttpWebRequest httpWebRequest) { try { if (httpWebRequest.CookieContainer != null) { string str; httpWebRequest.Headers.RemoveInternal("Cookie"); string cookieHeader = httpWebRequest.CookieContainer.GetCookieHeader(httpWebRequest.GetRemoteResourceUri(), out str); if (cookieHeader.Length > 0) { httpWebRequest.Headers["Cookie"] = cookieHeader; } } } catch { } }
private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { NTAuthentication securityContext = null; string incomingBlob = null; SecurityStatus status; if (!preAuthenticate) { int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return(null); } securityContext = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); incomingBlob = RefineDigestChallenge(challenge, index); } else { HttpDigestChallenge challenge2 = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (challenge2 == null) { return(null); } challenge2 = challenge2.CopyAndIncrementNonce(); challenge2.SetFromRequest(httpWebRequest); incomingBlob = challenge2.ToBlob(); } UriComponents uriParts = 0; if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; } else if (httpWebRequest.UsesProxySemantics) { uriParts = UriComponents.HttpRequestUrl; } else { uriParts = UriComponents.PathAndQuery; } string parts = httpWebRequest.GetRemoteResourceUri().GetParts(uriParts, UriFormat.UriEscaped); if (securityContext == null) { NetworkCredential credential = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); if ((credential == null) || (!(credential is SystemNetworkCredential) && (credential.InternalGetUserName().Length == 0))) { return(null); } ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy; if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, credential, this)) { return(null); } string computeSpn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); ChannelBinding channelBinding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { channelBinding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } securityContext = new NTAuthentication("WDigest", credential, computeSpn, httpWebRequest, channelBinding); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(securityContext, this); } string str4 = securityContext.GetOutgoingDigestBlob(incomingBlob, httpWebRequest.CurrentMethod.Name, parts, null, false, false, out status); if (str4 == null) { return(null); } Authorization authorization = new Authorization("Digest " + str4, securityContext.IsCompleted, string.Empty, securityContext.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { HttpDigestChallenge challenge3 = HttpDigest.Interpret(incomingBlob, -1, httpWebRequest); string[] strArray = (challenge3.Domain == null) ? new string[] { httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped) } : challenge3.Domain.Split(singleSpaceArray); authorization.ProtectionRealm = (challenge3.Domain == null) ? null : strArray; for (int i = 0; i < strArray.Length; i++) { challengeCache.Add(strArray[i], challenge3); } } return(authorization); }