/// <exception cref="System.Exception"></exception> public virtual Buffer Read(Buffer buf) { int j = 0; while (true) { buf.Reset(); io.GetByte(buf.buffer, buf.index, s2ccipher_size); buf.index += s2ccipher_size; if (s2ccipher != null) { s2ccipher.Update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0); } j = ((buf.buffer[0] << 24) & unchecked((int)(0xff000000))) | ((buf.buffer[1] << 16 ) & unchecked((int)(0x00ff0000))) | ((buf.buffer[2] << 8) & unchecked((int)(0x0000ff00 ))) | ((buf.buffer[3]) & unchecked((int)(0x000000ff))); // RFC 4253 6.1. Maximum Packet Length if (j < 5 || j > PACKET_MAX_SIZE) { Start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE); } int need = j + 4 - s2ccipher_size; //if(need<0){ // throw new IOException("invalid data"); //} if ((buf.index + need) > buf.buffer.Length) { byte[] foo = new byte[buf.index + need]; System.Array.Copy(buf.buffer, 0, foo, 0, buf.index); buf.buffer = foo; } if ((need % s2ccipher_size) != 0) { string message = "Bad packet length " + need; if (JSch.GetLogger().IsEnabled(Logger.FATAL)) { JSch.GetLogger().Log(Logger.FATAL, message); } Start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE - s2ccipher_size); } if (need > 0) { io.GetByte(buf.buffer, buf.index, need); buf.index += (need); if (s2ccipher != null) { s2ccipher.Update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size); } } if (s2cmac != null) { s2cmac.Update(seqi); s2cmac.Update(buf.buffer, 0, buf.index); s2cmac.DoFinal(s2cmac_result1, 0); io.GetByte(s2cmac_result2, 0, s2cmac_result2.Length); if (!Arrays.Equals(s2cmac_result1, s2cmac_result2)) { if (need > PACKET_MAX_SIZE) { throw new IOException("MAC Error"); } Start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE - need); continue; } } seqi++; if (inflater != null) { //inflater.uncompress(buf); int pad = buf.buffer[4]; uncompress_len[0] = buf.index - 5 - pad; byte[] foo = inflater.Uncompress(buf.buffer, 5, uncompress_len); if (foo != null) { buf.buffer = foo; buf.index = 5 + uncompress_len[0]; } else { System.Console.Error.WriteLine("fail in inflater"); break; } } int type = buf.GetCommand() & unchecked((int)(0xff)); //System.err.println("read: "+type); if (type == SSH_MSG_DISCONNECT) { buf.Rewind(); buf.GetInt(); buf.GetShort(); int reason_code = buf.GetInt(); byte[] description = buf.GetString(); byte[] language_tag = buf.GetString(); throw new JSchException("SSH_MSG_DISCONNECT: " + reason_code + " " + Util.Byte2str (description) + " " + Util.Byte2str(language_tag)); } else { //break; if (type == SSH_MSG_IGNORE) { } else { if (type == SSH_MSG_UNIMPLEMENTED) { buf.Rewind(); buf.GetInt(); buf.GetShort(); int reason_id = buf.GetInt(); if (JSch.GetLogger().IsEnabled(Logger.INFO)) { JSch.GetLogger().Log(Logger.INFO, "Received SSH_MSG_UNIMPLEMENTED for " + reason_id ); } } else { if (type == SSH_MSG_DEBUG) { buf.Rewind(); buf.GetInt(); buf.GetShort(); } else { if (type == SSH_MSG_CHANNEL_WINDOW_ADJUST) { buf.Rewind(); buf.GetInt(); buf.GetShort(); Channel c = Channel.GetChannel(buf.GetInt(), this); if (c == null) { } else { c.AddRemoteWindowSize(buf.GetInt()); } } else { if (type == UserAuth.SSH_MSG_USERAUTH_SUCCESS) { isAuthed = true; if (inflater == null && deflater == null) { string method; method = guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; InitDeflater(method); method = guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; InitInflater(method); } break; } else { break; } } } } } } } buf.Rewind(); return buf; }
/// <exception cref="System.IO.IOException"></exception> private ChannelHeader Header(Buffer buf, ChannelHeader header) { buf.Rewind(); int i = Fill(buf.buffer, 0, 9); header.length = buf.GetInt() - 5; header.type = buf.GetByte() & unchecked((int)(0xff)); header.rid = buf.GetInt(); return header; }