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.ReadInt(); buf.ReadByte(); buf.ReadByte(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); foo=buf.ReadString(start, length); if(channel==null) { break; } try { channel.write(foo, start[0], length[0]); } catch(Exception) { //System.Console.WriteLine(e); try{channel.disconnect();} catch(Exception){} break; } int len=length[0]; channel.setLocalWindowSize(channel.lwsize-len); if(channel.lwsize<channel.lwsize_max/2) { packet.reset(); buf.WriteByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.WriteInt(channel.getRecipient()); buf.WriteInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_EXTENDED_DATA: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); buf.ReadInt(); // data_type_code == 1 foo=buf.ReadString(start, length); //System.Console.WriteLine("stderr: "+Encoding.UTF8.GetString(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.WriteByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.WriteInt(channel.getRecipient()); buf.WriteInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_WINDOW_ADJUST: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.addRemoteWindowSize(buf.ReadInt()); break; case SSH_MSG_CHANNEL_EOF: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); 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.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); 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.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } channel.setRecipient(buf.ReadInt()); channel.setRemoteWindowSize(buf.ReadInt()); channel.setRemotePacketSize(buf.ReadInt()); break; case SSH_MSG_CHANNEL_OPEN_FAILURE: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } int reason_code=buf.ReadInt(); //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.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); foo=buf.ReadString(); bool reply=(buf.ReadByte()!=0); channel=Channel.getChannel(i, this); if(channel!=null) { byte reply_type=(byte)SSH_MSG_CHANNEL_FAILURE; if((Encoding.UTF8.GetString(foo)) == "exit-status") { i=buf.ReadInt(); // 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.WriteByte(reply_type); buf.WriteInt(channel.getRecipient()); write(packet); } } else { } break; case SSH_MSG_CHANNEL_OPEN: buf.ReadInt(); buf.ReadShort(); foo=buf.ReadString(); String ctyp=Encoding.UTF8.GetString(foo); //System.Console.WriteLine("type="+ctyp); if(!("forwarded-tcpip" == ctyp) && !("x11" == 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.WriteByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION); buf.WriteInt(channel.getRecipient()); buf.WriteInt(channel.id); buf.WriteInt(channel.lwsize); buf.WriteInt(channel.lmpsize); write(packet); System.Threading.Thread tmp = new System.Threading.Thread(channel.run); tmp.Name = "Channel "+ctyp+" "+host; tmp.Start(); break; } case SSH_MSG_CHANNEL_SUCCESS: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=1; break; case SSH_MSG_CHANNEL_FAILURE: buf.ReadInt(); buf.ReadShort(); i=buf.ReadInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=0; break; case SSH_MSG_GLOBAL_REQUEST: buf.ReadInt(); buf.ReadShort(); foo=buf.ReadString(); // request name reply=(buf.ReadByte()!=0); if(reply) { packet.reset(); buf.WriteByte((byte)SSH_MSG_REQUEST_FAILURE); write(packet); } break; case SSH_MSG_REQUEST_FAILURE: case SSH_MSG_REQUEST_SUCCESS: System.Threading.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) { //System.Console.WriteLine("# Session.run"); //e.printStackTrace(); } try { disconnect(); } catch(NullReferenceException) { //System.Console.WriteLine("@1"); //e.printStackTrace(); } catch(Exception) { //System.Console.WriteLine("@2"); //e.printStackTrace(); } _isConnected=false; }
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 (!result.SequenceEqual(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.ReadInt();buf.ReadShort(); int reason_code=buf.ReadInt(); byte[] description=buf.ReadString(); byte[] language_tag=buf.ReadString(); /* System.Console.Error.WriteLine("SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+Encoding.UTF8.GetString(description)+ " "+Encoding.UTF8.GetString(language_tag)); */ throw new JSchException( "SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+description+ " "+language_tag); //break; } else if(type==SSH_MSG_IGNORE) { } else if(type==SSH_MSG_DEBUG) { buf.Rewind(); buf.ReadInt();buf.ReadShort(); /* byte always_display=(byte)buf.getByte(); byte[] message=buf.getString(); byte[] language_tag=buf.getString(); System.Console.Error.WriteLine("SSH_MSG_DEBUG:"+ " "+Encoding.UTF8.GetString(message)+ " "+Encoding.UTF8.GetString(language_tag)); */ } else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST) { buf.Rewind(); buf.ReadInt();buf.ReadShort(); Channel c=Channel.getChannel(buf.ReadInt(), this); if(c==null) { } else { c.addRemoteWindowSize(buf.ReadInt()); } } else { break; } } buf.Rewind(); return buf; }