Пример #1
0
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            _disposed = true;

            Timer timer = Interlocked.Exchange(ref _connectionCheckTimer, null);

            if (timer != null)
            {
                timer.Change(Timeout.Infinite, Timeout.Infinite);
                timer.Dispose();
            }

            NamedPipeServerLogger logger = Interlocked.Exchange(ref _logger, null);

            if (logger != null)
            {
                Log.RemoveLogger(logger);
                logger.Dispose();
            }

            lock (_namedPipeConnections)
            {
                foreach (NamedPipeConnection connection in _namedPipeConnections.ToArray())
                {
                    // ReSharper disable once PossibleNullReferenceException
                    connection.OnDisconnect();
                }

                // Should already be clear, but do anyway.
                _namedPipeConnections.Clear();
            }
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NamedPipeServer" /> class.
        /// </summary>
        /// <param name="service">The service.</param>
        /// <param name="configuration">The configuration.</param>
        /// <exception cref="ServiceException">
        /// </exception>
        public NamedPipeServer(
            [NotNull] BaseService service,
            [NotNull] ServerConfig configuration)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }
            if (configuration.MaximumConnections < 1)
            {
                throw new ArgumentOutOfRangeException("configuration", CommonResources.NamedPipeServer_MaxConnections);
            }

            Service            = service;
            MaximumConnections = configuration.MaximumConnections;
            if (!string.IsNullOrWhiteSpace(configuration.Name))
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                Name = configuration.Name;
            }
            else
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(Guid.NewGuid().ToString("D"))
                .Append('_');
                Debug.Assert(service.ServiceName != null);
                foreach (char c in service.ServiceName)
                {
                    builder.Append(char.IsLetterOrDigit(c) ? c : '_');
                }
                builder.Append(Constants.NameSuffix);
                Name = builder.ToString();
            }

            // Create security context
            try
            {
                WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
                if (currentIdentity == null ||
                    currentIdentity.Owner == null)
                {
                    throw new ServiceException(() => ServiceResources.Err_NamedPipeServer_CannotGetCurrentOwner);
                }

                _pipeSecurity = new PipeSecurity();
                _pipeSecurity.AddAccessRule(
                    new PipeAccessRule(
                        configuration.Identity,
                        PipeAccessRights.ReadWrite,
                        AccessControlType.Allow));
                _pipeSecurity.AddAccessRule(
                    new PipeAccessRule(
                        currentIdentity.Owner,
                        PipeAccessRights.FullControl,
                        AccessControlType.Allow));
            }
            catch (Exception exception)
            {
                throw new ServiceException(exception, () => ServiceResources.Err_NamedPipeServer_Fatal_Error_Securing);
            }

            // Check no one has tried to create the pipe before us, combined with the GUID name this makes the most common
            // form of pipe attack (pre-registration) impossible.
            if (File.Exists(@"\\.\pipe\" + Name))
            {
                throw new ServiceException(() => ServiceResources.Err_NamedPipeServer_PipeAlreadyExists);
            }

            // Create a connection, before adding it to the list and starting.
            NamedPipeConnection connection = new NamedPipeConnection(this);

            _namedPipeConnections = new List <NamedPipeConnection>(MaximumConnections)
            {
                connection
            };
            connection.Start();
            _logger = new NamedPipeServerLogger(this);
            Log.AddLogger(_logger);

            _heartbeat = configuration.Heartbeat;
            if (_heartbeat < TimeSpan.Zero)
            {
                return;
            }

            _connectionCheckTimer = new Timer(CheckConnections);
            _connectionCheckTimer.Change(_heartbeat, Timeout.InfiniteTimeSpan);
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NamedPipeServer" /> class.
        /// </summary>
        /// <param name="service">The service.</param>
        /// <param name="configuration">The configuration.</param>
        /// <exception cref="ServiceException">
        /// </exception>
        public NamedPipeServer(
            [NotNull] BaseService service,
            [NotNull] ServerConfig configuration)
        {
            if (service == null) throw new ArgumentNullException("service");
            if (configuration == null) throw new ArgumentNullException("configuration");
            if (configuration.MaximumConnections < 1)
                throw new ArgumentOutOfRangeException("configuration", CommonResources.NamedPipeServer_MaxConnections);

            Service = service;
            MaximumConnections = configuration.MaximumConnections;
            if (!string.IsNullOrWhiteSpace(configuration.Name))
                // ReSharper disable once AssignNullToNotNullAttribute
                Name = configuration.Name;
            else
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(Guid.NewGuid().ToString("D"))
                    .Append('_');
                Debug.Assert(service.ServiceName != null);
                foreach (char c in service.ServiceName)
                    builder.Append(char.IsLetterOrDigit(c) ? c : '_');
                builder.Append(Constants.NameSuffix);
                Name = builder.ToString();
            }

            // Create security context
            try
            {
                WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
                if (currentIdentity == null ||
                    currentIdentity.Owner == null)
                    throw new ServiceException(() => ServiceResources.Err_NamedPipeServer_CannotGetCurrentOwner);

                _pipeSecurity = new PipeSecurity();
                _pipeSecurity.AddAccessRule(
                    new PipeAccessRule(
                        configuration.Identity,
                        PipeAccessRights.ReadWrite,
                        AccessControlType.Allow));
                _pipeSecurity.AddAccessRule(
                    new PipeAccessRule(
                        currentIdentity.Owner,
                        PipeAccessRights.FullControl,
                        AccessControlType.Allow));
            }
            catch (Exception exception)
            {
                throw new ServiceException(exception, () => ServiceResources.Err_NamedPipeServer_Fatal_Error_Securing);
            }

            // Check no one has tried to create the pipe before us, combined with the GUID name this makes the most common
            // form of pipe attack (pre-registration) impossible.
            if (File.Exists(@"\\.\pipe\" + Name))
                throw new ServiceException(() => ServiceResources.Err_NamedPipeServer_PipeAlreadyExists);

            // Create a connection, before adding it to the list and starting.
            NamedPipeConnection connection = new NamedPipeConnection(this);
            _namedPipeConnections = new List<NamedPipeConnection>(MaximumConnections) { connection };
            connection.Start();
            _logger = new NamedPipeServerLogger(this);
            Log.AddLogger(_logger);

            _heartbeat = configuration.Heartbeat;
            if (_heartbeat < TimeSpan.Zero) return;

            _connectionCheckTimer = new Timer(CheckConnections);
            _connectionCheckTimer.Change(_heartbeat, Timeout.InfiniteTimeSpan);
        }