public Buffer read(Buffer buf) { int j=0; while(true) { buf.reset(); io.getByte(buf.buffer, buf.index, cipher_size); buf.index+=cipher_size; if(s2ccipher!=null) { s2ccipher.update(buf.buffer, 0, cipher_size, buf.buffer, 0); } // j=((buf.buffer[0]<<24)&0xff000000)| // ((buf.buffer[1]<<16)&0x00ff0000)| // ((buf.buffer[2]<< 8)&0x0000ff00)| // ((buf.buffer[3] )&0x000000ff); j=Util.ToInt32( buf.buffer, 0 ); j=j-4-cipher_size+8; if(j<0 || (buf.index+j)>buf.buffer.Length) { throw new IOException("invalid data"); } if(j>0) { io.getByte(buf.buffer, buf.index, j); buf.index+=(j); if(s2ccipher!=null) { s2ccipher.update(buf.buffer, cipher_size, j, buf.buffer, cipher_size); } } if(s2cmac!=null) { s2cmac.update(seqi); s2cmac.update(buf.buffer, 0, buf.index); byte[] result=s2cmac.doFinal(); io.getByte(mac_buf, 0, mac_buf.Length); if(!Arrays.equals(result, mac_buf)) { throw new IOException("MAC Error"); } } 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.buffer[5]&0xff; //System.Console.WriteLine("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(); /* System.Console.Error.WriteLine("SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+new String(description)+ " "+new String(language_tag)); */ throw new JSchException("SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+new String(description)+ " "+new String(language_tag)); //break; } else if(type==SSH_MSG_IGNORE) { } else if(type==SSH_MSG_DEBUG) { buf.rewind(); buf.getInt();buf.getShort(); /* byte always_display=(byte)buf.getByte(); byte[] message=buf.getString(); byte[] language_tag=buf.getString(); System.Console.Error.WriteLine("SSH_MSG_DEBUG:"+ " "+new String(message)+ " "+new String(language_tag)); */ } 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 { break; } } buf.rewind(); return buf; }
public void run() { thread=this; byte[] foo; Buffer buf=new Buffer(); Packet packet=new Packet(buf); int i=0; Channel channel; int[] start=new int[1]; int[] length=new int[1]; KeyExchange kex=null; try { while(_isConnected && thread!=null) { buf=read(buf); int msgType=buf.buffer[5]&0xff; // if(msgType!=94) //System.Console.WriteLine("read: 94 ? "+msgType); if(kex!=null && kex.getState()==msgType) { bool result=kex.next(buf); if(!result) { throw new JSchException("verify: "+result); } continue; } switch(msgType) { case SSH_MSG_KEXINIT: //System.Console.WriteLine("KEXINIT"); kex=receive_kexinit(buf); break; case SSH_MSG_NEWKEYS: //System.Console.WriteLine("NEWKEYS"); send_newkeys(); receive_newkeys(buf, kex); kex=null; break; case SSH_MSG_CHANNEL_DATA: buf.getInt(); buf.getByte(); buf.getByte(); i=buf.getInt(); channel=Channel.getChannel(i, this); foo=buf.getString(start, length); if(channel==null) { break; } try { channel.write(foo, start[0], length[0]); } catch(Exception e) { //System.Console.WriteLine(e); try{channel.disconnect();} catch(Exception ee){} break; } int len=length[0]; channel.setLocalWindowSize(channel.lwsize-len); if(channel.lwsize<channel.lwsize_max/2) { packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_EXTENDED_DATA: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); buf.getInt(); // data_type_code == 1 foo=buf.getString(start, length); //System.Console.WriteLine("stderr: "+new String(foo,start[0],length[0])); if(channel==null) { break; } //channel.write(foo, start[0], length[0]); channel.write_ext(foo, start[0], length[0]); len=length[0]; channel.setLocalWindowSize(channel.lwsize-len); if(channel.lwsize<channel.lwsize_max/2) { packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_WINDOW_ADJUST: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.addRemoteWindowSize(buf.getInt()); break; case SSH_MSG_CHANNEL_EOF: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel!=null) { //channel._eof_remote=true; //channel.eof(); channel.eof_remote(); } /* packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_EOF); buf.putInt(channel.getRecipient()); write(packet); */ break; case SSH_MSG_CHANNEL_CLOSE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel!=null) { // channel.close(); channel.disconnect(); } /* if(Channel.pool.size()==0){ thread=null; } */ break; case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } channel.setRecipient(buf.getInt()); channel.setRemoteWindowSize(buf.getInt()); channel.setRemotePacketSize(buf.getInt()); break; case SSH_MSG_CHANNEL_OPEN_FAILURE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } int reason_code=buf.getInt(); //foo=buf.getString(); // additional textual information //foo=buf.getString(); // language tag channel.exitstatus=reason_code; channel._close=true; channel._eof_remote=true; channel.setRecipient(0); break; case SSH_MSG_CHANNEL_REQUEST: buf.getInt(); buf.getShort(); i=buf.getInt(); foo=buf.getString(); bool reply=(buf.getByte()!=0); channel=Channel.getChannel(i, this); if(channel!=null) { byte reply_type=(byte)SSH_MSG_CHANNEL_FAILURE; if((new String(foo)).equals("exit-status")) { i=buf.getInt(); // exit-status channel.setExitStatus(i); // System.Console.WriteLine("exit-stauts: "+i); // channel.close(); reply_type=(byte)SSH_MSG_CHANNEL_SUCCESS; } if(reply) { packet.reset(); buf.putByte(reply_type); buf.putInt(channel.getRecipient()); write(packet); } } else { } break; case SSH_MSG_CHANNEL_OPEN: buf.getInt(); buf.getShort(); foo=buf.getString(); String ctyp=new String(foo); //System.Console.WriteLine("type="+ctyp); if(!new String("forwarded-tcpip").equals(ctyp) && !(new String("x11").equals(ctyp) && x11_forwarding)) { System.Console.WriteLine("Session.run: CHANNEL OPEN "+ctyp); throw new IOException("Session.run: CHANNEL OPEN "+ctyp); } else { channel=Channel.getChannel(ctyp); addChannel(channel); channel.getData(buf); channel.init(); packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION); buf.putInt(channel.getRecipient()); buf.putInt(channel.id); buf.putInt(channel.lwsize); buf.putInt(channel.lmpsize); write(packet); Thread tmp=new Thread(channel); tmp.setName("Channel "+ctyp+" "+host); tmp.start(); break; } case SSH_MSG_CHANNEL_SUCCESS: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=1; break; case SSH_MSG_CHANNEL_FAILURE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=0; break; case SSH_MSG_GLOBAL_REQUEST: buf.getInt(); buf.getShort(); foo=buf.getString(); // request name reply=(buf.getByte()!=0); if(reply) { packet.reset(); buf.putByte((byte)SSH_MSG_REQUEST_FAILURE); write(packet); } break; case SSH_MSG_REQUEST_FAILURE: case SSH_MSG_REQUEST_SUCCESS: Thread t=grr.getThread(); if(t!=null) { grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0); t.interrupt(); } break; default: System.Console.WriteLine("Session.run: unsupported type "+msgType); throw new IOException("Unknown SSH message type "+msgType); } } } catch(Exception e) { //System.Console.WriteLine("# Session.run"); //e.printStackTrace(); } try { disconnect(); } catch(NullReferenceException e) { //System.Console.WriteLine("@1"); //e.printStackTrace(); } catch(Exception e) { //System.Console.WriteLine("@2"); //e.printStackTrace(); } _isConnected=false; }