Exemplo n.º 1
0
        /// <summary>
        /// Frees managed resources.
        /// </summary>
        public void Dispose()
        {
            BeforeDispose?.Invoke();

            _keyPair?.Dispose();
            _delegateProxyFactory = null;
            _delegateProxyCache.Clear();
            _delegateProxyCache  = null;
            _rawMessageTransport = null;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new instance of the RemotingClient class.
        /// </summary>
        /// <param name="config">Configuration settings</param>
        public RemotingClient(ClientConfig config) : this()
        {
            if (config == null)
            {
                throw new ArgumentException("No config provided and no default configuration found.");
            }

            Serializer        = config.Serializer ?? new BsonSerializerAdapter();
            MessageEncryption = config.MessageEncryption;

            _config = config;

            if (MessageEncryption)
            {
                _keyPair = new RsaKeyPair(config.KeySize);
            }

            _channel = config.Channel ?? new WebsocketClientChannel();

            _channel.Init(this);
            _rawMessageTransport = _channel.RawMessageTransport;
            _rawMessageTransport.ReceiveMessage += OnMessage;
            _rawMessageTransport.ErrorOccured   += (s, exception) =>
            {
                if (exception != null)
                {
                    throw exception;
                }

                throw new NetworkException(s);
            };

            _clientInstances.AddOrUpdate(
                key: config.UniqueClientInstanceName,
                addValueFactory: uniqueInstanceName => this,
                updateValueFactory: (uniqueInstanceName, oldClient) =>
            {
                oldClient?.Dispose();
                return(this);
            });

            if (!config.IsDefault)
            {
                return;
            }

            RemotingClient.DefaultRemotingClient ??= this;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Frees managed resources.
        /// </summary>
        public void Dispose()
        {
            if (RemotingClient.DefaultRemotingClient == this)
            {
                RemotingClient.DefaultRemotingClient = null;
            }

            _clientInstances.TryRemove(_config.UniqueClientInstanceName, out _);

            Disconnect();

            _cancellationTokenSource.Cancel();
            _delegateRegistry.Clear();

            if (_rawMessageTransport != null)
            {
                _rawMessageTransport.ReceiveMessage -= OnMessage;
                _rawMessageTransport = null;
            }

            if (_channel != null)
            {
                _channel.Dispose();
                _channel = null;
            }

            if (_handshakeCompletedWaitHandle != null)
            {
                _handshakeCompletedWaitHandle.Dispose();
                _handshakeCompletedWaitHandle = null;
            }

            if (_authenticationCompletedWaitHandle != null)
            {
                _authenticationCompletedWaitHandle.Dispose();
                _authenticationCompletedWaitHandle = null;
            }

            if (_goodbyeCompletedWaitHandle != null)
            {
                _goodbyeCompletedWaitHandle.Dispose();
                _goodbyeCompletedWaitHandle = null;
            }

            _keyPair?.Dispose();
        }
Exemplo n.º 4
0
        /// <summary>
        /// Creates a new session.
        /// </summary>
        /// <param name="clientPublicKey">Client's public key</param>
        /// <param name="server">Server instance</param>
        /// <param name="rawMessageTransport">Component that does the raw message transport</param>
        /// <returns>The newly created session</returns>
        public RemotingSession CreateSession(byte[] clientPublicKey, IRemotingServer server, IRawMessageTransport rawMessageTransport)
        {
            if (server == null)
            {
                throw new ArgumentException(nameof(server));
            }

            if (rawMessageTransport == null)
            {
                throw new ArgumentNullException(nameof(rawMessageTransport));
            }

            var session = new RemotingSession(
                KeySize,
                clientPublicKey,
                server,
                rawMessageTransport);

            _sessions.TryAdd(session.SessionId, session);

            return(session);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates a new instance of the RemotingSession class.
        /// </summary>
        /// <param name="keySize">Key size of the RSA keys for asymmetric encryption</param>
        /// <param name="clientPublicKey">Public key of this session's client</param>
        /// <param name="server">Server instance, that hosts this session</param>
        /// <param name="rawMessageTransport">Component, that does the raw message transport (send and receive)</param>
        internal RemotingSession(int keySize, byte[] clientPublicKey, IRemotingServer server,
                                 IRawMessageTransport rawMessageTransport)
        {
            _sessionId             = Guid.NewGuid();
            _lastActivityTimestamp = DateTime.Now;
            _isAuthenticated       = false;
            _keyPair  = new RsaKeyPair(keySize);
            CreatedOn = DateTime.Now;
            _remoteDelegateInvocationEventAggregator = new RemoteDelegateInvocationEventAggregator();
            _server = server ?? throw new ArgumentNullException(nameof(server));
            _delegateProxyFactory = _server.ServiceRegistry.GetService <IDelegateProxyFactory>();
            _delegateProxyCache   = new ConcurrentDictionary <Guid, IDelegateProxy>();
            _rawMessageTransport  = rawMessageTransport ?? throw new ArgumentNullException(nameof(rawMessageTransport));
            _clientPublicKeyBlob  = clientPublicKey;

            _rawMessageTransport.ReceiveMessage += OnReceiveMessage;
            _rawMessageTransport.ErrorOccured   += OnErrorOccured;

            MessageEncryption = clientPublicKey != null;

            WireMessage completeHandshakeMessage;

            if (MessageEncryption)
            {
                var encryptedSessionId =
                    RsaKeyExchange.EncryptSecret(
                        keySize: _server.SessionRepository.KeySize,
                        receiversPublicKeyBlob: clientPublicKey,
                        secretToEncrypt: _sessionId.ToByteArray(),
                        sendersPublicKeyBlob: _keyPair.PublicKey);

                var rawContent = _server.Serializer.Serialize(encryptedSessionId);

                var signedMessageData =
                    new SignedMessageData()
                {
                    MessageRawData = rawContent,
                    Signature      =
                        RsaSignature.CreateSignature(
                            keySize: keySize,
                            sendersPrivateKeyBlob: _keyPair.PrivateKey,
                            rawData: rawContent)
                };

                var rawData = _server.Serializer.Serialize(typeof(SignedMessageData), signedMessageData);

                completeHandshakeMessage =
                    new WireMessage
                {
                    MessageType = "complete_handshake",
                    Data        = rawData
                };
            }
            else
            {
                completeHandshakeMessage =
                    new WireMessage
                {
                    MessageType = "complete_handshake",
                    Data        = _sessionId.ToByteArray()
                };
            }

            _remoteDelegateInvocationEventAggregator.RemoteDelegateInvocationNeeded +=
                (delegateType, uniqueCallKey, handlerKey, arguments) =>
            {
                var sharedSecret =
                    MessageEncryption
                            ? _sessionId.ToByteArray()
                            : null;

                var remoteDelegateInvocationMessage =
                    new RemoteDelegateInvocationMessage
                {
                    UniqueCallKey     = uniqueCallKey,
                    HandlerKey        = handlerKey,
                    DelegateArguments = arguments
                };

                var remoteDelegateInvocationWebsocketMessage =
                    _server.MessageEncryptionManager
                    .CreateWireMessage(
                        serializedMessage: _server.Serializer.Serialize(remoteDelegateInvocationMessage),
                        serializer: _server.Serializer,
                        sharedSecret: sharedSecret,
                        keyPair: _keyPair,
                        messageType: "invoke");

                // Invoke remote delegate on client
                _rawMessageTransport.SendMessage(
                    _server.Serializer.Serialize(remoteDelegateInvocationWebsocketMessage));

                return(null);
            };

            _rawMessageTransport.SendMessage(_server.Serializer.Serialize(completeHandshakeMessage));
        }