/// <summary> /// Sets <see cref="PipeSecurity"/>'s for each <see cref="NamedPipeServerStream"/> that will be created by <see cref="PipeServer{T}"/> <br/> /// Overrides <see cref="PipeServer{T}.CreatePipeStreamFunc"/> /// </summary> /// <param name="server"></param> /// <param name="pipeSecurity"></param> /// <exception cref="ArgumentNullException"></exception> /// <returns></returns> public static void SetPipeSecurity <T>(this IPipeServer <T> server, PipeSecurity pipeSecurity) { server = server ?? throw new ArgumentNullException(nameof(server)); pipeSecurity = pipeSecurity ?? throw new ArgumentNullException(nameof(pipeSecurity)); server.CreatePipeStreamFunc = pipeName => NamedPipeServerStreamConstructors.New(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); }
/// <summary> /// Constructs a new named pipe server for IPC, with a channel name derived from the class /// namespace and the current machine's digital fingerprint. /// </summary> public IPCServer() { m_logger = LoggerUtil.GetAppWideLogger(); var channel = string.Format("{0}.{1}", nameof(Citadel.IPC), FingerprintService.Default.Value2).ToLower(); m_server = PlatformTypes.New <IPipeServer>(channel); //m_server = new NamedPipeServer<BaseMessage>(channel, security); m_server.ClientConnected += OnClientConnected; m_server.ClientDisconnected += OnClientDisconnected; m_server.ClientMessage += OnClientMessage; m_server.Error += M_server_Error; // Server is no longer started by constructor. We start the IPCServer after everything else has been set up by the FilterServiceProvider. m_ipcQueue = new IPCMessageTracker(this); m_callbacks.Add(typeof(AddSelfModerationEntryMessage), (msg) => { AddSelfModerationEntry?.Invoke(msg as AddSelfModerationEntryMessage); }); m_callbacks.Add(typeof(IpcMessage), (msg) => { // The new IPC message Request/Send API handles HandleIpcMessage(msg); }); }
protected virtual void InitInterface() { appCenter = EasyInject.Get <AppCenter>(); tcpCenter = EasyInject.Get <TcpCenter>(); configManager = EasyInject.Get <IConfig>(); P2PClient = EasyInject.Get <P2PClient>(); pipeServer = EasyInject.Get <IPipeServer>(); }
public ServerPipe(string name, IPipeServer server) : base(name) { this.server = server; thread = new Thread(new ThreadStart(PipeListener)); thread.IsBackground = true; thread.Name = "Pipe Thread"; thread.Start(); }
protected void InitSelf() { appCenter = EasyInject.Get <AppCenter>(); tcpCenter = EasyInject.Get <TcpCenter>(); configManager = EasyInject.Get <IConfig>(); P2PClient = EasyInject.Get <P2PClient>(); pipeServer = EasyInject.Get <IPipeServer>(); pipeServer.Start(); }
/// <summary> /// Adds <see cref="PipeAccessRule"/>'s for each <see cref="NamedPipeServerStream"/> that will be created by <see cref="PipeServer{T}"/> /// </summary> /// <param name="server"></param> /// <param name="rules"></param> /// <exception cref="ArgumentNullException"></exception> /// <returns></returns> public static void AddAccessRules <T>(this IPipeServer <T> server, params PipeAccessRule[] rules) { server = server ?? throw new ArgumentNullException(nameof(rules)); rules = rules ?? throw new ArgumentNullException(nameof(rules)); var pipeSecurity = new PipeSecurity(); foreach (var rule in rules) { pipeSecurity.AddAccessRule(rule); } server.SetPipeSecurity(pipeSecurity); }
private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { if (m_server != null) { #if CLIFTON m_server.Close(); #else m_server.Stop(); #endif m_server = null; } } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } }
/// <summary> /// Handles a received client message. /// </summary> /// <param name="connection"> /// The connection over which the message was received. /// </param> /// <param name="message"> /// The client's message to us. /// </param> private void OnClientMessage(IPipeServer server, BaseMessage message) { // This is so gross, but unfortuantely we can't just switch on a type. We can come up // with a nice mapping system so we can do a switch, but this can wait. m_logger.Debug("Got IPC message from client."); if (m_ipcQueue.HandleMessage(message)) { return; } var msgRealType = message.GetType(); Action <BaseMessage> callback = null; if (m_callbacks.TryGetValue(msgRealType, out callback)) { m_logger.Debug("Client message is {0}", msgRealType.Name); callback?.Invoke(message); } if (msgRealType == typeof(Messages.AuthenticationMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.AuthenticationMessage)); var cast = (Messages.AuthenticationMessage)message; if (cast != null) { if (string.IsNullOrEmpty(cast.Username) || string.IsNullOrWhiteSpace(cast.Username)) { PushMessage(new AuthenticationMessage(AuthenticationAction.InvalidInput)); return; } if (cast.Password == null || cast.Password.Length <= 0) { PushMessage(new AuthenticationMessage(AuthenticationAction.InvalidInput)); return; } var args = new AuthenticationRequestArgs(cast); AttemptAuthentication?.Invoke(args); } } else if (msgRealType == typeof(Messages.DeactivationMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.DeactivationMessage)); var cast = (Messages.DeactivationMessage)message; if (cast != null && cast.Command == DeactivationCommand.Requested) { var args = new DeactivationRequestEventArgs(); // This fills args.DeactivationCommand. DeactivationRequested?.Invoke(args); PushMessage(new DeactivationMessage(args.DeactivationCommand)); } } else if (msgRealType == typeof(Messages.RelaxedPolicyMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.RelaxedPolicyMessage)); var cast = (Messages.RelaxedPolicyMessage)message; if (cast != null) { var args = new RelaxedPolicyEventArgs(cast); RelaxedPolicyRequested?.Invoke(args); } } else if (msgRealType == typeof(Messages.ClientToClientMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.ClientToClientMessage)); var cast = (Messages.ClientToClientMessage)message; if (cast != null) { // Just relay this message to all clients. PushMessage(cast); } } else if (msgRealType == typeof(Messages.FilterStatusMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.FilterStatusMessage)); var cast = (Messages.FilterStatusMessage)message; if (cast != null) { ClientServerStateQueried?.Invoke(new StateChangeEventArgs(cast)); } } else if (msgRealType == typeof(Messages.ClientUpdateResponseMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.ClientUpdateResponseMessage)); var cast = (Messages.ClientUpdateResponseMessage)message; if (cast != null) { if (cast.Accepted) { m_logger.Debug("Client has accepted update."); ClientAcceptedPendingUpdate?.Invoke(); } } } else if (msgRealType == typeof(Messages.BlockActionReviewRequestMessage)) { m_logger.Debug("Client message is {0}", nameof(Messages.BlockActionReviewRequestMessage)); var cast = (Messages.BlockActionReviewRequestMessage)message; if (cast != null) { Uri output; if (Uri.TryCreate(cast.FullRequestUrl, UriKind.Absolute, out output)) { // Here we'll just recycle the block action message and handler. ClientRequestsBlockActionReview?.Invoke(new NotifyBlockActionMessage(BlockType.OtherContentClassification, output, string.Empty, cast.CategoryName, DateTime.Now)); } else { m_logger.Info("Failed to create absolute URI for string \"{0}\".", cast.FullRequestUrl); } } } else if (msgRealType == typeof(Messages.CaptivePortalDetectionMessage)) { m_logger.Debug("Server message is {0}", nameof(Messages.CaptivePortalDetectionMessage)); var cast = (Messages.CaptivePortalDetectionMessage)message; if (cast != null) { RequestCaptivePortalDetection?.Invoke(cast); } } else if (msgRealType == typeof(Messages.CertificateExemptionMessage)) { m_logger.Debug("Server message is {0}", nameof(Messages.CertificateExemptionMessage)); var cast = (Messages.CertificateExemptionMessage)message; if (cast != null) { this.OnCertificateExemptionGranted?.Invoke(new CertificateExemptionEventArgs(cast)); } } else if (msgRealType == typeof(Messages.DiagnosticsMessage)) { m_logger.Debug("Server message is {0}", nameof(Messages.DiagnosticsMessage)); var cast = (Messages.DiagnosticsMessage)message; if (cast != null) { this.OnDiagnosticsEnable?.Invoke(cast); } } else { // Unknown type. } }
private void OnClientDisconnected(IPipeServer server) { m_logger.Debug("Client disconnected."); ClientDisconnected?.Invoke(); }
private void UnregisterFromServerEvents(IPipeServer server) { server.ClientConnectedEvent -= ClientConnectedHandler; server.ClientDisconnectedEvent -= ClientDisconnectedHandler; server.MessageReceivedEvent -= MessageReceivedHandler; }
public static async Task DataTestAsync <T>(IPipeServer <T> server, IPipeClient <T> client, List <T> values, Func <T, string>?hashFunc = null, CancellationToken cancellationToken = default) { Trace.WriteLine("Setting up test..."); var completionSource = new TaskCompletionSource <bool>(false); // ReSharper disable once AccessToModifiedClosure using var registration = cancellationToken.Register(() => completionSource.TrySetCanceled(cancellationToken)); var actualHash = (string?)null; var clientDisconnected = false; server.ClientConnected += (sender, args) => { Trace.WriteLine("Client connected"); }; server.ClientDisconnected += (sender, args) => { Trace.WriteLine("Client disconnected"); clientDisconnected = true; // ReSharper disable once AccessToModifiedClosure completionSource.TrySetResult(true); }; server.MessageReceived += (sender, args) => { Trace.WriteLine($"Server_OnMessageReceived: {args.Message}"); actualHash = hashFunc?.Invoke(args.Message); Trace.WriteLine($"ActualHash: {actualHash}"); // ReSharper disable once AccessToModifiedClosure completionSource.TrySetResult(true); }; server.ExceptionOccurred += (sender, args) => { Trace.WriteLine($"Server exception occurred: {args.Exception}"); // ReSharper disable once AccessToModifiedClosure completionSource.TrySetException(args.Exception); }; client.Connected += (sender, args) => Trace.WriteLine("Client_OnConnected"); client.Disconnected += (sender, args) => Trace.WriteLine("Client_OnDisconnected"); client.MessageReceived += (sender, args) => Trace.WriteLine($"Client_OnMessageReceived: {args.Message}"); client.ExceptionOccurred += (sender, args) => { Trace.WriteLine($"Client exception occurred: {args.Exception}"); // ReSharper disable once AccessToModifiedClosure completionSource.TrySetException(args.Exception); }; AppDomain.CurrentDomain.UnhandledException += (sender, args) => { if (args.ExceptionObject is Exception exception) { // ReSharper disable once AccessToModifiedClosure completionSource.TrySetException(exception); } }; server.ExceptionOccurred += (sender, args) => Trace.WriteLine(args.Exception.ToString()); client.ExceptionOccurred += (sender, args) => Trace.WriteLine(args.Exception.ToString()); await server.StartAsync(cancellationToken).ConfigureAwait(false); await client.ConnectAsync(cancellationToken).ConfigureAwait(false); Trace.WriteLine("Client and server started"); Trace.WriteLine("---"); var watcher = Stopwatch.StartNew(); foreach (var value in values) { var expectedHash = hashFunc?.Invoke(value); Trace.WriteLine($"ExpectedHash: {expectedHash}"); await client.WriteAsync(value, cancellationToken).ConfigureAwait(false); await completionSource.Task.ConfigureAwait(false); if (hashFunc != null) { Assert.IsNotNull(actualHash, "Server should have received a zero-byte message from the client"); } Assert.AreEqual(expectedHash, actualHash, "SHA-1 hashes for zero-byte message should match"); Assert.IsFalse(clientDisconnected, "Server should not disconnect the client for explicitly sending zero-length data"); Trace.WriteLine("---"); completionSource = new TaskCompletionSource <bool>(false); } Trace.WriteLine($"Test took {watcher.Elapsed}"); Trace.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~"); }