private void ProcessIntegratedSecurityAuthentication(IAsyncResult asyncResult) { Tuple<TransportProvider<TlsSocket>, NegotiateStream> state = (Tuple<TransportProvider<TlsSocket>, NegotiateStream>)asyncResult.AsyncState; TransportProvider<TlsSocket> client = state.Item1; IPEndPoint remoteEndPoint = client.Provider.Socket.RemoteEndPoint as IPEndPoint; NegotiateStream negotiateStream = state.Item2; WindowsPrincipal clientPrincipal = null; try { try { negotiateStream.EndAuthenticateAsServer(asyncResult); if (negotiateStream.RemoteIdentity is WindowsIdentity) clientPrincipal = new WindowsPrincipal((WindowsIdentity)negotiateStream.RemoteIdentity); } catch (InvalidCredentialException) { if (!m_ignoreInvalidCredentials) throw; } TlsClientInfo clientInfo = new TlsClientInfo { Client = client, SendLock = new object(), SendQueue = new ConcurrentQueue<TlsServerPayload>(), ClientPrincipal = clientPrincipal }; // Create operation to dump send queue payloads when the queue grows too large. clientInfo.DumpPayloadsOperation = new ShortSynchronizedOperation(() => { TlsServerPayload payload; // Check to see if the client has reached the maximum send queue size. if (m_maxSendQueueSize > 0 && clientInfo.SendQueue.Count >= m_maxSendQueueSize) { for (int i = 0; i < m_maxSendQueueSize; i++) { if (clientInfo.SendQueue.TryDequeue(out payload)) { payload.WaitHandle.Set(); payload.WaitHandle.Dispose(); payload.WaitHandle = null; } } throw new InvalidOperationException($"Client {clientInfo.Client.ID} connected to TCP server reached maximum send queue size. {m_maxSendQueueSize} payloads dumped from the queue."); } }, ex => OnSendClientDataException(clientInfo.Client.ID, ex)); // We can proceed further with receiving data from the client. m_clientInfoLookup.TryAdd(client.ID, clientInfo); OnClientConnected(client.ID); ReceivePayloadAsync(client); } catch (Exception ex) { // Notify of the exception. if ((object)remoteEndPoint != null) { string clientAddress = remoteEndPoint.Address.ToString(); string errorMessage = $"Unable to authenticate connection to client [{clientAddress}]: {ex.Message}"; OnClientConnectingException(new Exception(errorMessage, ex)); } TerminateConnection(client, false); } finally { negotiateStream.Dispose(); } }
/// <summary> /// Callback method for asynchronous authenticate operation. /// </summary> private void ProcessTlsAuthentication(IAsyncResult asyncResult) { TransportProvider<TlsSocket> client = (TransportProvider<TlsSocket>)asyncResult.AsyncState; IPEndPoint remoteEndPoint = client.Provider.Socket.RemoteEndPoint as IPEndPoint; SslStream stream = client.Provider.SslStream; try { stream.EndAuthenticateAsServer(asyncResult); if (EnabledSslProtocols != SslProtocols.None) { if (!stream.IsAuthenticated) throw new InvalidOperationException("Unable to authenticate."); if (!stream.IsEncrypted) throw new InvalidOperationException("Unable to encrypt data stream."); } if (m_integratedSecurity) { #if !MONO NegotiateStream negotiateStream = new NegotiateStream(stream, true); negotiateStream.BeginAuthenticateAsServer(ProcessIntegratedSecurityAuthentication, Tuple.Create(client, negotiateStream)); #endif } else { TlsClientInfo clientInfo = new TlsClientInfo { Client = client, SendLock = new object(), SendQueue = new ConcurrentQueue<TlsServerPayload>() }; // Create operation to dump send queue payloads when the queue grows too large. clientInfo.DumpPayloadsOperation = new ShortSynchronizedOperation(() => { TlsServerPayload payload; // Check to see if the client has reached the maximum send queue size. if (m_maxSendQueueSize > 0 && clientInfo.SendQueue.Count >= m_maxSendQueueSize) { for (int i = 0; i < m_maxSendQueueSize; i++) { if (clientInfo.SendQueue.TryDequeue(out payload)) { payload.WaitHandle.Set(); payload.WaitHandle.Dispose(); payload.WaitHandle = null; } } throw new InvalidOperationException($"Client {clientInfo.Client.ID} connected to TCP server reached maximum send queue size. {m_maxSendQueueSize} payloads dumped from the queue."); } }, ex => OnSendClientDataException(clientInfo.Client.ID, ex)); // We can proceed further with receiving data from the client. m_clientInfoLookup.TryAdd(client.ID, clientInfo); OnClientConnected(client.ID); ReceivePayloadAsync(client); } } catch (Exception ex) { // Notify of the exception. if ((object)remoteEndPoint != null) { string clientAddress = remoteEndPoint.Address.ToString(); string errorMessage = $"Unable to authenticate connection to client [{clientAddress}]: {CertificateChecker.ReasonForFailure ?? ex.Message}"; OnClientConnectingException(new Exception(errorMessage, ex)); } TerminateConnection(client, false); } }