修复ssh远程连接后执行 rz 命令无法工作的问题。

pull/130/head
Apex Liu 2018-11-04 08:58:30 +08:00
parent b1524fd6a0
commit 46cd77420d
17 changed files with 1336 additions and 1388 deletions

19
.gitignore vendored
View File

@ -12,7 +12,6 @@
# for CMake # for CMake
CMakeFiles CMakeFiles
cmake_install.cmake cmake_install.cmake
Makefile
cmake-build cmake-build
cmake-build-debug cmake-build-debug
client/tp_assist_macos/build client/tp_assist_macos/build
@ -23,15 +22,15 @@ __pycache__
*.pyc *.pyc
# for pyCharm # for JetBrains IDEs.
**/.idea/workspace.xml **/.idea/workspace.xml
**/.idea/watcherTasks.xml
**/.idea/dictionaries
**/.idea/vcs.xml
**/.idea/misc.xml **/.idea/misc.xml
**/.idea/modules.xml **/.idea/modules.xml
**/.idea/dictionaries
**/.idea/watcherTasks.xml
**/.idea/inspectionProfiles
**/.idea/vcs.xml
**/.idea/codeStyles **/.idea/codeStyles
**/.idea/inspectionProfiles
*.css.map *.css.map
@ -45,15 +44,11 @@ __pycache__
/external/openssl /external/openssl
/external/python /external/python
/external/libssh /external/libssh
/external/libssh-win-static/include/libssh
/external/libssh-win-static/src
/external/libssh-win-static/lib
/external/mbedtls /external/mbedtls
/external/sqlite /external/sqlite
/external/libuv /external/libuv
/client/tools/putty /client/tools/putty
/client/tools/winscp /client/tools/winscp
/client/tp_assist_macos/DerivedData
# for dist folder # for dist folder
**/_tmp_ **/_tmp_
@ -72,6 +67,7 @@ __pycache__
# for generated files. # for generated files.
/config.ini /config.ini
/build.bat /build.bat
/build.sh
# for not finished code # for not finished code
/common/libex/test /common/libex/test
@ -85,7 +81,7 @@ __pycache__
# for MacOS. # for MacOS.
.DS_Store .DS_Store
# Xcode # for Xcode
build/* build/*
*.pbxuser *.pbxuser
!default.pbxuser !default.pbxuser
@ -101,4 +97,3 @@ xcuserdata
profile profile
*.moved-aside *.moved-aside
/server/share/tmp /server/share/tmp
/build.sh

51
.idea/encodings.xml Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/common/libex/include/ex/ex_log.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/include/ex/ex_path.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/include/ex/ex_thread.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/include/ex/ex_util.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/src/ex_ini.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/src/ex_log.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/src/ex_util.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/include/pys.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/src/pys_api.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/src/pys_core.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/teleport/teleport_const.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/base_env.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/base_record.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/base_record.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/protocol_interface.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/ts_const.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/ts_membuf.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/ts_membuf.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/ts_memstream.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_env.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_http_rpc.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_http_rpc.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_web_rpc.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/core/ts_web_rpc.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/rdp/rdp_conn.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/rdp/rdp_conn.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/rdp/rdp_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/rdp/rdp_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/rdp/rdp_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_proxy.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_recorder.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_recorder.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/ssh/ssh_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_web/src/main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_web/src/ts_env.cpp" charset="GBK" />
</component>
</project>

2
.idea/teleport.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

37
CMakeLists.txt Normal file
View File

@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.5)
project(teleport)
MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}")
MESSAGE(STATUS "current source directory is ${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/out/server/x64/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/out/server/x64/bin")
set(CMAKE_CONFIGURATION_TYPES Debug Release)
# Determine the platform.
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
MESSAGE(STATUS "build on macOS...")
set(OS_MACOS 1)
set(OS_POSIX 1)
set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/macos/release")
elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(OS_LINUX 1)
set(OS_POSIX 1)
MESSAGE(STATUS "build on Linux...")
add_subdirectory(server/tp_web/src)
set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/linux/release")
elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
# MESSAGE(FATAL_ERROR "unsupported platform: Windows")
else ()
MESSAGE(FATAL_ERROR "unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif ()
add_subdirectory(server/tp_core/core)
add_subdirectory(server/tp_core/protocol/ssh)
add_subdirectory(server/tp_core/protocol/telnet)
#add_subdirectory(server/testssh/testssh)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/server/tp_core/protocol/rdp")
add_subdirectory(server/tp_core/protocol/rdp)
endif ()

View File

@ -20,9 +20,8 @@ void *ExThreadBase::_thread_func(void *pParam)
_this->m_is_running = false; _this->m_is_running = false;
_this->m_handle = 0; _this->m_handle = 0;
_this->_on_stopped();
EXLOGV(" # thread [%s] exit.\n", _this->m_thread_name.c_str()); EXLOGV(" # thread [%s] exit.\n", _this->m_thread_name.c_str());
_this->_on_stopped();
return 0; return 0;
} }
@ -49,7 +48,7 @@ bool ExThreadBase::start(void) {
{ {
return false; return false;
} }
m_listener_handle = h; m_handle = h;
#else #else
pthread_t ptid = 0; pthread_t ptid = 0;
int ret = pthread_create(&ptid, NULL, _thread_func, (void *) this); int ret = pthread_create(&ptid, NULL, _thread_func, (void *) this);
@ -76,7 +75,7 @@ bool ExThreadBase::stop(void) {
EXLOGV("[thread] wait thread [%s] exit.\n", m_thread_name.c_str()); EXLOGV("[thread] wait thread [%s] exit.\n", m_thread_name.c_str());
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
if (WaitForSingleObject(m_listener_handle, INFINITE) != WAIT_OBJECT_0) if (WaitForSingleObject(m_handle, INFINITE) != WAIT_OBJECT_0)
{ {
return false; return false;
} }
@ -91,7 +90,7 @@ bool ExThreadBase::stop(void) {
bool ExThreadBase::terminate(void) { bool ExThreadBase::terminate(void) {
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
return (TerminateThread(m_listener_handle, 1) == TRUE); return (TerminateThread(m_handle, 1) == TRUE);
#else #else
return (pthread_cancel(m_handle) == 0); return (pthread_cancel(m_handle) == 0);
#endif #endif

View File

@ -1 +0,0 @@
teleport

View File

@ -1,29 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/../common/libex/include/ex/ex_log.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/include/ex/ex_path.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/include/ex/ex_thread.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/include/ex/ex_util.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/src/ex_ini.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/src/ex_log.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/libex/src/ex_util.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/pyshell/include/pys.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/pyshell/src/pys_api.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/pyshell/src/pys_core.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/../common/teleport/teleport_const.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/base_env.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/base_record.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/base_record.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/protocol_interface.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/ts_const.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/ts_membuf.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/ts_membuf.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/common/ts_memstream.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_env.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_http_rpc.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_http_rpc.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_web_rpc.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/core/ts_web_rpc.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/rdp/rdp_conn.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/rdp/rdp_conn.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/rdp/rdp_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/rdp/rdp_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/rdp/rdp_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_proxy.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_recorder.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_recorder.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/ssh/ssh_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/telnet/telnet_conn.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/telnet/telnet_conn.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/telnet/telnet_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_core/protocol/telnet/telnet_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_web/src/main.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/tp_web/src/ts_env.cpp" charset="GBK" />
</component>
</project>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

View File

@ -1,38 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(teleport)
MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}")
MESSAGE(STATUS "current source directory is ${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../out/server/x64/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../out/server/x64/bin")
set(CMAKE_CONFIGURATION_TYPES Debug Release)
# Determine the platform.
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
MESSAGE(STATUS "build on macOS...")
set(OS_MACOS 1)
set(OS_POSIX 1)
set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/macos/release")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(OS_LINUX 1)
set(OS_POSIX 1)
MESSAGE(STATUS "build on Linux...")
add_subdirectory(tp_web/src)
set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/linux/release")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
MESSAGE(FATAL_ERROR "unsupported platform: Windows")
else()
MESSAGE(FATAL_ERROR "unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
add_subdirectory(tp_core/core)
add_subdirectory(tp_core/protocol/ssh)
add_subdirectory(tp_core/protocol/telnet)
#add_subdirectory(testssh/testssh)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tp_core/protocol/rdp")
add_subdirectory(tp_core/protocol/rdp)
endif()

View File

@ -68,17 +68,46 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data)
} }
} }
static struct mg_mgr g_mg_mgr; //static struct mg_mgr g_mg_mgr;
static bool is_mg_mgr_initialized = false; //static bool is_mg_mgr_initialized = false;
class MongooseManager {
public:
MongooseManager() {
mg_mgr_free(&m_mg_mgr);
m_initialized = false;
}
~MongooseManager() {
if (m_initialized) {
mg_mgr_free(&m_mg_mgr);
m_initialized = false;
}
}
struct mg_mgr* get_mg_mgr() {
if (!m_initialized) {
mg_mgr_init(&m_mg_mgr, NULL);
m_initialized = true;
}
return &m_mg_mgr;
}
private:
bool m_initialized;
struct mg_mgr m_mg_mgr;
};
static MongooseManager g_mg_mgr;
bool ts_http_get(const ex_astr& url, ex_astr& body) bool ts_http_get(const ex_astr& url, ex_astr& body)
{ {
if(!is_mg_mgr_initialized) { // if(!is_mg_mgr_initialized) {
mg_mgr_init(&g_mg_mgr, NULL); // mg_mgr_init(&g_mg_mgr, NULL);
is_mg_mgr_initialized = true; // is_mg_mgr_initialized = true;
} // }
mg_connection* nc = mg_connect_http(&g_mg_mgr, ev_handler, url.c_str(), NULL, NULL); mg_connection* nc = mg_connect_http(g_mg_mgr.get_mg_mgr(), ev_handler, url.c_str(), NULL, NULL);
if (NULL == nc) if (NULL == nc)
return false; return false;
@ -92,7 +121,7 @@ bool ts_http_get(const ex_astr& url, ex_astr& body)
// int count = 0; // int count = 0;
while (!hdata.exit_flag) while (!hdata.exit_flag)
{ {
mg_mgr_poll(&g_mg_mgr, 100); mg_mgr_poll(g_mg_mgr.get_mg_mgr(), 100);
// count++; // count++;
// if (count > 2) // if (count > 2)
// break; // break;

View File

@ -5,40 +5,34 @@ SshProxy g_ssh_proxy;
SshProxy::SshProxy() : SshProxy::SshProxy() :
ExThreadBase("ssh-proxy-thread"), ExThreadBase("ssh-proxy-thread"),
m_bind(NULL) m_bind(NULL) {
{
m_timer_counter = 0; m_timer_counter = 0;
m_noop_timeout_sec = 900; // default to 15 minutes. m_noop_timeout_sec = 900; // default to 15 minutes.
} }
SshProxy::~SshProxy() SshProxy::~SshProxy() {
{
if (NULL != m_bind) if (NULL != m_bind)
ssh_bind_free(m_bind); ssh_bind_free(m_bind);
ssh_finalize(); ssh_finalize();
} }
bool SshProxy::init() bool SshProxy::init() {
{
m_host_ip = g_ssh_env.bind_ip; m_host_ip = g_ssh_env.bind_ip;
m_host_port = g_ssh_env.bind_port; m_host_port = g_ssh_env.bind_port;
m_bind = ssh_bind_new(); m_bind = ssh_bind_new();
if (NULL == m_bind) if (NULL == m_bind) {
{
EXLOGE("[ssh] can not create bind.\n"); EXLOGE("[ssh] can not create bind.\n");
return false; return false;
} }
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDADDR, m_host_ip.c_str())) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDADDR, m_host_ip.c_str())) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDADDR.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDADDR.\n");
return false; return false;
} }
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDPORT, &m_host_port)) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDPORT, &m_host_port)) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDPORT.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDPORT.\n");
return false; return false;
} }
@ -49,14 +43,12 @@ bool SshProxy::init()
ex_wstr2astr(_key_file, key_file); ex_wstr2astr(_key_file, key_file);
EXLOGV("[ssh] try to load ssh-server-key: %s\n", key_file.c_str()); EXLOGV("[ssh] try to load ssh-server-key: %s\n", key_file.c_str());
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_RSAKEY, key_file.c_str())) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_RSAKEY, key_file.c_str())) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n");
return false; return false;
} }
if (ssh_bind_listen(m_bind) < 0) if (ssh_bind_listen(m_bind) < 0) {
{
EXLOGE("[ssh] listening to socket: %s\n", ssh_get_error(m_bind)); EXLOGE("[ssh] listening to socket: %s\n", ssh_get_error(m_bind));
return false; return false;
} }
@ -101,12 +93,10 @@ void SshProxy::kill_sessions(const ex_astrs& sessions) {
} }
void SshProxy::_thread_loop() void SshProxy::_thread_loop() {
{
EXLOGI("[ssh] TeleportServer-SSH ready on %s:%d\n", m_host_ip.c_str(), m_host_port); EXLOGI("[ssh] TeleportServer-SSH ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
for (;;) for (;;) {
{
// 注意ssh_new()出来的指针如果遇到停止标志本函数内部就释放了否则这个指针交给了SshSession类实例管理其析构时会释放。 // 注意ssh_new()出来的指针如果遇到停止标志本函数内部就释放了否则这个指针交给了SshSession类实例管理其析构时会释放。
ssh_session sess_to_client = ssh_new(); ssh_session sess_to_client = ssh_new();
// int verbosity = 4; // int verbosity = 4;
@ -118,15 +108,13 @@ void SshProxy::_thread_loop()
char ip[32] = {0}; char ip[32] = {0};
int len = sizeof(ip); int len = sizeof(ip);
if (ssh_bind_accept(m_bind, sess_to_client) != SSH_OK) if (ssh_bind_accept(m_bind, sess_to_client) != SSH_OK) {
{
EXLOGE("[ssh] accepting a connection failed: %s.\n", ssh_get_error(m_bind)); EXLOGE("[ssh] accepting a connection failed: %s.\n", ssh_get_error(m_bind));
continue; continue;
} }
EXLOGD("[ssh] ssh_bind_accept() returned...\n"); EXLOGD("[ssh] ssh_bind_accept() returned...\n");
if (m_stop_flag) if (m_need_stop) {
{
ssh_free(sess_to_client); ssh_free(sess_to_client);
break; break;
} }
@ -140,8 +128,7 @@ void SshProxy::_thread_loop()
#endif #endif
sockaddr_in *addrin = (sockaddr_in *) &sock_client; sockaddr_in *addrin = (sockaddr_in *) &sock_client;
if (0 == ex_ip4_name(addrin, ip, sizeof(ip))) if (0 == ex_ip4_name(addrin, ip, sizeof(ip))) {
{
sess->client_ip(ip); sess->client_ip(ip);
sess->client_port(addrin->sin_port); sess->client_port(addrin->sin_port);
} }
@ -159,17 +146,33 @@ void SshProxy::_thread_loop()
} }
// 等待所有工作线程退出 // 等待所有工作线程退出
m_thread_mgr.stop_all(); //m_thread_mgr.stop_all();
{
ExThreadSmartLock locker(m_lock);
ts_ssh_sessions::iterator it = m_sessions.begin();
for (; it != m_sessions.end(); ++it) {
it->first->check_noop_timeout(0, 0); // Á¢¼´½áÊø
}
}
for(;;)
{
{
ExThreadSmartLock locker(m_lock);
if (m_sessions.empty())
break;
ex_sleep_ms(100);
}
}
EXLOGV("[ssh] main-loop end.\n"); EXLOGV("[ssh] main-loop end.\n");
} }
void SshProxy::_set_stop_flag() void SshProxy::_on_stop() {
{ ExThreadBase::_on_stop();
m_stop_flag = true;
if (m_is_running) if (m_is_running) {
{
// 用一个变通的方式来结束阻塞中的监听,就是连接一下它。 // 用一个变通的方式来结束阻塞中的监听,就是连接一下它。
ex_astr host_ip = m_host_ip; ex_astr host_ip = m_host_ip;
if (host_ip == "0.0.0.0") if (host_ip == "0.0.0.0")
@ -185,22 +188,18 @@ void SshProxy::_set_stop_flag()
ssh_free(_session); ssh_free(_session);
} }
m_thread_mgr.stop_all(); // m_thread_mgr.stop_all();
} }
void SshProxy::session_finished(SshSession* sess) void SshProxy::session_finished(SshSession *sess) {
{
// TODO: 向核心模块汇报此会话终止,以减少对应连接信息的引用计数 // TODO: 向核心模块汇报此会话终止,以减少对应连接信息的引用计数
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
ts_ssh_sessions::iterator it = m_sessions.find(sess); ts_ssh_sessions::iterator it = m_sessions.find(sess);
if (it != m_sessions.end()) if (it != m_sessions.end()) {
{
m_sessions.erase(it); m_sessions.erase(it);
EXLOGV("[ssh] client %s:%d session removed.\n", sess->client_ip(), sess->client_port()); EXLOGV("[ssh] client %s:%d session removed.\n", sess->client_ip(), sess->client_port());
} } else {
else
{
EXLOGW("[ssh] when session %s:%d end, it not in charge.\n", sess->client_ip(), sess->client_port()); EXLOGW("[ssh] when session %s:%d end, it not in charge.\n", sess->client_ip(), sess->client_port());
} }

View File

@ -22,7 +22,7 @@ public:
protected: protected:
void _thread_loop(); void _thread_loop();
void _set_stop_flag(); void _on_stop();
private: private:
ssh_bind m_bind; ssh_bind m_bind;
@ -35,7 +35,7 @@ private:
ts_ssh_sessions m_sessions; ts_ssh_sessions m_sessions;
ExThreadManager m_thread_mgr; // ExThreadManager m_thread_mgr;
// //
ex_u32 m_noop_timeout_sec; ex_u32 m_noop_timeout_sec;

View File

@ -32,8 +32,7 @@ SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
m_proxy(proxy), m_proxy(proxy),
m_cli_session(sess_client), m_cli_session(sess_client),
m_srv_session(NULL), m_srv_session(NULL),
m_conn_info(NULL) m_conn_info(NULL) {
{
m_auth_type = TP_AUTH_TYPE_PASSWORD; m_auth_type = TP_AUTH_TYPE_PASSWORD;
m_ssh_ver = 2; // default to SSHv2 m_ssh_ver = 2; // default to SSHv2
@ -61,7 +60,7 @@ SshSession::SshSession(SshProxy *proxy, ssh_session sess_client) :
SshSession::~SshSession() { SshSession::~SshSession() {
_set_stop_flag(); //_on_stop();
if (NULL != m_conn_info) { if (NULL != m_conn_info) {
g_ssh_env.free_connect_info(m_conn_info); g_ssh_env.free_connect_info(m_conn_info);
@ -72,10 +71,11 @@ SshSession::~SshSession() {
void SshSession::_thread_loop(void) { void SshSession::_thread_loop(void) {
_run(); _run();
m_proxy->session_finished(this);
} }
void SshSession::_set_stop_flag(void) { void SshSession::_on_stop(void) {
ExThreadBase::_on_stop();
_close_channels(); _close_channels();
if (NULL != m_cli_session) { if (NULL != m_cli_session) {
@ -90,10 +90,13 @@ void SshSession::_set_stop_flag(void) {
} }
} }
void SshSession::_on_stopped() {
m_proxy->session_finished(this);
}
void SshSession::_session_error(int err_code) { void SshSession::_session_error(int err_code) {
int db_id = 0; int db_id = 0;
if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0) if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0) {
{
EXLOGE("[ssh] can not write session error to database.\n"); EXLOGE("[ssh] can not write session error to database.\n");
return; return;
} }
@ -101,13 +104,11 @@ void SshSession::_session_error(int err_code) {
g_ssh_env.session_end(m_sid.c_str(), db_id, err_code); g_ssh_env.session_end(m_sid.c_str(), db_id, err_code);
} }
bool SshSession::_record_begin(TP_SSH_CHANNEL_PAIR* cp) bool SshSession::_record_begin(TP_SSH_CHANNEL_PAIR *cp) {
{
if (!g_ssh_env.session_begin(m_conn_info, &(cp->db_id))) { if (!g_ssh_env.session_begin(m_conn_info, &(cp->db_id))) {
EXLOGE("[ssh] can not save to database, channel begin failed.\n"); EXLOGE("[ssh] can not save to database, channel begin failed.\n");
return false; return false;
} } else {
else {
cp->channel_id = cp->db_id; cp->channel_id = cp->db_id;
//EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id); //EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id);
} }
@ -124,10 +125,8 @@ bool SshSession::_record_begin(TP_SSH_CHANNEL_PAIR* cp)
return true; return true;
} }
void SshSession::_record_end(TP_SSH_CHANNEL_PAIR* cp) void SshSession::_record_end(TP_SSH_CHANNEL_PAIR *cp) {
{ if (cp->db_id > 0) {
if (cp->db_id > 0)
{
//EXLOGD("[ssh] [channel:%d] channel end with code: %d\n", cp->channel_id, cp->state); //EXLOGD("[ssh] [channel:%d] channel end with code: %d\n", cp->channel_id, cp->state);
// 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值 // 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值
@ -137,8 +136,7 @@ void SshSession::_record_end(TP_SSH_CHANNEL_PAIR* cp)
g_ssh_env.session_end(m_sid.c_str(), cp->db_id, cp->state); g_ssh_env.session_end(m_sid.c_str(), cp->db_id, cp->state);
cp->db_id = 0; cp->db_id = 0;
} } else {
else {
//EXLOGD("[ssh] [channel:%d] when channel end, no db-id.\n", cp->channel_id); //EXLOGD("[ssh] [channel:%d] when channel end, no db-id.\n", cp->channel_id);
} }
} }
@ -304,12 +302,9 @@ void SshSession::_run(void) {
//err = ssh_event_dopoll(event_loop, 5000); //err = ssh_event_dopoll(event_loop, 5000);
err = ssh_event_dopoll(event_loop, 1000); err = ssh_event_dopoll(event_loop, 1000);
if (err == 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));
} } else if (0 != ssh_get_error_code(m_srv_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)); EXLOGE("[ssh] ssh_event_dopoll() [srv] %s\n", ssh_get_error(m_srv_session));
} }
@ -328,9 +323,9 @@ void SshSession::_run(void) {
// timeout. // timeout.
_check_channels(); _check_channels();
} }
} while (m_channels.size() > 0); } while (!m_channels.empty());
if (m_channels.size() == 0) if (m_channels.empty())
EXLOGV("[ssh] [%s:%d] all channel in this session are closed.\n", m_client_ip.c_str(), m_client_port); 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);
@ -341,8 +336,7 @@ void SshSession::_run(void) {
// 如果一边是走SSHv1另一边是SSHv2放在同一个event_loop时SSHv1会收不到数据放到循环中时SSHv2得不到数据 // 如果一边是走SSHv1另一边是SSHv2放在同一个event_loop时SSHv1会收不到数据放到循环中时SSHv2得不到数据
// 所以当SSHv1的远程主机连接后到建立好shell环境之后就进入另一种读取数据的循环不再使用ssh_event_dopoll()了。 // 所以当SSHv1的远程主机连接后到建立好shell环境之后就进入另一种读取数据的循环不再使用ssh_event_dopoll()了。
if (m_ssh_ver == 1) if (m_ssh_ver == 1) {
{
tp_channels::iterator it = m_channels.begin(); // SSHv1只能打开一个channel tp_channels::iterator it = m_channels.begin(); // SSHv1只能打开一个channel
ssh_channel cli = (*it)->cli_channel; ssh_channel cli = (*it)->cli_channel;
ssh_channel srv = (*it)->srv_channel; ssh_channel srv = (*it)->srv_channel;
@ -434,8 +428,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_have_error = true; _this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_SESSION); _this->_session_error(TP_SESS_STAT_ERR_SESSION);
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} } else {
else {
_this->m_conn_ip = _this->m_conn_info->conn_ip; _this->m_conn_ip = _this->m_conn_info->conn_ip;
_this->m_conn_port = _this->m_conn_info->conn_port; _this->m_conn_port = _this->m_conn_info->conn_port;
_this->m_auth_type = _this->m_conn_info->auth_type; _this->m_auth_type = _this->m_conn_info->auth_type;
@ -508,19 +501,15 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
#endif #endif
int auth_methods = SSH_AUTH_METHOD_INTERACTIVE | SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY; 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)) if (SSH_AUTH_ERROR != ssh_userauth_none(_this->m_srv_session, NULL)) {
{
auth_methods = ssh_userauth_list(_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); EXLOGV("[ssh] allowed auth method: 0x%08x\n", auth_methods);
} } else {
else
{
EXLOGW("[ssh] can not get allowed auth method, try each method we can.\n"); EXLOGW("[ssh] can not get allowed auth method, try each method we can.\n");
} }
if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) { if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) {
if (!(((auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) || ((auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD))) 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); _this->_session_error(TP_SESS_STAT_ERR_AUTH_TYPE);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
@ -529,8 +518,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
int retry_count = 0; int retry_count = 0;
// first try interactive login mode if server allow. // first try interactive login mode if server allow.
if ((auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) if ((auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) {
{
retry_count = 0; retry_count = 0;
rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL); rc = ssh_userauth_kbdint(_this->m_srv_session, NULL, NULL);
for (;;) { for (;;) {
@ -571,8 +559,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
} }
// and then try password login mode if server allow. // and then try password login mode if server allow.
if ((auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD) if ((auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD) {
{
retry_count = 0; retry_count = 0;
rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_acc_secret.c_str()); rc = ssh_userauth_password(_this->m_srv_session, NULL, _this->m_acc_secret.c_str());
for (;;) { for (;;) {
@ -588,8 +575,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
EXLOGW("[ssh] logon with password mode.\n"); EXLOGW("[ssh] logon with password mode.\n");
_this->m_is_logon = true; _this->m_is_logon = true;
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
} } else {
else {
EXLOGE("[ssh] failed to login with password mode, got %d.\n", rc); EXLOGE("[ssh] failed to login with password mode, got %d.\n", rc);
break; break;
} }
@ -600,8 +586,7 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_have_error = true; _this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED); _this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} } else if (_this->m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) {
else if (_this->m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) {
if ((auth_methods & SSH_AUTH_METHOD_PUBLICKEY) != SSH_AUTH_METHOD_PUBLICKEY) { if ((auth_methods & SSH_AUTH_METHOD_PUBLICKEY) != SSH_AUTH_METHOD_PUBLICKEY) {
_this->m_have_error = true; _this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_TYPE); _this->_session_error(TP_SESS_STAT_ERR_AUTH_TYPE);
@ -629,12 +614,10 @@ int SshSession::_on_auth_password_request(ssh_session session, const char *user,
_this->m_have_error = true; _this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED); _this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} } else if (_this->m_auth_type == TP_AUTH_TYPE_NONE) {
else if (_this->m_auth_type == TP_AUTH_TYPE_NONE) {
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED); _this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} } else {
else {
EXLOGE("[ssh] invalid auth mode.\n"); EXLOGE("[ssh] invalid auth mode.\n");
_this->m_have_error = true; _this->m_have_error = true;
_this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED); _this->_session_error(TP_SESS_STAT_ERR_AUTH_DENIED);
@ -709,8 +692,7 @@ TP_SSH_CHANNEL_PAIR* SshSession::_get_channel_pair(int channel_side, ssh_channel
if (channel_side == TP_SSH_CLIENT_SIDE) { if (channel_side == TP_SSH_CLIENT_SIDE) {
if ((*it)->cli_channel == channel) if ((*it)->cli_channel == channel)
return (*it); return (*it);
} } else {
else {
if ((*it)->srv_channel == channel) if ((*it)->srv_channel == channel)
return (*it); return (*it);
} }
@ -744,8 +726,7 @@ int SshSession::_on_client_shell_request(ssh_session session, ssh_channel channe
SshSession *_this = (SshSession *) userdata; SshSession *_this = (SshSession *) userdata;
EXLOGD("[ssh] client request shell\n"); EXLOGD("[ssh] client request shell\n");
if ((_this->m_flags & TP_FLAG_SSH_SHELL) != TP_FLAG_SSH_SHELL) if ((_this->m_flags & TP_FLAG_SSH_SHELL) != TP_FLAG_SSH_SHELL) {
{
EXLOGE("[ssh] ssh-shell disabled by ops-policy.\n"); EXLOGE("[ssh] ssh-shell disabled by ops-policy.\n");
return SSH_ERROR; return SSH_ERROR;
} }
@ -790,8 +771,7 @@ void SshSession::_on_client_channel_close(ssh_session session, ssh_channel chann
if (cp->srv_channel == NULL) { if (cp->srv_channel == NULL) {
EXLOGW("[ssh] when client channel close, server-channel not exists.\n"); EXLOGW("[ssh] when client channel close, server-channel not exists.\n");
} } else {
else {
if (!ssh_channel_is_closed(cp->srv_channel)) { if (!ssh_channel_is_closed(cp->srv_channel)) {
// ssh_channel_close(cp->srv_channel); // ssh_channel_close(cp->srv_channel);
//cp->need_close = true; //cp->need_close = true;
@ -800,9 +780,9 @@ 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);
//EXLOGD(" ---> recv from client %d B\n", len);
SshSession *_this = (SshSession *) userdata; SshSession *_this = (SshSession *) userdata;
@ -829,22 +809,17 @@ int SshSession::_on_client_channel_data(ssh_session session, ssh_channel channel
return 0; return 0;
} }
// 如果用户复制粘贴多行文本,我们将其拆分为每一行发送一次数据包 // 不可以拆分!!否则执行 rz 命令会出错!
for (unsigned int i = 0; i < len; ++i) { // xxxx 如果用户复制粘贴多行文本,我们将其拆分为每一行发送一次数据包
if (((ex_u8*)data)[i] == 0x0d) { // for (unsigned int i = 0; i < len; ++i) {
_len = i + 1; // if (((ex_u8 *) data)[i] == 0x0d) {
break; // _len = i + 1;
} // break;
} // }
// }
_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);
} else {
// 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());
}
else {
_this->_process_sftp_command(cp, (ex_u8 *) data, _len); _this->_process_sftp_command(cp, (ex_u8 *) data, _len);
} }
@ -909,8 +884,7 @@ int SshSession::_on_client_channel_subsystem_request(ssh_session session, ssh_ch
return SSH_ERROR; return SSH_ERROR;
} }
if ((_this->m_flags & TP_FLAG_SSH_SFTP) != TP_FLAG_SSH_SFTP) if ((_this->m_flags & TP_FLAG_SSH_SFTP) != TP_FLAG_SSH_SFTP) {
{
EXLOGE("[ssh] ssh-sftp disabled by ops-policy.\n"); EXLOGE("[ssh] ssh-sftp disabled by ops-policy.\n");
return SSH_ERROR; return SSH_ERROR;
} }
@ -934,6 +908,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);
//EXLOGD(" <--- send to server %d B\n", len);
SshSession *_this = (SshSession *) userdata; SshSession *_this = (SshSession *) userdata;
@ -952,8 +927,7 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
_this->m_recving_from_srv = true; _this->m_recving_from_srv = true;
if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL && !is_stderr) if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL && !is_stderr) {
{
if (!cp->server_ready) { if (!cp->server_ready) {
if (len >= 2 && (((ex_u8 *) data)[len - 2] != 0x0d && ((ex_u8 *) data)[len - 1] != 0x0a)) { if (len >= 2 && (((ex_u8 *) data)[len - 2] != 0x0d && ((ex_u8 *) data)[len - 1] != 0x0a)) {
cp->server_ready = true; cp->server_ready = true;
@ -973,12 +947,10 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
// 收到第一包服务端返回的数据时,在输出数据之前显示一些自定义的信息 // 收到第一包服务端返回的数据时,在输出数据之前显示一些自定义的信息
#if 1 #if 1
if (!is_stderr && cp->is_first_server_data) if (!is_stderr && cp->is_first_server_data) {
{
cp->is_first_server_data = false; cp->is_first_server_data = false;
if (cp->type != TS_SSH_CHANNEL_TYPE_SFTP) if (cp->type != TS_SSH_CHANNEL_TYPE_SFTP) {
{
char buf[512] = {0}; char buf[512] = {0};
const char *auth_mode = NULL; const char *auth_mode = NULL;
@ -1109,8 +1081,7 @@ int SshSession::_on_server_channel_data(ssh_session session, ssh_channel channel
EXLOGE("[ssh] send data(%dB) to client failed. [%d][cli:%s][srv:%s]\n", len, ret, ssh_get_error(_this->m_cli_session), ssh_get_error(_this->m_srv_session)); EXLOGE("[ssh] send data(%dB) to client failed. [%d][cli:%s][srv:%s]\n", len, ret, ssh_get_error(_this->m_cli_session), ssh_get_error(_this->m_srv_session));
cp->need_close = true; cp->need_close = true;
_this->m_have_error = true; _this->m_have_error = true;
} } else if (ret != len) {
else if (ret != len) {
EXLOGW("[ssh] received server data, got %dB, processed %dB.\n", len, ret); EXLOGW("[ssh] received server data, got %dB, processed %dB.\n", len, ret);
} }
@ -1136,8 +1107,7 @@ void SshSession::_on_server_channel_close(ssh_session session, ssh_channel chann
// will the server-channel exist, the client-channel must exist too. // will the server-channel exist, the client-channel must exist too.
if (cp->cli_channel == NULL) { if (cp->cli_channel == NULL) {
EXLOGE("[ssh] when server channel close, client-channel not exists.\n"); EXLOGE("[ssh] when server channel close, client-channel not exists.\n");
} } else {
else {
if (!ssh_channel_is_closed(cp->cli_channel)) { if (!ssh_channel_is_closed(cp->cli_channel)) {
//ssh_channel_close(cp->cli_channel); //ssh_channel_close(cp->cli_channel);
//cp->need_close = true; //cp->need_close = true;
@ -1146,8 +1116,7 @@ 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) void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR *cp, int from, const ex_u8 *data, int len) {
{
if (len == 0) if (len == 0)
return; return;
@ -1173,8 +1142,7 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
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;
} } else if (TP_SSH_SERVER_SIDE == from) {
else if (TP_SSH_SERVER_SIDE == from) {
if (!cp->process_srv) if (!cp->process_srv)
return; return;
@ -1212,13 +1180,11 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
// 删除光标到行尾的字符串 // 删除光标到行尾的字符串
cp->cmd_char_list.erase(cp->cmd_char_pos, cp->cmd_char_list.end()); cp->cmd_char_list.erase(cp->cmd_char_pos, cp->cmd_char_list.end());
cp->cmd_char_pos = cp->cmd_char_list.end(); cp->cmd_char_pos = cp->cmd_char_list.end();
} } else if (1 == esc_arg) {
else if (1 == esc_arg) {
// 删除从开始到光标处的字符串 // 删除从开始到光标处的字符串
cp->cmd_char_list.erase(cp->cmd_char_list.begin(), cp->cmd_char_pos); cp->cmd_char_list.erase(cp->cmd_char_list.begin(), cp->cmd_char_pos);
cp->cmd_char_pos = cp->cmd_char_list.end(); cp->cmd_char_pos = cp->cmd_char_list.end();
} } else if (2 == esc_arg) {
else if (2 == esc_arg) {
// 删除整行 // 删除整行
cp->cmd_char_list.clear(); cp->cmd_char_list.clear();
cp->cmd_char_pos = cp->cmd_char_list.begin(); cp->cmd_char_pos = cp->cmd_char_list.begin();
@ -1293,10 +1259,8 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
cp->cmd_char_pos--; cp->cmd_char_pos--;
break; break;
} }
case 0x1b: case 0x1b: {
{ if (offset + 1 < len) {
if (offset + 1 < len)
{
if (data[offset + 1] == 0x5b || data[offset + 1] == 0x5d) { if (data[offset + 1] == 0x5b || data[offset + 1] == 0x5d) {
if (offset == 0 && cp->client_single_char) { if (offset == 0 && cp->client_single_char) {
cp->cmd_char_list.clear(); cp->cmd_char_list.clear();
@ -1318,14 +1282,12 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
break; break;
} }
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);
@ -1335,8 +1297,7 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
cp->cmd_char_pos = cp->cmd_char_list.begin(); cp->cmd_char_pos = cp->cmd_char_list.begin();
cp->maybe_cmd = false; cp->maybe_cmd = false;
} }
} } else {
else {
cp->cmd_char_list.clear(); cp->cmd_char_list.clear();
cp->cmd_char_pos = cp->cmd_char_list.begin(); cp->cmd_char_pos = cp->cmd_char_list.begin();
} }
@ -1345,14 +1306,11 @@ void SshSession::_process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const e
break; break;
} }
default: default:
if (cp->cmd_char_pos != cp->cmd_char_list.end()) 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.erase(cp->cmd_char_pos);
cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, ch); cp->cmd_char_pos = cp->cmd_char_list.insert(cp->cmd_char_pos, ch);
cp->cmd_char_pos++; cp->cmd_char_pos++;
} } else {
else
{
cp->cmd_char_list.push_back(ch); cp->cmd_char_list.push_back(ch);
cp->cmd_char_pos = cp->cmd_char_list.end(); cp->cmd_char_pos = cp->cmd_char_list.end();
} }
@ -1447,8 +1405,7 @@ void SshSession::_process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* dat
if (str2_len == 0) { if (str2_len == 0) {
ex_astr str1((char *) ((ex_u8 *) data + 13), str1_len); ex_astr str1((char *) ((ex_u8 *) data + 13), str1_len);
ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str()); ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str());
} } else {
else {
ex_astr str1((char *) (str1_ptr + 4), str1_len); ex_astr str1((char *) (str1_ptr + 4), str1_len);
ex_astr str2((char *) (str2_ptr + 4), str2_len); ex_astr str2((char *) (str2_ptr + 4), str2_len);
ex_strformat(msg, 2048, "%d,%d,%s:%s", sftp_cmd, 0, str1.c_str(), str2.c_str()); ex_strformat(msg, 2048, "%d,%d,%s:%s", sftp_cmd, 0, str1.c_str(), str2.c_str());

View File

@ -82,8 +82,9 @@ public:
const ex_astr& sid() { return m_sid; } const ex_astr& sid() { return m_sid; }
protected: protected:
void _thread_loop(void); void _thread_loop();
void _set_stop_flag(void); void _on_stop();
void _on_stopped();
// record an error when session connecting or auth-ing. // record an error when session connecting or auth-ing.
void _session_error(int err_code); void _session_error(int err_code);

View File

@ -11,9 +11,9 @@
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
# ifdef EX_DEBUG # ifdef EX_DEBUG
# pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\lib\\debug\\ssh.lib") # pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\build\\src\\Debug\\ssh.lib")
# else # else
# pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\lib\\release\\ssh.lib") # pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\build\\src\\Release\\ssh.lib")
# endif # endif
# pragma comment(lib, "libeay32.lib") # pragma comment(lib, "libeay32.lib")
# pragma comment(lib, "ws2_32.lib") # pragma comment(lib, "ws2_32.lib")

View File

@ -4,7 +4,6 @@
#include <teleport_const.h> #include <teleport_const.h>
#include <json/json.h> #include <json/json.h>
TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args) TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args)
{ {
#ifdef EX_OS_UNIX #ifdef EX_OS_UNIX