private void ServiceRequest(string servicename) { SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_SERVICE_REQUEST); wr.Write(servicename); TransmitPacket(wr.ToByteArray()); byte[] response = ReceivePacket().Data; SSH2DataReader re = new SSH2DataReader(response); PacketType t = re.ReadPacketType(); if(t!=PacketType.SSH_MSG_SERVICE_ACCEPT) { throw new SSHException("service establishment failed "+t); } string s = Encoding.ASCII.GetString(re.ReadString()); if(servicename!=s) throw new SSHException("protocol error"); }
private bool ProcessPacket(SSH2Packet packet) { SSH2DataReader r = new SSH2DataReader(packet.Data); PacketType pt = r.ReadPacketType(); //Debug.WriteLine("ProcessPacket pt="+pt); if(pt==PacketType.SSH_MSG_DISCONNECT) { int errorcode = r.ReadInt32(); //string description = Encoding.ASCII.GetString(r.ReadString()); _eventReceiver.OnConnectionClosed(); return false; } else if(_waitingForPortForwardingResponse) { if(pt!=PacketType.SSH_MSG_REQUEST_SUCCESS) _eventReceiver.OnUnknownMessage((byte)pt, r.Image); _waitingForPortForwardingResponse = false; return true; } else if(pt==PacketType.SSH_MSG_CHANNEL_OPEN) { ProcessPortforwardingRequest(_eventReceiver, r); return true; } else if(pt>=PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt<=PacketType.SSH_MSG_CHANNEL_FAILURE) { int local_channel = r.ReadInt32(); ChannelEntry e = FindChannelEntry(local_channel); if(e!=null) //throw new SSHException("Unknown channel "+local_channel); ((SSH2Channel)e._channel).ProcessPacket(e._receiver, pt, 5+r.Rest, r); else Debug.WriteLine("unexpected channel pt="+pt+" local_channel="+local_channel.ToString()); return true; } else if(pt==PacketType.SSH_MSG_IGNORE) { _eventReceiver.OnIgnoreMessage(r.ReadString()); return true; } else if(_asyncKeyExchanger!=null) { _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else if(pt==PacketType.SSH_MSG_KEXINIT) { Debug.WriteLine("Host sent KEXINIT"); _asyncKeyExchanger = new KeyExchanger(this, _sessionID); _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else { _eventReceiver.OnUnknownMessage((byte)pt, r.Image); return false; } }
//synchronous reception internal SSH2Packet ReceivePacket() { while(true) { SSH2Packet p = null; SynchronizedSSH2PacketHandler handler = (SynchronizedSSH2PacketHandler)_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(); SSH2DataReader r = new SSH2DataReader(p.Data); PacketType pt = r.ReadPacketType(); if(pt==PacketType.SSH_MSG_IGNORE) { if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(r.ReadString()); } else if(pt==PacketType.SSH_MSG_DEBUG) { bool f = r.ReadBool(); if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(f, r.ReadString()); } else return p; } }
private AuthenticationResult ProcessAuthenticationResponse() { do { SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data); PacketType h = response.ReadPacketType(); if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) { string msg = Encoding.ASCII.GetString(response.ReadString()); return AuthenticationResult.Failure; } else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) { Debug.WriteLine("USERAUTH_BANNER"); } else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) { _packetBuilder.Handler = 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); return AuthenticationResult.Prompt; } else throw new SSHException("protocol error: unexpected packet type "+h); } while(true); }
private bool ProcessKEXDHREPLY(SSH2Packet packet) { //Round2 receives response SSH2DataReader re = new SSH2DataReader(packet.Data); PacketType h = re.ReadPacketType(); if(h!=PacketType.SSH_MSG_KEXDH_REPLY) throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h)); 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()); if(!VerifyHostKey(key_and_cert, signature, _hash)) return false; //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash)); if(_sessionID==null) _sessionID = _hash; return true; }