修正了无法远程连接SSHv1.99的交换机的问题。

pull/111/head
Apex Liu 2018-09-22 00:51:56 +08:00
parent 0437cb16d3
commit e326b3ac48
13 changed files with 156 additions and 124 deletions

View File

@ -1,3 +1,3 @@
# -*- coding: utf8 -*-
VER_TP_SERVER = "3.0.3.12"
VER_TP_ASSIST = "3.0.1.6"
# -*- coding: utf8 -*-
VER_TP_SERVER = "3.0.4.16"
VER_TP_ASSIST = "3.0.1.6"

View File

@ -51,6 +51,7 @@
#define TP_SESS_STAT_ERR_RESET 7 // 会话结束因为teleport核心服务重置了
#define TP_SESS_STAT_ERR_IO 8 // 会话结束,因为网络中断
#define TP_SESS_STAT_ERR_SESSION 9 // 会话结束因为无效的会话ID
#define TP_SESS_STAT_ERR_AUTH_TYPE 10 // 会话结束,因为不被允许的认证方式
#define TP_SESS_STAT_STARTED 100 // 已经连接成功了,开始记录录像了
#define TP_SESS_STAT_ERR_START_INTERNAL 104 // 会话结束,因为内部错误
#define TP_SESS_STAT_ERR_START_BAD_PKG 106 // 会话结束,因为收到错误的报文

Binary file not shown.

View File

@ -1,6 +1,6 @@
#ifndef __TS_SERVER_VER_H__
#define __TS_SERVER_VER_H__
#define TP_SERVER_VER L"3.0.3.12"
#endif // __TS_SERVER_VER_H__
#ifndef __TS_SERVER_VER_H__
#define __TS_SERVER_VER_H__
#define TP_SERVER_VER L"3.0.4.16"
#endif // __TS_SERVER_VER_H__

View File

@ -422,7 +422,7 @@ void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) {
}
int SshSession::_on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata) {
// 这里拿到的user就是我们要的session-id。
// here, `user` is the session-id we need.
SshSession *_this = (SshSession *)userdata;
_this->m_sid = user;
EXLOGV("[ssh] authenticating, session-id: %s\n", _this->m_sid.c_str());
@ -441,6 +441,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_auth_type = _this->m_conn_info->auth_type;
_this->m_acc_name = _this->m_conn_info->acc_username;
_this->m_acc_secret = _this->m_conn_info->acc_secret;
_this->m_flags = _this->m_conn_info->protocol_flag;
if (_this->m_conn_info->protocol_type != TP_PROTOCOL_TYPE_SSH) {
EXLOGE("[ssh] session '%s' is not for SSH.\n", _this->m_sid.c_str());
_this->m_have_error = true;
@ -449,21 +450,18 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
}
}
// 现在尝试根据session-id获取得到的信息连接并登录真正的SSH服务器
// config and try to connect to real SSH host.
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();
// int verbosity = 4;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
//ssh_set_blocking(_this->m_srv_session, 1);
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_HOST, _this->m_conn_ip.c_str());
int port = (int)_this->m_conn_port;
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_PORT, &port);
#ifdef EX_DEBUG
// int flag = SSH_LOG_FUNCTIONS;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_LOG_VERBOSITY, &flag);
// int flag = SSH_LOG_FUNCTIONS;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_LOG_VERBOSITY, &flag);
#endif
// int val = 0;
// ssh_options_set(_this->m_srv_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &val);
int val = 0;
ssh_options_set(_this->m_srv_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &val);
if (_this->m_auth_type != TP_AUTH_TYPE_NONE)
@ -490,108 +488,113 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_ssh_ver = ssh_get_version(_this->m_srv_session);
EXLOGW("[ssh] real host is SSHv%d\n", _this->m_ssh_ver);
#if 0
// check supported auth type by host
//ssh_userauth_none(_this->m_srv_session, _this->m_acc_name.c_str());
// rc = ssh_userauth_none(_this->m_srv_session, NULL);
// if (rc == SSH_AUTH_ERROR) {
// EXLOGE("[ssh] can not got auth type supported by real SSH server %s:%d.\n", _this->m_server_ip.c_str(), _this->m_server_port);
// _this->m_have_error = true;
// _this->m_retcode = SESS_STAT_ERR_AUTH_DENIED;
// return SSH_AUTH_ERROR;
// }
// // int auth_methods = ssh_userauth_list(_this->m_srv_session, NULL);
// const char* banner = ssh_get_issue_banner(_this->m_srv_session);
// if (NULL != banner) {
// EXLOGE("[ssh] issue banner: %s\n", banner);
// }
ssh_userauth_none(_this->m_srv_session, _this->m_acc_name.c_str());
rc = ssh_userauth_none(_this->m_srv_session, NULL);
if (rc == SSH_AUTH_ERROR) {
EXLOGE("[ssh] can not got auth type supported by real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_SESSION);
return SSH_AUTH_ERROR;
}
int auth_methods = ssh_userauth_list(_this->m_srv_session, _this->m_acc_name.c_str());
const char* banner = ssh_get_issue_banner(_this->m_srv_session);
if (NULL != banner) {
EXLOGE("[ssh] issue banner: %s\n", banner);
}
#endif
int auth_methods = SSH_AUTH_METHOD_INTERACTIVE | SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY;
if (SSH_AUTH_ERROR != ssh_userauth_none(_this->m_srv_session, NULL))
{
auth_methods = ssh_userauth_list(_this->m_srv_session, NULL);
EXLOGV("[ssh] allowed auth method: 0x%08x\n", auth_methods);
}
else
{
EXLOGW("[ssh] can not get allowed auth method, try each method we can.\n");
}
if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) {
int retry_count = 0;
if (!(((auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) || ((auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD)))
{
_this->_session_error(TP_SESS_STAT_ERR_AUTH_TYPE);
return SSH_AUTH_ERROR;
}
int retry_count = 0;
if (_this->m_ssh_ver == 1) {
// first try password for SSHv1
rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str());
for (;;) {
if (rc == SSH_AUTH_AGAIN) {
retry_count += 1;
if (retry_count >= 3)
break;
ex_sleep_ms(100);
rc = ssh_userauth_password(_this->m_srv_session, _this->m_acc_name.c_str(), _this->m_acc_secret.c_str());
continue;
}
if (rc == SSH_AUTH_SUCCESS) {
EXLOGW("[ssh] logon with password mode.\n");
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else {
EXLOGW("[ssh] failed to login with password mode, got %d.\n", rc);
}
}
}
// first try interactive login mode if server allow.
if ((auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE)
{
retry_count = 0;
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
for (;;) {
if (rc == SSH_AUTH_AGAIN) {
retry_count += 1;
if (retry_count >= 5)
break;
ex_sleep_ms(500);
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
continue;
}
// first try interactive login mode for SSHv2.
retry_count = 0;
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
for (;;) {
if (rc == SSH_AUTH_AGAIN) {
retry_count += 1;
if (retry_count >= 5)
break;
ex_sleep_ms(500);
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
continue;
}
if (rc != SSH_AUTH_INFO)
break;
if (rc != SSH_AUTH_INFO)
break;
int nprompts = ssh_userauth_kbdint_getnprompts(_this->m_srv_session);
if (0 == nprompts) {
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
continue;
}
int nprompts = ssh_userauth_kbdint_getnprompts(_this->m_srv_session);
if (0 == nprompts) {
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
continue;
}
for (int iprompt = 0; iprompt < nprompts; ++iprompt) {
char echo = 0;
const char* prompt = ssh_userauth_kbdint_getprompt(_this->m_srv_session, iprompt, &echo);
EXLOGV("[ssh] interactive login prompt: %s\n", prompt);
for (int iprompt = 0; iprompt < nprompts; ++iprompt) {
char echo = 0;
const char* prompt = ssh_userauth_kbdint_getprompt(_this->m_srv_session, iprompt, &echo);
EXLOGV("[ssh] interactive login prompt: %s\n", prompt);
rc = ssh_userauth_kbdint_setanswer(_this->m_srv_session, iprompt, _this->m_acc_secret.c_str());
if (rc < 0) {
EXLOGE("[ssh] invalid password for interactive mode to login to real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR;
}
}
rc = ssh_userauth_kbdint_setanswer(_this->m_srv_session, iprompt, _this->m_acc_secret.c_str());
if (rc < 0) {
EXLOGE("[ssh] invalid password for interactive mode to login to real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR;
}
}
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
}
}
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
}
if (rc == SSH_AUTH_SUCCESS) {
EXLOGW("[ssh] logon with keyboard interactive mode.\n");
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else {
EXLOGW("[ssh] failed to login with keyboard interactive mode, got %d, try password mode.\n", rc);
}
if (_this->m_ssh_ver != 1) {
// then try password mode if interactive mode does not supported by host with SSHv2.
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) {
EXLOGW("[ssh] logon with password mode.\n");
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else {
EXLOGW("[ssh] failed to login with password mode, got %d.\n", rc);
}
}
// and then try password login mode if server allow.
if ((auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD)
{
retry_count = 0;
rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_acc_secret.c_str());
for (;;) {
if (rc == SSH_AUTH_AGAIN) {
retry_count += 1;
if (retry_count >= 3)
break;
ex_sleep_ms(100);
rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_acc_secret.c_str());
continue;
}
if (rc == SSH_AUTH_SUCCESS) {
EXLOGW("[ssh] logon with password mode.\n");
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else {
EXLOGE("[ssh] failed to login with password mode, got %d.\n", rc);
break;
}
}
}
EXLOGE("[ssh] can not use password mode or interactive mode to login to real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
@ -599,7 +602,13 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
return SSH_AUTH_ERROR;
}
else if (_this->m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) {
ssh_key key = NULL;
if ((auth_methods & SSH_AUTH_METHOD_PUBLICKEY) != SSH_AUTH_METHOD_PUBLICKEY) {
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_TYPE);
return SSH_AUTH_ERROR;
}
ssh_key key = NULL;
if (SSH_OK != ssh_pki_import_privkey_base64(_this->m_acc_secret.c_str(), NULL, NULL, NULL, &key)) {
EXLOGE("[ssh] can not import private-key for auth.\n");
_this->m_have_error = true;
@ -615,12 +624,11 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_is_logon = true;
return SSH_AUTH_SUCCESS;
}
else {
EXLOGE("[ssh] failed to use private-key to login to real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR;
}
EXLOGE("[ssh] failed to use private-key to login to real SSH server %s:%d.\n", _this->m_conn_ip.c_str(), _this->m_conn_port);
_this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR;
}
else if (_this->m_auth_type == TP_AUTH_TYPE_NONE) {
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
@ -736,6 +744,11 @@ int SshSession::_on_client_shell_request(ssh_session session, ssh_channel channe
SshSession *_this = (SshSession *)userdata;
EXLOGD("[ssh] client request shell\n");
if ((_this->m_flags & TP_FLAG_SSH_SHELL) != TP_FLAG_SSH_SHELL)
{
EXLOGE("[ssh] ssh-shell disabled by ops-policy.\n");
return SSH_ERROR;
}
TP_SSH_CHANNEL_PAIR* cp = _this->_get_channel_pair(TP_SSH_CLIENT_SIDE, channel);
if (NULL == cp) {
@ -761,7 +774,7 @@ int SshSession::_on_client_shell_request(ssh_session session, ssh_channel channe
}
void SshSession::_on_client_channel_close(ssh_session session, ssh_channel channel, void *userdata) {
EXLOGV("---client channel closed.\n");
EXLOGV("[ssh] ---client channel closed.\n");
SshSession *_this = (SshSession *)userdata;
TP_SSH_CHANNEL_PAIR* cp = _this->_get_channel_pair(TP_SSH_CLIENT_SIDE, channel);
@ -896,6 +909,13 @@ int SshSession::_on_client_channel_subsystem_request(ssh_session session, ssh_ch
return SSH_ERROR;
}
if ((_this->m_flags & TP_FLAG_SSH_SFTP) != TP_FLAG_SSH_SFTP)
{
EXLOGE("[ssh] ssh-sftp disabled by ops-policy.\n");
return SSH_ERROR;
}
cp->type = TS_SSH_CHANNEL_TYPE_SFTP;
g_ssh_env.session_update(cp->db_id, TP_PROTOCOL_TYPE_SSH_SFTP, TP_SESS_STAT_STARTED);
@ -1099,7 +1119,7 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
}
void SshSession::_on_server_channel_close(ssh_session session, ssh_channel channel, void *userdata) {
EXLOGV("---server channel closed.\n");
EXLOGV("[ssh] ---server channel closed.\n");
SshSession *_this = (SshSession *)userdata;
TP_SSH_CHANNEL_PAIR* cp = _this->_get_channel_pair(TP_SSH_SERVER_SIDE, channel);
if (NULL == cp) {

View File

@ -132,6 +132,7 @@ private:
ex_u16 m_conn_port;
ex_astr m_acc_name;
ex_astr m_acc_secret;
ex_u32 m_flags;
int m_auth_type;
bool m_is_logon;

View File

@ -109,6 +109,7 @@
<ClInclude Include="..\..\..\..\common\libex\include\ex\ex_types.h" />
<ClInclude Include="..\..\..\..\common\libex\include\ex\ex_util.h" />
<ClInclude Include="..\..\..\..\common\libex\include\ex\ex_winsrv.h" />
<ClInclude Include="..\..\..\..\common\teleport\teleport_const.h" />
<ClInclude Include="..\..\..\..\external\jsoncpp\include\json\json.h" />
<ClInclude Include="..\..\..\..\external\libssh-win-static\include\libssh\callbacks.h" />
<ClInclude Include="..\..\..\..\external\libssh-win-static\include\libssh\libssh.h" />

View File

@ -113,6 +113,9 @@
<ClInclude Include="..\..\..\..\external\jsoncpp\include\json\json.h">
<Filter>jsoncpp</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\common\teleport\teleport_const.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="tpssh.cpp">

View File

@ -859,7 +859,6 @@ $app.create_dlg_edit_host = function () {
cid: dlg.field_cid,
desc: dlg.field_desc
};
console.log(args);
// 如果id为-1表示创建否则表示更新
$tp.ajax_post_json('/asset/update-host', args,
@ -1148,7 +1147,6 @@ $app.create_dlg_accounts = function () {
$tp.ajax_post_json('/asset/get-accounts', {host_id: dlg.host.id},
function (ret) {
if (ret.code === TPE_OK) {
console.log('account:', ret.data);
$app.table_acc.set_data(cb_stack, {}, {total: ret.data.length, page_index: 1, data: ret.data});
} else {
$app.table_acc.set_data(cb_stack, {}, {total: 0, page_index: 1, data: {}});
@ -1519,6 +1517,10 @@ $app.create_dlg_edit_account = function () {
}
dlg.dom.auth_type.empty().append($(html.join('')));
if(!_.isNull(dlg.account))
dlg.dom.auth_type.val(dlg.account.auth_type);
dlg.on_auth_change();
};

View File

@ -328,6 +328,9 @@ $app.on_table_host_render_created = function (render) {
case TP_SESS_STAT_ERR_SESSION:
msg = '无效会话';
break;
case TP_SESS_STAT_ERR_AUTH_TYPE:
msg = '无效认证方式';
break;
default:
msg = '未知状态 [' + fields.state + ']';
}

View File

@ -49,6 +49,7 @@ var TP_SESS_STAT_ERR_BAD_PKG = 6; // 会话结束,因为收到错误的报文
var TP_SESS_STAT_ERR_RESET = 7; // 会话结束因为teleport核心服务重置了
var TP_SESS_STAT_ERR_IO = 8; // 会话结束,因为网络中断
var TP_SESS_STAT_ERR_SESSION = 9; // 会话结束因为无效的会话ID
var TP_SESS_STAT_ERR_AUTH_TYPE = 10; // // 会话结束,因为服务端不支持此认证方式
var TP_SESS_STAT_STARTED = 100; // 已经连接成功了,开始记录录像了
var TP_SESS_STAT_ERR_START_INTERNAL = 104; // 会话结束,因为内部错误
var TP_SESS_STAT_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文

View File

@ -1,2 +1,2 @@
# -*- coding: utf8 -*-
TP_SERVER_VER = "3.0.3.12"
# -*- coding: utf8 -*-
TP_SERVER_VER = "3.0.4.16"

View File

@ -13,7 +13,7 @@ Revision 修订号。主版本号和次版本号都相同但修订号不同
Build 构建号。构建号用于表明此版本发布之前进行了多少次构建及测试。某些情况下此版本号可以省略。
TP_SERVER 3.0.3.12 # 整个服务端打包的版本
TP_TPCORE 3.0.3.12 # 核心服务 tp_core 的版本
TP_SERVER 3.0.4.16 # 整个服务端打包的版本
TP_TPCORE 3.0.4.16 # 核心服务 tp_core 的版本
TP_TPWEB 3.0.0.1 # web服务 tp_web 的版本一般除非升级Python否则不会变化
TP_ASSIST 3.0.1.6 # 助手版本