private void ServiceRequest(string servicename) {
            SSH2DataWriter wr = OpenTransmissionPacket();
            wr.WritePacketType(PacketType.SSH_MSG_SERVICE_REQUEST);
            wr.Write(servicename);
            TraceTransmissionEvent("SSH_MSG_SERVICE_REQUEST", servicename);
            TransmitPacket(wr);

            DataFragment response = ReceivePacket();
            SSH2DataReader re = new SSH2DataReader(response);
            PacketType t = re.ReadPacketType();
            if(t!=PacketType.SSH_MSG_SERVICE_ACCEPT) {
                TraceReceptionEvent(t.ToString(), "service request failed");
                throw new SSHException("service establishment failed "+t);
            }

            string s = Encoding.ASCII.GetString(re.ReadString());
            if(servicename!=s)
                throw new SSHException("protocol error");
        }
 private AuthenticationResult ProcessAuthenticationResponse() {
     do {
         SSH2DataReader response = new SSH2DataReader(ReceivePacket());
         PacketType h = response.ReadPacketType();
         if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) {
             string msg = Encoding.ASCII.GetString(response.ReadString());
             TraceReceptionEvent(h, "user authentication failed:" + msg);
             return AuthenticationResult.Failure;
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) {
             TraceReceptionEvent(h, "");
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) {
             TraceReceptionEvent(h, "user authentication succeeded");
             _packetBuilder.InnerHandler = new CallbackSSH2PacketHandler(this);
             return AuthenticationResult.Success; //successfully exit
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) {
             string name = Encoding.ASCII.GetString(response.ReadString());
             string inst = Encoding.ASCII.GetString(response.ReadString());
             string lang = Encoding.ASCII.GetString(response.ReadString());
             int num = response.ReadInt32();
             string[] prompts = new string[num];
             for(int i=0; i<num; i++) {
                 prompts[i] = Encoding.ASCII.GetString(response.ReadString());
                 bool echo = response.ReadBool();
             }
             _eventReceiver.OnAuthenticationPrompt(prompts);
             _requiredResponseCount = num;
             return AuthenticationResult.Prompt;
         }
         else
             throw new SSHException("protocol error: unexpected packet type "+h);
     } while(true);
 }
        //synchronous reception
        internal DataFragment ReceivePacket() {
            while(true) {
                DataFragment data = _packetReceiver.WaitResponse();

                PacketType pt = (PacketType)data.ByteAt(0); //sneak

                //filter unnecessary packet
                if(pt==PacketType.SSH_MSG_IGNORE) {
                    SSH2DataReader r = new SSH2DataReader(data);
                    r.ReadPacketType(); //skip
                    byte[] msg = r.ReadString();
                    if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(msg);
                    TraceReceptionEvent(pt, msg);
                }
                else if(pt==PacketType.SSH_MSG_DEBUG) {
                    SSH2DataReader r = new SSH2DataReader(data);
                    r.ReadPacketType(); //skip
                    bool f = r.ReadBool();
                    byte[] msg = r.ReadString();
                    if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(f, msg);
                    TraceReceptionEvent(pt, msg);
                }
                else {
                    return data;
                }
            }
        }
        private bool ProcessKEXDHREPLY(DataFragment packet) {
            //Round2 receives response
            SSH2DataReader re = null;
            PacketType h;
            do {
                re = new SSH2DataReader(packet);
                h = re.ReadPacketType();
                if(h==PacketType.SSH_MSG_KEXDH_REPLY)
                    break; //successfully exit
                else if(h==PacketType.SSH_MSG_IGNORE || h==PacketType.SSH_MSG_DEBUG) { //continue
                    packet = _connection.ReceivePacket();
                }
                else
                    throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h));
            } while(true);

            byte[] key_and_cert = re.ReadString();
            BigInteger f = re.ReadMPInt();
            byte[] signature = re.ReadString();
            Debug.Assert(re.Rest==0);

            //Round3 calc hash H
            SSH2DataWriter wr = new SSH2DataWriter();
            _k = f.modPow(_x, DH_PRIME);
            wr = new SSH2DataWriter();
            wr.Write(_cInfo._clientVersionString);
            wr.Write(_cInfo._serverVersionString);
            wr.WriteAsString(_clientKEXINITPayload);
            wr.WriteAsString(_serverKEXINITPayload);
            wr.WriteAsString(key_and_cert);
            wr.Write(_e);
            wr.Write(f);
            wr.Write(_k);
            _hash = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());

            _connection.TraceReceptionEvent(h, "verifying host key");
            if(!VerifyHostKey(key_and_cert, signature, _hash)) return false;

            //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash));
            if(_sessionID==null) _sessionID = _hash;
            return true;
        }