public static bool IsServiceAvailable() { string pipeName = null; var callerProcessId = Process.GetCurrentProcess().Id; string user = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value; while (callerProcessId > 0) { callerProcessId = ProcessHelper.GetParentProcessId(callerProcessId); pipeName = NamedPipeNameFactory.GetPipeName(user, callerProcessId); // Does the pipe exists? if (NamedPipeUtils.ExistsNamedPipe(pipeName)) { break; } pipeName = null; // try grandfather. } return(pipeName != null); }
public async Task Listen() { var ps = new PipeSecurity(); ps.AddAccessRule(new PipeAccessRule( new SecurityIdentifier(_allowedSid), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow)); var networkSid = new SecurityIdentifier("S-1-5-2"); // deny remote connections. ps.AddAccessRule(new PipeAccessRule( networkSid, PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Deny)); var pipeName = NamedPipeNameFactory.GetPipeName(_allowedSid, _allowedPid); Logger.Instance.Log($"Listening on named pipe {pipeName}.", LogLevel.Debug); Logger.Instance.Log($"Access allowed only for ProcessID {_allowedPid} and children", LogLevel.Debug); _ = Task.Factory.StartNew(CancelIfAllowedProcessEnds, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current); do { using (NamedPipeServerStream dataPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, MAX_SERVER_INSTANCES, PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps)) { using (NamedPipeServerStream controlPipe = new NamedPipeServerStream(pipeName + "_control", PipeDirection.InOut, MAX_SERVER_INSTANCES, PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps)) { Logger.Instance.Log("NamedPipeServer listening.", LogLevel.Debug); Task.WaitAll( new Task[] { dataPipe.WaitForConnectionAsync(_cancellationTokenSource.Token), controlPipe.WaitForConnectionAsync(_cancellationTokenSource.Token), }, _cancellationTokenSource.Token ); if (dataPipe.IsConnected && controlPipe.IsConnected && !_cancellationTokenSource.IsCancellationRequested) { var connection = new Connection() { ControlStream = controlPipe, DataStream = dataPipe }; ConnectionKeepAliveThread.Start(connection); Logger.Instance.Log("Incoming Connection.", LogLevel.Info); var clientPid = dataPipe.GetClientProcessId(); if (!IsAuthorized(clientPid, _allowedPid)) { Logger.Instance.Log($"Unauthorized access from PID {clientPid}", LogLevel.Warning); await controlPipe.WriteAsync($"{Constants.TOKEN_ERROR}Unauthorized.{Constants.TOKEN_ERROR}").ConfigureAwait(false); await controlPipe.FlushAsync().ConfigureAwait(false); controlPipe.WaitForPipeDrain(); dataPipe.Disconnect(); controlPipe.Disconnect(); // kill the server. return; } ConnectionAccepted?.Invoke(this, connection); while (connection.IsAlive) { await Task.Delay(10).ConfigureAwait(false); } ConnectionClosed?.Invoke(this, connection); Logger.Instance.Log("Connection Closed.", LogLevel.Info); } } } } while (!_singleUse && !_cancellationTokenSource.IsCancellationRequested); Logger.Instance.Log("Listener Closed.", LogLevel.Debug); _exeLock?.Close(); }
public async Task <Connection> Connect(int?clientPid, bool failFast) { int timeoutMilliseconds = failFast ? 300 : 5000; var server = "."; string pipeName = null; string user = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value; NamedPipeClientStream dataPipe = null; NamedPipeClientStream controlPipe = null; try { if (clientPid.HasValue) { pipeName = NamedPipeNameFactory.GetPipeName(user, clientPid.Value); if (!NamedPipeUtils.ExistsNamedPipe(pipeName) && failFast) { // fail fast without timeout. return(null); } } else { var callerProcessId = Process.GetCurrentProcess().Id; while (callerProcessId > 0) { callerProcessId = ProcessHelper.GetParentProcessId(callerProcessId); pipeName = NamedPipeNameFactory.GetPipeName(user, callerProcessId); // Does the pipe exists? if (NamedPipeUtils.ExistsNamedPipe(pipeName)) { break; } pipeName = null; // try grandfather. } } if (pipeName == null) { return(null); } dataPipe = new NamedPipeClientStream(server, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous, System.Security.Principal.TokenImpersonationLevel.Identification, HandleInheritability.None); await dataPipe.ConnectAsync(timeoutMilliseconds).ConfigureAwait(false); controlPipe = new NamedPipeClientStream(server, pipeName + "_control", PipeDirection.InOut, PipeOptions.Asynchronous, System.Security.Principal.TokenImpersonationLevel.Identification, HandleInheritability.None); await controlPipe.ConnectAsync(timeoutMilliseconds).ConfigureAwait(false); Logger.Instance.Log($"Connected via Named Pipe {pipeName}.", LogLevel.Debug); var conn = new Connection() { ControlStream = controlPipe, DataStream = dataPipe, }; return(conn); } catch (System.TimeoutException) { dataPipe?.Dispose(); controlPipe?.Dispose(); return(null); } catch { dataPipe?.Dispose(); controlPipe?.Dispose(); throw; } }