public static void Main(string[] args) { if(args.Length != 1) { Console.WriteLine("need ipadress "); return; } IPAddress ipAddress = IPAddress.Parse(args[0]); int port = 7681; TcpClient client = new TcpClient(); client.ConnectAsync(ipAddress, port).Wait(); Console.WriteLine("connected"); using (NegotiateStream stream = new NegotiateStream(client.GetStream())) { Console.WriteLine("authenticating"); stream.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, null, "HOST/skapilac10.fareast.corp.microsoft.com").Wait(); Console.WriteLine("authenticated"); var sendBuffer = Encoding.UTF8.GetBytes("Request from client"); stream.Write(sendBuffer, 0, sendBuffer.Length); var recvBuffer = new byte[1024]; var byteCount = stream.Read(recvBuffer, 0, recvBuffer.Length); Console.WriteLine("Recieved: {0}", Encoding.UTF8.GetString(recvBuffer, 0, byteCount)); } }
/// <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; } }
/// <summary> /// Authenticates the client using the supplied stream. /// </summary> /// <param name="stream">the stream to use to authenticate the connection.</param> /// <param name="additionalChallenge">Additional data that much match between the client and server /// for the connection to succeed.</param> /// <returns> /// True if authentication succeded, false otherwise. /// </returns> public bool TryAuthenticateAsClient(Stream stream, byte[] additionalChallenge = null) { 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.AuthenticateAsClient(m_credentials, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); } catch (Exception ex) { Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", null, ex); return false; } //Exchange the challenge data. //Since NegotiateStream is already a trusted stream //Simply writing the raw is as secure as creating a challenge response 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)) { return true; } else { 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; } } }
private void AcceptCallback(IAsyncResult ar) { try { Socket acceptSocket; acceptSocket = server.EndAccept(ar); nws = new NetworkStream(acceptSocket); ns = new NegotiateStream(nws); ns.BeginAuthenticateAsServer(AuthCallback, ns); } catch (Exception e) { Console.WriteLine(e.Message); } }
public bool AuthenticateAsClient(Stream stream) { using (var negotiateStream = new NegotiateStream(stream, true)) { try { negotiateStream.AuthenticateAsClient(m_credentials, string.Empty); } catch (Exception) { return false; } return true; } }
private static async Task RespondToOneMsg(TcpListener listener) { var socket = await listener.AcceptSocketAsync(); var client = await listener.AcceptTcpClientAsync(); Console.WriteLine("Connected"); using (var stream = new NegotiateStream(client.GetStream())) { await stream.AuthenticateAsServerAsync(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); Console.WriteLine($"remote {stream.RemoteIdentity.AuthenticationType}"); Console.WriteLine($"remote name = {stream.RemoteIdentity.Name}"); var recvBuffer = new byte[1024]; var byteCount = stream.Read(recvBuffer, 0, recvBuffer.Length); Console.WriteLine(Encoding.UTF8.GetString(recvBuffer, 0, byteCount)); var sendBuffer = Encoding.UTF8.GetBytes("Reply from server"); stream.Write(sendBuffer, 0, sendBuffer.Length); } }
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 ""; } }
protected override Stream OnAcceptUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { #if SUPPORTS_WINDOWSIDENTITY // NegotiateStream // wrap stream NegotiateStream negotiateStream = new NegotiateStream(stream); // authenticate try { if (WcfEventSource.Instance.WindowsStreamSecurityOnAcceptUpgradeIsEnabled()) { WcfEventSource.Instance.WindowsStreamSecurityOnAcceptUpgrade(EventTraceActivity); } negotiateStream.AuthenticateAsServerAsync(_parent.ServerCredential, _parent.ProtectionLevel, TokenImpersonationLevel.Identification).GetAwaiter().GetResult(); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.Format(SR.NegotiationFailedIO, ioException.Message), ioException)); } remoteSecurity = CreateClientSecurity(negotiateStream, _parent.ExtractGroupsForWindowsAccounts); return negotiateStream; #else throw ExceptionHelper.PlatformNotSupported(ExceptionHelper.WinsdowsStreamSecurityNotSupported); #endif // SUPPORTS_WINDOWSIDENTITY }
SecurityMessageProperty CreateClientSecurity(NegotiateStream negotiateStream, bool extractGroupsForWindowsAccounts) { WindowsIdentity remoteIdentity = (WindowsIdentity)negotiateStream.RemoteIdentity; SecurityUtils.ValidateAnonymityConstraint(remoteIdentity, false); WindowsSecurityTokenAuthenticator authenticator = new WindowsSecurityTokenAuthenticator(extractGroupsForWindowsAccounts); // When NegotiateStream returns a WindowsIdentity the AuthenticationType is passed in the constructor to WindowsIdentity // by it's internal NegoState class. If this changes, then the call to remoteIdentity.AuthenticationType could fail if the // current process token doesn't have sufficient priviledges. It is a first class exception, and caught by the CLR // null is returned. SecurityToken token = new WindowsSecurityToken(remoteIdentity, SecurityUniqueId.Create().Value, remoteIdentity.AuthenticationType); ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = authenticator.ValidateToken(token); _clientSecurity = new SecurityMessageProperty(); _clientSecurity.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies); _clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies); return _clientSecurity; }
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; } }
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 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 SecurityMessageProperty CreateClientSecurity(NegotiateStream negotiateStream, bool extractGroupsForWindowsAccounts) { WindowsIdentity remoteIdentity = (WindowsIdentity) negotiateStream.RemoteIdentity; System.ServiceModel.Security.SecurityUtils.ValidateAnonymityConstraint(remoteIdentity, false); WindowsSecurityTokenAuthenticator authenticator = new WindowsSecurityTokenAuthenticator(extractGroupsForWindowsAccounts); SecurityToken token = new WindowsSecurityToken(remoteIdentity, SecurityUniqueId.Create().Value, remoteIdentity.AuthenticationType); ReadOnlyCollection<IAuthorizationPolicy> tokenPolicies = authenticator.ValidateToken(token); this.clientSecurity = new SecurityMessageProperty(); this.clientSecurity.TransportToken = new SecurityTokenSpecification(token, tokenPolicies); this.clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(tokenPolicies); return this.clientSecurity; }
/// <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); } }
void ValidateMutualAuth(EndpointIdentity expectedIdentity, NegotiateStream negotiateStream, SecurityMessageProperty remoteSecurity, bool allowNtlm) { if (negotiateStream.IsMutuallyAuthenticated) { if (expectedIdentity != null) { if (!_parent.IdentityVerifier.CheckAccess(expectedIdentity, remoteSecurity.ServiceSecurityContext.AuthorizationContext)) { string primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(remoteSecurity.ServiceSecurityContext.AuthorizationContext); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.Format( SR.RemoteIdentityFailedVerification, primaryIdentity))); } } } else if (!allowNtlm) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.Format(SR.StreamMutualAuthNotSatisfied))); } }
private void ValidateMutualAuth(EndpointIdentity expectedIdentity, NegotiateStream negotiateStream, SecurityMessageProperty remoteSecurity, bool allowNtlm) { if (negotiateStream.IsMutuallyAuthenticated) { if ((expectedIdentity != null) && !this.parent.IdentityVerifier.CheckAccess(expectedIdentity, remoteSecurity.ServiceSecurityContext.AuthorizationContext)) { string identityNamesFromContext = System.ServiceModel.Security.SecurityUtils.GetIdentityNamesFromContext(remoteSecurity.ServiceSecurityContext.AuthorizationContext); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("RemoteIdentityFailedVerification", new object[] { identityNamesFromContext }))); } } else if (!allowNtlm) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("StreamMutualAuthNotSatisfied"))); } }
} // CreateSocketHandler #if !FEATURE_PAL private Stream CreateAuthenticatedStream(Stream netStream, String machinePortAndSid) { //Check for explicitly set userName, and authenticate using it NetworkCredential credentials = null; NegotiateStream negoClient = null; if (_securityUserName != null) { credentials = new NetworkCredential(_securityUserName, _securityPassword, _securityDomain); } //else use default Credentials else { credentials = (NetworkCredential)CredentialCache.DefaultCredentials; } try { negoClient = new NegotiateStream(netStream); negoClient.AuthenticateAsClient(credentials, _spn, _protectionLevel, _tokenImpersonationLevel); } catch(IOException e){ throw new RemotingException( String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_AuthenticationFailed")), e); } return negoClient; }
private void InitiateUpgradePrepare(Stream stream, out NegotiateStream negotiateStream, out string targetName, out EndpointIdentity identity) { negotiateStream = new NegotiateStream(stream); targetName = string.Empty; identity = null; if (this.parent.IdentityVerifier.TryGetIdentity(base.RemoteAddress, base.Via, out identity)) { targetName = System.ServiceModel.Security.SecurityUtils.GetSpnFromIdentity(identity, base.RemoteAddress); } else { targetName = System.ServiceModel.Security.SecurityUtils.GetSpnFromTarget(base.RemoteAddress); } }
private static SecurityMessageProperty CreateServerSecurity(NegotiateStream negotiateStream) { GenericIdentity remoteIdentity = (GenericIdentity) negotiateStream.RemoteIdentity; string name = remoteIdentity.Name; if ((name != null) && (name.Length > 0)) { ReadOnlyCollection<IAuthorizationPolicy> tokenPolicies = System.ServiceModel.Security.SecurityUtils.CreatePrincipalNameAuthorizationPolicies(name); return new SecurityMessageProperty { TransportToken = new SecurityTokenSpecification(null, tokenPolicies), ServiceSecurityContext = new ServiceSecurityContext(tokenPolicies) }; } return null; }
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; }
static SecurityMessageProperty CreateServerSecurity(NegotiateStream negotiateStream) { GenericIdentity remoteIdentity = (GenericIdentity)negotiateStream.RemoteIdentity; string principalName = remoteIdentity.Name; if ((principalName != null) && (principalName.Length > 0)) { ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = SecurityUtils.CreatePrincipalNameAuthorizationPolicies(principalName); SecurityMessageProperty result = new SecurityMessageProperty(); result.TransportToken = new SecurityTokenSpecification(null, authorizationPolicies); result.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies); return result; } else { return null; } }
private Stream CreateAuthenticatedStream(Stream netStream, string machinePortAndSid) { NetworkCredential defaultCredentials = null; NegotiateStream stream = null; if (this._securityUserName != null) { defaultCredentials = new NetworkCredential(this._securityUserName, this._securityPassword, this._securityDomain); } else { defaultCredentials = (NetworkCredential) CredentialCache.DefaultCredentials; } try { stream = new NegotiateStream(netStream); stream.AuthenticateAsClient(defaultCredentials, this._spn, this._protectionLevel, this._tokenImpersonationLevel); } catch (IOException exception) { throw new RemotingException(string.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_AuthenticationFailed"), new object[0]), exception); } return stream; }
void InitiateUpgradePrepare( Stream stream, out NegotiateStream negotiateStream, out string targetName, out EndpointIdentity identity) { negotiateStream = new NegotiateStream(stream); targetName = string.Empty; identity = null; if (_parent.IdentityVerifier.TryGetIdentity(RemoteAddress, Via, out identity)) { targetName = SecurityUtils.GetSpnFromIdentity(identity, RemoteAddress); } else { targetName = SecurityUtils.GetSpnFromTarget(RemoteAddress); } }
protected override IAsyncResult OnBegin(Stream stream, AsyncCallback callback) { this.negotiateStream = new NegotiateStream(stream); return this.negotiateStream.BeginAuthenticateAsServer(this.acceptor.parent.ServerCredential, this.acceptor.parent.ProtectionLevel, TokenImpersonationLevel.Identification, callback, this); }
public static int Main(string[] args) { if (args.Length < 7) { Help(); return -1; } int port; if (!Int32.TryParse(args[0], out port)) { Console.WriteLine("Got bad port number for arg 1"); return -2; } Guid authGuid; if (!Guid.TryParse(args[1], out authGuid)) { Console.WriteLine("Got bad auth guid for arg 2"); return -3; } var addrs = Dns.GetHostAddresses(args[2]); if (addrs.Length == 0) { Console.WriteLine("Cannot connect back to VisualStudio machine"); return -4; } string curDir = args[3]; string projectDir = args[4]; string options = args[5]; string exe = args[6]; if (!File.Exists(exe)) { Console.WriteLine("{0} does not exist, please install the Python interpreter or update the project debug settings to point at the correct interpreter.", exe); } Guid launchId = Guid.NewGuid(); ManualResetEvent launchEvent = new ManualResetEvent(false); #pragma warning disable 618 // Handle is obsolete but we need it. string msVsMonArgs = "/__dbgautolaunch 0x" + launchEvent.Handle.ToString("X") + " 0x" + Process.GetCurrentProcess().Id.ToString("X") + " /name " + launchId.ToString() + " /timeout:600"; #pragma warning restore 618 Process msvsmonProc; try { var procStartInfo = new ProcessStartInfo( Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "msvsmon.exe"), msVsMonArgs); procStartInfo.UseShellExecute = false; msvsmonProc = Process.Start(procStartInfo); } catch(Exception e) { Console.WriteLine("Failed to start " + Path.Combine(Assembly.GetExecutingAssembly().Location, "msvsmon.exe")); Console.WriteLine(e); return -7; } var processEvent = new ManualResetEvent(true); processEvent.SafeWaitHandle = new SafeWaitHandle(msvsmonProc.Handle, false); if (WaitHandle.WaitAny(new[] { launchEvent, processEvent }) != 0) { Console.WriteLine("Failed to initialize msvsmon"); return -5; } try { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)) { socket.Blocking = true; socket.Connect(new IPEndPoint(addrs[0], port)); var secureStream = new NegotiateStream(new NetworkStream(socket, false), true); secureStream.AuthenticateAsClient(); var writer = new StreamWriter(secureStream); writer.WriteLine(authGuid.ToString()); writer.WriteLine(exe); writer.WriteLine(curDir); writer.WriteLine(projectDir); writer.WriteLine(String.Join(" ", args.Skip(7).Select(MaybeQuote))); writer.WriteLine(launchId + "@" + Environment.MachineName); writer.WriteLine(options); writer.Flush(); var reader = new StreamReader(secureStream); var procId = reader.ReadLine(); var processId = Int32.Parse(procId); if (processId != 0) { var debuggee = Process.GetProcessById(processId); debuggee.WaitForExit(); msvsmonProc.WaitForExit(); } else { int errorLen = Int32.Parse(reader.ReadLine()); char[] buffer = new char[errorLen]; int bytesRead = reader.Read(buffer, 0, buffer.Length); Console.WriteLine("failed to get process to debug: {0}", new string(buffer, 0, bytesRead)); return -6; } } } catch (SocketException) { Console.WriteLine("Failed to connect back to Visual Studio process."); msvsmonProc.Kill(); return -8; } GC.KeepAlive(launchEvent); GC.KeepAlive(msvsmonProc); return 0; }
/// <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); } } }
/// <summary> /// Performs NTLM and Kerberos authentication via the Security Support /// Provider Interface (SSPI). /// </summary> /// <param name="tag">The tag identifier to use for performing the /// authentication commands.</param> /// <param name="username">The username with which to login in to the /// IMAP server.</param> /// <param name="password">The password with which to log in to the /// IMAP server.</param> /// <param name="useNtlm">True to authenticate using NTLM, otherwise /// GSSAPI (Kerberos) is used.</param> /// <returns>The response sent by the server.</returns> private string SspiAuthenticate(string tag, string username, string password, bool useNtlm) { string response = SendCommandGetResponse(tag + "AUTHENTICATE " + (useNtlm ? "NTLM" : "GSSAPI")); // If we get a BAD or NO response, the mechanism is not supported. if (response.StartsWith(tag + "BAD") || response.StartsWith(tag + "NO")) { throw new NotSupportedException("The requested authentication " + "mechanism is not supported by the server."); } using (FilterStream fs = new FilterStream(stream, true)) { using (NegotiateStream ns = new NegotiateStream(fs, true)) { try { ns.AuthenticateAsClient( new NetworkCredential(username, password), null, String.Empty, useNtlm ? ProtectionLevel.None : ProtectionLevel.EncryptAndSign, System.Security.Principal.TokenImpersonationLevel.Delegation); } catch { return String.Empty; } } } response = GetResponse(); // Swallow any continuation data we unexpectedly receive from the server. while (response.StartsWith("+ ")) response = SendCommandGetResponse(String.Empty); return response; }
/// <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); } } }
/// <summary> /// Callback method for asynchronous connect operation. /// </summary> private void ProcessConnect() { try { // Perform post-connect operations. m_connectionAttempts++; if (m_connectArgs.SocketError != SocketError.Success) throw new SocketException((int)m_connectArgs.SocketError); #if !MONO // Send current Windows credentials for authentication. if (m_integratedSecurity) { NetworkStream socketStream = null; NegotiateStream authenticationStream = null; try { socketStream = new NetworkStream(m_tcpClient.Provider); authenticationStream = new NegotiateStream(socketStream); authenticationStream.AuthenticateAsClient(); } finally { if (socketStream != null) socketStream.Dispose(); if (authenticationStream != null) authenticationStream.Dispose(); } } #endif // Set up send and receive args. using (SocketAsyncEventArgs sendArgs = m_sendArgs, receiveArgs = m_receiveArgs) { m_sendArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(); m_receiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(); } m_tcpClient.SetSendBuffer(SendBufferSize); m_sendArgs.SetBuffer(m_tcpClient.SendBuffer, 0, m_tcpClient.SendBufferSize); m_sendArgs.Completed += m_sendHandler; m_receiveArgs.Completed += ReceiveHandler; // Notify user of established connection. m_connectWaitHandle.Set(); OnConnectionEstablished(); // Set up send buffer and begin receiving. ReceivePayloadAsync(); } catch (SocketException ex) { OnConnectionException(ex); if (ex.SocketErrorCode == SocketError.ConnectionRefused && (MaxConnectionAttempts == -1 || m_connectionAttempts < MaxConnectionAttempts)) { // Server is unavailable, so keep retrying connection to the server. try { ConnectAsync(); } catch { TerminateConnection(); } } else { // For any other reason, clean-up as if the client was disconnected. TerminateConnection(); } } catch (Exception ex) { // This is highly unlikely, but we must handle this situation just-in-case. OnConnectionException(ex); TerminateConnection(); } }
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; }