public void OnPacket(SSH2Packet packet) { lock (this) { _packets.Add(packet); if (_packets.Count > 0) { SetReady(); } } }
//returns true if a new packet could be obtained private SSH2Packet ConstructPacket() { SSH2Packet packet = null; if (_event != null && !_event.WaitOne(3000, false)) { throw new Exception("waithandle timed out"); } if (_cipher == null) { if (_writeOffset - _readOffset < 4) { return(null); } int len = SSHUtil.ReadInt32(_buffer, _readOffset); if (_writeOffset - _readOffset < 4 + len) { return(null); } packet = SSH2Packet.FromPlainStream(_buffer, _readOffset); _readOffset += 4 + len; _sequence++; } else { if (_head == null) { if (_writeOffset - _readOffset < _cipher.BlockSize) { return(null); } _head = new byte[_cipher.BlockSize]; byte[] eh = new byte[_cipher.BlockSize]; Array.Copy(_buffer, _readOffset, eh, 0, eh.Length); _readOffset += eh.Length; _cipher.Decrypt(eh, 0, eh.Length, _head, 0); } int len = SSHUtil.ReadInt32(_head, 0); if (_writeOffset - _readOffset < len + 4 - _head.Length + _mac.Size) { return(null); } packet = SSH2Packet.FromDecryptedHead(_head, _buffer, _readOffset, _cipher, _sequence++, _mac); _readOffset += 4 + len - _head.Length + _mac.Size; _head = null; } return(packet); }
public static SSH2Packet FromPlainPayload(byte[] payload, int blocksize, Random rnd) { SSH2Packet p = new SSH2Packet(); int r = 11 - payload.Length % blocksize; while (r < 4) { r += blocksize; } p._padding = new byte[r]; //block size is 8, and padding length is at least 4 bytes rnd.NextBytes(p._padding); p._payload = payload; p._packetLength = 1 + payload.Length + p._padding.Length; return(p); }
public static SSH2Packet FromDecryptedHead(byte[] head, byte[] buffer, int offset, Cipher cipher, int sequence, MAC mac) { SSH2Packet p = new SSH2Packet(); p._packetLength = SSHUtil.ReadInt32(head, 0); if (p._packetLength <= 0 || p._packetLength >= MAX_PACKET_LENGTH) { throw new SSHException(String.Format("packet size {0} is invalid", p._packetLength)); } SSH2DataWriter buf = new SSH2DataWriter(); buf.Write(sequence); buf.Write(head); if (p._packetLength > (cipher.BlockSize - 4)) { byte[] tmp = new byte[p._packetLength - (cipher.BlockSize - 4)]; cipher.Decrypt(buffer, offset, tmp.Length, tmp, 0); offset += tmp.Length; buf.Write(tmp); } byte[] result = buf.ToByteArray(); int padding_len = (int)result[8]; if (padding_len < 4) { throw new SSHException("padding length is invalid"); } byte[] payload = new byte[result.Length - 9 - padding_len]; Array.Copy(result, 9, payload, 0, payload.Length); p._payload = payload; if (mac != null) { p._mac = mac.Calc(result); if (SSHUtil.memcmp(p._mac, 0, buffer, offset, mac.Size) != 0) { throw new SSHException("MAC Error"); } } return(p); }
public SSH2Packet PopPacket() { lock (this) { if (_packets.Count == 0) { return(null); } else { SSH2Packet p = null; p = (SSH2Packet)_packets[0]; _packets.RemoveAt(0); if (_packets.Count == 0) { _event.Reset(); } return(p); } } }
//no decryption, no mac public static SSH2Packet FromPlainStream(byte[] buffer, int offset) { SSH2Packet p = new SSH2Packet(); p._packetLength = SSHUtil.ReadInt32(buffer, offset); if (p._packetLength <= 0 || p._packetLength >= MAX_PACKET_LENGTH) { throw new SSHException(String.Format("packet size {0} is invalid", p._packetLength)); } offset += 4; byte pl = buffer[offset++]; if (pl < 4) { throw new SSHException(String.Format("padding length {0} is invalid", pl)); } p._payload = new byte[p._packetLength - 1 - pl]; Array.Copy(buffer, offset, p._payload, 0, p._payload.Length); return(p); }
public void OnData(byte[] data, int offset, int length) { try { while (_buffer.Length - _writeOffset < length) { ExpandBuffer(); } Array.Copy(data, offset, _buffer, _writeOffset, length); _writeOffset += length; SSH2Packet p = ConstructPacket(); while (p != null) { _handler.OnPacket(p); p = ConstructPacket(); } ReduceBuffer(); } catch (Exception ex) { OnError(ex, ex.Message); } }
public void OnPacket(SSH2Packet packet) { _connection.AsyncReceivePacket(packet); }