/// <summary>
        /// Starts receiving the WebSocket handshake requests.
        /// </summary>
        public void Start()
        {
            string msg;

            if (!checkIfAvailable(true, false, false, true, out msg))
            {
                _logger.Error(msg);
                return;
            }

            var sslConfig = getSslConfiguration();

            if (!checkSslConfiguration(sslConfig, out msg))
            {
                _logger.Error(msg);
                return;
            }

            lock (_sync) {
                if (!checkIfAvailable(true, false, false, true, out msg))
                {
                    _logger.Error(msg);
                    return;
                }

                _realmInUse     = getRealm();
                _sslConfigInUse = sslConfig;

                _services.Start();
                startReceiving();

                _state = ServerState.Start;
            }
        }
    internal TcpListenerWebSocketContext (
      TcpClient tcpClient,
      string protocol,
      bool secure,
      ServerSslConfiguration sslConfig,
      Logger logger)
    {
      _tcpClient = tcpClient;
      _secure = secure;
      _logger = logger;

      var netStream = tcpClient.GetStream ();
      if (secure) {
        var sslStream = new SslStream (
          netStream, false, sslConfig.ClientCertificateValidationCallback);

        sslStream.AuthenticateAsServer (
          sslConfig.ServerCertificate,
          sslConfig.ClientCertificateRequired,
          sslConfig.EnabledSslProtocols,
          sslConfig.CheckCertificateRevocation);

        _stream = sslStream;
      }
      else {
        _stream = netStream;
      }

      _request = HttpRequest.Read (_stream, 90000);
      _uri = HttpUtility.CreateRequestUrl (
        _request.RequestUri, _request.Headers["Host"], _request.IsWebSocketRequest, secure);

      _websocket = new WebSocket (this, protocol);
    }
예제 #3
0
        private void Start(ServerSslConfiguration sslConfig)
        {
            lock (_sync)
            {
                if (_state == ServerState.Start)
                {
                    _log.Info("The server has already started.");
                    return;
                }

                if (_state == ServerState.ShuttingDown)
                {
                    _log.Warn("The server is shutting down.");
                    return;
                }

                _sslConfigInUse = sslConfig;
                _realmInUse     = GetRealm();
                _services.Start();

                try
                {
                    StartClientsReceiving();
                }
                catch
                {
                    _services.Stop(1011, String.Empty);

                    throw;
                }

                _state = ServerState.Start;
            }
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WebSocketServer"/> class with the specified
        /// <paramref name="address"/>, <paramref name="port"/>, and <paramref name="secure"/>.
        /// </summary>
        /// <remarks>
        /// An instance initialized by this constructor listens for the incoming connection requests
        /// on <paramref name="port"/>.
        /// </remarks>
        /// <param name="address">
        /// A <see cref="System.Net.IPAddress"/> that represents the local IP address of the server.
        /// </param>
        /// <param name="port">
        /// An <see cref="int"/> that represents the port number on which to listen.
        /// </param>
        /// <param name="certificate">
        /// A <see cref="X509Certificate2"/> used to secure the connection.
        /// </param>
        /// <param name="authenticationSchemes">Supported authentication schemes.</param>
        /// <exception cref="ArgumentException">
        ///   <para>
        ///   <paramref name="address"/> isn't a local IP address.
        ///   </para>
        ///   <para>
        ///   -or-
        ///   </para>
        ///   <para>
        ///   Pair of <paramref name="port"/> and <paramref name="certificate"/> is invalid.
        ///   </para>
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="address"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> isn't between 1 and 65535.</exception>
        public WebSocketServer(IPAddress address = null, int port = 80, ServerSslConfiguration certificate = null, AuthenticationSchemes authenticationSchemes = AuthenticationSchemes.Anonymous, int fragmentSize = 102392)
        {
            if (address == null)
            {
                address = IPAddress.Any;
            }

            if (!address.IsLocal())
            {
                throw new ArgumentException("Not a local IP address: " + address, nameof(address));
            }

            if (!port.IsPortNumber())
            {
                throw new ArgumentOutOfRangeException("port", "Not between 1 and 65535: " + port);
            }

            var secure = certificate != null;

            if ((port == 80 && secure) || (port == 443 && !secure))
            {
                throw new ArgumentException(string.Format("An invalid pair of 'port' and 'secure': {0}, {1}", port, secure));
            }

            _address      = address;
            _port         = port;
            _sslConfig    = certificate;
            _fragmentSize = fragmentSize;
            _secure       = secure;
            _uri          = "/".ToUri();

            Init(authenticationSchemes);
        }
예제 #5
0
        private bool checkSslConfiguration(
            ServerSslConfiguration configuration, out string message
            )
        {
            message = null;

            if (!_secure)
            {
                return(true);
            }

            if (configuration == null)
            {
                message = "There is no configuration.";
                return(false);
            }

            if (configuration.ServerCertificate == null)
            {
                message = "The configuration has no server certificate.";
                return(false);
            }

            return(true);
        }
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
            ServerSslConfiguration sslConfiguration)
        {
            _tcpClient = tcpClient;
            _secure    = secure;

            var netStream = tcpClient.GetStream();

            if (secure)
            {
                var sslStream = new SslStream(netStream, false, sslConfiguration.ClientCertificateValidationCallback, sslConfiguration.UserCertificateSelectionCallback);
                sslStream.AuthenticateAsServer(
                    sslConfiguration.ServerCertificate,
                    sslConfiguration.ClientCertificateRequired,
                    sslConfiguration.EnabledSslProtocols,
                    sslConfiguration.CheckCertificateRevocation);

                _stream = sslStream;
            }
            else
            {
                _stream = netStream;
            }

            _request = HttpRequest.Read(_stream, 90000);
            _uri     = CreateRequestUri(secure);

            _websocket = new WebSocket(this, protocol);
        }
예제 #7
0
        /// <summary>
        /// Starts receiving incoming handshake requests.
        /// </summary>
        /// <remarks>
        /// This method does nothing if the server has already started or
        /// it is shutting down.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        ///   <para>
        ///   There is no server certificate for secure connection.
        ///   </para>
        ///   <para>
        ///   -or-
        ///   </para>
        ///   <para>
        ///   The underlying <see cref="TcpListener"/> has failed to start.
        ///   </para>
        /// </exception>
        public void Start()
        {
            ServerSslConfiguration sslConfig = null;

            if (_secure)
            {
                var src = GetSslConfiguration();
                sslConfig = new ServerSslConfiguration(src);

                if (sslConfig.ServerCertificate == null)
                {
                    var msg = "There is no server certificate for secure connection.";
                    throw new InvalidOperationException(msg);
                }
            }

            if (_state == ServerState.Start)
            {
                _log.Info("The server has already started.");
                return;
            }

            if (_state == ServerState.ShuttingDown)
            {
                _log.Warn("The server is shutting down.");
                return;
            }

            Start(sslConfig);
        }
예제 #8
0
 internal static TcpListenerWebSocketContext GetWebSocketContext(
     this TcpClient tcpClient,
     string protocol,
     bool secure,
     ServerSslConfiguration sslConfiguration)
 {
     return(new TcpListenerWebSocketContext(tcpClient, protocol, secure, sslConfiguration));
 }
예제 #9
0
        private ServerSslConfiguration getSslConfiguration()
        {
            if (_sslConfig == null)
            {
                _sslConfig = new ServerSslConfiguration();
            }

            return(_sslConfig);
        }
            public void Setup()
            {
                var cert = GetRandomCertificate();
                var serverSslConfiguration = new ServerSslConfiguration(
                    cert,
                    true,
                    SslProtocols.Tls,
                    clientCertificateValidationCallback: (sender, certificate, chain, errors) => true);

                _sut = new WebSocketServer(port: 443, certificate: serverSslConfiguration);
                _sut.AddWebSocketService <TestEchoService>("/echo");
                _sut.AddWebSocketService <TestRadioService>("/radio");
                _sut.Start();
            }
예제 #11
0
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
#if !NETCF || BCC || SSL
            ServerSslConfiguration sslConfig,
#endif
            Logger log)
        {
            _tcpClient = tcpClient;
            _secure    = secure;
            _log       = log;

            Stream netStream = tcpClient.GetStream();

#if BUFFERED
            netStream = new BufferedNetworkStream((NetworkStream)netStream);
#endif
#if !NETCF || BCC || SSL
            if (secure)
            {
                var sslStream = new SslStream(netStream, false, sslConfig.ClientCertificateValidationCallback);

                sslStream.AuthenticateAsServer(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation);

                _stream = sslStream;
            }
            else
#endif
            {
                _stream = netStream;
            }

#if SSHARP
            var sock = tcpClient;
#else
            var sock = tcpClient.Client;
#endif
            _serverEndPoint = sock.LocalEndPoint;
            _userEndPoint   = sock.RemoteEndPoint;

            _request = HttpRequest.Read(_stream, 90000);

            _websocket = new WebSocket(this, protocol);
        }
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
            ServerSslConfiguration sslConfig,
            Logger logger,
            bool alreadySentHeaders = false // (Extension for SelfHostedRemoteDesktop)
            )
        {
            _tcpClient = tcpClient;
            _secure    = secure;
            _logger    = logger;

            var netStream = tcpClient.GetStream();

            if (secure)
            {
                var sslStream =
                    new SslStream(netStream, false, sslConfig.ClientCertificateValidationCallback);

                sslStream.AuthenticateAsServer(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation
                    );

                _stream = sslStream;
            }
            else
            {
                _stream = netStream;
            }
            if (alreadySentHeaders)     // (Extension for SelfHostedRemoteDesktop)
            {
                _request = new HttpRequest("GET", "/nstws");
                _request.Headers.Add("Host", "TEST");
            }
            else
            {
                _request = HttpRequest.Read(_stream, 90000);
            }
            _uri =
                HttpUtility.CreateRequestUrl(
                    _request.RequestUri, _request.Headers["Host"], _request.IsWebSocketRequest, secure
                    );
            _websocket = new WebSocket(this, protocol);
        }
예제 #13
0
        private void start(ServerSslConfiguration sslConfig)
        {
            if (_state == ServerState.Start)
            {
                _log.Info("The server has already started.");
                return;
            }

            if (_state == ServerState.ShuttingDown)
            {
                _log.Warn("The server is shutting down.");
                return;
            }

            lock (_sync)
            {
                if (_state == ServerState.Start)
                {
                    _log.Info("The server has already started.");
                    return;
                }

                if (_state == ServerState.ShuttingDown)
                {
                    _log.Warn("The server is shutting down.");
                    return;
                }


#if !NETCF || BCC || SSL
                _sslConfigInUse = sslConfig;
#endif
                _realmInUse = getRealm();

                _services.Start();
                try
                {
                    startReceiving();
                }
                catch
                {
                    _services.Stop(1011, String.Empty);
                    throw;
                }

                _state = ServerState.Start;
            }
        }
예제 #14
0
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
            bool noDelay,
            ServerSslConfiguration sslConfig,
            Logger log
            )
        {
            _tcpClient         = tcpClient;
            _tcpClient.NoDelay = noDelay;

            _secure = secure;
            _log    = log;

            var netStream = tcpClient.GetStream();

            if (secure)
            {
                var sslStream = new SslStream(
                    netStream,
                    false,
                    sslConfig.ClientCertificateValidationCallback
                    );

                sslStream.AuthenticateAsServer(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation
                    );

                _stream = sslStream;
            }
            else
            {
                _stream = netStream;
            }

            var sock = tcpClient.Client;

            _serverEndPoint = sock.LocalEndPoint;
            _userEndPoint   = sock.RemoteEndPoint;

            _request   = HttpRequest.Read(_stream, 90000);
            _websocket = new WebSocket(this, protocol);
        }
예제 #15
0
        /// <summary>
        /// Starts receiving incoming handshake requests.
        /// </summary>
        /// <remarks>
        /// This method does nothing if the server has already started or
        /// it is shutting down.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        ///   <para>
        ///   There is no server certificate for secure connection.
        ///   </para>
        ///   <para>
        ///   -or-
        ///   </para>
        ///   <para>
        ///   The underlying <see cref="TcpListener"/> has failed to start.
        ///   </para>
        /// </exception>
        public void Start()
        {
            ServerSslConfiguration sslConfig = null;

            if (_secure)
            {
                var src = getSslConfiguration();
                sslConfig = new ServerSslConfiguration(src);

                if (sslConfig.ServerCertificate == null)
                {
                    var msg = "There is no server certificate for secure connection.";

                    throw new InvalidOperationException(msg);
                }
            }

            start(sslConfig);
        }
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
#if !NETCF || BCC || SSL
            ServerSslConfiguration sslConfig,
#endif
            Logger logger)
        {
            _tcpClient = tcpClient;
            _secure    = secure;
            _logger    = logger;

            Stream netStream = tcpClient.GetStream();

#if BUFFERED
            netStream = new BufferedNetworkStream((NetworkStream)netStream);
#endif
#if !NETCF || BCC || SSL
            if (secure)
            {
                var sslStream = new SslStream(netStream, false, sslConfig.ClientCertificateValidationCallback);

                sslStream.AuthenticateAsServer(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation);

                _stream = sslStream;
            }
            else
#endif
            {
                _stream = netStream;
            }

            _request = HttpRequest.Read(_stream, 90000);
            _uri     = HttpUtility.CreateRequestUrl(_request.RequestUri, _request.Headers["Host"], _request.IsWebSocketRequest, secure);

            _websocket = new WebSocket(this, protocol);
        }
        internal TcpListenerWebSocketContext(
            TcpClient tcpClient,
            string protocol,
            bool secure,
            ServerSslConfiguration sslConfig,
            Logger logger
            )
        {
            _tcpClient = tcpClient;
            _secure    = secure;
            _logger    = logger;

            var netStream = tcpClient.GetStream();

            if (secure)
            {
                var sslStream =
                    new SslStream(netStream, false, sslConfig.ClientCertificateValidationCallback);

                // TODO Rever este ponto se o Async não faz diferença
                sslStream.AuthenticateAsServerAsync(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation
                    );

                _stream = sslStream;
            }
            else
            {
                _stream = netStream;
            }

            _request = HttpRequest.Read(_stream, 90000);
            _uri     =
                HttpUtility.CreateRequestUrl(
                    _request.RequestUri, _request.Headers["Host"], _request.IsWebSocketRequest, secure
                    );

            _websocket = new WebSocket(this, protocol);
        }
예제 #18
0
        private void start()
        {
            lock (_sync) {
                if (_state == ServerState.Start || _state == ServerState.ShuttingDown)
                {
                    return;
                }

                if (_secure)
                {
                    var src  = getSslConfiguration();
                    var conf = new ServerSslConfiguration(src);

                    if (conf.ServerCertificate == null)
                    {
                        var msg = "There is no server certificate for secure connection.";

                        throw new InvalidOperationException(msg);
                    }

                    _sslConfigInUse = conf;
                }

                _realmInUse = getRealm();

                _services.Start();

                try {
                    startReceiving();
                }
                catch {
                    _services.Stop(1011, String.Empty);

                    throw;
                }

                _state = ServerState.Start;
            }
        }
예제 #19
0
        private ServerSslConfiguration getSslConfiguration()
        {
            var sslConfig = _sslConfig;

            if (sslConfig == null)
            {
                return(null);
            }

            var ret =
                new ServerSslConfiguration(
                    sslConfig.ServerCertificate,
                    sslConfig.ClientCertificateRequired,
                    sslConfig.EnabledSslProtocols,
                    sslConfig.CheckCertificateRevocation
                    );

            ret.ClientCertificateValidationCallback =
                sslConfig.ClientCertificateValidationCallback;

            return(ret);
        }
예제 #20
0
        internal TcpListenerWebSocketContext(TcpClient tcpClient, string protocol, bool secure, ServerSslConfiguration sslConfig, Logger logger)
        {
            _tcpClient = tcpClient;
            _secure    = secure;
            _logger    = logger;
            NetworkStream stream = tcpClient.GetStream();

            if (secure)
            {
                SslStream sslStream = new SslStream(stream, leaveStreamOpen: false, sslConfig.ClientCertificateValidationCallback);
                sslStream.AuthenticateAsServer(sslConfig.ServerCertificate, sslConfig.ClientCertificateRequired, sslConfig.EnabledSslProtocols, sslConfig.CheckCertificateRevocation);
                _stream = sslStream;
            }
            else
            {
                _stream = stream;
            }
            _request   = HttpRequest.Read(_stream, 90000);
            _uri       = HttpUtility.CreateRequestUrl(_request.RequestUri, _request.Headers["Host"], _request.IsWebSocketRequest, secure);
            _websocket = new WebSocket(this, protocol);
        }
        internal TcpListenerWebSocketContext(TcpClient tcpClient, string protocol, bool secure, ServerSslConfiguration sslConfig, Logger logger)
        {
            this._tcpClient = tcpClient;
            this._secure    = secure;
            this._logger    = logger;
            NetworkStream innerStream = tcpClient.GetStream();

            if (!secure)
            {
                this._stream = innerStream;
            }
            else
            {
                SslStream stream2 = new SslStream(innerStream, false, sslConfig.ClientCertificateValidationCallback);
                stream2.AuthenticateAsServer(sslConfig.ServerCertificate, sslConfig.ClientCertificateRequired, sslConfig.EnabledSslProtocols, sslConfig.CheckCertificateRevocation);
                this._stream = stream2;
            }
            this._request   = HttpRequest.Read(this._stream, 0x15f90);
            this._uri       = HttpUtility.CreateRequestUrl(this._request.RequestUri, this._request.Headers["Host"], this._request.IsWebSocketRequest, secure);
            this._websocket = new WebSocketSharp.WebSocket(this, protocol);
        }