temp.
							parent
							
								
									3dd61ebfae
								
							
						
					
					
						commit
						1aa89aea9a
					
				| 
						 | 
				
			
			@ -14,9 +14,10 @@ TP_SSH_CHANNEL_PAIR::TP_SSH_CHANNEL_PAIR() {
 | 
			
		|||
	retcode = TP_SESS_STAT_RUNNING;
 | 
			
		||||
	db_id = 0;
 | 
			
		||||
	channel_id = 0;
 | 
			
		||||
 | 
			
		||||
	is_first_server_data = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
 | 
			
		||||
	ExThreadBase("ssh-session-thread"),
 | 
			
		||||
	m_proxy(proxy),
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +27,7 @@ SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
 | 
			
		|||
{
 | 
			
		||||
	m_auth_type = TP_AUTH_TYPE_PASSWORD;
 | 
			
		||||
 | 
			
		||||
	m_is_first_server_data = true;
 | 
			
		||||
// 	m_is_first_server_data = true;
 | 
			
		||||
 | 
			
		||||
	m_is_logon = false;
 | 
			
		||||
	m_have_error = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -45,8 +46,8 @@ SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
 | 
			
		|||
	ssh_callbacks_init(&m_srv_channel_cb);
 | 
			
		||||
	m_srv_channel_cb.userdata = this;
 | 
			
		||||
 | 
			
		||||
	m_command_flag = 0;
 | 
			
		||||
	m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
// 	m_command_flag = 0;
 | 
			
		||||
// 	m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SshSession::~SshSession() {
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +92,6 @@ void SshSession::_session_error(int err_code) {
 | 
			
		|||
	g_ssh_env.session_end(m_sid.c_str(), db_id, err_code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool SshSession::_record_begin(TP_SSH_CHANNEL_PAIR* cp)
 | 
			
		||||
{
 | 
			
		||||
	if (!g_ssh_env.session_begin(m_conn_info, &(cp->db_id))) {
 | 
			
		||||
| 
						 | 
				
			
			@ -555,389 +555,6 @@ TP_SSH_CHANNEL_PAIR* SshSession::_get_channel_pair(int channel_side, ssh_channel
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SshSession::_process_ssh_command(TppSshRec* rec, int from, const ex_u8* data, int len)
 | 
			
		||||
{
 | 
			
		||||
	if (TP_SSH_CLIENT_SIDE == from)
 | 
			
		||||
	{
 | 
			
		||||
		m_command_flag = 0;
 | 
			
		||||
 | 
			
		||||
		if (len == 3)
 | 
			
		||||
		{
 | 
			
		||||
			if ((data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x41)			// key-up
 | 
			
		||||
				|| (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x42)		// key-down
 | 
			
		||||
				)
 | 
			
		||||
			{
 | 
			
		||||
				m_command_flag = 1;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x43)		// key-right
 | 
			
		||||
			{
 | 
			
		||||
				if (m_cmd_char_pos != m_cmd_char_list.end())
 | 
			
		||||
					m_cmd_char_pos++;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x44)		// key-left
 | 
			
		||||
			{
 | 
			
		||||
				if (m_cmd_char_pos != m_cmd_char_list.begin())
 | 
			
		||||
					m_cmd_char_pos--;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (
 | 
			
		||||
				(data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x41)
 | 
			
		||||
				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x42)
 | 
			
		||||
				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x43)
 | 
			
		||||
				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x44)
 | 
			
		||||
				)
 | 
			
		||||
			{
 | 
			
		||||
				// 编辑模式下的上下左右键
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (len == 1)
 | 
			
		||||
		{
 | 
			
		||||
			if (data[0] == 0x08 || data[0] == 0x09)  // 08=光标左移
 | 
			
		||||
			{
 | 
			
		||||
				m_command_flag = 1;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (data[0] == 0x7f)	// Backspace (回删一个字符)
 | 
			
		||||
			{
 | 
			
		||||
				if (m_cmd_char_pos != m_cmd_char_list.begin())
 | 
			
		||||
				{
 | 
			
		||||
					m_cmd_char_pos--;
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.erase(m_cmd_char_pos);
 | 
			
		||||
				}
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (data[0] == 0x1b)
 | 
			
		||||
			{
 | 
			
		||||
				// 按下 Esc 键
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (data[0] != 0x0d && !isprint(data[0]))
 | 
			
		||||
				return;
 | 
			
		||||
		}
 | 
			
		||||
		else if (len > 3)
 | 
			
		||||
		{
 | 
			
		||||
			if (data[0] == 0x1b && data[1] == 0x5b)
 | 
			
		||||
			{
 | 
			
		||||
				m_command_flag = 1;
 | 
			
		||||
// 
 | 
			
		||||
// 				// 不是命令行上的上下左右,也不是编辑模式下的上下左右,那么就忽略(应该是编辑模式下的其他输入)
 | 
			
		||||
// 				m_cmd_char_list.clear();
 | 
			
		||||
// 				m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int processed = 0;
 | 
			
		||||
		for (int i = 0; i < len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (data[i] == 0x0d)
 | 
			
		||||
			{
 | 
			
		||||
				m_command_flag = 0;
 | 
			
		||||
 | 
			
		||||
				for (int j = processed; j < i; ++j)
 | 
			
		||||
				{
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.insert(m_cmd_char_pos, data[j]);
 | 
			
		||||
					m_cmd_char_pos++;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (m_cmd_char_list.size() > 0)
 | 
			
		||||
				{
 | 
			
		||||
					ex_astr str(m_cmd_char_list.begin(), m_cmd_char_list.end());
 | 
			
		||||
					ex_replace_all(str, "\r", "");
 | 
			
		||||
					ex_replace_all(str, "\n", "");
 | 
			
		||||
					EXLOGD("[ssh] save cmd: [%s]\n", str.c_str());
 | 
			
		||||
					str += "\r\n";
 | 
			
		||||
					rec->record_command(str);
 | 
			
		||||
				}
 | 
			
		||||
				m_cmd_char_list.clear();
 | 
			
		||||
				m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
 | 
			
		||||
				processed = i + 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (processed < len)
 | 
			
		||||
		{
 | 
			
		||||
			for (int j = processed; j < len; ++j)
 | 
			
		||||
			{
 | 
			
		||||
				m_cmd_char_pos = m_cmd_char_list.insert(m_cmd_char_pos, data[j]);
 | 
			
		||||
				m_cmd_char_pos++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (TP_SSH_SERVER_SIDE == from)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_command_flag == 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		bool esc_mode = false;
 | 
			
		||||
		int esc_arg = 0;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (esc_mode)
 | 
			
		||||
			{
 | 
			
		||||
				switch (data[i])
 | 
			
		||||
				{
 | 
			
		||||
				case '0':
 | 
			
		||||
				case '1':
 | 
			
		||||
				case '2':
 | 
			
		||||
				case '3':
 | 
			
		||||
				case '4':
 | 
			
		||||
				case '5':
 | 
			
		||||
				case '6':
 | 
			
		||||
				case '7':
 | 
			
		||||
				case '8':
 | 
			
		||||
				case '9':
 | 
			
		||||
					esc_arg = esc_arg * 10 + (data[i] - '0');
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 0x3f:
 | 
			
		||||
				case ';':
 | 
			
		||||
				case '>':
 | 
			
		||||
					m_cmd_char_list.clear();
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
					return;
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 0x4b:	// 'K'
 | 
			
		||||
				{
 | 
			
		||||
					if (0 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除光标到行尾的字符串
 | 
			
		||||
						m_cmd_char_list.erase(m_cmd_char_pos, m_cmd_char_list.end());
 | 
			
		||||
						m_cmd_char_pos = m_cmd_char_list.end();
 | 
			
		||||
					}
 | 
			
		||||
					else if (1 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除从开始到光标处的字符串
 | 
			
		||||
						m_cmd_char_list.erase(m_cmd_char_list.begin(), m_cmd_char_pos);
 | 
			
		||||
						m_cmd_char_pos = m_cmd_char_list.end();
 | 
			
		||||
					}
 | 
			
		||||
					else if (2 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除整行
 | 
			
		||||
						m_cmd_char_list.clear();
 | 
			
		||||
						m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 0x43:	// ^[C
 | 
			
		||||
				{
 | 
			
		||||
					// 光标右移
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (m_cmd_char_pos != m_cmd_char_list.end())
 | 
			
		||||
							m_cmd_char_pos++;
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 0x44:  // ^[D
 | 
			
		||||
				{
 | 
			
		||||
					// 光标左移
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (m_cmd_char_pos != m_cmd_char_list.begin())
 | 
			
		||||
							m_cmd_char_pos--;
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 0x50:	// 'P' 删除指定数量的字符
 | 
			
		||||
				{
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (m_cmd_char_pos != m_cmd_char_list.end())
 | 
			
		||||
							m_cmd_char_pos = m_cmd_char_list.erase(m_cmd_char_pos);
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 0x40:	// '@' 插入指定数量的空白字符
 | 
			
		||||
				{
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						m_cmd_char_pos = m_cmd_char_list.insert(m_cmd_char_pos, ' ');
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch (data[i])
 | 
			
		||||
			{
 | 
			
		||||
			case 0x07:
 | 
			
		||||
			{
 | 
			
		||||
				// 响铃
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x08:
 | 
			
		||||
			{
 | 
			
		||||
				// 光标左移
 | 
			
		||||
				if (m_cmd_char_pos != m_cmd_char_list.begin())
 | 
			
		||||
					m_cmd_char_pos--;
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x1b:
 | 
			
		||||
			{
 | 
			
		||||
				if (i + 1 < len)
 | 
			
		||||
				{
 | 
			
		||||
					if (data[i + 1] == 0x5b)
 | 
			
		||||
					{
 | 
			
		||||
						esc_mode = true;
 | 
			
		||||
						esc_arg = 0;
 | 
			
		||||
 | 
			
		||||
						i += 1;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x0d:
 | 
			
		||||
			{
 | 
			
		||||
				m_cmd_char_list.clear();
 | 
			
		||||
				m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			default:
 | 
			
		||||
				if (m_cmd_char_pos != m_cmd_char_list.end())
 | 
			
		||||
				{
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.erase(m_cmd_char_pos);
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.insert(m_cmd_char_pos, data[i]);
 | 
			
		||||
					m_cmd_char_pos++;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					m_cmd_char_list.push_back(data[i]);
 | 
			
		||||
					m_cmd_char_pos = m_cmd_char_list.end();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SshSession::_process_sftp_command(TppSshRec* rec, const ex_u8* data, int len) {
 | 
			
		||||
	// SFTP protocol: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
 | 
			
		||||
	//EXLOG_BIN(data, len, "[sftp] client channel data");
 | 
			
		||||
 | 
			
		||||
	if (len < 9)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	int pkg_len = (int)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
 | 
			
		||||
	if (pkg_len + 4 != len)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ex_u8 sftp_cmd = data[4];
 | 
			
		||||
 | 
			
		||||
	if (sftp_cmd == 0x01) {
 | 
			
		||||
		// 0x01 = 1 = SSH_FXP_INIT
 | 
			
		||||
		rec->record_command("SFTP INITIALIZE\r\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 需要的数据至少14字节
 | 
			
		||||
	// uint32 + byte + uint32 + (uint32 + char + ...)
 | 
			
		||||
	// pkg_len + cmd + req_id + string( length + content...)
 | 
			
		||||
	if (len < 14)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ex_u8* str1_ptr = (ex_u8*)data + 9;
 | 
			
		||||
	int str1_len = (int)((str1_ptr[0] << 24) | (str1_ptr[1] << 16) | (str1_ptr[2] << 8) | str1_ptr[3]);
 | 
			
		||||
	// 	if (str1_len + 9 != pkg_len)
 | 
			
		||||
	// 		return;
 | 
			
		||||
	ex_u8* str2_ptr = NULL;// (ex_u8*)data + 13;
 | 
			
		||||
	int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	const char* act = NULL;
 | 
			
		||||
	switch (sftp_cmd) {
 | 
			
		||||
	case 0x03:
 | 
			
		||||
		// 0x03 = 3 = SSH_FXP_OPEN
 | 
			
		||||
		act = "open file";
 | 
			
		||||
		break;
 | 
			
		||||
		// 	case 0x0b:
 | 
			
		||||
		// 		// 0x0b = 11 = SSH_FXP_OPENDIR
 | 
			
		||||
		// 		act = "open dir";
 | 
			
		||||
		// 		break;
 | 
			
		||||
	case 0x0d:
 | 
			
		||||
		// 0x0d = 13 = SSH_FXP_REMOVE
 | 
			
		||||
		act = "remove file";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x0e:
 | 
			
		||||
		// 0x0e = 14 = SSH_FXP_MKDIR
 | 
			
		||||
		act = "create dir";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x0f:
 | 
			
		||||
		// 0x0f = 15 = SSH_FXP_RMDIR
 | 
			
		||||
		act = "remove dir";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x12:
 | 
			
		||||
		// 0x12 = 18 = SSH_FXP_RENAME
 | 
			
		||||
		// rename操作数据中包含两个字符串
 | 
			
		||||
		act = "rename";
 | 
			
		||||
		str2_ptr = str1_ptr + str1_len + 4;
 | 
			
		||||
		str2_len = (int)((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x15:
 | 
			
		||||
		// 0x15 = 21 = SSH_FXP_LINK
 | 
			
		||||
		// link操作数据中包含两个字符串,前者是新的链接文件名,后者是现有被链接的文件名
 | 
			
		||||
		act = "create link";
 | 
			
		||||
		str2_ptr = str1_ptr + str1_len + 4;
 | 
			
		||||
		str2_len = (int)((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int total_len = 5 + str1_len + 4;
 | 
			
		||||
	if (str2_len > 0)
 | 
			
		||||
		total_len += str2_len + 4;
 | 
			
		||||
	if (total_len > pkg_len)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	char msg[2048] = { 0 };
 | 
			
		||||
	if (str2_len == 0) {
 | 
			
		||||
		ex_astr str1((char*)((ex_u8*)data + 13), str1_len);
 | 
			
		||||
		ex_strformat(msg, 2048, "%d:%s:%s:\r\n", sftp_cmd, act, str1.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ex_astr str1((char*)(str1_ptr + 4), str1_len);
 | 
			
		||||
		ex_astr str2((char*)(str2_ptr + 4), str2_len);
 | 
			
		||||
		ex_strformat(msg, 2048, "%d:%s:%s:%s\r\n", sftp_cmd, act, str1.c_str(), str2.c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rec->record_command(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SshSession::_on_client_pty_request(ssh_session session, ssh_channel channel, const char *term, int x, int y, int px, int py, void *userdata) {
 | 
			
		||||
	SshSession *_this = (SshSession *)userdata;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1027,9 +644,9 @@ int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel
 | 
			
		|||
	{
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			_this->_process_ssh_command(&cp->rec, TP_SSH_CLIENT_SIDE, (ex_u8*)data, len);
 | 
			
		||||
			_this->_process_ssh_command(cp, TP_SSH_CLIENT_SIDE, (ex_u8*)data, len);
 | 
			
		||||
 | 
			
		||||
			ex_astr str(_this->m_cmd_char_list.begin(), _this->m_cmd_char_list.end());
 | 
			
		||||
			ex_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end());
 | 
			
		||||
			ex_replace_all(str, "\r", "");
 | 
			
		||||
			ex_replace_all(str, "\n", "");
 | 
			
		||||
			EXLOGD("[ssh]   -- [%s]\n", str.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -1040,7 +657,7 @@ int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		_this->_process_sftp_command(&cp->rec, (ex_u8*)data, len);
 | 
			
		||||
		_this->_process_sftp_command(cp, (ex_u8*)data, len);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1149,8 +766,8 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
 | 
			
		|||
	{
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			_this->_process_ssh_command(&cp->rec, TP_SSH_SERVER_SIDE, (ex_u8*)data, len);
 | 
			
		||||
			ex_astr str(_this->m_cmd_char_list.begin(), _this->m_cmd_char_list.end());
 | 
			
		||||
			_this->_process_ssh_command(cp, TP_SSH_SERVER_SIDE, (ex_u8*)data, len);
 | 
			
		||||
			ex_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end());
 | 
			
		||||
			ex_replace_all(str, "\r", "");
 | 
			
		||||
			ex_replace_all(str, "\n", "");
 | 
			
		||||
			EXLOGD("[ssh]   -- [%s]\n", str.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -1167,9 +784,9 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
 | 
			
		|||
 | 
			
		||||
	// 收到第一包服务端返回的数据时,在输出数据之前显示一些自定义的信息
 | 
			
		||||
#if 1
 | 
			
		||||
	if (!is_stderr && _this->m_is_first_server_data)
 | 
			
		||||
	if (!is_stderr && cp->is_first_server_data)
 | 
			
		||||
	{
 | 
			
		||||
		_this->m_is_first_server_data = false;
 | 
			
		||||
		cp->is_first_server_data = false;
 | 
			
		||||
 | 
			
		||||
		if (cp->type != TS_SSH_CHANNEL_TYPE_SFTP)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -1244,3 +861,391 @@ void SshSession::_on_server_channel_close(ssh_session session, ssh_channel chann
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const ex_u8* data, int len)
 | 
			
		||||
{
 | 
			
		||||
	if (TP_SSH_CLIENT_SIDE == from)
 | 
			
		||||
	{
 | 
			
		||||
		// 客户端输入回车时,可能时执行了一条命令,需要根据服务端返回的数据进行进一步判断
 | 
			
		||||
		if (data[len - 1] == 0x0d)
 | 
			
		||||
			cp->cmd_flag = 1;
 | 
			
		||||
 | 
			
		||||
// 		cp->cmd_flag = 0;
 | 
			
		||||
// 
 | 
			
		||||
// 		if (len == 3)
 | 
			
		||||
// 		{
 | 
			
		||||
// 			if ((data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x41)			// key-up
 | 
			
		||||
// 				|| (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x42)		// key-down
 | 
			
		||||
// 				)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				cp->cmd_flag = 1;
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 			else if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x43)		// key-right
 | 
			
		||||
// 			{
 | 
			
		||||
// 				if (cp->cmd_char_pos != cp->cmd_char_list.end())
 | 
			
		||||
// 					cp->cmd_char_pos++;
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 			else if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x44)		// key-left
 | 
			
		||||
// 			{
 | 
			
		||||
// 				if (cp->cmd_char_pos != cp->cmd_char_list.begin())
 | 
			
		||||
// 					cp->cmd_char_pos--;
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 			else if (
 | 
			
		||||
// 				(data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x41)
 | 
			
		||||
// 				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x42)
 | 
			
		||||
// 				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x43)
 | 
			
		||||
// 				|| (data[0] == 0x1b && data[1] == 0x4f && data[2] == 0x44)
 | 
			
		||||
// 				)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				// 编辑模式下的上下左右键
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 		}
 | 
			
		||||
// 		else if (len == 1)
 | 
			
		||||
// 		{
 | 
			
		||||
// 			if (data[0] == 0x08 || data[0] == 0x09)  // 08=光标左移
 | 
			
		||||
// 			{
 | 
			
		||||
// 				cp->cmd_flag = 1;
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 			else if (data[0] == 0x7f)	// Backspace (回删一个字符)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				if (cp->cmd_char_pos != cp->cmd_char_list.begin())
 | 
			
		||||
// 				{
 | 
			
		||||
// 					cp->cmd_char_pos--;
 | 
			
		||||
// 					cp->cmd_char_pos = cp->cmd_char_list.erase(cp->cmd_char_pos);
 | 
			
		||||
// 				}
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 			else if (data[0] == 0x1b)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				// 按下 Esc 键
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 
 | 
			
		||||
// 			if (data[0] != 0x0d && !isprint(data[0]))
 | 
			
		||||
// 				return;
 | 
			
		||||
// 		}
 | 
			
		||||
// 		else if (len > 3)
 | 
			
		||||
// 		{
 | 
			
		||||
// 			if (data[0] == 0x1b && data[1] == 0x5b)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				cp->cmd_flag = 1;
 | 
			
		||||
// 				// 
 | 
			
		||||
// 				// 				// 不是命令行上的上下左右,也不是编辑模式下的上下左右,那么就忽略(应该是编辑模式下的其他输入)
 | 
			
		||||
// 				// 				m_cmd_char_list.clear();
 | 
			
		||||
// 				// 				m_cmd_char_pos = m_cmd_char_list.begin();
 | 
			
		||||
// 				return;
 | 
			
		||||
// 			}
 | 
			
		||||
// 		}
 | 
			
		||||
// 
 | 
			
		||||
// 		int processed = 0;
 | 
			
		||||
// 		for (int i = 0; i < len; i++)
 | 
			
		||||
// 		{
 | 
			
		||||
// 			if (data[i] == 0x0d)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				cp->cmd_flag = 0;
 | 
			
		||||
// 
 | 
			
		||||
// 				for (int j = processed; j < i; ++j)
 | 
			
		||||
// 				{
 | 
			
		||||
// 					cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, data[j]);
 | 
			
		||||
// 					cp->cmd_char_pos++;
 | 
			
		||||
// 				}
 | 
			
		||||
// 
 | 
			
		||||
// 				if (cp->cmd_char_list.size() > 0)
 | 
			
		||||
// 				{
 | 
			
		||||
// 					ex_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end());
 | 
			
		||||
// 					ex_replace_all(str, "\r", "");
 | 
			
		||||
// 					ex_replace_all(str, "\n", "");
 | 
			
		||||
// 					EXLOGD("[ssh] save cmd: [%s]\n", str.c_str());
 | 
			
		||||
// 					str += "\r\n";
 | 
			
		||||
// 					cp->rec.record_command(str);
 | 
			
		||||
// 				}
 | 
			
		||||
// 				cp->cmd_char_list.clear();
 | 
			
		||||
// 				cp->cmd_char_pos = cp->cmd_char_list.begin();
 | 
			
		||||
// 
 | 
			
		||||
// 				processed = i + 1;
 | 
			
		||||
// 			}
 | 
			
		||||
// 		}
 | 
			
		||||
// 
 | 
			
		||||
// 		if (processed < len)
 | 
			
		||||
// 		{
 | 
			
		||||
// 			for (int j = processed; j < len; ++j)
 | 
			
		||||
// 			{
 | 
			
		||||
// 				cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, data[j]);
 | 
			
		||||
// 				cp->cmd_char_pos++;
 | 
			
		||||
// 			}
 | 
			
		||||
// 		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (TP_SSH_SERVER_SIDE == from)
 | 
			
		||||
	{
 | 
			
		||||
		if (cp->cmd_flag == 0)
 | 
			
		||||
			return;
 | 
			
		||||
		if (len != 2 || !(data[0] == 0x0d && data[1] == 0x0a))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		bool esc_mode = false;
 | 
			
		||||
		int esc_arg = 0;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (esc_mode)
 | 
			
		||||
			{
 | 
			
		||||
				switch (data[i])
 | 
			
		||||
				{
 | 
			
		||||
				case '0':
 | 
			
		||||
				case '1':
 | 
			
		||||
				case '2':
 | 
			
		||||
				case '3':
 | 
			
		||||
				case '4':
 | 
			
		||||
				case '5':
 | 
			
		||||
				case '6':
 | 
			
		||||
				case '7':
 | 
			
		||||
				case '8':
 | 
			
		||||
				case '9':
 | 
			
		||||
					esc_arg = esc_arg * 10 + (data[i] - '0');
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 0x3f:
 | 
			
		||||
				case ';':
 | 
			
		||||
				case '>':
 | 
			
		||||
					cp->cmd_char_list.clear();
 | 
			
		||||
					cp->cmd_char_pos = cp->cmd_char_list.begin();
 | 
			
		||||
					return;
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 0x4b:	// 'K'
 | 
			
		||||
				{
 | 
			
		||||
					if (0 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除光标到行尾的字符串
 | 
			
		||||
						cp->cmd_char_list.erase(cp->cmd_char_pos, cp->cmd_char_list.end());
 | 
			
		||||
						cp->cmd_char_pos = cp->cmd_char_list.end();
 | 
			
		||||
					}
 | 
			
		||||
					else if (1 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除从开始到光标处的字符串
 | 
			
		||||
						cp->cmd_char_list.erase(cp->cmd_char_list.begin(), cp->cmd_char_pos);
 | 
			
		||||
						cp->cmd_char_pos = cp->cmd_char_list.end();
 | 
			
		||||
					}
 | 
			
		||||
					else if (2 == esc_arg)
 | 
			
		||||
					{
 | 
			
		||||
						// 删除整行
 | 
			
		||||
						cp->cmd_char_list.clear();
 | 
			
		||||
						cp->cmd_char_pos = cp->cmd_char_list.begin();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 0x43:	// ^[C
 | 
			
		||||
				{
 | 
			
		||||
					// 光标右移
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (cp->cmd_char_pos != cp->cmd_char_list.end())
 | 
			
		||||
							cp->cmd_char_pos++;
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 0x44:  // ^[D
 | 
			
		||||
				{
 | 
			
		||||
					// 光标左移
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (cp->cmd_char_pos != cp->cmd_char_list.begin())
 | 
			
		||||
							cp->cmd_char_pos--;
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 0x50:	// 'P' 删除指定数量的字符
 | 
			
		||||
				{
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						if (cp->cmd_char_pos != cp->cmd_char_list.end())
 | 
			
		||||
							cp->cmd_char_pos = cp->cmd_char_list.erase(cp->cmd_char_pos);
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 0x40:	// '@' 插入指定数量的空白字符
 | 
			
		||||
				{
 | 
			
		||||
					if (esc_arg == 0)
 | 
			
		||||
						esc_arg = 1;
 | 
			
		||||
					for (int j = 0; j < esc_arg; ++j)
 | 
			
		||||
					{
 | 
			
		||||
						cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, ' ');
 | 
			
		||||
					}
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
					esc_mode = false;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch (data[i])
 | 
			
		||||
			{
 | 
			
		||||
			case 0x07:
 | 
			
		||||
			{
 | 
			
		||||
				// 响铃
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x08:
 | 
			
		||||
			{
 | 
			
		||||
				// 光标左移
 | 
			
		||||
				if (cp->cmd_char_pos != cp->cmd_char_list.begin())
 | 
			
		||||
					cp->cmd_char_pos--;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x1b:
 | 
			
		||||
			{
 | 
			
		||||
				if (i + 1 < len)
 | 
			
		||||
				{
 | 
			
		||||
					if (data[i + 1] == 0x5b)
 | 
			
		||||
					{
 | 
			
		||||
						esc_mode = true;
 | 
			
		||||
						esc_arg = 0;
 | 
			
		||||
 | 
			
		||||
						i += 1;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case 0x0d:
 | 
			
		||||
			{
 | 
			
		||||
				cp->cmd_char_list.clear();
 | 
			
		||||
				cp->cmd_char_pos = cp->cmd_char_list.begin();
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			default:
 | 
			
		||||
				if (cp->cmd_char_pos != cp->cmd_char_list.end())
 | 
			
		||||
				{
 | 
			
		||||
					cp->cmd_char_pos = cp->cmd_char_list.erase(cp->cmd_char_pos);
 | 
			
		||||
					cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, data[i]);
 | 
			
		||||
					cp->cmd_char_pos++;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					cp->cmd_char_list.push_back(data[i]);
 | 
			
		||||
					cp->cmd_char_pos = cp->cmd_char_list.end();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SshSession::_process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* data, int len) {
 | 
			
		||||
	// SFTP protocol: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
 | 
			
		||||
	//EXLOG_BIN(data, len, "[sftp] client channel data");
 | 
			
		||||
 | 
			
		||||
	if (len < 9)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	int pkg_len = (int)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
 | 
			
		||||
	if (pkg_len + 4 != len)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ex_u8 sftp_cmd = data[4];
 | 
			
		||||
 | 
			
		||||
	if (sftp_cmd == 0x01) {
 | 
			
		||||
		// 0x01 = 1 = SSH_FXP_INIT
 | 
			
		||||
		cp->rec.record_command("SFTP INITIALIZE\r\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 需要的数据至少14字节
 | 
			
		||||
	// uint32 + byte + uint32 + (uint32 + char + ...)
 | 
			
		||||
	// pkg_len + cmd + req_id + string( length + content...)
 | 
			
		||||
	if (len < 14)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ex_u8* str1_ptr = (ex_u8*)data + 9;
 | 
			
		||||
	int str1_len = (int)((str1_ptr[0] << 24) | (str1_ptr[1] << 16) | (str1_ptr[2] << 8) | str1_ptr[3]);
 | 
			
		||||
	// 	if (str1_len + 9 != pkg_len)
 | 
			
		||||
	// 		return;
 | 
			
		||||
	ex_u8* str2_ptr = NULL;// (ex_u8*)data + 13;
 | 
			
		||||
	int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	const char* act = NULL;
 | 
			
		||||
	switch (sftp_cmd) {
 | 
			
		||||
	case 0x03:
 | 
			
		||||
		// 0x03 = 3 = SSH_FXP_OPEN
 | 
			
		||||
		act = "open file";
 | 
			
		||||
		break;
 | 
			
		||||
		// 	case 0x0b:
 | 
			
		||||
		// 		// 0x0b = 11 = SSH_FXP_OPENDIR
 | 
			
		||||
		// 		act = "open dir";
 | 
			
		||||
		// 		break;
 | 
			
		||||
	case 0x0d:
 | 
			
		||||
		// 0x0d = 13 = SSH_FXP_REMOVE
 | 
			
		||||
		act = "remove file";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x0e:
 | 
			
		||||
		// 0x0e = 14 = SSH_FXP_MKDIR
 | 
			
		||||
		act = "create dir";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x0f:
 | 
			
		||||
		// 0x0f = 15 = SSH_FXP_RMDIR
 | 
			
		||||
		act = "remove dir";
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x12:
 | 
			
		||||
		// 0x12 = 18 = SSH_FXP_RENAME
 | 
			
		||||
		// rename操作数据中包含两个字符串
 | 
			
		||||
		act = "rename";
 | 
			
		||||
		str2_ptr = str1_ptr + str1_len + 4;
 | 
			
		||||
		str2_len = (int)((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x15:
 | 
			
		||||
		// 0x15 = 21 = SSH_FXP_LINK
 | 
			
		||||
		// link操作数据中包含两个字符串,前者是新的链接文件名,后者是现有被链接的文件名
 | 
			
		||||
		act = "create link";
 | 
			
		||||
		str2_ptr = str1_ptr + str1_len + 4;
 | 
			
		||||
		str2_len = (int)((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int total_len = 5 + str1_len + 4;
 | 
			
		||||
	if (str2_len > 0)
 | 
			
		||||
		total_len += str2_len + 4;
 | 
			
		||||
	if (total_len > pkg_len)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	char msg[2048] = { 0 };
 | 
			
		||||
	if (str2_len == 0) {
 | 
			
		||||
		ex_astr str1((char*)((ex_u8*)data + 13), str1_len);
 | 
			
		||||
		ex_strformat(msg, 2048, "%d:%s:%s:\r\n", sftp_cmd, act, str1.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ex_astr str1((char*)(str1_ptr + 4), str1_len);
 | 
			
		||||
		ex_astr str2((char*)(str2_ptr + 4), str2_len);
 | 
			
		||||
		ex_strformat(msg, 2048, "%d:%s:%s:%s\r\n", sftp_cmd, act, str1.c_str(), str2.c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cp->rec.record_command(msg);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,12 +40,17 @@ private:
 | 
			
		|||
	int retcode;
 | 
			
		||||
	int db_id;
 | 
			
		||||
	int channel_id;	// for debug only.
 | 
			
		||||
 | 
			
		||||
	bool is_first_server_data;
 | 
			
		||||
 | 
			
		||||
	// for ssh command record cache.
 | 
			
		||||
	int cmd_flag;
 | 
			
		||||
	std::list<char> cmd_char_list;
 | 
			
		||||
	std::list<char>::iterator cmd_char_pos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef std::list<TP_SSH_CHANNEL_PAIR*> tp_channels;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SshSession : public ExThreadBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -75,8 +80,8 @@ protected:
 | 
			
		|||
	// stop record because channel closed.
 | 
			
		||||
	void _record_end(TP_SSH_CHANNEL_PAIR* cp);
 | 
			
		||||
 | 
			
		||||
	void _process_ssh_command(TppSshRec* rec, int from, const ex_u8* data, int len);
 | 
			
		||||
	void _process_sftp_command(TppSshRec* rec, const ex_u8* data, int len);
 | 
			
		||||
	void _process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const ex_u8* data, int len);
 | 
			
		||||
	void _process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* data, int len);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void _run(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -84,9 +89,6 @@ private:
 | 
			
		|||
	void _close_channels(void);
 | 
			
		||||
	void _check_channels(void);
 | 
			
		||||
 | 
			
		||||
// 	void _client_channel_closed(TP_SSH_CHANNEL_PAIR* cp, bool& need_removed);
 | 
			
		||||
// 	void _server_channel_closed(TP_SSH_CHANNEL_PAIR* cp, bool& need_removed);
 | 
			
		||||
 | 
			
		||||
	static int _on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata);
 | 
			
		||||
	static ssh_channel _on_new_channel_request(ssh_session session, void *userdata);
 | 
			
		||||
	static int _on_client_pty_request(ssh_session session, ssh_channel channel, const char *term, int x, int y, int px, int py, void *userdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -121,8 +123,6 @@ private:
 | 
			
		|||
	ex_astr m_acc_secret;
 | 
			
		||||
	int m_auth_type;
 | 
			
		||||
 | 
			
		||||
	bool m_is_first_server_data;
 | 
			
		||||
 | 
			
		||||
	bool m_is_logon;
 | 
			
		||||
	// Ò»¸össh_sessionÖпÉÒÔ´ò¿ª¶à¸össh_channel
 | 
			
		||||
	tp_channels m_channels;
 | 
			
		||||
| 
						 | 
				
			
			@ -135,11 +135,6 @@ private:
 | 
			
		|||
	struct ssh_server_callbacks_struct m_srv_cb;
 | 
			
		||||
	struct ssh_channel_callbacks_struct m_cli_channel_cb;
 | 
			
		||||
	struct ssh_channel_callbacks_struct m_srv_channel_cb;
 | 
			
		||||
 | 
			
		||||
	int m_command_flag;
 | 
			
		||||
 | 
			
		||||
	std::list<char> m_cmd_char_list;
 | 
			
		||||
	std::list<char>::iterator m_cmd_char_pos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // __SSH_SESSION_H__
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue