部分支持SSHv1(SFTP还不行)...

pull/105/head
Apex Liu 2017-11-29 04:53:24 +08:00
parent c8ee43b924
commit c5af4d0ad2
3 changed files with 190 additions and 68 deletions

View File

@ -88,6 +88,7 @@ void SshProxy::_thread_loop()
ssh_session sess_to_client = ssh_new(); ssh_session sess_to_client = ssh_new();
// int verbosity = 4; // int verbosity = 4;
// ssh_options_set(sess_to_client, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); // ssh_options_set(sess_to_client, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_set_blocking(sess_to_client, 1); ssh_set_blocking(sess_to_client, 1);
struct sockaddr_storage sock_client; struct sockaddr_storage sock_client;

View File

@ -7,7 +7,6 @@
TP_SSH_CHANNEL_PAIR::TP_SSH_CHANNEL_PAIR() { TP_SSH_CHANNEL_PAIR::TP_SSH_CHANNEL_PAIR() {
type = TS_SSH_CHANNEL_TYPE_UNKNOWN; type = TS_SSH_CHANNEL_TYPE_UNKNOWN;
cli_channel = NULL; cli_channel = NULL;
srv_channel = NULL; srv_channel = NULL;
@ -35,7 +34,7 @@ SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
{ {
m_auth_type = TP_AUTH_TYPE_PASSWORD; m_auth_type = TP_AUTH_TYPE_PASSWORD;
// m_is_first_server_data = true; m_ssh_ver = 2; // default to SSHv2
m_is_logon = false; m_is_logon = false;
m_have_error = false; m_have_error = false;
@ -173,7 +172,7 @@ void SshSession::_close_channels(void) {
} }
void SshSession::_check_channels() { void SshSession::_check_channels() {
EXLOGD("[ssh] -- check channels\n"); //EXLOGD("[ssh] -- check channels\n");
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
//EXLOGD("[ssh] -- check channels, have %d\n", m_channels.size()); //EXLOGD("[ssh] -- check channels, have %d\n", m_channels.size());
@ -215,18 +214,23 @@ void SshSession::_check_channels() {
m_channels.erase(it++); m_channels.erase(it++);
} }
else { else {
// if ((*it)->type == TS_SSH_CHANNEL_TYPE_SHELL) { // if ((*it)->type == TS_SSH_CHANNEL_TYPE_SHELL) {
// // 尝试发点信息:看看还会不会继续卡住 // // 尝试从服务器读取点东西
// char* msg = "\r\n\r\n"; // ex_u8 buf[4096] = { 0 };
// int len = ssh_channel_write(srv, msg, strlen(msg)); // int len = 0;
// if (len != strlen(msg)) { //
// EXLOGE("[ssh] -- try send failed. srv:err:%s\n", ssh_get_error(m_srv_session)); // len = ssh_channel_read_nonblocking(srv, buf, 4096, 0);
// EXLOGE("[ssh] -- try send failed. cli:err:%s\n", ssh_get_error(m_cli_session)); // if (len < 0) {
// } // EXLOGE("[ssh] -- try read failed. srv:err:%s\n", ssh_get_error(m_srv_session));
// else { // EXLOGE("[ssh] -- try read failed. cli:err:%s\n", ssh_get_error(m_cli_session));
// EXLOGD("[ssh] -- try send ok.\n"); // ssh_channel_close(srv);
// } // }
// } // else if(len > 0) {
// EXLOGD("[ssh] -- try read server ok.\n");
// EXLOG_BIN(buf, len, "RECV\n");
// _on_server_channel_data(m_srv_session, srv, buf, len, 0, this);
// }
// }
++it; ++it;
} }
@ -258,25 +262,35 @@ void SshSession::_run(void) {
ssh_set_server_callbacks(m_cli_session, &m_srv_cb); ssh_set_server_callbacks(m_cli_session, &m_srv_cb);
int err = SSH_OK;
// 安全连接(密钥交换) // 安全连接(密钥交换)
if (ssh_handle_key_exchange(m_cli_session)) { err = ssh_handle_key_exchange(m_cli_session);
if (err != SSH_OK) {
EXLOGE("[ssh] key exchange with client failed: %s\n", ssh_get_error(m_cli_session)); EXLOGE("[ssh] key exchange with client failed: %s\n", ssh_get_error(m_cli_session));
return; return;
} }
ssh_event event_loop = ssh_event_new(); ssh_event event_loop = ssh_event_new();
ssh_event_add_session(event_loop, m_cli_session); if (NULL == event_loop) {
EXLOGE("[ssh] can not create event loop.\n");
return;
}
err = ssh_event_add_session(event_loop, m_cli_session);
if (err != SSH_OK) {
EXLOGE("[ssh] can not add client-session into event loop.\n");
return;
}
// 认证,并打开一个通道 // 认证,并打开一个通道
int r = 0;
while (!(m_is_logon && m_channels.size() > 0)) { while (!(m_is_logon && m_channels.size() > 0)) {
if (m_have_error) if (m_have_error)
break; break;
r = ssh_event_dopoll(event_loop, -1); err = ssh_event_dopoll(event_loop, -1);
if (r == SSH_ERROR) { if (err != SSH_OK) {
EXLOGE("[ssh] Error : %s\n", ssh_get_error(m_cli_session)); EXLOGE("[ssh] error when event poll: %s\n", ssh_get_error(m_cli_session));
ssh_disconnect(m_cli_session); m_have_error = true;
return; break;
} }
} }
@ -289,12 +303,53 @@ void SshSession::_run(void) {
EXLOGW("[ssh] authenticated and got a channel.\n"); EXLOGW("[ssh] authenticated and got a channel.\n");
// 现在双方的连接已经建立好了,开始转发 // // 现在双方的连接已经建立好了,开始转发
// err = ssh_event_add_session(event_loop, m_srv_session);
// if (err != SSH_OK) {
// EXLOGE("[ssh] can not add server-session into event loop.\n");
// ssh_event_remove_session(event_loop, m_cli_session);
// return;
// }
//
// do {
// err = ssh_event_dopoll(event_loop, 5000);
// if (err == SSH_ERROR) {
// if (0 != ssh_get_error_code(m_cli_session))
// {
// EXLOGE("[ssh] ssh_event_dopoll() [cli] %s\n", ssh_get_error(m_cli_session));
// }
// else if (0 != ssh_get_error_code(m_srv_session))
// {
// EXLOGE("[ssh] ssh_event_dopoll() [srv] %s\n", ssh_get_error(m_srv_session));
// }
//
// _close_channels();
// }
// else if (err == SSH_AGAIN) {
// // timeout.
// _check_channels();
// }
// } while (m_channels.size() > 0);
//
// EXLOGV("[ssh] [%s:%d] all channel in this session are closed.\n", m_client_ip.c_str(), m_client_port);
//
// ssh_event_remove_session(event_loop, m_cli_session);
// ssh_event_remove_session(event_loop, m_srv_session);
// ssh_event_free(event_loop);
//
// 如果是SSHv2
//if (m_ssh_ver == 2) {
// 现在双方的连接已经建立好了,开始转发
ssh_event_add_session(event_loop, m_srv_session); ssh_event_add_session(event_loop, m_srv_session);
do { do {
r = ssh_event_dopoll(event_loop, 5000); err = ssh_event_dopoll(event_loop, 5000);
//EXLOGD("ssh_event_dopoll() return %d.\n", r); //EXLOGD("ssh_event_dopoll() return %d.\n", r);
if (r == SSH_ERROR) { if (err == SSH_ERROR) {
if (0 != ssh_get_error_code(m_cli_session)) if (0 != ssh_get_error_code(m_cli_session))
{ {
EXLOGE("[ssh] ssh_event_dopoll() [cli] %s\n", ssh_get_error(m_cli_session)); EXLOGE("[ssh] ssh_event_dopoll() [cli] %s\n", ssh_get_error(m_cli_session));
@ -306,17 +361,80 @@ void SshSession::_run(void) {
_close_channels(); _close_channels();
} }
else if (r == SSH_AGAIN) {
if (m_ssh_ver == 1) {
tp_channels::iterator it = m_channels.begin();
if ((*it)->type == TS_SSH_CHANNEL_TYPE_SHELL || (*it)->type == TS_SSH_CHANNEL_TYPE_SFTP)
break;
}
if (err == SSH_AGAIN) {
// timeout. // timeout.
_check_channels(); _check_channels();
} }
} while (m_channels.size() > 0); } while (m_channels.size() > 0);
EXLOGV("[ssh] [%s:%d] all channel in this session are closed.\n", m_client_ip.c_str(), m_client_port); if (m_channels.size() == 0)
EXLOGV("[ssh] [%s:%d] all channel in this session are closed.\n", m_client_ip.c_str(), m_client_port);
ssh_event_remove_session(event_loop, m_cli_session); ssh_event_remove_session(event_loop, m_cli_session);
ssh_event_remove_session(event_loop, m_srv_session); ssh_event_remove_session(event_loop, m_srv_session);
ssh_event_free(event_loop); ssh_event_free(event_loop);
//}
// TODO: 这里还是有问题如果一边是走SSHv1另一边是SSHv2放在同一个event_loop时SSHv1会收不到数据放到循环中时SSHv2得不到数据
if (m_ssh_ver == 1)
{
tp_channels::iterator it = m_channels.begin(); // SSHv1只能打开一个channel
ssh_channel cli = (*it)->cli_channel;
ssh_channel srv = (*it)->srv_channel;
bool ok = true;
do {
ex_u8 buf[4096] = { 0 };
int len = 0;
if (ok) {
len = ssh_channel_read_nonblocking(cli, buf, 4096, 0);
if (len < 0) {
EXLOGE("[ssh] -- try read failed. srv:err:%s\n", ssh_get_error(m_srv_session));
EXLOGE("[ssh] -- try read failed. cli:err:%s\n", ssh_get_error(m_cli_session));
ok = false;
}
else if (len > 0) {
EXLOGD("[ssh] -- try read client ok.\n");
//EXLOG_BIN(buf, len, "RECV\n");
_on_client_channel_data(m_cli_session, cli, buf, len, 0, this);
}
len = ssh_channel_read_nonblocking(srv, buf, 4096, 0);
if (len < 0) {
EXLOGE("[ssh] -- try read failed. srv:err:%s\n", ssh_get_error(m_srv_session));
EXLOGE("[ssh] -- try read failed. cli:err:%s\n", ssh_get_error(m_cli_session));
ok = false;
}
else if (len > 0) {
EXLOGD("[ssh] -- try read server ok.\n");
//EXLOG_BIN(buf, len, "RECV\n");
_on_server_channel_data(m_srv_session, srv, buf, len, 0, this);
}
if (!ok)
_close_channels();
}
if (!ok) {
_check_channels();
ex_sleep_ms(1000);
continue;
}
ex_sleep_ms(30);
} while (m_channels.size() > 0);
}
} }
void SshSession::save_record() { void SshSession::save_record() {
@ -334,8 +452,8 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_sid = user; _this->m_sid = user;
EXLOGV("[ssh] authenticating, session-id: %s\n", _this->m_sid.c_str()); EXLOGV("[ssh] authenticating, session-id: %s\n", _this->m_sid.c_str());
// int protocol = 0; // int protocol = 0;
//TPP_CONNECT_INFO* sess_info = g_ssh_env.get_connect_info(_this->m_sid.c_str()); //TPP_CONNECT_INFO* sess_info = g_ssh_env.get_connect_info(_this->m_sid.c_str());
_this->m_conn_info = g_ssh_env.get_connect_info(_this->m_sid.c_str()); _this->m_conn_info = g_ssh_env.get_connect_info(_this->m_sid.c_str());
if (NULL == _this->m_conn_info) { if (NULL == _this->m_conn_info) {
@ -358,12 +476,12 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
} }
// 现在尝试根据session-id获取得到的信息连接并登录真正的SSH服务器 // 现在尝试根据session-id获取得到的信息连接并登录真正的SSH服务器
EXLOGV("[ssh] try to connect to real SSH server %s:%d\n", _this->m_conn_ip.c_str(), _this->m_conn_port); EXLOGV("[ssh] try to connect to real SSH server %s:%d\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_srv_session = ssh_new(); _this->m_srv_session = ssh_new();
// int verbosity = 4; // int verbosity = 4;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); // ssh_options_set(_this->m_srv_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_set_blocking(_this->m_srv_session, 1); ssh_set_blocking(_this->m_srv_session, 1);
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_HOST, _this->m_conn_ip.c_str()); ssh_options_set(_this->m_srv_session, SSH_OPTIONS_HOST, _this->m_conn_ip.c_str());
int port = (int)_this->m_conn_port; int port = (int)_this->m_conn_port;
@ -380,6 +498,10 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
int _timeout = 30; // 30 sec. int _timeout = 30; // 30 sec.
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_TIMEOUT, &_timeout); ssh_options_set(_this->m_srv_session, SSH_OPTIONS_TIMEOUT, &_timeout);
// int val = 0;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &val);
int rc = 0; int rc = 0;
rc = ssh_connect(_this->m_srv_session); rc = ssh_connect(_this->m_srv_session);
if (rc != SSH_OK) { if (rc != SSH_OK) {
@ -393,7 +515,8 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_TIMEOUT, &_timeout); ssh_options_set(_this->m_srv_session, SSH_OPTIONS_TIMEOUT, &_timeout);
// TODO: 获取服务端ssh版本是v1还是v2 // TODO: 获取服务端ssh版本是v1还是v2
int ssh_ver = ssh_get_version(_this->m_srv_session); _this->m_ssh_ver = ssh_get_version(_this->m_srv_session);
EXLOGW("[ssh] real host is SSHv%d\n", _this->m_ssh_ver);
// // 检查服务端支持的认证协议 // // 检查服务端支持的认证协议
//ssh_userauth_none(_this->m_srv_session, _this->m_acc_name.c_str()); //ssh_userauth_none(_this->m_srv_session, _this->m_acc_name.c_str());
@ -414,7 +537,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) { if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) {
int retry_count = 0; int retry_count = 0;
if (ssh_ver == 1) { if (_this->m_ssh_ver == 1) {
// 远程主机是SSHv1则优先尝试密码登录 // 远程主机是SSHv1则优先尝试密码登录
rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str()); rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str());
for (;;) { for (;;) {
@ -485,7 +608,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
EXLOGW("[ssh] failed to login with keyboard interactive mode, got %d, try password mode.\n", rc); EXLOGW("[ssh] failed to login with keyboard interactive mode, got %d, try password mode.\n", rc);
} }
if (ssh_ver != 1) { if (_this->m_ssh_ver != 1) {
// 不支持交互式登录,则尝试密码方式 // 不支持交互式登录,则尝试密码方式
rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str()); rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str());
if (rc == SSH_AUTH_SUCCESS) { if (rc == SSH_AUTH_SUCCESS) {
@ -640,8 +763,11 @@ int SshSession::_on_client_shell_request(ssh_session session, ssh_channel channe
} }
cp->type = TS_SSH_CHANNEL_TYPE_SHELL; cp->type = TS_SSH_CHANNEL_TYPE_SHELL;
if (_this->m_ssh_ver == 1)
cp->server_ready = true;
g_ssh_env.session_update(cp->db_id, TP_PROTOCOL_TYPE_SSH_SHELL, TP_SESS_STAT_STARTED); g_ssh_env.session_update(cp->db_id, TP_PROTOCOL_TYPE_SSH_SHELL, TP_SESS_STAT_STARTED);
// FIXME: sometimes it will block here. the following function will never return. // FIXME: sometimes it will block here. the following function will never return.
// at this time, can not write data to this channel. read from this channel with timeout, got 0 byte. // at this time, can not write data to this channel. read from this channel with timeout, got 0 byte.
// I have no idea how to fix it... :( // I have no idea how to fix it... :(
@ -649,14 +775,6 @@ int SshSession::_on_client_shell_request(ssh_session session, ssh_channel channe
if (err != SSH_OK) { if (err != SSH_OK) {
EXLOGE("[ssh] shell request from server got %d\n", err); EXLOGE("[ssh] shell request from server got %d\n", err);
} }
// else {
// // 尝试发点信息:看看还会不会继续卡住
// char* msg = "\r\n\r\n";
// err = ssh_channel_write(cp->srv_channel, msg, strlen(msg));
// if (err != SSH_OK) {
// EXLOGE("[ssh] -- try send failed.\n");
// }
// }
return err; return err;
} }
@ -685,7 +803,7 @@ void SshSession::_on_client_channel_close(ssh_session session, ssh_channel chann
int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata) int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata)
{ {
EXLOG_BIN((ex_u8*)data, len, "on_client_channel_data [is_stderr=%d]:", is_stderr); //EXLOG_BIN((ex_u8*)data, len, "on_client_channel_data [is_stderr=%d]:", is_stderr);
SshSession *_this = (SshSession *)userdata; SshSession *_this = (SshSession *)userdata;
@ -721,10 +839,10 @@ int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel
_this->_process_ssh_command(cp, TP_SSH_CLIENT_SIDE, (ex_u8*)data, _len); _this->_process_ssh_command(cp, TP_SSH_CLIENT_SIDE, (ex_u8*)data, _len);
// ex_astr str(cp->cmd_char_list.begin(), cp->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, "\r", "");
// ex_replace_all(str, "\n", ""); // ex_replace_all(str, "\n", "");
// EXLOGD("[ssh] -- [%s]\n", str.c_str()); // EXLOGD("[ssh] -- [%s]\n", str.c_str());
} }
else { else {
_this->_process_sftp_command(cp, (ex_u8*)data, _len); _this->_process_sftp_command(cp, (ex_u8*)data, _len);
@ -797,7 +915,7 @@ int SshSession::_on_client_channel_exec_request(ssh_session session, ssh_channel
} }
int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata) { int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata) {
EXLOG_BIN((ex_u8*)data, len, "on_server_channel_data [is_stderr=%d]:", is_stderr); //EXLOG_BIN((ex_u8*)data, len, "on_server_channel_data [is_stderr=%d]:", is_stderr);
SshSession *_this = (SshSession *)userdata; SshSession *_this = (SshSession *)userdata;
@ -836,10 +954,10 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
} }
_this->_process_ssh_command(cp, TP_SSH_SERVER_SIDE, (ex_u8*)data, len); _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_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end());
// ex_replace_all(str, "\r", ""); // ex_replace_all(str, "\r", "");
// ex_replace_all(str, "\n", ""); // ex_replace_all(str, "\n", "");
// EXLOGD("[ssh] -- [%s]\n", str.c_str()); // EXLOGD("[ssh] -- [%s]\n", str.c_str());
cp->rec.record(TS_RECORD_TYPE_SSH_DATA, (unsigned char *)data, len); cp->rec.record(TS_RECORD_TYPE_SSH_DATA, (unsigned char *)data, len);
} }
@ -942,7 +1060,7 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
if (mbuf.size() > 0) if (mbuf.size() > 0)
{ {
for(;;){ for (;;) {
ret = ssh_channel_write(cp->cli_channel, mbuf.data(), mbuf.size()); ret = ssh_channel_write(cp->cli_channel, mbuf.data(), mbuf.size());
if (ret == SSH_ERROR) if (ret == SSH_ERROR)
break; break;
@ -955,10 +1073,10 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
ex_sleep_ms(100); ex_sleep_ms(100);
} }
} }
// if (ret <= 0) // if (ret <= 0)
// EXLOGE("[ssh] send to client failed (1).\n"); // EXLOGE("[ssh] send to client failed (1).\n");
// else // else
// ret = len; // ret = len;
} }
else else
{ {
@ -1033,11 +1151,11 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
// 客户端输入回车时,可能时执行了一条命令,需要根据服务端返回的数据进行进一步判断 // 客户端输入回车时,可能时执行了一条命令,需要根据服务端返回的数据进行进一步判断
cp->maybe_cmd = (data[len - 1] == 0x0d); cp->maybe_cmd = (data[len - 1] == 0x0d);
// if (cp->maybe_cmd) // if (cp->maybe_cmd)
// EXLOGD("[ssh] maybe cmd.\n"); // EXLOGD("[ssh] maybe cmd.\n");
// 有时在执行类似top命令的情况下输入一个字母'q'就退出程序,没有输入回车,可能会导致后续记录命令时将返回的命令行提示符作为命令 // 有时在执行类似top命令的情况下输入一个字母'q'就退出程序,没有输入回车,可能会导致后续记录命令时将返回的命令行提示符作为命令
// 记录下来了,要避免这种情况,排除的方式是:客户端单个字母,后续服务端如果收到的是控制序列 1b 5b xx xx就不计做命令。 // 记录下来了,要避免这种情况,排除的方式是:客户端单个字母,后续服务端如果收到的是控制序列 1b 5b xx xx就不计做命令。
cp->client_single_char = (len == 1 && isprint(data[0])); cp->client_single_char = (len == 1 && isprint(data[0]));
cp->process_srv = true; cp->process_srv = true;
@ -1189,13 +1307,13 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
case 0x0d: case 0x0d:
{ {
if (offset + 1 < len && data[offset + 1] == 0x0a) { if (offset + 1 < len && data[offset + 1] == 0x0a) {
// if (cp->maybe_cmd) // if (cp->maybe_cmd)
// EXLOGD("[ssh] maybe cmd.\n"); // EXLOGD("[ssh] maybe cmd.\n");
if (cp->maybe_cmd) { if (cp->maybe_cmd) {
if (cp->cmd_char_list.size() > 0) if (cp->cmd_char_list.size() > 0)
{ {
ex_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end()); ex_astr str(cp->cmd_char_list.begin(), cp->cmd_char_list.end());
// EXLOGD("[ssh] --==--==-- save cmd: [%s]\n", str.c_str()); // EXLOGD("[ssh] --==--==-- save cmd: [%s]\n", str.c_str());
cp->rec.record_command(0, str); cp->rec.record_command(0, str);
} }
@ -1263,7 +1381,7 @@ void SshSession::_process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* dat
// pkg_len + cmd + req_id + string( length + content...) // pkg_len + cmd + req_id + string( length + content...)
if (len < 14) if (len < 14)
return; return;
ex_u8* str1_ptr = (ex_u8*)data + 9; 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]); 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) // if (str1_len + 9 != pkg_len)

View File

@ -32,6 +32,7 @@ public:
private: private:
int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP
ssh_channel cli_channel; ssh_channel cli_channel;
ssh_channel srv_channel; ssh_channel srv_channel;
@ -109,7 +110,6 @@ private:
static void _on_server_channel_close(ssh_session session, ssh_channel channel, void* userdata); static void _on_server_channel_close(ssh_session session, ssh_channel channel, void* userdata);
private: private:
SshProxy* m_proxy; SshProxy* m_proxy;
ssh_session m_cli_session; ssh_session m_cli_session;
ssh_session m_srv_session; ssh_session m_srv_session;
@ -129,6 +129,9 @@ private:
int m_auth_type; int m_auth_type;
bool m_is_logon; bool m_is_logon;
int m_ssh_ver;
// 一个ssh_session中可以打开多个ssh_channel // 一个ssh_session中可以打开多个ssh_channel
tp_channels m_channels; tp_channels m_channels;