private void ProcessChannelLocalData(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader re) { switch (pt) { case PacketType.SSH_MSG_CHANNEL_DATA: { int len = re.ReadInt32(); receiver.OnData(re.Image, re.Offset, len); } break; case PacketType.SSH_MSG_CHANNEL_EXTENDED_DATA: { int t = re.ReadInt32(); byte[] data = re.ReadString(); receiver.OnExtendedData(t, data); } break; case PacketType.SSH_MSG_CHANNEL_REQUEST: { string request = Encoding.ASCII.GetString(re.ReadString()); bool reply = re.ReadBool(); if (request == "exit-status") { int status = re.ReadInt32(); } else if (reply) { //we reject unknown requests including keep-alive check SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_FAILURE); wr.WriteInt32(_remoteID); TransmitPayload(wr.ToByteArray()); } } break; case PacketType.SSH_MSG_CHANNEL_EOF: receiver.OnChannelEOF(); break; case PacketType.SSH_MSG_CHANNEL_CLOSE: _connection.ChannelCollection.UnregisterChannelEventReceiver(_localID); receiver.OnChannelClosed(); break; case PacketType.SSH_MSG_CHANNEL_FAILURE: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); break; default: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); //Debug.WriteLine("Unknown Packet " + pt); break; } }
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 void ProcessKEXINIT(DataFragment packet) { SSH2DataReader re = null; do { _serverKEXINITPayload = packet.ToNewArray(); re = new SSH2DataReader(_serverKEXINITPayload); byte[] head = re.Read(17); //Type and cookie PacketType pt = (PacketType)head[0]; if (pt == PacketType.SSH_MSG_KEXINIT) break; //successfully exit else if (pt == PacketType.SSH_MSG_IGNORE || pt == PacketType.SSH_MSG_DEBUG) { //continue packet = _connection.ReceivePacket(); } else throw new SSHException(String.Format("Server response is not SSH_MSG_KEXINIT but {0}", head[0])); } while (true); Encoding enc = Encoding.ASCII; string kex = enc.GetString(re.ReadString()); _cInfo._supportedKEXAlgorithms = kex; _cInfo._kexAlgorithm = DecideKexAlgorithm(kex); string host_key = enc.GetString(re.ReadString()); _cInfo._supportedHostKeyAlgorithms = host_key; _cInfo._algorithmForHostKeyVerification = DecideHostKeyAlgorithm(host_key); string enc_cs = enc.GetString(re.ReadString()); _cInfo._supportedCipherAlgorithms = enc_cs; _cInfo._algorithmForTransmittion = DecideCipherAlgorithm(enc_cs); string enc_sc = enc.GetString(re.ReadString()); _cInfo._algorithmForReception = DecideCipherAlgorithm(enc_sc); string mac_cs = enc.GetString(re.ReadString()); CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1"); string mac_sc = enc.GetString(re.ReadString()); CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1"); string comp_cs = enc.GetString(re.ReadString()); CheckAlgorithmSupport("compression", comp_cs, "none"); string comp_sc = enc.GetString(re.ReadString()); CheckAlgorithmSupport("compression", comp_sc, "none"); string lang_cs = enc.GetString(re.ReadString()); string lang_sc = enc.GetString(re.ReadString()); bool flag = re.ReadBool(); int reserved = re.ReadInt32(); Debug.Assert(re.Rest == 0); if (_connection.IsEventTracerAvailable) { StringBuilder bld = new StringBuilder(); bld.Append("kex_algorithm="); bld.Append(kex); bld.Append("; server_host_key_algorithms="); bld.Append(host_key); bld.Append("; encryption_algorithms_client_to_server="); bld.Append(enc_cs); bld.Append("; encryption_algorithms_server_to_client="); bld.Append(enc_sc); bld.Append("; mac_algorithms_client_to_server="); bld.Append(mac_cs); bld.Append("; mac_algorithms_server_to_client="); bld.Append(mac_sc); bld.Append("; comression_algorithms_client_to_server="); bld.Append(comp_cs); bld.Append("; comression_algorithms_server_to_client="); bld.Append(comp_sc); TraceReceptionNegotiation(PacketType.SSH_MSG_KEXINIT, bld.ToString()); } if (flag) throw new SSHException("Algorithm negotiation failed"); }