private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1Packet packet)
        {
            SSH1DataReader reader         = new SSH1DataReader(packet.Data);
            int            server_channel = reader.ReadInt32();
            string         host           = Encoding.Default.GetString(reader.ReadString());
            int            port           = reader.ReadInt32();

            SSH1DataWriter            writer = new SSH1DataWriter();
            PortForwardingCheckResult result = receiver.CheckPortForwardingRequest(host, port, "", 0);

            if (result.allowed)
            {
                int local_id = this.RegisterChannelEventReceiver(null, result.channel)._localID;
                _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel));

                writer.Write(server_channel);
                writer.Write(local_id);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
            else
            {
                writer.Write(server_channel);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
        }
        private void ReceiveServerKeys()
        {
            SSH1Packet SSH1Packet = ReceivePacket();
            if(SSH1Packet.Type!=PacketType.SSH_SMSG_PUBLIC_KEY) throw new SSHException("unexpected SSH SSH1Packet type " + SSH1Packet.Type, SSH1Packet.Data);

            SSH1DataReader reader = new SSH1DataReader(SSH1Packet.Data);
            _cInfo._serverinfo = new SSHServerInfo(reader);
            _cInfo._hostkey = new RSAPublicKey(_cInfo._serverinfo.host_key_public_exponent, _cInfo._serverinfo.host_key_public_modulus);

            //read protocol support parameters
            int protocol_flags = reader.ReadInt32();
            int supported_ciphers_mask = reader.ReadInt32();
            _cInfo.SetSupportedCipherAlgorithms(supported_ciphers_mask);
            int supported_authentications_mask = reader.ReadInt32();
            //Debug.WriteLine(String.Format("ServerOptions {0} {1} {2}", protocol_flags, supported_ciphers_mask, supported_authentications_mask));

            if(reader.Rest>0) throw new SSHException("data length mismatch", SSH1Packet.Data);

            //Debug Info
            /*
            System.out.println("Flags="+protocol_flags);
            System.out.println("Cipher="+supported_ciphers_mask);
            System.out.println("Auth="+supported_authentications_mask);
            */

            bool found = false;
            foreach(CipherAlgorithm a in _param.PreferableCipherAlgorithms) {
                if(a!=CipherAlgorithm.Blowfish && a!=CipherAlgorithm.TripleDES)
                    continue;
                else if(a==CipherAlgorithm.Blowfish && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.Blowfish))==0)
                    continue;
                else if(a==CipherAlgorithm.TripleDES && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.TripleDES))==0)
                    continue;

                _cInfo._algorithmForReception = _cInfo._algorithmForTransmittion = a;
                found = true;
                break;
            }

            if(!found)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedX"), "Blowfish/TripleDES"));

            if(_param.AuthenticationType==AuthenticationType.Password && (supported_authentications_mask & (1 << (int)AuthenticationType.Password))==0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedPassword")), SSH1Packet.Data);
            if(_param.AuthenticationType==AuthenticationType.PublicKey && (supported_authentications_mask & (1 << (int)AuthenticationType.PublicKey))==0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedRSA")), SSH1Packet.Data);
        }
        private void ReceiveServerKeys()
        {
            SSH1Packet SSH1Packet = ReceivePacket();

            if (SSH1Packet.Type != PacketType.SSH_SMSG_PUBLIC_KEY)
            {
                throw new SSHException("unexpected SSH SSH1Packet type " + SSH1Packet.Type, SSH1Packet.Data);
            }

            SSH1DataReader reader = new SSH1DataReader(SSH1Packet.Data);

            _cInfo._serverinfo = new SSHServerInfo(reader);
            _cInfo._hostkey    = new RSAPublicKey(_cInfo._serverinfo.host_key_public_exponent, _cInfo._serverinfo.host_key_public_modulus);

            //read protocol support parameters
            int protocol_flags         = reader.ReadInt32();
            int supported_ciphers_mask = reader.ReadInt32();

            _cInfo.SetSupportedCipherAlgorithms(supported_ciphers_mask);
            int supported_authentications_mask = reader.ReadInt32();

            //Debug.WriteLine(String.Format("ServerOptions {0} {1} {2}", protocol_flags, supported_ciphers_mask, supported_authentications_mask));

            if (reader.Rest > 0)
            {
                throw new SSHException("data length mismatch", SSH1Packet.Data);
            }

            //Debug Info

            /*
             * System.out.println("Flags="+protocol_flags);
             * System.out.println("Cipher="+supported_ciphers_mask);
             * System.out.println("Auth="+supported_authentications_mask);
             */

            bool found = false;

            foreach (CipherAlgorithm a in _param.PreferableCipherAlgorithms)
            {
                if (a != CipherAlgorithm.Blowfish && a != CipherAlgorithm.TripleDES)
                {
                    continue;
                }
                else if (a == CipherAlgorithm.Blowfish && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.Blowfish)) == 0)
                {
                    continue;
                }
                else if (a == CipherAlgorithm.TripleDES && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.TripleDES)) == 0)
                {
                    continue;
                }

                _cInfo._algorithmForReception = _cInfo._algorithmForTransmittion = a;
                found = true;
                break;
            }

            if (!found)
            {
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedX"), "Blowfish/TripleDES"));
            }

            if (_param.AuthenticationType == AuthenticationType.Password && (supported_authentications_mask & (1 << (int)AuthenticationType.Password)) == 0)
            {
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedPassword")), SSH1Packet.Data);
            }
            if (_param.AuthenticationType == AuthenticationType.PublicKey && (supported_authentications_mask & (1 << (int)AuthenticationType.PublicKey)) == 0)
            {
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedRSA")), SSH1Packet.Data);
            }
        }
        private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1Packet packet)
        {
            SSH1DataReader reader = new SSH1DataReader(packet.Data);
            int server_channel = reader.ReadInt32();
            string host = Encoding.Default.GetString(reader.ReadString());
            int port = reader.ReadInt32();

            SSH1DataWriter writer = new SSH1DataWriter();
            PortForwardingCheckResult result = receiver.CheckPortForwardingRequest(host, port, "", 0);
            if(result.allowed) {
                int local_id = this.RegisterChannelEventReceiver(null, result.channel)._localID;
                _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel));

                writer.Write(server_channel);
                writer.Write(local_id);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
            else {
                writer.Write(server_channel);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
        }