Пример #1
0
        void ReplaceHandler(IChannelHandlerContext context, ServerTlsSettings serverTlsSetting)
        {
            Contract.Requires(serverTlsSetting != null);
            var tlsHandler = new TlsHandler(this.sslStreamFactory, serverTlsSetting);

            context.Channel.Pipeline.Replace(this, nameof(TlsHandler), tlsHandler);
        }
Пример #2
0
 public X509TlsTenancyHandler(ServerTlsSettings tlsSettings, ISettingsProvider settingsProvider)
 {
     Contract.Requires(tlsSettings != null);
     this.tlsHandler       = new TlsHandler(stream => new SslStream(stream, true, ClientCertValidatorCallback), tlsSettings);
     this.closeFuture      = new TaskCompletionSource();
     this.settingsProvider = settingsProvider;
 }
Пример #3
0
        static async Task RunTcpServerAsyncLibuv()
        {
            Console.WriteLine("Initializing Server...");
            ConsoleLoggerOptions loggeroptions = new ConsoleLoggerOptions()
            {
                IncludeScopes = false
            };
            LoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Error, false);


            InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false));

            var dispatcher = new DispatcherEventLoopGroup();

            bossGroup   = dispatcher;
            workerGroup = new WorkerEventLoopGroup(dispatcher);

            X509Certificate2 tlsServerCertificate = new X509Certificate2(@"protocol-gateway.contoso.com.pfx", "password");
            IChannel         boundChannel         = null;

            try
            {
                var bootstrap = new ServerBootstrap();
                bootstrap.Group(bossGroup, workerGroup);
                bootstrap.Channel <TcpServerChannel>();
                bootstrap
                .Option(ChannelOption.SoBacklog, 100)
                .Handler(new LoggingHandler("SRV_LSTN"))
                .ChildHandler(new ActionChannelInitializer <IChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    if (tlsServerCertificate != null)
                    {
                        var tlsSettings = new ServerTlsSettings(tlsServerCertificate, true, true, System.Security.Authentication.SslProtocols.Tls);
                        var handler     = new TlsHandler(stream => new System.Net.Security.SslStream(stream, true, ValidateClientCertificate), tlsSettings);
                        pipeline.AddLast("certTls", handler);
                    }
                    pipeline.AddLast("framing-enc", new LengthFieldPrepender(2));
                    pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));
                    pipeline.AddLast("echo", new EchoServerHandler());
                }));

                boundChannel = await bootstrap.BindAsync(IPAddress.Any, 3382);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                //boundChannel.CloseAsync().Wait();
                //await bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
                //await workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
        public static TlsHandlerWrapper Server(X509Certificate certificate)
        {
            TlsHandlerWrapper wrapper = new TlsHandlerWrapper();

            ServerTlsSettings serverTls = new ServerTlsSettings(certificate, true);

            Func <Stream, SslStream> customSslStream = CreateSslStream;

            TlsHandler tlsHandler = new TlsHandler(CreateSslStream, serverTls);

            wrapper.handler = tlsHandler;
            return(wrapper);
        }
        /**
         * Configure the pipeline for TLS NPN negotiation to HTTP/2.
         */
        void ConfigureSsl(IChannel ch)
        {
            var tlsSettings = new ServerTlsSettings(this.tlsCertificate)
            {
                ApplicationProtocols = new List <SslApplicationProtocol>(new[]
                {
                    SslApplicationProtocol.Http2,
                    SslApplicationProtocol.Http11
                })
            };

            tlsSettings.AllowAnyClientCertificate();
            ch.Pipeline.AddLast(new TlsHandler(tlsSettings));
            ch.Pipeline.AddLast(new Http2OrHttpHandler());
        }
Пример #6
0
        public Task <IChannel> StartAsync()
        {
            var bootstrap = new ServerBootstrap();

            bootstrap.Group(_bossGroup, _workGroup);

            if (ServerSettings.UseLibuv)
            {
                bootstrap.Channel <TcpServerChannel>();
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
                    RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    bootstrap
                    .Option(ChannelOption.SoReuseport, true)
                    .ChildOption(ChannelOption.SoReuseaddr, true);
                }
            }
            else
            {
                bootstrap.Channel <TcpServerSocketChannel>();
            }

            var tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");

            bootstrap
            .Option(ChannelOption.SoBacklog, 1024)
            //.Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)

            .Handler(new LoggingHandler("LSTN"))

            .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                var tlsSettings = new ServerTlsSettings(tlsCertificate)
                {
                    ApplicationProtocols = new List <SslApplicationProtocol>(new[]
                    {
                        SslApplicationProtocol.Http2,
                        SslApplicationProtocol.Http11
                    })
                };
                tlsSettings.AllowAnyClientCertificate();
                ch.Pipeline.AddLast(new TlsHandler(tlsSettings));
                ch.Pipeline.AddLast(new Http2OrHttpHandler());
            }));

            return(bootstrap.BindAsync(IPAddress.Loopback, PORT));
        }
Пример #7
0
        /// <summary>
        /// Bootstraps the Tcp IoT Hub Gateway for X509 cert based Tls
        /// </summary>
        /// <param name="certificate2">Server certificate for Tls</param>
        /// <param name="threadCount"># of threads to be used</param>
        /// <param name="cancellationToken">Cancellation flag</param>
        /// <returns></returns>
        public async Task RunAsync(X509Certificate2 certificate2, int threadCount, CancellationToken cancellationToken)
        {
            Contract.Requires(threadCount > 0);

            try
            {
                var serverTlsSettings = new ServerTlsSettings(certificate2, true, true, System.Security.Authentication.SslProtocols.Tls12);
                //var tlsHandler = new Tenancy.X509TlsTenancyHandler(serverTlsSettings);
                var tlsHandler = TlsHandler.Server(certificate2);

                this.RunAsync(threadCount, cancellationToken, tlsHandler, true);
            }
            catch (Exception ex)
            {
                //BootstrapperEventSource.Log.Error("Failed to start", ex);
                this.CloseAsync();
            }
        }
Пример #8
0
        ServerBootstrap SetupBootstrap()
        {
            return(new ServerBootstrap()
                   .Group(this.parentEventLoopGroup, this.eventLoopGroup)
                   .Option(ChannelOption.SoBacklog, ListenBacklogSize)
                   .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                   .ChildOption(ChannelOption.AutoRead, true)
                   .Channel <TcpServerSocketChannel>()
                   .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
            {
                if (this.tlsCertificate != null)
                {
                    var tlsSettings = new ServerTlsSettings(this.tlsCertificate, true, true, System.Security.Authentication.SslProtocols.Tls12);
                    var handler = new Tenancy.X509TlsTenancyHandler(tlsSettings, this.settingsProvider);
                    channel.Pipeline.AddLast("certTls", handler);
                }

                var messagingAddressConverter = new ConfigurableMessageAddressConverter();

                channel.Pipeline.AddLast(DeviceTopicDecoder.HandlerName, new DeviceTopicDecoder(this.credentialProvider, messagingAddressConverter.TopicTemplates));
                channel.Pipeline.AddLast(SocketIoTHubAdapter.HandlerName, new SocketIoTHubAdapter(this.settings, credentialProvider, this.authProvider));
            })));
        }
Пример #9
0
        ServerBootstrap SetupServerBootstrap()
        {
            int maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", DefaultMaxInboundMessageSize);
            int threadCount           = this.settingsProvider.GetIntegerSetting("ThreadCount", DefaultThreadCount);
            int listenBacklogSize     = this.settingsProvider.GetIntegerSetting("ListenBacklogSize", DefaultListenBacklogSize);
            int parentEventLoopCount  = this.settingsProvider.GetIntegerSetting("EventLoopCount", DefaultParentEventLoopCount);
            var settings = new Settings(this.settingsProvider);

            MessagingBridgeFactoryFunc bridgeFactory = this.mqttConnectionProvider.Connect;

            var bootstrap = new ServerBootstrap();
            // multithreaded event loop that handles the incoming connection
            IEventLoopGroup parentEventLoopGroup = new MultithreadEventLoopGroup(parentEventLoopCount);

            // multithreaded event loop (worker) that handles the traffic of the accepted connections
            this.eventLoopGroup = new MultithreadEventLoopGroup(threadCount);

            bootstrap.Group(parentEventLoopGroup, this.eventLoopGroup)
            .Option(ChannelOption.SoBacklog, listenBacklogSize)
            // Allow listening socket to force bind to port if previous socket is still in TIME_WAIT
            // Fixes "address is already in use" errors
            .Option(ChannelOption.SoReuseaddr, true)
            .ChildOption(ChannelOption.Allocator, this.byteBufferAllocator)
            .ChildOption(ChannelOption.AutoRead, AutoRead)
            // channel that accepts incoming connections
            .Channel <TcpServerSocketChannel>()
            // Channel initializer, it is handler that is purposed to help configure a new channel
            .ChildHandler(
                new ActionChannelInitializer <ISocketChannel>(
                    channel =>
            {
                var identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, this.clientCertAuthAllowed);
                // configure the channel pipeline of the new Channel by adding handlers
                TlsSettings serverSettings = new ServerTlsSettings(
                    certificate: this.tlsCertificate,
                    negotiateClientCertificate: this.clientCertAuthAllowed
                    );

                channel.Pipeline.AddLast(
                    new TlsHandler(
                        stream =>
                        new SslStream(
                            stream,
                            true,
                            (sender, remoteCertificate, remoteChain, sslPolicyErrors) => this.RemoteCertificateValidationCallback(identityProvider, remoteCertificate, remoteChain)),
                        serverSettings));

                channel.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttAdapter(
                        settings,
                        this.sessionProvider,
                        identityProvider,
                        null,
                        bridgeFactory));
            }));

            var mqttWebSocketListener = new MqttWebSocketListener(
                settings,
                bridgeFactory,
                this.authenticator,
                this.clientCredentialsFactory,
                () => this.sessionProvider,
                new MultithreadEventLoopGroup(Environment.ProcessorCount),
                this.byteBufferAllocator,
                AutoRead,
                maxInboundMessageSize,
                this.clientCertAuthAllowed);

            this.webSocketListenerRegistry.TryRegister(mqttWebSocketListener);

            return(bootstrap);
        }
Пример #10
0
        static async Task <Tuple <EmbeddedChannel, SslStream> > SetupStreamAndChannelAsync(bool isClient, IEventExecutor executor, IWriteStrategy writeStrategy, SslProtocols protocol, List <Task> writeTasks, string targetHost)
        {
            IChannelHandler tlsHandler = isClient ?
                                         (IChannelHandler) new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) =>
            {
                Assert.Equal(targetHost, certificate.Issuer.Replace("CN=", string.Empty));
                return(true);
            }), new ClientTlsSettings(protocol, false, new List <X509Certificate>(), targetHost)) :
                                         new SniHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ServerTlsSniSettings(CertificateSelector));
            //var ch = new EmbeddedChannel(new LoggingHandler("BEFORE"), tlsHandler, new LoggingHandler("AFTER"));
            var ch = new EmbeddedChannel(tlsHandler);

            if (!isClient)
            {
                // check if in the beginning snihandler exists in the pipeline, but not tls handler
                Assert.NotNull(ch.Pipeline.Get <SniHandler>());
                Assert.Null(ch.Pipeline.Get <TlsHandler>());
            }

            IByteBuffer readResultBuffer = Unpooled.Buffer(4 * 1024);
            Func <ArraySegment <byte>, Task <int> > readDataFunc = async output =>
            {
                if (writeTasks.Count > 0)
                {
                    await Task.WhenAll(writeTasks).WithTimeout(TestTimeout);

                    writeTasks.Clear();
                }

                if (readResultBuffer.ReadableBytes < output.Count)
                {
                    if (ch.Active)
                    {
                        await ReadOutboundAsync(async() => ch.ReadOutbound <IByteBuffer>(), output.Count - readResultBuffer.ReadableBytes, readResultBuffer, TestTimeout, readResultBuffer.ReadableBytes != 0? 0 : 1);
                    }
                }
                int read = Math.Min(output.Count, readResultBuffer.ReadableBytes);
                readResultBuffer.ReadBytes(output.Array, output.Offset, read);
                return(read);
            };
            var mediationStream = new MediationStream(readDataFunc, input =>
            {
                Task task = executor.SubmitAsync(() => writeStrategy.WriteToChannelAsync(ch, input)).Unwrap();
                writeTasks.Add(task);
                return(task);
            });

            var driverStream = new SslStream(mediationStream, true, (_1, _2, _3, _4) => true);

            if (isClient)
            {
                ServerTlsSettings serverTlsSettings = CertificateSelector(targetHost).Result;
                await Task.Run(() => driverStream.AuthenticateAsServerAsync(serverTlsSettings.Certificate, false, protocol | serverTlsSettings.EnabledProtocols, false).WithTimeout(TimeSpan.FromSeconds(5)));
            }
            else
            {
                await Task.Run(() => driverStream.AuthenticateAsClientAsync(targetHost, null, protocol, false)).WithTimeout(TimeSpan.FromSeconds(5));
            }
            writeTasks.Clear();

            return(Tuple.Create(ch, driverStream));
        }
        public async Task RunAsync2(int threadCount, CancellationToken cancellationToken, X509Certificate2 cert = null, ServerTlsSettings serverTlsSettings = null, RemoteCertificateValidationCallback rcvb = null)
        {
            Contract.Requires(threadCount > 0);

            try
            {
                //BootstrapperEventSource.Log.Info("Starting", null);

                //PerformanceCounters.ConnectionsEstablishedTotal.RawValue = 0;
                //PerformanceCounters.ConnectionsCurrent.RawValue = 0;

                this.parentEventLoopGroup = new MultithreadEventLoopGroup(1);
                this.eventLoopGroup       = new MultithreadEventLoopGroup(threadCount);

                ChannelHandlerAdapter handler = null;
                if (cert != null && serverTlsSettings != null)
                {
                    handler = new TlsHandler(stream => new SslStream(stream, true, rcvb), serverTlsSettings);
                }
                else
                {
                    handler = new DataBasedTenancyHandler();
                }

                ServerBootstrap bootstrap = this.SetupBootstrap(handler);

                //BootstrapperEventSource.Log.Info($"Initializing TLS endpoint on port {this.settings.ListeningPort.ToString()} with certificate {this.tlsCertificate.Thumbprint}.", null);
                this.serverChannel = await bootstrap.BindAsync(IPAddress.Any, rcvb != null?this.settings.SecureListeningPort : this.settings.ListeningPort);

                this.serverChannel.CloseCompletion.LinkOutcome(this.closeCompletionSource);
                cancellationToken.Register(this.CloseAsync);

                //BootstrapperEventSource.Log.Info("Started", null);
            }
            catch (Exception ex)
            {
                //BootstrapperEventSource.Log.Error("Failed to start", ex);
                this.CloseAsync();
            }
        }