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;
}