//writer util private SSH2DataWriter OpenWriter(AgentForwadPacketType pt) { SSH2DataWriter wr = new SSH2DataWriter(); wr.WriteInt32(0); //length field wr.WriteByte((byte)pt); return wr; }
private byte[] DeriveKey(BigInteger key, byte[] hash, char ch, int length) { byte[] result = new byte[length]; SSH2DataWriter wr = new SSH2DataWriter(); wr.WriteBigInteger(key); wr.Write(hash); wr.WriteByte((byte)ch); wr.Write(_sessionID); byte[] h1 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray()); if (h1.Length >= length) { Array.Copy(h1, 0, result, 0, length); return result; } else { wr = new SSH2DataWriter(); wr.WriteBigInteger(key); wr.Write(_sessionID); wr.Write(h1); byte[] h2 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray()); if (h1.Length + h2.Length >= length) { Array.Copy(h1, 0, result, 0, h1.Length); Array.Copy(h2, 0, result, h1.Length, length - h1.Length); return result; } else throw new SSHException("necessary key length is too big"); //long key is not supported } }
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; } }