private bool ProcessPacket(DataFragment packet) { SSH2DataReader r = new SSH2DataReader(packet); SSH2PacketType pt = (SSH2PacketType) r.ReadByte(); if (pt == SSH2PacketType.SSH_MSG_DISCONNECT) { int errorcode = r.ReadInt32(); _eventReceiver.OnConnectionClosed(); return false; } else if (_waitingForPortForwardingResponse) { if (pt != SSH2PacketType.SSH_MSG_REQUEST_SUCCESS) _eventReceiver.OnUnknownMessage((byte)pt, packet.GetBytes()); _waitingForPortForwardingResponse = false; return true; } else if (pt == SSH2PacketType.SSH_MSG_CHANNEL_OPEN) { string method = r.ReadString(); if (method == "forwarded-tcpip") ProcessPortforwardingRequest(_eventReceiver, r); else if (method.StartsWith("auth-agent")) //in most cases, method is "*****@*****.**" ProcessAgentForwardRequest(_eventReceiver, r); else { SSH2DataWriter wr = new SSH2DataWriter(); wr.WriteByte((byte)SSH2PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE); wr.WriteInt32(r.ReadInt32()); wr.WriteInt32(0); wr.WriteString("unknown method"); wr.WriteString(""); //lang tag TraceReceptionEvent("SSH_MSG_CHANNEL_OPEN rejected", "method={0}", method); } return true; } else if (pt >= SSH2PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt <= SSH2PacketType.SSH_MSG_CHANNEL_FAILURE) { int local_channel = r.ReadInt32(); ChannelCollection.Entry e = this.ChannelCollection.FindChannelEntry(local_channel); if (e != null) ((SSH2Channel)e.Channel).ProcessPacket(e.Receiver, pt, r); else Debug.WriteLine("unexpected channel pt=" + pt + " local_channel=" + local_channel.ToString()); return true; } else if (pt == SSH2PacketType.SSH_MSG_IGNORE) { _eventReceiver.OnIgnoreMessage(r.ReadByteString()); return true; } else if (_asyncKeyExchanger != null) { _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else if (pt == SSH2PacketType.SSH_MSG_KEXINIT) { //Debug.WriteLine("Host sent KEXINIT"); _asyncKeyExchanger = new KeyExchanger(this, _sessionID); _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else { _eventReceiver.OnUnknownMessage((byte)pt, packet.GetBytes()); return false; } }
internal void AsyncReceivePacket(DataFragment data) { try { SSH1DataReader re = new SSH1DataReader(data); SSH1PacketType pt = (SSH1PacketType)re.ReadByte(); switch (pt) { case SSH1PacketType.SSH_SMSG_STDOUT_DATA: { int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(_shellID).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_SMSG_STDERR_DATA: { _channel_collection.FindChannelEntry(_shellID).Receiver.OnExtendedData((int)SSH1PacketType.SSH_SMSG_STDERR_DATA, re.ReadByteString()); } break; case SSH1PacketType.SSH_MSG_CHANNEL_DATA: { int channel = re.ReadInt32(); int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(channel).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_MSG_PORT_OPEN: ProcessPortforwardingRequest(_eventReceiver, re); break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE: { int channel = re.ReadInt32(); ISSHChannelEventReceiver r = _channel_collection.FindChannelEntry(channel).Receiver; _channel_collection.UnregisterChannelEventReceiver(channel); r.OnChannelClosed(); } break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: { int channel = re.ReadInt32(); } break; case SSH1PacketType.SSH_MSG_DISCONNECT: _eventReceiver.OnConnectionClosed(); break; case SSH1PacketType.SSH_SMSG_EXITSTATUS: _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelClosed(); break; case SSH1PacketType.SSH_MSG_DEBUG: _eventReceiver.OnDebugMessage(false, re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_IGNORE: _eventReceiver.OnIgnoreMessage(re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: { int local = re.ReadInt32(); int remote = re.ReadInt32(); _channel_collection.FindChannelEntry(local).Receiver.OnChannelReady(); } break; case SSH1PacketType.SSH_SMSG_SUCCESS: if (_executingShell) { ExecShell(); _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelReady(); _executingShell = false; } break; default: _eventReceiver.OnUnknownMessage((byte)pt, data.GetBytes()); break; } } catch (Exception ex) { _eventReceiver.OnError(ex); } }
private void ProcessKEXINIT(DataFragment packet) { SSH2DataReader re = null; do { _serverKEXINITPayload = packet.GetBytes(); re = new SSH2DataReader(_serverKEXINITPayload); byte[] head = re.Read(17); //Type and cookie SSH2PacketType pt = (SSH2PacketType)head[0]; if (pt == SSH2PacketType.SSH_MSG_KEXINIT) break; //successfully exit if (pt == SSH2PacketType.SSH_MSG_IGNORE || pt == SSH2PacketType.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); string kex = re.ReadString(); _cInfo.SupportedKEXAlgorithms = kex; _cInfo.KEXAlgorithm = DecideKexAlgorithm(kex); string host_key = re.ReadString(); _cInfo.SupportedHostKeyAlgorithms = host_key; _cInfo.HostKeyAlgorithm = DecideHostKeyAlgorithm(host_key); string enc_cs = re.ReadString(); _cInfo.SupportedEncryptionAlgorithmsClientToServer = enc_cs; _cInfo.OutgoingPacketCipher = DecideCipherAlgorithm(enc_cs); string enc_sc = re.ReadString(); _cInfo.SupportedEncryptionAlgorithmsServerToClient = enc_sc; _cInfo.IncomingPacketCipher = DecideCipherAlgorithm(enc_sc); string mac_cs = re.ReadString(); CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1"); string mac_sc = re.ReadString(); CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1"); string comp_cs = re.ReadString(); CheckAlgorithmSupport("compression", comp_cs, "none"); string comp_sc = re.ReadString(); CheckAlgorithmSupport("compression", comp_sc, "none"); string lang_cs = re.ReadString(); string lang_sc = re.ReadString(); bool flag = re.ReadBool(); int reserved = re.ReadInt32(); Debug.Assert(re.RemainingDataLength == 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(SSH2PacketType.SSH_MSG_KEXINIT, bld.ToString()); } if (flag) throw new SSHException("Algorithm negotiation failed"); }