Пример #1
0
		/// <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;
		}
Пример #2
0
		public virtual 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;
			int stimeout = 0;
			try
			{
				while (isConnected && thread != null)
				{
					try
					{
						buf = Read(buf);
						stimeout = 0;
					}
					catch (ThreadInterruptedException ee)
					{
						if (!in_kex && stimeout < serverAliveCountMax)
						{
							SendKeepAliveMsg();
							stimeout++;
							continue;
						}
						throw;
					}
					int msgType = buf.GetCommand() & unchecked((int)(0xff));
					if (kex != null && kex.GetState() == msgType)
					{
						kex_start_time = Runtime.CurrentTimeMillis();
						bool result = kex.Next(buf);
						if (!result)
						{
							throw new JSchException("verify: " + result);
						}
						continue;
					}
					switch (msgType)
					{
						case SSH_MSG_KEXINIT:
						{
							//System.err.println("KEXINIT");
							kex = Receive_kexinit(buf);
							break;
						}

						case SSH_MSG_NEWKEYS:
						{
							//System.err.println("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;
							}
							if (length[0] == 0)
							{
								break;
							}
							try
							{
								channel.Write(foo, start[0], length[0]);
							}
							catch (Exception)
							{
								//System.err.println(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.PutByte(unchecked((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.err.println("stderr: "+new String(foo,start[0],length[0]));
							if (channel == null)
							{
								break;
							}
							if (length[0] == 0)
							{
								break;
							}
							channel.Write_ext(foo, start[0], length[0]);
							int len = length[0];
							channel.SetLocalWindowSize(channel.lwsize - len);
							if (channel.lwsize < channel.lwsize_max / 2)
							{
								packet.Reset();
								buf.PutByte(unchecked((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();
							}
							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();
							}
							break;
						}

						case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
						{
							buf.GetInt();
							buf.GetShort();
							i = buf.GetInt();
							channel = Channel.GetChannel(i, this);
							if (channel == null)
							{
							}
							//break;
							int r = buf.GetInt();
							long rws = buf.GetUInt();
							int rps = buf.GetInt();
							channel.SetRemoteWindowSize(rws);
							channel.SetRemotePacketSize(rps);
							channel.SetRecipient(r);
							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 = unchecked((byte)SSH_MSG_CHANNEL_FAILURE);
								if ((Util.Byte2str(foo)).Equals("exit-status"))
								{
									i = buf.GetInt();
									// exit-status
									channel.SetExitStatus(i);
									reply_type = unchecked((byte)SSH_MSG_CHANNEL_SUCCESS);
								}
								if (reply)
								{
									packet.Reset();
									buf.PutByte(reply_type);
									buf.PutInt(channel.GetRecipient());
									Write(packet);
								}
							}
							break;
						}

						case SSH_MSG_CHANNEL_OPEN:
						{
							buf.GetInt();
							buf.GetShort();
							foo = buf.GetString();
							string ctyp = Util.Byte2str(foo);
							if (!"forwarded-tcpip".Equals(ctyp) && !("x11".Equals(ctyp) && x11_forwarding) &&
								 !("*****@*****.**".Equals(ctyp) && agent_forwarding))
							{
								//System.err.println("Session.run: CHANNEL OPEN "+ctyp); 
								//throw new IOException("Session.run: CHANNEL OPEN "+ctyp);
								packet.Reset();
								buf.PutByte(unchecked((byte)SSH_MSG_CHANNEL_OPEN_FAILURE));
								buf.PutInt(buf.GetInt());
								buf.PutInt(Channel.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
								buf.PutString(Util.empty);
								buf.PutString(Util.empty);
								Write(packet);
							}
							else
							{
								channel = Channel.GetChannel(ctyp);
								AddChannel(channel);
								channel.GetData(buf);
								channel.Init();
								Sharpen.Thread tmp = new Sharpen.Thread(channel);
								tmp.SetName("Channel " + ctyp + " " + host);
								if (daemon_thread)
								{
									tmp.SetDaemon(daemon_thread);
								}
								tmp.Start();
								break;
							}
							goto case SSH_MSG_CHANNEL_SUCCESS;
						}

						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
							bool reply = (buf.GetByte() != 0);
							if (reply)
							{
								packet.Reset();
								buf.PutByte(unchecked((byte)SSH_MSG_REQUEST_FAILURE));
								Write(packet);
							}
							break;
						}

						case SSH_MSG_REQUEST_FAILURE:
						case SSH_MSG_REQUEST_SUCCESS:
						{
							Sharpen.Thread t = grr.GetThread();
							if (t != null)
							{
								grr.SetReply(msgType == SSH_MSG_REQUEST_SUCCESS ? 1 : 0);
								t.Interrupt();
							}
							break;
						}

						default:
						{
							//System.err.println("Session.run: unsupported type "+msgType); 
							throw new IOException("Unknown SSH message type " + msgType);
						}
					}
				}
			}
			catch (Exception e)
			{
				in_kex = false;
				if (JSch.GetLogger().IsEnabled(Logger.INFO))
				{
					JSch.GetLogger().Log(Logger.INFO, "Caught an exception, leaving main loop due to "
						 + e.Message);
				}
			}
			//System.err.println("# Session.run");
			//e.printStackTrace();
			try
			{
				Disconnect();
			}
			catch (ArgumentNullException)
			{
			}
			catch (Exception)
			{
			}
			//System.err.println("@1");
			//e.printStackTrace();
			//System.err.println("@2");
			//e.printStackTrace();
			isConnected = false;
		}