protected override void Dispose(bool disposing) { try { _exception = new ObjectDisposedException(nameof(NegotiateStream)); _context?.CloseContext(); } finally { base.Dispose(disposing); } }
protected override void Dispose(bool disposing) { try { _exception = s_disposedSentinel; _context?.CloseContext(); } finally { base.Dispose(disposing); } }
// // private Exception SetException(Exception e) { if (_Exception == null || !(_Exception is ObjectDisposedException)) { _Exception = e; } if (_Exception != null && _Context != null) { _Context.CloseContext(); } return(_Exception); }
private static async Task <HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, bool isProxyAuth, HttpConnection connection, CancellationToken cancellationToken) { HttpResponseMessage response = await InnerSendAsync(request, isProxyAuth, connection, cancellationToken).ConfigureAwait(false); if (!isProxyAuth && connection.Kind == HttpConnectionKind.Proxy && !ProxySupportsConnectionAuth(response)) { // Proxy didn't indicate that it supports connection-based auth, so we can't proceed. if (NetEventSource.IsEnabled) { NetEventSource.Error(connection, $"Proxy doesn't support connection-based auth, uri={authUri}"); } return(response); } if (TryGetAuthenticationChallenge(response, isProxyAuth, authUri, credentials, out AuthenticationChallenge challenge)) { if (challenge.AuthenticationType == AuthenticationType.Negotiate || challenge.AuthenticationType == AuthenticationType.Ntlm) { string challengeData = challenge.ChallengeData; string spn = "HTTP/" + authUri.IdnHost; ChannelBinding channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); NTAuthentication authContext = new NTAuthentication(isServer: false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection, channelBinding); try { while (true) { string challengeResponse = authContext.GetOutgoingBlob(challengeData); if (challengeResponse == null) { // Response indicated denial even after login, so stop processing and return current response. break; } await connection.DrainResponseAsync(response).ConfigureAwait(false); SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(challenge.SchemeName, challengeResponse), isProxyAuth); response = await InnerSendAsync(request, isProxyAuth, connection, cancellationToken).ConfigureAwait(false); if (authContext.IsCompleted || !TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out challengeData)) { break; } } } finally { authContext.CloseContext(); } } } return(response); }
public void CloseContext(object sessionCookie) { NTAuthentication clientContext = null; lock (_sessions) { if (_sessions.TryGetValue(sessionCookie, out clientContext)) { _sessions.Remove(sessionCookie); } } if (clientContext != null) { clientContext.CloseContext(); } }
public void CloseContext(object sessionCookie) { NTAuthentication clientContext = null; lock (sessions) { clientContext = sessions[sessionCookie] as NTAuthentication; if (clientContext != null) { sessions.Remove(sessionCookie); } } if (clientContext != null) { clientContext.CloseContext(); } }
public void CloseContext(object sessionCookie) { NTAuthentication authentication = null; lock (this.sessions) { authentication = this.sessions[sessionCookie] as NTAuthentication; if (authentication != null) { this.sessions.Remove(sessionCookie); } } if (authentication != null) { authentication.CloseContext(); } }
private static async Task <HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, bool isProxyAuth, HttpConnection connection, CancellationToken cancellationToken) { HttpResponseMessage response = await InnerSendAsync(request, isProxyAuth, connection, cancellationToken).ConfigureAwait(false); if (TryGetAuthenticationChallenge(response, isProxyAuth, authUri, credentials, out AuthenticationChallenge challenge) && (!isProxyAuth || CheckIfProxySupportsConnectionAuth(response))) { if (challenge.AuthenticationType == AuthenticationType.Negotiate || challenge.AuthenticationType == AuthenticationType.Ntlm) { string challengeData = challenge.ChallengeData; string spn = "HTTP/" + authUri.IdnHost; ChannelBinding channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); NTAuthentication authContext = new NTAuthentication(false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection, channelBinding); try { while (true) { string challengeResponse = authContext.GetOutgoingBlob(challengeData); if (authContext.IsCompleted) { break; } await connection.DrainResponseAsync(response).ConfigureAwait(false); SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(challenge.SchemeName, challengeResponse), isProxyAuth); response = await InnerSendAsync(request, isProxyAuth, connection, cancellationToken).ConfigureAwait(false); if (!TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out challengeData)) { break; } } } finally { authContext.CloseContext(); } } } return(response); }
private static async Task <HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, bool async, ICredentials credentials, bool isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) { HttpResponseMessage response = await InnerSendAsync(request, async, isProxyAuth, connectionPool, connection, cancellationToken).ConfigureAwait(false); if (!isProxyAuth && connection.Kind == HttpConnectionKind.Proxy && !ProxySupportsConnectionAuth(response)) { // Proxy didn't indicate that it supports connection-based auth, so we can't proceed. if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(connection, $"Proxy doesn't support connection-based auth, uri={authUri}"); } return(response); } if (TryGetAuthenticationChallenge(response, isProxyAuth, authUri, credentials, out AuthenticationChallenge challenge)) { if (challenge.AuthenticationType == AuthenticationType.Negotiate || challenge.AuthenticationType == AuthenticationType.Ntlm) { bool isNewConnection = false; bool needDrain = true; try { if (response.Headers.ConnectionClose.GetValueOrDefault()) { // Server is closing the connection and asking us to authenticate on a new connection. // First, detach the current connection from the pool. This means it will no longer count against the connection limit. // Instead, it will be replaced by the new connection below. connection.DetachFromPool(); connection = await connectionPool.CreateHttp11ConnectionAsync(request, async, cancellationToken).ConfigureAwait(false); connection !.Acquire(); isNewConnection = true; needDrain = false; } if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, Uri: {authUri.AbsoluteUri}"); } // Calculate SPN (Service Principal Name) using the host name of the request. // Use the request's 'Host' header if available. Otherwise, use the request uri. // Ignore the 'Host' header if this is proxy authentication since we need to use // the host name of the proxy itself for SPN calculation. string hostName; if (!isProxyAuth && request.HasHeaders && request.Headers.Host != null) { // Use the host name without any normalization. hostName = request.Headers.Host; if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, Host: {hostName}"); } } else { // Need to use FQDN normalized host so that CNAME's are traversed. // Use DNS to do the forward lookup to an A (host) record. // But skip DNS lookup on IP literals. Otherwise, we would end up // doing an unintended reverse DNS lookup. UriHostNameType hnt = authUri.HostNameType; if (hnt == UriHostNameType.IPv6 || hnt == UriHostNameType.IPv4) { hostName = authUri.IdnHost; } else { IPHostEntry result = await Dns.GetHostEntryAsync(authUri.IdnHost, cancellationToken).ConfigureAwait(false); hostName = result.HostName; } if (!isProxyAuth && !authUri.IsDefaultPort && UsePortInSpn) { hostName = string.Create(null, stackalloc char[128], $"{hostName}:{authUri.Port}"); } } string spn = "HTTP/" + hostName; if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, SPN: {spn}"); } ChannelBinding? channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); NTAuthentication authContext = new NTAuthentication(isServer: false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection | ContextFlagsPal.InitIntegrity, channelBinding); string? challengeData = challenge.ChallengeData; try { while (true) { string?challengeResponse = authContext.GetOutgoingBlob(challengeData); if (challengeResponse == null) { // Response indicated denial even after login, so stop processing and return current response. break; } if (needDrain) { await connection.DrainResponseAsync(response !, cancellationToken).ConfigureAwait(false); } SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(challenge.SchemeName, challengeResponse), isProxyAuth); response = await InnerSendAsync(request, async, isProxyAuth, connectionPool, connection, cancellationToken).ConfigureAwait(false); if (authContext.IsCompleted || !TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out challengeData)) { break; } needDrain = true; } } finally { authContext.CloseContext(); } } finally { if (isNewConnection) { connection !.Release(); } } } } return(response !); }
private static async Task <HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, bool isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) { HttpResponseMessage response = await InnerSendAsync(request, isProxyAuth, connectionPool, connection, cancellationToken).ConfigureAwait(false); if (!isProxyAuth && connection.Kind == HttpConnectionKind.Proxy && !ProxySupportsConnectionAuth(response)) { // Proxy didn't indicate that it supports connection-based auth, so we can't proceed. if (NetEventSource.IsEnabled) { NetEventSource.Error(connection, $"Proxy doesn't support connection-based auth, uri={authUri}"); } return(response); } if (TryGetAuthenticationChallenge(response, isProxyAuth, authUri, credentials, out AuthenticationChallenge challenge)) { if (challenge.AuthenticationType == AuthenticationType.Negotiate || challenge.AuthenticationType == AuthenticationType.Ntlm) { bool isNewConnection = false; bool needDrain = true; try { if (response.Headers.ConnectionClose.GetValueOrDefault()) { // Server is closing the connection and asking us to authenticate on a new connection. (connection, response) = await connectionPool.CreateHttp11ConnectionAsync(request, cancellationToken).ConfigureAwait(false); if (response != null) { return(response); } connectionPool.IncrementConnectionCount(); connection.Acquire(); isNewConnection = true; needDrain = false; } string challengeData = challenge.ChallengeData; // Need to use FQDN normalized host so that CNAME's are traversed. // Use DNS to do the forward lookup to an A (host) record. // But skip DNS lookup on IP literals. Otherwise, we would end up // doing an unintended reverse DNS lookup. string spn; UriHostNameType hnt = authUri.HostNameType; if (hnt == UriHostNameType.IPv6 || hnt == UriHostNameType.IPv4) { spn = authUri.IdnHost; } else { IPHostEntry result = await Dns.GetHostEntryAsync(authUri.IdnHost).ConfigureAwait(false); spn = result.HostName; } spn = "HTTP/" + spn; if (NetEventSource.IsEnabled) { NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, Host: {authUri.IdnHost}, SPN: {spn}"); } ChannelBinding channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); NTAuthentication authContext = new NTAuthentication(isServer: false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection, channelBinding); try { while (true) { string challengeResponse = authContext.GetOutgoingBlob(challengeData); if (challengeResponse == null) { // Response indicated denial even after login, so stop processing and return current response. break; } if (needDrain) { await connection.DrainResponseAsync(response).ConfigureAwait(false); } SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(challenge.SchemeName, challengeResponse), isProxyAuth); response = await InnerSendAsync(request, isProxyAuth, connectionPool, connection, cancellationToken).ConfigureAwait(false); if (authContext.IsCompleted || !TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out challengeData)) { break; } needDrain = true; } } finally { authContext.CloseContext(); } } finally { if (isNewConnection) { connection.Release(); } } } } return(response); }