示例#1
0
        public void MultipleProcessesCanWriteToTheLog()
        {
            var logFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            TimestampedFileLogger logger = new(logFile);

            // Log requests operates using PipeTransmissionMode.Message
            NamedPipeServerStream np1   = CreateServerPipe("np1");
            PipeStreamSetupLogger pssl1 = new PipeStreamSetupLogger(np1, "np1");
            NamedPipeServerStream np2   = CreateServerPipe("np2");
            PipeStreamSetupLogger pssl2 = new PipeStreamSetupLogger(np2, "np2");

            logger.AddNamedPipe("np1");
            logger.AddNamedPipe("np2");
            logger.LogMessage("Foo");

            var t1 = Task.Run(() => { pssl1.Connect(); pssl1.LogMessage("Hello from np1"); });
            var t2 = Task.Run(() => { pssl2.Connect(); pssl2.LogMessage("Hello from np2"); });

            // Give the other threads time to connect to the logging thread.
            Task.WaitAll(t1, t2);
            logger.Dispose();

            string logContent = File.ReadAllText(logFile);

            Assert.Contains("Hello from np1", logContent);
            Assert.Contains("Hello from np2", logContent);
        }
示例#2
0
        private void LogTask(string pipeName)
        {
            using NamedPipeServerStream serverPipe = CreateServerPipe(pipeName);
            PipeStreamSetupLogger logger = new PipeStreamSetupLogger(serverPipe, pipeName);

            logger.Connect();

            for (int i = 0; i < 10; i++)
            {
                logger.LogMessage($"Hello from {pipeName} ({i}).");
            }
        }
示例#3
0
        /// <summary>
        /// Creates a new <see cref="NetSdkMsiInstallerServer"/> instance.
        /// </summary>
        /// <returns></returns>
        public static NetSdkMsiInstallerServer Create()
        {
            if (!WindowsUtils.IsAdministrator())
            {
                throw new UnauthorizedAccessException(LocalizableStrings.InsufficientPrivilegeToStartServer);
            }

            // Best effort to verify that the server was not started indirectly or being spoofed.
            if ((ParentProcess == null) || (ParentProcess.StartTime > CurrentProcess.StartTime) ||
                string.IsNullOrWhiteSpace(CurrentProcess.MainModule.FileName) ||
                !string.Equals(ParentProcess.MainModule.FileName, CurrentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase))
            {
                throw new SecurityException(String.Format(LocalizableStrings.NoTrustWithParentPID, ParentProcess?.Id));
            }

            // Configure pipe DACLs
            SecurityIdentifier authenticatedUserIdentifier = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
            SecurityIdentifier currentOwnerIdentifier      = WindowsIdentity.GetCurrent().Owner;
            PipeSecurity       pipeSecurity = new();

            // The current user has full control and should be running as Administrator.
            pipeSecurity.SetOwner(currentOwnerIdentifier);
            pipeSecurity.AddAccessRule(new PipeAccessRule(currentOwnerIdentifier, PipeAccessRights.FullControl, AccessControlType.Allow));

            // Restrict read/write access to authenticated users
            pipeSecurity.AddAccessRule(new PipeAccessRule(authenticatedUserIdentifier,
                                                          PipeAccessRights.Read | PipeAccessRights.Write | PipeAccessRights.Synchronize, AccessControlType.Allow));

            // Initialize the named pipe for dispatching commands. The name of the pipe is based off the server PID since
            // the client knows this value and ensures both processes can generate the same name.
            string pipeName = WindowsUtils.CreatePipeName(CurrentProcess.Id);
            NamedPipeServerStream serverPipe = NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message,
                                                                               PipeOptions.None, 65535, 65535, pipeSecurity);
            InstallMessageDispatcher dispatcher = new(serverPipe);

            // The client process will generate the actual log file. The server will log messages through a separate pipe.
            string logPipeName            = WindowsUtils.CreatePipeName(CurrentProcess.Id, "log");
            NamedPipeServerStream logPipe = NamedPipeServerStreamAcl.Create(logPipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message,
                                                                            PipeOptions.None, 65535, 65535, pipeSecurity);
            PipeStreamSetupLogger         logger           = new PipeStreamSetupLogger(logPipe, logPipeName);
            InstallServerElevationContext elevationContext = new(serverPipe);

            return(new NetSdkMsiInstallerServer(elevationContext, logger));
        }
示例#4
0
        public NetSdkMsiInstallerServer(InstallElevationContextBase elevationContext, PipeStreamSetupLogger logger)
            : base(elevationContext, logger)
        {
            // Establish a connection with the install client and logger. We're relying on tasks to handle
            // this, otherwise, the ordering needs to be lined up with how the client configures
            // the underlying pipe streams to avoid deadlock.
            Task dispatchTask = new Task(() => Dispatcher.Connect());
            Task loggerTask   = new Task(() => logger.Connect());

            dispatchTask.Start();
            loggerTask.Start();

            Task.WaitAll(dispatchTask, loggerTask);
        }