Esempio n. 1
0
        /// <summary>
        /// Processes a RPC result message from server.
        /// </summary>
        /// <param name="message">Deserialized WireMessage that contains a MethodCallResultMessage or a RemoteInvocationException</param>
        /// <exception cref="KeyNotFoundException">Thrown, when the received result is of a unknown call</exception>
        private void ProcessRpcResultMessage(WireMessage message)
        {
            byte[] sharedSecret =
                MessageEncryption
                    ? _sessionId.ToByteArray()
                    : null;

            Guid unqiueCallKey =
                message.UniqueCallKey == null
                    ? Guid.Empty
                    : new Guid(message.UniqueCallKey);

            if (!_activeCalls.TryGetValue(unqiueCallKey, out ClientRpcContext clientRpcContext))
            {
                throw new KeyNotFoundException("Received a result for a unknown call.");
            }

            clientRpcContext.Error = message.Error;

            if (message.Error)
            {
                var remoteException =
                    Serializer.Deserialize <RemoteInvocationException>(
                        MessageEncryptionManager.GetDecryptedMessageData(
                            message: message,
                            serializer: Serializer,
                            sharedSecret: sharedSecret,
                            sendersPublicKeyBlob: _serverPublicKeyBlob,
                            sendersPublicKeySize: _keyPair?.KeySize ?? 0));

                clientRpcContext.RemoteException = remoteException;
            }
            else
            {
                try
                {
                    var rawMessage =
                        MessageEncryptionManager.GetDecryptedMessageData(
                            message: message,
                            serializer: Serializer,
                            sharedSecret: sharedSecret,
                            sendersPublicKeyBlob: _serverPublicKeyBlob,
                            sendersPublicKeySize: _keyPair?.KeySize ?? 0);

                    var resultMessage =
                        Serializer
                        .Deserialize <MethodCallResultMessage>(rawMessage);

                    clientRpcContext.ResultMessage = resultMessage;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            }
            clientRpcContext.WaitHandle.Set();
        }
Esempio n. 2
0
        /// <summary>
        /// Authenticates this CoreRemoting client instance with the specified credentials.
        /// </summary>
        /// <exception cref="SecurityException">Thrown, if authentication failed or timed out</exception>
        private void Authenticate()
        {
            if (_config.Credentials == null || (_config.Credentials != null && _config.Credentials.Length == 0))
            {
                return;
            }

            if (_authenticationCompletedWaitHandle.IsSet)
            {
                return;
            }

            byte[] sharedSecret =
                MessageEncryption
                    ? _sessionId.ToByteArray()
                    : null;

            var authRequestMessage =
                new AuthenticationRequestMessage()
            {
                Credentials = _config.Credentials
            };

            var wireMessage =
                MessageEncryptionManager.CreateWireMessage(
                    messageType: "auth",
                    serializer: Serializer,
                    serializedMessage: Serializer.Serialize(authRequestMessage),
                    keyPair: _keyPair,
                    sharedSecret: sharedSecret);

            byte[] rawData = Serializer.Serialize(wireMessage);

            _rawMessageTransport.LastException = null;

            _rawMessageTransport.SendMessage(rawData);

            if (_rawMessageTransport.LastException != null)
            {
                throw _rawMessageTransport.LastException;
            }

            _authenticationCompletedWaitHandle.Wait(_config.AuthenticationTimeout * 1000);

            if (!_authenticationCompletedWaitHandle.IsSet)
            {
                throw new SecurityException("Authentication timeout.");
            }

            if (!_isAuthenticated)
            {
                throw new SecurityException("Authentication failed. Please check credentials.");
            }
        }
Esempio n. 3
0
 private RemotingClient()
 {
     MethodCallMessageBuilder           = new MethodCallMessageBuilder();
     MessageEncryptionManager           = new MessageEncryptionManager();
     _proxyGenerator                    = new ProxyGenerator();
     _activeCalls                       = new ConcurrentDictionary <Guid, ClientRpcContext>();
     _cancellationTokenSource           = new CancellationTokenSource();
     _delegateRegistry                  = new ClientDelegateRegistry();
     _handshakeCompletedWaitHandle      = new ManualResetEventSlim(initialState: false);
     _authenticationCompletedWaitHandle = new ManualResetEventSlim(initialState: false);
     _goodbyeCompletedWaitHandle        = new ManualResetEventSlim(initialState: false);
 }
Esempio n. 4
0
        /// <summary>
        /// Calls a method on a remote service synchronously.
        /// </summary>
        /// <param name="methodCallMessage">Details of the remote method to be invoked</param>
        /// <param name="oneWay">Invoke method without waiting for or processing result.</param>
        /// <returns>Results of the remote method invocation</returns>
        internal ClientRpcContext InvokeRemoteMethod(MethodCallMessage methodCallMessage, bool oneWay = false)
        {
            byte[] sharedSecret =
                MessageEncryption
                    ? _sessionId.ToByteArray()
                    : null;

            var clientRpcContext = new ClientRpcContext();

            if (!_activeCalls.TryAdd(clientRpcContext.UniqueCallKey, clientRpcContext))
            {
                throw new ApplicationException("Duplicate unique call key.");
            }

            var wireMessage =
                MessageEncryptionManager.CreateWireMessage(
                    messageType: "rpc",
                    serializer: Serializer,
                    serializedMessage: Serializer.Serialize(methodCallMessage),
                    sharedSecret: sharedSecret,
                    keyPair: _keyPair,
                    uniqueCallKey: clientRpcContext.UniqueCallKey.ToByteArray());

            byte[] rawData = Serializer.Serialize(wireMessage);

            _rawMessageTransport.LastException = null;

            _rawMessageTransport.SendMessage(rawData);

            if (_rawMessageTransport.LastException != null)
            {
                throw _rawMessageTransport.LastException;
            }

            if (!oneWay && clientRpcContext.ResultMessage == null)
            {
                if (_config.InvocationTimeout <= 0)
                {
                    clientRpcContext.WaitHandle.WaitOne();
                }
                else
                {
                    clientRpcContext.WaitHandle.WaitOne(_config.InvocationTimeout * 1000);
                }
            }

            return(clientRpcContext);
        }
Esempio n. 5
0
        /// <summary>
        /// Disconnects from the server. The server is actively notified about disconnection.
        /// </summary>
        public void Disconnect()
        {
            if (_channel != null && HasSession)
            {
                if (_keepSessionAliveTimer != null)
                {
                    _keepSessionAliveTimer.Stop();
                    _keepSessionAliveTimer.Dispose();
                    _keepSessionAliveTimer = null;
                }

                byte[] sharedSecret =
                    MessageEncryption
                        ? _sessionId.ToByteArray()
                        : null;

                var goodbyeMessage =
                    new GoodbyeMessage()
                {
                    SessionId = _sessionId
                };

                var wireMessage =
                    MessageEncryptionManager.CreateWireMessage(
                        messageType: "goodbye",
                        serializer: Serializer,
                        serializedMessage: Serializer.Serialize(goodbyeMessage),
                        keyPair: _keyPair,
                        sharedSecret: sharedSecret);

                byte[] rawData = Serializer.Serialize(wireMessage);

                _goodbyeCompletedWaitHandle.Reset();

                _channel.RawMessageTransport.SendMessage(rawData);

                _goodbyeCompletedWaitHandle.Wait(10000);
            }

            _channel?.Disconnect();
            _handshakeCompletedWaitHandle?.Reset();
            _authenticationCompletedWaitHandle?.Reset();
            Identity = null;
        }
Esempio n. 6
0
        /// <summary>
        /// Creates a new instance of the RemotingServer class.
        /// </summary>
        /// <param name="config">Configuration settings to be used (Default configuration is used, if left null)</param>
        public RemotingServer(ServerConfig config = null)
        {
            _config = config ?? new ServerConfig();

            _uniqueServerInstanceName =
                string.IsNullOrWhiteSpace(_config.UniqueServerInstanceName)
                    ? Guid.NewGuid().ToString()
                    : _config.UniqueServerInstanceName;

            _serverInstances.AddOrUpdate(
                key: _config.UniqueServerInstanceName,
                addValueFactory: uniqueInstanceName => this,
                updateValueFactory: (uniqueInstanceName, oldServer) =>
            {
                oldServer?.Dispose();
                return(this);
            });

            SessionRepository =
                _config.SessionRepository ??
                new SessionRepository(
                    keySize: _config.KeySize,
                    inactiveSessionSweepInterval: _config.InactiveSessionSweepInterval,
                    maximumSessionInactivityTime: _config.MaximumSessionInactivityTime);

            _container = _config.DependencyInjectionContainer ?? new CastleWindsorDependencyInjectionContainer();
            Serializer = _config.Serializer ?? new BsonSerializerAdapter();
            MethodCallMessageBuilder = new MethodCallMessageBuilder();
            MessageEncryptionManager = new MessageEncryptionManager();

            _container.RegisterService <IDelegateProxyFactory, DelegateProxyFactory>(
                lifetime: ServiceLifetime.Singleton);

            _config.RegisterServicesAction?.Invoke(_container);

            Channel = _config.Channel ?? new WebsocketServerChannel();

            Channel.Init(this);

            if (_config.IsDefault)
            {
                RemotingServer.DefaultRemotingServer ??= this;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Processes a remote delegate invocation message from server.
        /// </summary>
        /// <param name="message">Deserialized WireMessage that contains a RemoteDelegateInvocationMessage</param>
        private void ProcessRemoteDelegateInvocationMessage(WireMessage message)
        {
            byte[] sharedSecret =
                MessageEncryption
                    ? _sessionId.ToByteArray()
                    : null;

            var delegateInvocationMessage =
                Serializer
                .Deserialize <RemoteDelegateInvocationMessage>(
                    MessageEncryptionManager.GetDecryptedMessageData(
                        message: message,
                        serializer: Serializer,
                        sharedSecret: sharedSecret,
                        sendersPublicKeyBlob: _serverPublicKeyBlob,
                        sendersPublicKeySize: _keyPair?.KeySize ?? 0));

            var localDelegate =
                _delegateRegistry.GetDelegateByHandlerKey(delegateInvocationMessage.HandlerKey);

            // Invoke local delegate with arguments from remote caller
            localDelegate.DynamicInvoke(delegateInvocationMessage.DelegateArguments);
        }
Esempio n. 8
0
        /// <summary>
        /// Processes a authentication response message from server.
        /// </summary>
        /// <param name="message">Deserialized WireMessage that contains a AuthenticationResponseMessage</param>
        private void ProcessAuthenticationResponseMessage(WireMessage message)
        {
            byte[] sharedSecret =
                MessageEncryption
                    ? _sessionId.ToByteArray()
                    : null;

            var authResponseMessage =
                Serializer
                .Deserialize <AuthenticationResponseMessage>(
                    MessageEncryptionManager.GetDecryptedMessageData(
                        message: message,
                        serializer: Serializer,
                        sharedSecret: sharedSecret,
                        sendersPublicKeyBlob: _serverPublicKeyBlob,
                        sendersPublicKeySize: _keyPair?.KeySize ?? 0));

            _isAuthenticated = authResponseMessage.IsAuthenticated;

            Identity = _isAuthenticated ? authResponseMessage.AuthenticatedIdentity : null;

            _authenticationCompletedWaitHandle.Set();
        }