Example #1
0
        /// <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);
        }
Example #2
0
        /// <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>();
 }
Example #4
0
        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();
 }
        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();
        }
Example #7
0
        /// <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);
        }
Example #8
0
        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;
            }
        }
Example #9
0
        /// <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.
            }
        }
Example #10
0
 private void OnClientDisconnected(IPipeServer server)
 {
     m_logger.Debug("Client disconnected.");
     ClientDisconnected?.Invoke();
 }
Example #11
0
 private void UnregisterFromServerEvents(IPipeServer server)
 {
     server.ClientConnectedEvent    -= ClientConnectedHandler;
     server.ClientDisconnectedEvent -= ClientDisconnectedHandler;
     server.MessageReceivedEvent    -= MessageReceivedHandler;
 }
Example #12
0
        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("~~~~~~~~~~~~~~~~~~~~~~~~~~");
        }