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);
            }
        }
        /// <summary>
        /// constructs from file
        /// </summary>
        /// <param name="path">file name</param>
        /// <param name="passphrase">passphrase or empty string if passphrase is not required</param>
        public SSH1UserAuthKey(string path, string passphrase)
        {
            Stream s = File.Open(path, FileMode.Open);

            byte[] header = new byte[32];
            s.Read(header, 0, header.Length);
            if (Encoding.ASCII.GetString(header) != "SSH PRIVATE KEY FILE FORMAT 1.1\n")
            {
                throw new SSHException(String.Format(Strings.GetString("BrokenKeyFile"), path));
            }

            SSH1DataReader reader = new SSH1DataReader(ReadAll(s));

            s.Close();

            byte[] cipher = reader.Read(2);             //first 2 bytes indicates algorithm and next 8 bytes is space
            reader.Read(8);

            _modulus        = reader.ReadMPInt();
            _publicExponent = reader.ReadMPInt();
            byte[] comment = reader.ReadString();
            byte[] prvt    = reader.ReadAll();
            //必要なら復号
            CipherAlgorithm algo = (CipherAlgorithm)cipher[1];

            if (algo != 0)
            {
                Cipher c   = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase));
                byte[] buf = new byte[prvt.Length];
                c.Decrypt(prvt, 0, prvt.Length, buf, 0);
                prvt = buf;
            }

            SSH1DataReader prvtreader = new SSH1DataReader(prvt);

            byte[] mark = prvtreader.Read(4);
            if (mark[0] != mark[2] || mark[1] != mark[3])
            {
                throw new SSHException(Strings.GetString("WrongPassphrase"));
            }

            _privateExponent = prvtreader.ReadMPInt();
            _crtCoefficient  = prvtreader.ReadMPInt();
            _primeP          = prvtreader.ReadMPInt();
            _primeQ          = prvtreader.ReadMPInt();
        }
        private SSH1Packet ReceivePacket()
        {
            while (true)
            {
                SSH1Packet p = null;
                SynchronizedSSH1PacketHandler handler = (SynchronizedSSH1PacketHandler)_packetBuilder.Handler;
                if (!handler.HasPacket)
                {
                    handler.Wait();
                    if (handler.State == ReceiverState.Error)
                    {
                        throw new SSHException(handler.ErrorMessage);
                    }
                    else if (handler.State == ReceiverState.Closed)
                    {
                        throw new SSHException("socket closed");
                    }
                }
                p = handler.PopPacket();

                SSH1DataReader r  = new SSH1DataReader(p.Data);
                PacketType     pt = p.Type;
                if (pt == PacketType.SSH_MSG_IGNORE)
                {
                    if (_eventReceiver != null)
                    {
                        _eventReceiver.OnIgnoreMessage(r.ReadString());
                    }
                }
                else if (pt == PacketType.SSH_MSG_DEBUG)
                {
                    if (_eventReceiver != null)
                    {
                        _eventReceiver.OnDebugMessage(false, r.ReadString());
                    }
                }
                else
                {
                    return(p);
                }
            }
        }
        //RSA authentication
        private void DoRSAChallengeResponse()
        {
            //read key
            SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password);
            SSH1DataWriter  w   = new SSH1DataWriter();

            w.Write(key.PublicModulus);
            SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA, w.ToByteArray());

            p.WriteTo(_stream, _tCipher);

            p = ReceivePacket();
            if (p.Type == PacketType.SSH_SMSG_FAILURE)
            {
                throw new SSHException(Strings.GetString("ServerRefusedRSA"));
            }
            else if (p.Type != PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE)
            {
                throw new SSHException(String.Format(Strings.GetString("UnexpectedResponse"), p.Type));
            }

            //creating challenge
            SSH1DataReader r         = new SSH1DataReader(p.Data);
            BigInteger     challenge = key.decryptChallenge(r.ReadMPInt());

            byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).getBytes();

            //building response
            MemoryStream bos = new MemoryStream();

            bos.Write(rawchallenge, 0, rawchallenge.Length);             //!!mindtermでは頭が0かどうかで変なハンドリングがあった
            bos.Write(_sessionID, 0, _sessionID.Length);
            byte[] response = new MD5CryptoServiceProvider().ComputeHash(bos.ToArray());

            w = new SSH1DataWriter();
            w.Write(response);
            p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, w.ToByteArray());
            p.WriteTo(_stream, _tCipher);
        }
        /// <summary>
        /// constructs from file
        /// </summary>
        /// <param name="path">file name</param>
        /// <param name="passphrase">passphrase or empty string if passphrase is not required</param>
        public SSH1UserAuthKey(string path, string passphrase)
        {
            Stream s = File.Open(path, FileMode.Open);
            byte[] header = new byte[32];
            s.Read(header, 0, header.Length);
            if(Encoding.Default.GetString(header) != "SSH PRIVATE KEY FILE FORMAT 1.1\n")
                throw new SSHException(String.Format(Strings.GetString("BrokenKeyFile"), path));

            SSH1DataReader reader = new SSH1DataReader(ReadAll(s));
            s.Close();

            byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space
            reader.Read(8);

            _modulus = reader.ReadMPInt();
            _publicExponent = reader.ReadMPInt();
            byte[] comment = reader.ReadString();
            byte[] prvt = reader.ReadAll();
            //�K�v�Ȃ畜��
            CipherAlgorithm algo = (CipherAlgorithm)cipher[1];
            if(algo!=0) {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase));
                byte[] buf = new byte[prvt.Length];
                c.Decrypt(prvt, 0, prvt.Length, buf, 0);
                prvt = buf;
            }

            SSH1DataReader prvtreader = new SSH1DataReader(prvt);
            byte[] mark = prvtreader.Read(4);
            if(mark[0]!=mark[2] || mark[1]!=mark[3])
                throw new SSHException(Strings.GetString("WrongPassphrase"));

            _privateExponent = prvtreader.ReadMPInt();
            _crtCoefficient = prvtreader.ReadMPInt();
            _primeP = prvtreader.ReadMPInt();
            _primeQ = prvtreader.ReadMPInt();
        }
        private bool ReceiveAuthenticationResult()
        {
            SSH1Packet SSH1Packet = ReceivePacket();
            PacketType type       = SSH1Packet.Type;

            if (type == PacketType.SSH_MSG_DEBUG)
            {
                SSH1DataReader r = new SSH1DataReader(SSH1Packet.Data);
                //Debug.WriteLine("receivedd debug message:"+Encoding.ASCII.GetString(r.ReadString()));
                return(ReceiveAuthenticationResult());
            }
            else if (type == PacketType.SSH_SMSG_SUCCESS)
            {
                return(true);
            }
            else if (type == PacketType.SSH_SMSG_FAILURE)
            {
                return(false);
            }
            else
            {
                throw new SSHException("type: " + type, SSH1Packet.Data);
            }
        }
        internal void AsyncReceivePacket(SSH1Packet p)
        {
            try {
                int len = 0, channel = 0;
                switch (p.Type)
                {
                case PacketType.SSH_SMSG_STDOUT_DATA:
                    len = SSHUtil.ReadInt32(p.Data, 0);
                    FindChannelEntry(_shellID)._receiver.OnData(p.Data, 4, len);
                    break;

                case PacketType.SSH_SMSG_STDERR_DATA: {
                    SSH1DataReader re = new SSH1DataReader(p.Data);
                    FindChannelEntry(_shellID)._receiver.OnExtendedData((int)PacketType.SSH_SMSG_STDERR_DATA, re.ReadString());
                }
                break;

                case PacketType.SSH_MSG_CHANNEL_DATA:
                    channel = SSHUtil.ReadInt32(p.Data, 0);
                    len     = SSHUtil.ReadInt32(p.Data, 4);
                    FindChannelEntry(channel)._receiver.OnData(p.Data, 8, len);
                    break;

                case PacketType.SSH_MSG_PORT_OPEN:
                    this.ProcessPortforwardingRequest(_eventReceiver, p);
                    break;

                case PacketType.SSH_MSG_CHANNEL_CLOSE: {
                    channel = SSHUtil.ReadInt32(p.Data, 0);
                    ISSHChannelEventReceiver r = FindChannelEntry(channel)._receiver;
                    UnregisterChannelEventReceiver(channel);
                    r.OnChannelClosed();
                }
                break;

                case PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
                    channel = SSHUtil.ReadInt32(p.Data, 0);
                    break;

                case PacketType.SSH_MSG_DISCONNECT:
                    _eventReceiver.OnConnectionClosed();
                    break;

                case PacketType.SSH_SMSG_EXITSTATUS:
                    FindChannelEntry(_shellID)._receiver.OnChannelClosed();
                    break;

                case PacketType.SSH_MSG_DEBUG: {
                    SSH1DataReader re = new SSH1DataReader(p.Data);
                    _eventReceiver.OnDebugMessage(false, re.ReadString());
                }
                break;

                case PacketType.SSH_MSG_IGNORE: {
                    SSH1DataReader re = new SSH1DataReader(p.Data);
                    _eventReceiver.OnIgnoreMessage(re.ReadString());
                }
                break;

                case PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: {
                    int local  = SSHUtil.ReadInt32(p.Data, 0);
                    int remote = SSHUtil.ReadInt32(p.Data, 4);
                    FindChannelEntry(local)._receiver.OnChannelReady();
                }
                break;

                case PacketType.SSH_SMSG_SUCCESS:
                    if (_executingShell)
                    {
                        ExecShell();
                        this.FindChannelEntry(_shellID)._receiver.OnChannelReady();
                        _executingShell = false;
                    }
                    break;

                default:
                    _eventReceiver.OnUnknownMessage((byte)p.Type, p.Data);
                    break;
                }
            }
            catch (Exception ex) {
                if (!_closed)
                {
                    _eventReceiver.OnError(ex, ex.Message);
                }
            }
        }
        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 SSH1Packet ReceivePacket()
        {
            while(true) {
                SSH1Packet p = null;
                SynchronizedSSH1PacketHandler handler = (SynchronizedSSH1PacketHandler)_packetBuilder.Handler;
                if(!handler.HasPacket) {
                    handler.Wait();
                    if(handler.State==ReceiverState.Error)
                        throw new SSHException(handler.ErrorMessage);
                    else if(handler.State==ReceiverState.Closed)
                        throw new SSHException("socket closed");
                }
                p = handler.PopPacket();

                SSH1DataReader r = new SSH1DataReader(p.Data);
                PacketType pt = p.Type;
                if(pt==PacketType.SSH_MSG_IGNORE) {
                    if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(r.ReadString());
                }
                else if(pt==PacketType.SSH_MSG_DEBUG) {
                    if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(false, r.ReadString());
                }
                else
                    return p;
            }
        }
 private bool ReceiveAuthenticationResult()
 {
     SSH1Packet SSH1Packet = ReceivePacket();
     PacketType type = SSH1Packet.Type;
     if(type==PacketType.SSH_MSG_DEBUG) {
         SSH1DataReader r = new SSH1DataReader(SSH1Packet.Data);
         //Debug.WriteLine("receivedd debug message:"+Encoding.ASCII.GetString(r.ReadString()));
         return ReceiveAuthenticationResult();
     }
     else if(type==PacketType.SSH_SMSG_SUCCESS)
         return true;
     else if(type==PacketType.SSH_SMSG_FAILURE)
         return false;
     else
         throw new SSHException("type: " + type, 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);
            }
        }
        //RSA authentication
        private void DoRSAChallengeResponse()
        {
            //read key
            SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password);
            SSH1DataWriter w = new SSH1DataWriter();
            w.Write(key.PublicModulus);
            SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA, w.ToByteArray());
            p.WriteTo(_stream, _tCipher);

            p = ReceivePacket();
            if(p.Type==PacketType.SSH_SMSG_FAILURE)
                throw new SSHException(Strings.GetString("ServerRefusedRSA"));
            else if(p.Type!=PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE)
                throw new SSHException(String.Format(Strings.GetString("UnexpectedResponse"), p.Type));

            //creating challenge
            SSH1DataReader r = new SSH1DataReader(p.Data);
            BigInteger challenge = key.decryptChallenge(r.ReadMPInt());
            byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).getBytes();

            //building response
            MemoryStream bos = new MemoryStream();
            bos.Write(rawchallenge, 0, rawchallenge.Length); //!!mindterm�ł͓����O���ǂ����ŕςȃn���h�����O��������
            bos.Write(_sessionID, 0, _sessionID.Length);
            byte[] response = new MD5CryptoServiceProvider().ComputeHash(bos.ToArray());

            w = new SSH1DataWriter();
            w.Write(response);
            p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, w.ToByteArray());
            p.WriteTo(_stream, _tCipher);
        }
 internal void AsyncReceivePacket(SSH1Packet p)
 {
     try {
         int len = 0, channel = 0;
         switch(p.Type) {
             case PacketType.SSH_SMSG_STDOUT_DATA:
                 len = SSHUtil.ReadInt32(p.Data, 0);
                 FindChannelEntry(_shellID)._receiver.OnData(p.Data, 4, len);
                 break;
             case PacketType.SSH_SMSG_STDERR_DATA: {
                 SSH1DataReader re = new SSH1DataReader(p.Data);
                 FindChannelEntry(_shellID)._receiver.OnExtendedData((int)PacketType.SSH_SMSG_STDERR_DATA, re.ReadString());
             }
                 break;
             case PacketType.SSH_MSG_CHANNEL_DATA:
                 channel = SSHUtil.ReadInt32(p.Data, 0);
                 len = SSHUtil.ReadInt32(p.Data, 4);
                 FindChannelEntry(channel)._receiver.OnData(p.Data, 8, len);
                 break;
             case PacketType.SSH_MSG_PORT_OPEN:
                 this.ProcessPortforwardingRequest(_eventReceiver, p);
                 break;
             case PacketType.SSH_MSG_CHANNEL_CLOSE: {
                 channel = SSHUtil.ReadInt32(p.Data, 0);
                 ISSHChannelEventReceiver r = FindChannelEntry(channel)._receiver;
                 UnregisterChannelEventReceiver(channel);
                 r.OnChannelClosed();
             }
                 break;
             case PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
                 channel = SSHUtil.ReadInt32(p.Data, 0);
                 break;
             case PacketType.SSH_MSG_DISCONNECT:
                 _eventReceiver.OnConnectionClosed();
                 break;
             case PacketType.SSH_SMSG_EXITSTATUS:
                 FindChannelEntry(_shellID)._receiver.OnChannelClosed();
                 break;
             case PacketType.SSH_MSG_DEBUG: {
                 SSH1DataReader re = new SSH1DataReader(p.Data);
                 _eventReceiver.OnDebugMessage(false, re.ReadString());
             }
                 break;
             case PacketType.SSH_MSG_IGNORE: {
                 SSH1DataReader re = new SSH1DataReader(p.Data);
                 _eventReceiver.OnIgnoreMessage(re.ReadString());
             }
                 break;
             case PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: {
                 int local = SSHUtil.ReadInt32(p.Data, 0);
                 int remote = SSHUtil.ReadInt32(p.Data, 4);
                 FindChannelEntry(local)._receiver.OnChannelReady();
             }
                 break;
             case PacketType.SSH_SMSG_SUCCESS:
                 if(_executingShell) {
                     ExecShell();
                     this.FindChannelEntry(_shellID)._receiver.OnChannelReady();
                     _executingShell = false;
                 }
                 break;
             default:
                 _eventReceiver.OnUnknownMessage((byte)p.Type, p.Data);
                 break;
         }
     }
     catch(Exception ex) {
         if(!_closed)
             _eventReceiver.OnError(ex, ex.Message);
     }
 }