public void Authenticate(ClientConnectionInfo cci, string encryptedCustomerID, string encryptedExtensionNumber, string encryptedPassword)
        {
            string userKey = encryptedCustomerID + " " + encryptedExtensionNumber + " " + encryptedPassword;

            if (IsAuthenticated(userKey) == false)
            {
                RijndaelHelper h = new RijndaelHelper(System.Text.Encoding.ASCII.GetString(cci.Provider.Key));

                int    customerID      = Convert.ToInt32(h.Decrypt(encryptedCustomerID));
                int    extensionNumber = Convert.ToInt32(h.Decrypt(encryptedExtensionNumber));
                string password        = h.Decrypt(encryptedPassword);

                if (OnAuthentication != null)
                {
                    AuthenticationEventArgs args = new AuthenticationEventArgs(customerID, extensionNumber, password);
                    OnAuthentication(this, args);

                    if (args.IsAuthenticated == false)
                    {
                        throw new Exception("Failed to authenticate");
                    }
                    else
                    {
                        lock (AuthUsers.SyncRoot)
                        {
                            AuthUsers.Add(userKey, DateTime.Now);
                        }
                    }
                }
                else
                {
                    throw new Exception("Failed to authenticate");
                }
            }
        }
        public void CheckForManagementAllowed(ClientConnectionInfo cci, string clientIpAddress, string extension)
        {
            RijndaelHelper h = new RijndaelHelper(System.Text.Encoding.ASCII.GetString(cci.Provider.Key));

            string extensionNumber = h.Decrypt(extension);

            if (OnManagementAllowed != null)
            {
                ManagementAllowedEventArgs args = new ManagementAllowedEventArgs(clientIpAddress, extensionNumber);

                OnManagementAllowed(this, args);

                if (args.ManagementAllowed == false)
                {
                    throw new Exception("Remote Management not allowed for : " + clientIpAddress);
                }
            }
            else
            {
                throw new Exception("Remote Management not allowed");
            }
        }
        private void SweepConnections(object sender, ElapsedEventArgs e)
        {
            lock (_connections.SyncRoot)
            {
                ArrayList toDelete = new ArrayList(_connections.Count);

                foreach (DictionaryEntry entry in _connections)
                {
                    ClientConnectionInfo cci = (ClientConnectionInfo)entry.Value;
                    if (cci.LastUsed.AddSeconds(_connectionAgeLimit).CompareTo(DateTime.UtcNow) < 0)
                    {
                        toDelete.Add(entry.Key);
                        ((IDisposable)cci).Dispose();
                    }
                }

                foreach (Object obj in toDelete)
                {
                    _connections.Remove(obj);
                }
                toDelete = null;
            }
        }
        private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            SymmetricAlgorithm symmetricProvider = CryptoHelper.GetNewSymmetricProvider(_algorithm);

            ClientConnectionInfo cci = new ClientConnectionInfo(transactID, symmetricProvider);

            lock (_connections.SyncRoot)
            {
                _connections[transactID.ToString()] = cci;
            }

            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();

            string publicKey = requestHeaders[CommonHeaders.PublicKey].ToString();

            if (publicKey == null || publicKey == string.Empty)
            {
                throw new SecureRemotingException("No public key found with which to encrypt the shared key.");
            }

            rsaProvider.FromXmlString(publicKey); // load the public key

            byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, false);
            byte[] encryptedIV  = rsaProvider.Encrypt(symmetricProvider.IV, false);

            responseHeaders = new TransportHeaders();
            responseHeaders[CommonHeaders.Transaction] = ((int)SecureTransaction.SendingSharedKey).ToString();
            responseHeaders[CommonHeaders.SharedKey]   = Convert.ToBase64String(encryptedKey);
            responseHeaders[CommonHeaders.SharedIV]    = Convert.ToBase64String(encryptedIV);

            IPAddress clientAddress = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;

            responseMsg    = null;
            responseStream = new MemoryStream();

            return(ServerProcessing.Complete);
        }
        public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            responseHeaders = null;

            string            strTransactID = (string)requestHeaders[CommonHeaders.ID];
            Guid              transactID    = (strTransactID == null ? Guid.Empty : new Guid(strTransactID));
            SecureTransaction transactType  = (SecureTransaction)Convert.ToInt32((string)requestHeaders[CommonHeaders.Transaction]);

            IPAddress clientAddress = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;

            sinkStack.Push(this, null);

            ServerProcessing processingResult;

            switch (transactType)
            {
            case SecureTransaction.SendingPublicKey:
            {
                processingResult = MakeSharedKey(transactID, requestHeaders, out responseMsg, out responseHeaders, out responseStream);
                System.Diagnostics.Debug.WriteLine("Connection added: " + transactID);
                break;
            }

            case SecureTransaction.SendingEncryptedMessage:
            {
                ClientConnectionInfo cci = (ClientConnectionInfo)_connections[transactID.ToString()];
                string customerID        = requestHeaders[CommonHeaders.CustomerID].ToString();
                string password          = requestHeaders[CommonHeaders.Password].ToString();
                string extensionNumber   = requestHeaders[CommonHeaders.ExtensionNumber].ToString();


                if (PreviousTransactionWithClient(transactID))
                {
                    if (RequireSecurity == true)
                    {
                        Authenticate(cci, customerID, extensionNumber, password);
                    }

                    processingResult = ProcessEncryptedMessage(transactID, sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);

                    if (clientAddress != null && cci != null)
                    {
                        CheckForManagementAllowed(cci, clientAddress.ToString(), extensionNumber);
                    }
                }
                else
                {
                    processingResult = SendEmptyToClient(SecureTransaction.UnknownIdentifier, out responseMsg, out responseHeaders, out responseStream);
                }


                break;
            }

            case SecureTransaction.Uninitialized:
            {
                if (!RequireSecurity)
                {
                    processingResult = _next.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
                }
                else
                {
                    throw new SecureRemotingException("Server requires a secure connection for this client");
                }
                break;
            }

            default:
            {
                // Houston, we have a problem!
                throw new SecureRemotingException("Invalid request from client: " + transactType + ".");
            }
            }

            sinkStack.Pop(this);
            return(processingResult);
        }
        private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            SymmetricAlgorithm symmetricProvider = CryptoHelper.GetNewSymmetricProvider(_algorithm);

            ClientConnectionInfo cci = new ClientConnectionInfo(transactID, symmetricProvider);

            lock (_connections.SyncRoot)
            {
                _connections[transactID.ToString()] = cci;
            }

            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();

            string publicKey = requestHeaders[CommonHeaders.PublicKey].ToString();

            if (publicKey == null || publicKey == string.Empty)
            {
                throw new SecureRemotingException("No public key found with which to encrypt the shared key.");
            }

            rsaProvider.FromXmlString(publicKey); // load the public key

            byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, false);
            byte[] encryptedIV = rsaProvider.Encrypt(symmetricProvider.IV, false);

            responseHeaders = new TransportHeaders();
            responseHeaders[CommonHeaders.Transaction] = ((int)SecureTransaction.SendingSharedKey).ToString();
            responseHeaders[CommonHeaders.SharedKey] = Convert.ToBase64String(encryptedKey);
            responseHeaders[CommonHeaders.SharedIV] = Convert.ToBase64String(encryptedIV);

            IPAddress clientAddress = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;

            responseMsg = null;
            responseStream = new MemoryStream();

            return ServerProcessing.Complete;
        }
        public void CheckForManagementAllowed(ClientConnectionInfo cci, string clientIpAddress, string extension)
        {
            RijndaelHelper h = new RijndaelHelper(System.Text.Encoding.ASCII.GetString(cci.Provider.Key));

            string extensionNumber = h.Decrypt(extension);
            if (OnManagementAllowed != null)
            {
                ManagementAllowedEventArgs args = new ManagementAllowedEventArgs( clientIpAddress, extensionNumber );

                OnManagementAllowed(this, args);

                if (args.ManagementAllowed == false)
                {
                    throw new Exception("Remote Management not allowed for : " + clientIpAddress);
                }
            }
            else
            {
                throw new Exception("Remote Management not allowed");
            }
        }
        public void Authenticate(ClientConnectionInfo cci, string encryptedCustomerID, string encryptedExtensionNumber, string encryptedPassword)
        {
            string userKey = encryptedCustomerID + " " + encryptedExtensionNumber + " " + encryptedPassword;

            if (IsAuthenticated(userKey) == false)
            {
                RijndaelHelper h = new RijndaelHelper(System.Text.Encoding.ASCII.GetString(cci.Provider.Key));

                int customerID = Convert.ToInt32(h.Decrypt(encryptedCustomerID));
                int extensionNumber = Convert.ToInt32(h.Decrypt(encryptedExtensionNumber));
                string password = h.Decrypt(encryptedPassword);

                if (OnAuthentication != null)
                {
                    AuthenticationEventArgs args = new AuthenticationEventArgs(customerID, extensionNumber, password);
                    OnAuthentication(this, args);

                    if (args.IsAuthenticated == false)
                    {
                        throw new Exception("Failed to authenticate");
                    }
                    else
                    {
                        lock (AuthUsers.SyncRoot)
                        {
                            AuthUsers.Add(userKey, DateTime.Now);
                        }
                    }
                }
                else
                {
                    throw new Exception("Failed to authenticate");
                }
            }
        }