/// <summary> /// Authenticates the client stream /// </summary> /// <param name="stream">The stream to autenticate</param> /// <param name="userToken">the user token associated with the identity match</param> /// <param name="additionalChallenge">Additional data that much match between the client and server /// for the connection to succeed.</param> /// <returns>true if successful authentication. False otherwise.</returns> public bool TryAuthenticateAsServer(Stream stream, out Guid userToken, byte[] additionalChallenge = null) { userToken = Guid.Empty; if (additionalChallenge == null) additionalChallenge = new byte[] { }; if (additionalChallenge.Length > short.MaxValue) throw new ArgumentOutOfRangeException("additionalChallenge", "Must be less than 32767 bytes"); using (var negotiateStream = new NegotiateStream(stream, true)) { try { negotiateStream.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); } catch (Exception ex) { Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", null, ex); return false; } negotiateStream.Write((short)additionalChallenge.Length); if (additionalChallenge.Length > 0) { negotiateStream.Write(additionalChallenge); } negotiateStream.Flush(); int len = negotiateStream.ReadInt16(); if (len < 0) { Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge Length is invalid: " + len.ToString()); return false; } byte[] remoteChallenge; if (len == 0) { remoteChallenge = new byte[0]; } else { remoteChallenge = negotiateStream.ReadBytes(len); } if (remoteChallenge.SecureEquals(additionalChallenge)) { if (Users.TryGetToken(negotiateStream.RemoteIdentity, out userToken)) { return true; } Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "User did not exist in the database: " + negotiateStream.RemoteIdentity.ToString()); return false; } Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge did not match. Potential man in the middle attack."); return false; } }
public string AuthenticateAsServer(Stream stream) { using (var negotiateStream = new NegotiateStream(stream, true)) { try { negotiateStream.AuthenticateAsServer(); } catch (Exception) { return null; } if (Users.Exists(negotiateStream.RemoteIdentity)) { return ""; } return ""; } }
private static WindowsIdentity LogonUserTCPListen(string userName, string domain, string password) { // need a full duplex stream - loopback is easiest way to get that TcpListener tcpListener = new TcpListener(IPAddress.Loopback, 0); tcpListener.Start(); ManualResetEvent done = new ManualResetEvent(false); WindowsIdentity id = null; tcpListener.BeginAcceptTcpClient(delegate(IAsyncResult asyncResult) { try { using (NegotiateStream serverSide = new NegotiateStream( tcpListener.EndAcceptTcpClient(asyncResult).GetStream())) { serverSide.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.None, TokenImpersonationLevel.Impersonation); id = (WindowsIdentity)serverSide.RemoteIdentity; } } catch { id = null; } finally { done.Set(); } }, null); using (NegotiateStream clientSide = new NegotiateStream(new TcpClient("localhost", ((IPEndPoint)tcpListener.LocalEndpoint).Port).GetStream())) { try { clientSide.AuthenticateAsClient(new NetworkCredential(userName, password, domain), "", ProtectionLevel.None, TokenImpersonationLevel.Impersonation); } catch { id = null; }//When the authentication fails it throws an exception } tcpListener.Stop(); done.WaitOne();//Wait until we really have the id populated to continue return id; }
private WindowsIdentity Authenticate(ref Stream netStream, TcpServerSocketHandler streamManager) { // Use the identity for impersonation etc. NegotiateStream negoServer = null; try { negoServer = new NegotiateStream(netStream); // Block for authentication request TokenImpersonationLevel impLevel = TokenImpersonationLevel.Identification; if (_impersonate) impLevel = TokenImpersonationLevel.Impersonation; negoServer.AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, _protectionLevel, impLevel); netStream = negoServer; return (WindowsIdentity)negoServer.RemoteIdentity; } catch { streamManager.SendErrorResponse( String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_ServerAuthenticationFailed")), false); if (negoServer != null) negoServer.Close(); throw; } }
/// <summary> /// Callback method for asynchronous accept operation. /// </summary> private void ProcessAccept() { TransportProvider<Socket> client = new TransportProvider<Socket>(); SocketAsyncEventArgs receiveArgs = null; TcpClientInfo clientInfo; try { if (CurrentState == ServerState.NotRunning) return; if (m_acceptArgs.SocketError != SocketError.Success) { // Error is unrecoverable. // We need to make sure to restart the // server before we throw the error. SocketError error = m_acceptArgs.SocketError; ThreadPool.QueueUserWorkItem(state => ReStart()); throw new SocketException((int)error); } // Process the newly connected client. client.Provider = m_acceptArgs.AcceptSocket; // Set up SocketAsyncEventArgs for receive operations. receiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(); receiveArgs.Completed += ReceiveHandler; // Return to accepting new connections. m_acceptArgs.AcceptSocket = null; if (!m_tcpServer.AcceptAsync(m_acceptArgs)) { ThreadPool.QueueUserWorkItem(state => ProcessAccept()); } #if !MONO // Authenticate the connected client Windows credentials. if (m_integratedSecurity) { NetworkStream socketStream = null; NegotiateStream authenticationStream = null; try { socketStream = new NetworkStream(client.Provider); authenticationStream = new NegotiateStream(socketStream); authenticationStream.AuthenticateAsServer(); if (authenticationStream.RemoteIdentity is WindowsIdentity) Thread.CurrentPrincipal = new WindowsPrincipal((WindowsIdentity)authenticationStream.RemoteIdentity); } finally { if (socketStream != null) socketStream.Dispose(); if (authenticationStream != null) authenticationStream.Dispose(); } } #endif if (MaxClientConnections != -1 && ClientIDs.Length >= MaxClientConnections) { // Reject client connection since limit has been reached. TerminateConnection(client, receiveArgs, false); } else { // We can proceed further with receiving data from the client. clientInfo = new TcpClientInfo() { Client = client, SendArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(), SendLock = new SpinLock(), SendQueue = new ConcurrentQueue<TcpServerPayload>() }; // Set up socket args. client.SetSendBuffer(SendBufferSize); clientInfo.SendArgs.Completed += m_sendHandler; clientInfo.SendArgs.SetBuffer(client.SendBuffer, 0, client.SendBufferSize); m_clientInfoLookup.TryAdd(client.ID, clientInfo); OnClientConnected(client.ID); if (!m_payloadAware) { receiveArgs.UserToken = client; } else { EventArgs<TransportProvider<Socket>, bool> userToken = ReusableObjectPool<EventArgs<TransportProvider<Socket>, bool>>.Default.TakeObject(); userToken.Argument1 = client; receiveArgs.UserToken = userToken; } ReceivePayloadAsync(client, receiveArgs); } } catch (Exception ex) { // Notify of the exception. if ((object)client.Provider != null) { string clientAddress = ((IPEndPoint)client.Provider.RemoteEndPoint).Address.ToString(); string errorMessage = string.Format("Unable to accept connection to client [{0}]: {1}", clientAddress, ex.Message); OnClientConnectingException(new Exception(errorMessage, ex)); } if ((object)receiveArgs != null) { TerminateConnection(client, receiveArgs, false); } } }
protected override Stream OnAcceptUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { // wrap stream NegotiateStream negotiateStream = new NegotiateStream(stream); // authenticate try { if (TD.WindowsStreamSecurityOnAcceptUpgradeIsEnabled()) { TD.WindowsStreamSecurityOnAcceptUpgrade(this.EventTraceActivity); } negotiateStream.AuthenticateAsServer(parent.ServerCredential, parent.ProtectionLevel, TokenImpersonationLevel.Identification); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.GetString(SR.NegotiationFailedIO, ioException.Message), ioException)); } remoteSecurity = CreateClientSecurity(negotiateStream, parent.ExtractGroupsForWindowsAccounts); return negotiateStream; }
protected override Stream OnAcceptUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { NegotiateStream negotiateStream = new NegotiateStream(stream); try { negotiateStream.AuthenticateAsServer(this.parent.ServerCredential, this.parent.ProtectionLevel, TokenImpersonationLevel.Identification); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("NegotiationFailedIO", new object[] { exception2.Message }), exception2)); } remoteSecurity = this.CreateClientSecurity(negotiateStream, this.parent.ExtractGroupsForWindowsAccounts); return negotiateStream; }
/// <summary> /// Callback method for asynchronous accept operation. /// </summary> private void ProcessAccept(SocketAsyncEventArgs acceptArgs) { TransportProvider<Socket> client = new TransportProvider<Socket>(); SocketAsyncEventArgs receiveArgs = null; WindowsPrincipal clientPrincipal = null; TcpClientInfo clientInfo; try { if (CurrentState == ServerState.NotRunning) return; // If acceptArgs was disposed, m_acceptArgs will either // be null or another instance of SocketAsyncEventArgs. // This check will tell us whether it's been disposed. if ((object)acceptArgs != m_acceptArgs) return; if (acceptArgs.SocketError != SocketError.Success) { // Error is unrecoverable. // We need to make sure to restart the // server before we throw the error. SocketError error = acceptArgs.SocketError; ThreadPool.QueueUserWorkItem(state => ReStart()); throw new SocketException((int)error); } // Process the newly connected client. client.Provider = acceptArgs.AcceptSocket; client.Provider.ReceiveBufferSize = ReceiveBufferSize; // Set up SocketAsyncEventArgs for receive operations. receiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(); receiveArgs.Completed += ReceiveHandler; // Return to accepting new connections. acceptArgs.AcceptSocket = null; if (!m_tcpServer.AcceptAsync(acceptArgs)) { ThreadPool.QueueUserWorkItem(state => ProcessAccept(acceptArgs)); } #if !MONO // Authenticate the connected client Windows credentials. if (m_integratedSecurity) { NetworkStream socketStream = null; NegotiateStream authenticationStream = null; try { socketStream = new NetworkStream(client.Provider); authenticationStream = new NegotiateStream(socketStream); authenticationStream.AuthenticateAsServer(); if (authenticationStream.RemoteIdentity is WindowsIdentity) clientPrincipal = new WindowsPrincipal((WindowsIdentity)authenticationStream.RemoteIdentity); } catch (InvalidCredentialException) { if (!m_ignoreInvalidCredentials) throw; } finally { if (socketStream != null) socketStream.Dispose(); if (authenticationStream != null) authenticationStream.Dispose(); } } #endif if (MaxClientConnections != -1 && ClientIDs.Length >= MaxClientConnections) { // Reject client connection since limit has been reached. TerminateConnection(client, receiveArgs, false); } else { // We can proceed further with receiving data from the client. clientInfo = new TcpClientInfo { Client = client, SendArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(), SendLock = new object(), SendQueue = new ConcurrentQueue<TcpServerPayload>(), ClientPrincipal = clientPrincipal }; // Create operation to dump send queue payloads when the queue grows too large. clientInfo.DumpPayloadsOperation = new ShortSynchronizedOperation(() => { TcpServerPayload 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(string.Format("Client {0} connected to TCP server reached maximum send queue size. {1} payloads dumped from the queue.", clientInfo.Client.ID, m_maxSendQueueSize)); } }, ex => OnSendClientDataException(clientInfo.Client.ID, ex)); // Set up socket args. client.SetSendBuffer(SendBufferSize); clientInfo.SendArgs.Completed += m_sendHandler; clientInfo.SendArgs.SetBuffer(client.SendBuffer, 0, client.SendBufferSize); m_clientInfoLookup.TryAdd(client.ID, clientInfo); OnClientConnected(client.ID); if (!m_payloadAware) { receiveArgs.UserToken = client; } else { EventArgs<TransportProvider<Socket>, bool> userToken = FastObjectFactory<EventArgs<TransportProvider<Socket>, bool>>.CreateObjectFunction(); userToken.Argument1 = client; receiveArgs.UserToken = userToken; } ReceivePayloadAsync(client, receiveArgs); } } catch (ObjectDisposedException) { // m_acceptArgs may be disposed while in the middle of accepting a connection } catch (Exception ex) { // Notify of the exception. if ((object)client.Provider != null && (object)client.Provider.RemoteEndPoint != null) { string clientAddress = ((IPEndPoint)client.Provider.RemoteEndPoint).Address.ToString(); string errorMessage = string.Format("Unable to accept connection to client [{0}]: {1}", clientAddress, ex.Message); OnClientConnectingException(new Exception(errorMessage, ex)); } else { string errorMessage = string.Format("Unable to accept connection to client [unknown]: {0}", ex.Message); OnClientConnectingException(new Exception(errorMessage, ex)); } if ((object)receiveArgs != null) { TerminateConnection(client, receiveArgs, false); } } }
private static void ProcessDebugRequest(object socket) { Socket request = (Socket)socket; try { var secureStream = new NegotiateStream(new NetworkStream(request, false), true); secureStream.AuthenticateAsServer(); if (!secureStream.IsAuthenticated || !secureStream.IsEncrypted) { request.Close(); return; } WindowsIdentity winIdentity = secureStream.RemoteIdentity as WindowsIdentity; if (winIdentity == null || winIdentity.User != System.Security.Principal.WindowsIdentity.GetCurrent().User) { request.Close(); return; } var reader = new StreamReader(secureStream); string auth = reader.ReadLine(); Guid g; if (!Guid.TryParse(auth, out g) || g != _authGuid) { request.Close(); return; } string exe = reader.ReadLine(); string curDir = reader.ReadLine(); string projectDir = reader.ReadLine(); string args = reader.ReadLine(); string machineName = reader.ReadLine(); string options = reader.ReadLine(); uint pid = 0; string errorText = ""; var res = _pumpForm.BeginInvoke((Action)(() => { pid = LaunchDebugger(exe, curDir, projectDir, args, machineName, options, out errorText); })); res.AsyncWaitHandle.WaitOne(); var writer = new StreamWriter(secureStream); writer.WriteLine(pid.ToString()); if (pid == 0) { writer.WriteLine(errorText.Length); writer.WriteLine(errorText); } writer.Flush(); } catch (IOException) { } catch (Exception) { Debug.Assert(false); } }
private WindowsIdentity Authenticate(ref Stream netStream, TcpServerSocketHandler streamManager) { NegotiateStream stream = null; WindowsIdentity remoteIdentity; try { stream = new NegotiateStream(netStream); TokenImpersonationLevel identification = TokenImpersonationLevel.Identification; if (this._impersonate) { identification = TokenImpersonationLevel.Impersonation; } stream.AuthenticateAsServer((NetworkCredential) CredentialCache.DefaultCredentials, this._protectionLevel, identification); netStream = stream; remoteIdentity = (WindowsIdentity) stream.RemoteIdentity; } catch { streamManager.SendErrorResponse(string.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_ServerAuthenticationFailed"), new object[0]), false); if (stream != null) { stream.Close(); } throw; } return remoteIdentity; }