Example #1
0
        /// <summary>
        /// Verarbeitet eine Anfragenachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="msg">Remoting-Nachricht</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            // Asynchroner Verarbeitungsstatus
            AsyncProcessingState state = null;

            // Verschlüsselter Datenstrom
            Stream encryptedStream = null;

            // Eindeutige Kennung der Sicherheitstransaktion
            Guid _secureTransactionID;

            lock (_lockObject)
            {
                // Sicherheitstransaktion starten
                _secureTransactionID = StartSecureTransaction(msg, headers);

                // Asynchronen Verarbeitungsstatus erzeugen
                state = new AsyncProcessingState(msg, headers, ref stream, _secureTransactionID);

                // Nachricht verschlüsseln
                encryptedStream = EncryptMessage(headers, stream);
            }
            // Aktuelle Senke auf den Senkenstapel legen (Damit ggf. die Verarbeitung der Antwort später asynchron aufgerufen werden kann)
            sinkStack.Push(this, state);

            // Nächste Kanalsenke aufrufen
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #2
0
        /// <summary>Requests asynchronous processing of a method call on the current sink.</summary>
        /// <param name="sinkStack">A stack of channel sinks.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to send to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(
            IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream     = null;
            Guid   id;

            lock (_transactionLock)            // could be a big lock... probably a faster way, but for now suffices
            {
                // Establish connection information with the server; the roundtrip will hopefully
                // only be done once, so we ensure that we have the necessary information.
                id = EnsureIDAndProvider(msg, headers);

                // Protect ourselves a bit.  If the asynchronous call fails because the server forgot about
                // us, we'll be in a bit of a fix.  We'll need the current arguments as we'll need
                // to retry the request synchronously.  Store them into a state object and use
                // that as the state when pushing ourself onto the stack.  That way, AsyncProcessResponse
                // have access to it.
                state = new AsyncProcessingState(msg, headers, ref stream, id);

                // Send encrypted message by encrypting the stream
                encryptedStream = SetupEncryptedMessage(headers, stream);
            }

            // Push ourselves onto the stack with the necessary state and forward on to the next sink
            sinkStack.Push(this, state);
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #3
0
        /// <summary>
        /// Requests asynchronous processing of a response to a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of sinks that called this sink.</param>
        /// <param name="state">Information generated on the request side that is associated with this sink.</param>
        /// <param name="headers">The headers retrieved from the server response stream.</param>
        /// <param name="stream">The stream coming back from the transport sink.</param>
        public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
        {
            // Gets the asynchronous processing state
            AsyncProcessingState asyncState = (AsyncProcessingState)state;

            try
            {
                SecureTransactionStage currentStage = (SecureTransactionStage)Convert.ToInt32((string)headers[CommonHeaderNames.SECURE_TRANSACTION_STATE]);
                switch (currentStage)
                {
                case SecureTransactionStage.SendingEncryptedResult:                         // Get the encrypted response from the server

                    lock (_lockObject)
                    {
                        if (asyncState.SecureTransactionID.Equals(_secureTransactionID))
                        {
                            stream = DecryptResponse(stream, headers);
                        }
                        else
                        {
                            throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_KeyChanged);
                        }
                    }
                    break;

                case SecureTransactionStage.UnknownTransactionID:                         // Bad transaction identifier

                    throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_InvalidTransactionID);

                default:

                case SecureTransactionStage.Uninitialized:                         // Secure transaction is not yet set up
                    break;
                }
            }
            catch (CryptoRemotingException)
            {
                lock (_lockObject)
                {
                    // If remote transaction identifier matches the local secure transaction identifier, reset the shared key
                    if (_provider == null || asyncState.SecureTransactionID.Equals(_secureTransactionID))
                    {
                        ClearSharedKey();
                    }

                    ProcessMessage(asyncState.Message, asyncState.Headers, asyncState.Stream, out headers, out stream);
                }
            }
            finally
            {
                // Close the input stream
                asyncState.Stream.Close();
            }

            // Pass on to the next sink to continue processing
            sinkStack.AsyncProcessResponse(headers, stream);
        }
Example #4
0
        public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState asyncState = (AsyncProcessingState)state;

            try
            {
                SecureTransaction transactType = (SecureTransaction)Convert.ToInt32((string)headers[CommonHeaders.Transaction]);
                switch (transactType)
                {
                case SecureTransaction.SendingEncryptedResult:
                {
                    lock (_transactionLock)
                    {
                        if (asyncState.ID.Equals(_transactID))
                        {
                            stream = DecryptResponse(stream, headers);
                        }
                        else
                        {
                            throw new SecureRemotingException("The key has changed since the message was decrypted.");
                        }
                    }
                    break;
                }

                case SecureTransaction.UnknownIdentifier:
                {
                    throw new SecureRemotingException("The server sink was unable to identify the client, most likely due to the connection information timing out.");
                }

                default:
                case SecureTransaction.Uninitialized:
                {
                    break;
                }
                }
            }
            catch (SecureRemotingException)
            {
                lock (_transactionLock)
                {
                    if (_provider == null || asyncState.ID.Equals(_transactID))
                    {
                        ClearSharedKey();
                    }
                    ProcessMessage(asyncState.Message, asyncState.Headers, asyncState.Stream, out headers, out stream);
                }
            }
            finally
            {
                asyncState.Stream.Close();
            }

            sinkStack.AsyncProcessResponse(headers, stream);
        }
Example #5
0
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream     = null;
            Guid   id;

            lock (_transactionLock)
            {
                id = EnsureIDAndProvider(msg, headers);

                state = new AsyncProcessingState(msg, headers, ref stream, id);

                encryptedStream = SetupEncryptedMessage(headers, stream, null);
            }

            sinkStack.Push(this, state);
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
        /// <summary>
        /// Verarbeitet eine Anfragenachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="msg">Remoting-Nachricht</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            // Asynchroner Verarbeitungsstatus
            AsyncProcessingState state = null;

            lock (_lockObject)
            {
                // Asynchronen Verarbeitungsstatus erzeugen
                state = new AsyncProcessingState(msg, headers, ref stream, new Guid());

                //Methode aufrufen die Verarbeitung übernimmt
                DoProcessMessageBefore(msg, headers, stream);
            }
            // Aktuelle Senke auf den Senkenstapel legen (Damit ggf. die Verarbeitung der Antwort später asynchron aufgerufen werden kann)
            sinkStack.Push(this, state);

            // Nächste Kanalsenke aufrufen
            _next.AsyncProcessRequest(sinkStack, msg, headers, stream);
        }
Example #7
0
        /// <summary>
        /// Verarbeitet eine Anfragenachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="msg">Remoting-Nachricht</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            // Asynchroner Verarbeitungsstatus
            AsyncProcessingState state = null;

            lock (_lockObject)
            {

                // Asynchronen Verarbeitungsstatus erzeugen
                state = new AsyncProcessingState(msg, headers, ref stream, new Guid());

                //Methode aufrufen die Verarbeitung übernimmt
                DoProcessMessageBefore(msg, headers, stream);

            }
            // Aktuelle Senke auf den Senkenstapel legen (Damit ggf. die Verarbeitung der Antwort später asynchron aufgerufen werden kann)
            sinkStack.Push(this, state);

            // Nächste Kanalsenke aufrufen
            _next.AsyncProcessRequest(sinkStack, msg, headers, stream);
        }
        /// <summary>
        /// Verarbeitet eine Antwort-Nachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="state">Asynchroner Verarbeitungsstatus</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
        {
            // Asychronen Verarbeitungsstatus abrufen
            AsyncProcessingState asyncState = (AsyncProcessingState)state;

            try
            {
                lock (_lockObject)
                {
                    //Todo: Was ist hier zu tun?
                }
            }
            finally
            {
            }

            ProcessMessage(asyncState.Message, asyncState.Headers, asyncState.Stream, out headers, out stream);

            asyncState.Stream.Close();

            // Verarbeitung in der nächsten Kanalsenke fortsetzen
            sinkStack.AsyncProcessResponse(headers, stream);
        }
Example #9
0
        /// <summary>
        /// Requests asynchronous processing of a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of channel sinks that called this sink.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream     = null;
            Guid   _secureTransactionID;

            lock (_lockObject)
            {
                // Start the secure transaction and save its identifier
                _secureTransactionID = StartSecureTransaction(msg, headers);

                // Prepare asynchronous state
                state = new AsyncProcessingState(msg, headers, ref stream, _secureTransactionID);

                // Encrypt the message
                encryptedStream = EncryptMessage(headers, stream);
            }

            // Push the current sink onto the sink stack so the processing of the response can be invoked asynchronously later
            sinkStack.Push(this, state);

            // Pass the message on to the next sink
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #10
0
        /// <summary>
        /// Verarbeitet eine Antwort-Nachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="state">Asynchroner Verarbeitungsstatus</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
        {
            // Asychronen Verarbeitungsstatus abrufen
            AsyncProcessingState asyncState = (AsyncProcessingState)state;

            try
            {
                // Aktuellen Verarbeitungsschritt der Sicherheitstransaktion ermitteln
                SecureTransactionStage currentStage = (SecureTransactionStage)Convert.ToInt32((string)headers[CommonHeaderNames.SECURE_TRANSACTION_STATE]);

                // Verarbeitungsschritt auswerten
                switch (currentStage)
                {
                case SecureTransactionStage.SendingEncryptedResult:     // Verschlüsselte Daten vom Server eingtroffen

                    lock (_lockObject)
                    {
                        // Wenn die Antwort auch tatsächlich zur aktuellen Sicherheitstransaktion gehört ...
                        if (asyncState.SecureTransactionID.Equals(_secureTransactionID))
                        {
                            // Datenstrom entschlüsseln
                            stream = DecryptResponse(stream, headers);
                        }
                        // Andernfalls ...
                        else
                        {
                            // Ausnahme werfen
                            throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_KeyChanged);
                        }
                    }
                    break;

                case SecureTransactionStage.UnknownTransactionID:                         // Unbekannte Transaktionskennung

                    // Ausnahme werfen
                    throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_InvalidTransactionID);

                default:

                case SecureTransactionStage.Uninitialized:     // Keine Sicherheitstransaktion eingerichtet
                    break;
                }
            }
            catch (CryptoRemotingException)
            {
                lock (_lockObject)
                {
                    // Wenn die gesendete Transaktionskennung mit der lokalen übereinstimmt ...
                    if (_provider == null || asyncState.SecureTransactionID.Equals(_secureTransactionID))
                    {
                        // Gemeinamen Schlüssel löschen
                        ClearSharedKey();
                    }

                    // Nachricht weiterverarbeiten
                    ProcessMessage(asyncState.Message, asyncState.Headers, asyncState.Stream, out headers, out stream);
                }
            }
            finally
            {
                // Datenstrom schließen
                asyncState.Stream.Close();
            }
            // Verarbeitung in der nächsten Kanalsenke fortsetzen
            sinkStack.AsyncProcessResponse(headers, stream);
        }
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream = null;
            Guid id;

            lock (_transactionLock)
            {
                id = EnsureIDAndProvider(msg, headers);

                state = new AsyncProcessingState(msg, headers, ref stream, id);

                encryptedStream = SetupEncryptedMessage(headers, stream, null);
            }

            sinkStack.Push(this, state);
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
        /// <summary>Requests asynchronous processing of a method call on the current sink.</summary>
        /// <param name="sinkStack">A stack of channel sinks.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to send to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(
			IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream = null;
            Guid id;

            lock(_transactionLock) // could be a big lock... probably a faster way, but for now suffices
            {
                // Establish connection information with the server; the roundtrip will hopefully
                // only be done once, so we ensure that we have the necessary information.
                id = EnsureIDAndProvider(msg, headers);

                // Protect ourselves a bit.  If the asynchronous call fails because the server forgot about
                // us, we'll be in a bit of a fix.  We'll need the current arguments as we'll need
                // to retry the request synchronously.  Store them into a state object and use
                // that as the state when pushing ourself onto the stack.  That way, AsyncProcessResponse
                // have access to it.
                state = new AsyncProcessingState(msg, headers, ref stream, id);

                // Send encrypted message by encrypting the stream
                encryptedStream = SetupEncryptedMessage(headers, stream);
            }

            // Push ourselves onto the stack with the necessary state and forward on to the next sink
            sinkStack.Push(this, state);
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #13
0
        /// <summary>
        /// Verarbeitet eine Anfragenachricht asynchron.
        /// </summary>
        /// <param name="sinkStack">Senkenstapel</param>
        /// <param name="msg">Remoting-Nachricht</param>
        /// <param name="headers">Anfrage-Header-Auflistung</param>
        /// <param name="stream">Anfrage-Datenstrom</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            // Asynchroner Verarbeitungsstatus
            AsyncProcessingState state = null;

            // Verschlüsselter Datenstrom
            Stream encryptedStream = null;

            // Eindeutige Kennung der Sicherheitstransaktion
            Guid _secureTransactionID;

            lock (_lockObject)
            {
                // Sicherheitstransaktion starten
                _secureTransactionID = StartSecureTransaction(msg, headers);

                // Asynchronen Verarbeitungsstatus erzeugen
                state = new AsyncProcessingState(msg, headers, ref stream, _secureTransactionID);

                // Nachricht verschlüsseln
                encryptedStream = EncryptMessage(headers, stream);
            }
            // Aktuelle Senke auf den Senkenstapel legen (Damit ggf. die Verarbeitung der Antwort später asynchron aufgerufen werden kann)
            sinkStack.Push(this, state);

            // Nächste Kanalsenke aufrufen
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #14
0
        /// <summary>
        /// Requests asynchronous processing of a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of channel sinks that called this sink.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            AsyncProcessingState state = null;
            Stream encryptedStream = null;
            Guid _secureTransactionID;

            lock (_lockObject)
            {
                // Start the secure transaction and save its identifier
                _secureTransactionID = StartSecureTransaction(msg, headers);

                // Prepare asynchronous state
                state = new AsyncProcessingState(msg, headers, ref stream, _secureTransactionID);

                // Encrypt the message
                encryptedStream = EncryptMessage(headers, stream);
            }

            // Push the current sink onto the sink stack so the processing of the response can be invoked asynchronously later
            sinkStack.Push(this, state);

            // Pass the message on to the next sink
            _next.AsyncProcessRequest(sinkStack, msg, headers, encryptedStream);
        }
Example #15
0
        /// <summary>Requests asynchronous processing of a response to a method call on the current sink.</summary>
        /// <param name="sinkStack">A stack of sinks that called this sink.</param>
        /// <param name="state">Information generated on the request side that is associated with this sink.</param>
        /// <param name="headers">The headers retrieved from the server response stream.</param>
        /// <param name="stream">The stream coming back from the transport sink.</param>
        public void AsyncProcessResponse(
            IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
        {
            // Get the async state we put on the stack
            AsyncProcessingState asyncState = (AsyncProcessingState)state;

            try
            {
                // Decrypt the response if possible
                SecureTransaction transactType = (SecureTransaction)Convert.ToInt32((string)headers[CommonHeaders.Transaction]);
                switch (transactType)
                {
                // The only valid value; the server is sending results encrypted,
                // so we need to decrypt them
                case SecureTransaction.SendingEncryptedResult:
                    lock (_transactionLock)
                    {
                        if (asyncState.ID.Equals(_transactID))
                        {
                            stream = DecryptResponse(stream, headers);
                        }
                        else
                        {
                            throw new SecureRemotingException("The key has changed since the message was decrypted.");
                        }
                    }
                    break;

                // The server has no record of the client, so error out.
                // If this were synchronous, we could try again, first renewing
                // the connection information.  The best we can do here is null
                // out our current connection information so that the next time
                // through we'll create a new provider and identifier.
                case SecureTransaction.UnknownIdentifier:
                    throw new SecureRemotingException(
                              "The server sink was unable to identify the client, " +
                              "most likely due to the connection information timing out.");

                // Something happened and the response is not encrypted, i.e. there
                // are no transport headers, or at least no transaction header, or it has
                // been explicitly set by the server to Uninitialized.
                // Regardless, do nothing.
                default:
                case SecureTransaction.Uninitialized:
                    break;
                }
            }
            catch (SecureRemotingException)
            {
                // We got back a secure remoting exceptionIt would be difficult to retry this as an
                // asynchronous call as we need to have the output ready to go before
                // we return.  Thus, we'll make a synchronous one by calling ProcessMessage()
                // just as if we were the previous sink.  Luckily, we kept all of the
                // necessary information sitting around.
                lock (_transactionLock)                // This is a big, big lock, as are many locks in this app!  Oh well.
                {
                    if (_provider == null || asyncState.ID.Equals(_transactID))
                    {
                        ClearSharedKey();
                    }
                    ProcessMessage(
                        asyncState.Message, asyncState.Headers, asyncState.Stream,
                        out headers, out stream);
                }
            }
            finally
            {
                // Close the old stream just in case it hasn't been closed yet.
                asyncState.Stream.Close();
            }

            // Process through the rest of the sinks.
            sinkStack.AsyncProcessResponse(headers, stream);
        }