diff --git a/common/libex/include/ex/ex_log.h b/common/libex/include/ex/ex_log.h index 1cd89ab..9399fc6 100644 --- a/common/libex/include/ex/ex_log.h +++ b/common/libex/include/ex/ex_log.h @@ -4,67 +4,65 @@ #include "ex_types.h" #include "ex_thread.h" -#define EX_LOG_LEVEL_DEBUG 0 -#define EX_LOG_LEVEL_VERBOSE 1 -#define EX_LOG_LEVEL_INFO 2 -#define EX_LOG_LEVEL_WARN 3 -#define EX_LOG_LEVEL_ERROR 4 +#define EX_LOG_LEVEL_DEBUG 0 +#define EX_LOG_LEVEL_VERBOSE 1 +#define EX_LOG_LEVEL_INFO 2 +#define EX_LOG_LEVEL_WARN 3 +#define EX_LOG_LEVEL_ERROR 4 -#define EX_LOG_FILE_MAX_SIZE 1024*1024*10 -#define EX_LOG_FILE_MAX_COUNT 10 +#define EX_LOG_FILE_MAX_SIZE 1024*1024*10 +#define EX_LOG_FILE_MAX_COUNT 10 class ExLogger { public: - ExLogger(); - ~ExLogger(); + ExLogger(); + ~ExLogger(); - bool set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count); - void log_a(int level, const char* fmt, va_list valist); - void log_w(int level, const wchar_t* fmt, va_list valist); - bool write_a(const char* buf); - bool write_w(const wchar_t* buf); + bool set_log_file(const ex_wstr &log_path, const ex_wstr &log_name, ex_u32 max_filesize, ex_u8 max_count); + void log_a(int level, const char *fmt, va_list valist); + void log_w(int level, const wchar_t *fmt, va_list valist); + bool write_a(const char *buf); + bool write_w(const wchar_t *buf); protected: - bool _open_file(); - bool _rotate_file(void); // 将现有日志文件改名备份,然后新开一个日志文件 + bool _open_file(); + + // 将现有日志文件改名备份,然后新开一个日志文件 + bool _rotate_file(); public: - ExThreadLock lock; - int min_level; - bool debug_mode; - bool to_console; + ExThreadLock lock; + int min_level; + bool debug_mode; + bool to_console; #ifdef EX_OS_WIN32 - HANDLE console_handle; + HANDLE console_handle; #endif protected: - ex_u32 m_filesize; - ex_u32 m_max_filesize; - ex_u8 m_max_count; - ex_wstr m_path; - ex_wstr m_filename; - ex_wstr m_fullname; + ex_u32 m_filesize; + ex_u32 m_max_filesize; + ex_u8 m_max_count; + ex_wstr m_path; + ex_wstr m_filename; + ex_wstr m_fullname; #ifdef EX_OS_WIN32 - HANDLE m_file; + HANDLE m_file; #else - FILE* m_file; + FILE *m_file; #endif }; -//extern ExLogger g_ex_logger; - -// extern void* ex_logger; - -void EXLOG_USE_LOGGER(ExLogger* logger); +void EXLOG_USE_LOGGER(ExLogger *logger); void EXLOG_LEVEL(int min_level); void EXLOG_DEBUG(bool debug_mode); // 设定日志文件名及路径,如未指定路径,则为可执行程序所在目录下的log目录。 -void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path = NULL, ex_u32 max_filesize = EX_LOG_FILE_MAX_SIZE, ex_u8 max_filecount = EX_LOG_FILE_MAX_COUNT); +void EXLOG_FILE(const wchar_t *log_file, const wchar_t *log_path = nullptr, ex_u32 max_filesize = EX_LOG_FILE_MAX_SIZE, ex_u8 max_filecount = EX_LOG_FILE_MAX_COUNT); void EXLOG_CONSOLE(bool output_to_console); @@ -82,20 +80,20 @@ void ex_printf_e_lasterror(const wchar_t* fmt, ...); #endif -void ex_printf_d(const char* fmt, ...); -void ex_printf_v(const char* fmt, ...); -void ex_printf_i(const char* fmt, ...); -void ex_printf_w(const char* fmt, ...); -void ex_printf_e(const char* fmt, ...); +void ex_printf_d(const char *fmt, ...); +void ex_printf_v(const char *fmt, ...); +void ex_printf_i(const char *fmt, ...); +void ex_printf_w(const char *fmt, ...); +void ex_printf_e(const char *fmt, ...); -void ex_printf_d(const wchar_t* fmt, ...); -void ex_printf_v(const wchar_t* fmt, ...); -void ex_printf_i(const wchar_t* fmt, ...); -void ex_printf_w(const wchar_t* fmt, ...); -void ex_printf_e(const wchar_t* fmt, ...); +void ex_printf_d(const wchar_t *fmt, ...); +void ex_printf_v(const wchar_t *fmt, ...); +void ex_printf_i(const wchar_t *fmt, ...); +void ex_printf_w(const wchar_t *fmt, ...); +void ex_printf_e(const wchar_t *fmt, ...); -void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...); -void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const wchar_t* fmt, ...); +void ex_printf_bin(const ex_u8 *bin_data, size_t bin_size, const char *fmt, ...); +void ex_printf_bin(const ex_u8 *bin_data, size_t bin_size, const wchar_t *fmt, ...); #endif // __EX_LOG_H__ diff --git a/common/libex/include/ex/ex_platform.h b/common/libex/include/ex/ex_platform.h index 099cfbf..ed2544e 100644 --- a/common/libex/include/ex/ex_platform.h +++ b/common/libex/include/ex/ex_platform.h @@ -81,7 +81,6 @@ # endif #endif - /* * On Windows PATH_MAX does not exist but MAX_PATH does. * WinAPI MAX_PATH limit is only 256. MSVCR fuctions does not have this limit. diff --git a/common/libex/include/ex/ex_thread.h b/common/libex/include/ex/ex_thread.h index 18baf17..9be0af5 100644 --- a/common/libex/include/ex/ex_thread.h +++ b/common/libex/include/ex/ex_thread.h @@ -206,6 +206,6 @@ int ex_atomic_inc(volatile int* pt); int ex_atomic_dec(volatile int* pt); // 线程相关操作 -ex_u64 ex_get_thread_id(); +uint64_t ex_get_thread_id(); #endif // __EX_THREAD_H__ diff --git a/common/libex/include/ex/ex_types.h b/common/libex/include/ex/ex_types.h index 3ad1a01..acb5173 100644 --- a/common/libex/include/ex/ex_types.h +++ b/common/libex/include/ex/ex_types.h @@ -2,6 +2,7 @@ #define __LIB_EX_TYPE_H__ #include "ex_platform.h" +#include #include @@ -31,7 +32,7 @@ typedef int EX_BOOL; typedef std::vector ex_bin; typedef std::vector ex_chars; -typedef ex_u32 ex_rv; +typedef uint32_t ex_rv; #if defined(EX_OS_WIN32) diff --git a/common/libex/include/ex/ex_util.h b/common/libex/include/ex/ex_util.h index 8565696..cee8668 100644 --- a/common/libex/include/ex/ex_util.h +++ b/common/libex/include/ex/ex_util.h @@ -32,7 +32,6 @@ void ex_sleep_ms(int ms); EX_BOOL ex_localtime_now(int* t, struct tm* dt); - FILE* ex_fopen(const ex_wstr& filename, const wchar_t* mode); FILE* ex_fopen(const ex_astr& filename, const char* mode); diff --git a/common/libex/src/ex_log.cpp b/common/libex/src/ex_log.cpp index b1b8fb8..2e0a56b 100644 --- a/common/libex/src/ex_log.cpp +++ b/common/libex/src/ex_log.cpp @@ -1,5 +1,6 @@ #include #include +#include //#include //#include //#include @@ -16,119 +17,125 @@ #define EX_LOG_CONTENT_MAX_LEN 2048 -//typedef std::deque log_file_deque; +static ExLogger* g_exlog = nullptr; -static ExLogger* g_exlog = NULL; - -void EXLOG_USE_LOGGER(ExLogger* logger) -{ +void EXLOG_USE_LOGGER(ExLogger* logger) { g_exlog = logger; } -void EXLOG_LEVEL(int min_level) -{ - if(NULL != g_exlog) - g_exlog->min_level = min_level; +void EXLOG_LEVEL(int min_level) { + if (nullptr != g_exlog) + g_exlog->min_level = min_level; } -void EXLOG_DEBUG(bool debug_mode) -{ - if (NULL != g_exlog) - g_exlog->debug_mode = debug_mode; +void EXLOG_DEBUG(bool debug_mode) { + if (nullptr != g_exlog) + g_exlog->debug_mode = debug_mode; } -void EXLOG_CONSOLE(bool output_to_console) -{ - if(NULL != g_exlog) - g_exlog->to_console = output_to_console; +void EXLOG_CONSOLE(bool output_to_console) { + if (nullptr != g_exlog) + g_exlog->to_console = output_to_console; } -void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path /*= NULL*/, ex_u32 max_filesize /*= EX_LOG_FILE_MAX_SIZE*/, ex_u8 max_filecount /*= EX_LOG_FILE_MAX_COUNT*/) -{ - if(NULL == g_exlog) +void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path /*= nullptr*/, ex_u32 max_filesize /*= EX_LOG_FILE_MAX_SIZE*/, ex_u8 max_filecount /*= EX_LOG_FILE_MAX_COUNT*/) { + if (nullptr == g_exlog) return; - ex_wstr _path; - if (NULL == log_path) - { - ex_exec_file(_path); - ex_dirname(_path); - ex_path_join(_path, false, L"log", NULL); - } - else - { - _path = log_path; - } + ex_wstr _path; + if (nullptr == log_path) { + ex_exec_file(_path); + ex_dirname(_path); + ex_path_join(_path, false, L"log", nullptr); + } + else { + _path = log_path; + } - g_exlog->set_log_file(_path, log_file, max_filesize, max_filecount); + g_exlog->set_log_file(_path, log_file, max_filesize, max_filecount); } -ExLogger::ExLogger() -{ +ExLogger::ExLogger() { #ifdef EX_OS_WIN32 - console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + console_handle = GetStdHandle(STD_OUTPUT_HANDLE); #endif - min_level = EX_LOG_LEVEL_INFO; - debug_mode = false; - to_console = true; + min_level = EX_LOG_LEVEL_INFO; + debug_mode = false; + to_console = true; - m_file = NULL; - m_filesize = 0; + m_file = nullptr; + m_filesize = 0; } -ExLogger::~ExLogger() -{ - if (NULL != m_file) - { +ExLogger::~ExLogger() { + if (nullptr != m_file) { #ifdef EX_OS_WIN32 - CloseHandle(m_file); + CloseHandle(m_file); #else - fclose(m_file); + fclose(m_file); #endif - m_file = NULL; - } + m_file = nullptr; + } } -void ExLogger::log_a(int level, const char* fmt, va_list valist) -{ - if (NULL == fmt) - return; +void ExLogger::log_a(int level, const char* fmt, va_list valist) { + if (nullptr == fmt) + return; - if (0 == strlen(fmt)) - return; + if (0 == strlen(fmt)) + return; - char szTmp[4096] = { 0 }; - size_t offset = 0; + const char* _level = ""; + if (level == EX_LOG_LEVEL_ERROR) + _level = " [E]"; + else if (level == EX_LOG_LEVEL_WARN) + _level = " [W]"; + else if (level == EX_LOG_LEVEL_INFO) + _level = " [I]"; - if (level == EX_LOG_LEVEL_ERROR) - { - szTmp[0] = '['; - szTmp[1] = 'E'; - szTmp[2] = ']'; - szTmp[3] = ' '; - offset = 4; - } + char prefix[100] = {0}; +#ifdef EX_OS_WIN32 + SYSTEMTIME st; + GetLocalTime(&st); + // sprintf_s(prefix, 100, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); + // sprintf_s(prefix, 100, "[%02d-%02d %02d:%02d:%02d %llu%s] ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); + sprintf_s(prefix, 100, "[%04d%02d%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); +#else + time_t timep; + struct tm* p; + time(&timep); + p = localtime(&timep); + if (p == nullptr) + return; + // sprintf(prefix, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); + // sprintf(prefix, "[%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); + sprintf(prefix, "[%04d%02d%02d %02d:%02d:%02d %llu]%s ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); +#endif + + size_t offset = strlen(prefix); + + char szTmp[4096] = {0}; + memcpy(szTmp, prefix, offset); #ifdef EX_OS_WIN32 - vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); - if(to_console) - { - if (NULL != console_handle) - { - printf_s("%s", szTmp); - fflush(stdout); - } - else - { - if(debug_mode) - OutputDebugStringA(szTmp); - } - } + vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); + if(to_console) + { + if (nullptr != console_handle) + { + printf_s("%s", szTmp); + fflush(stdout); + } + else + { + if(debug_mode) + OutputDebugStringA(szTmp); + } + } #else - vsnprintf(szTmp+offset, 4095-offset, fmt, valist); - if(to_console) - { + vsnprintf(szTmp + offset, 4095 - offset, fmt, valist); + if (to_console) { // On linux, the stdout only output the first time output format (char or wchar_t). // e.g.: first time you use printf(), then after that, every wprintf() not work, and vice versa. // so we always use wprintf() to fix that. @@ -138,164 +145,186 @@ void ExLogger::log_a(int level, const char* fmt, va_list valist) ex_astr2wstr(tmp, _tmp); wprintf(L"%ls", _tmp.c_str()); fflush(stdout); - -// printf("%s", szTmp); -// fflush(stdout); - } + } #endif - write_a(szTmp); + write_a(szTmp); } -void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist) -{ - if (NULL == fmt || 0 == wcslen(fmt)) - return; +void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist) { + if (nullptr == fmt || 0 == wcslen(fmt)) + return; - wchar_t szTmp[4096] = { 0 }; - size_t offset = 0; - - if (level == EX_LOG_LEVEL_ERROR) - { - szTmp[0] = L'['; - szTmp[1] = L'E'; - szTmp[2] = L']'; - szTmp[3] = L' '; - offset = 4; - } + const char* _level = ""; + if (level == EX_LOG_LEVEL_ERROR) + _level = " [E]"; + else if (level == EX_LOG_LEVEL_WARN) + _level = " [W]"; + else if (level == EX_LOG_LEVEL_INFO) + _level = " [I]"; + char prefix[100] = {0}; #ifdef EX_OS_WIN32 - _vsnwprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); - if(to_console) - { - if (NULL != console_handle) - { - wprintf_s(_T("%s"), szTmp); - fflush(stdout); - } - else - { - if(debug_mode) - OutputDebugStringW(szTmp); - } - } + SYSTEMTIME st; + GetLocalTime(&st); + // sprintf_s(prefix, 100, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); + // sprintf_s(prefix, 100, "[%02d-%02d %02d:%02d:%02d %llu%s] ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); + sprintf_s(prefix, 100, "[%04d%02d-%02d %02d:%02d:%02d %llu]%s ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level); #else - vswprintf(szTmp+offset, 4095-offset, fmt, valist); - if(to_console) - { - wprintf(L"%ls", szTmp); - fflush(stdout); - } + time_t timep; + struct tm* p; + time(&timep); + p = localtime(&timep); + if (p == nullptr) + return; + // sprintf(prefix, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); + // sprintf(prefix, "[%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); + sprintf(prefix, "[%04d%02d%02d %02d:%02d:%02d %llu]%s ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level); #endif - write_w(szTmp); + ex_wstr w_prefix; + ex_astr2wstr(prefix, w_prefix); + size_t offset = wcslen(w_prefix.c_str()); + + + wchar_t szTmp[4096] = {0}; + memcpy(szTmp, w_prefix.c_str(), offset * sizeof(wchar_t)); + +#ifdef EX_OS_WIN32 + _vsnwprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); + if(to_console) + { + if (nullptr != console_handle) + { + wprintf_s(_T("%s"), szTmp); + fflush(stdout); + } + else + { + if(debug_mode) + OutputDebugStringW(szTmp); + } + } +#else + vswprintf(szTmp + offset, 4095 - offset, fmt, valist); + if (to_console) { + wprintf(L"%ls", szTmp); + fflush(stdout); + } +#endif + + write_w(szTmp); } #define EX_PRINTF_XA(fn, level) \ void fn(const char* fmt, ...) \ { \ - if(NULL == g_exlog) \ + if(nullptr == g_exlog) \ return; \ - if (g_exlog->min_level > level) \ - return; \ - ExThreadSmartLock locker(g_exlog->lock); \ - va_list valist; \ - va_start(valist, fmt); \ - g_exlog->log_a(level, fmt, valist); \ - va_end(valist); \ + if (g_exlog->min_level > level) \ + return; \ + ExThreadSmartLock locker(g_exlog->lock); \ + va_list valist; \ + va_start(valist, fmt); \ + g_exlog->log_a(level, fmt, valist); \ + va_end(valist); \ } #define EX_PRINTF_XW(fn, level) \ void fn(const wchar_t* fmt, ...) \ { \ - if(NULL == g_exlog) \ + if(nullptr == g_exlog) \ return; \ - if (g_exlog->min_level > level) \ - return; \ - ExThreadSmartLock locker(g_exlog->lock); \ - va_list valist; \ - va_start(valist, fmt); \ - g_exlog->log_w(level, fmt, valist); \ - va_end(valist); \ + if (g_exlog->min_level > level) \ + return; \ + ExThreadSmartLock locker(g_exlog->lock); \ + va_list valist; \ + va_start(valist, fmt); \ + g_exlog->log_w(level, fmt, valist); \ + va_end(valist); \ } EX_PRINTF_XA(ex_printf_d, EX_LOG_LEVEL_DEBUG) + EX_PRINTF_XA(ex_printf_v, EX_LOG_LEVEL_VERBOSE) + EX_PRINTF_XA(ex_printf_i, EX_LOG_LEVEL_INFO) + EX_PRINTF_XA(ex_printf_w, EX_LOG_LEVEL_WARN) + EX_PRINTF_XA(ex_printf_e, EX_LOG_LEVEL_ERROR) EX_PRINTF_XW(ex_printf_d, EX_LOG_LEVEL_DEBUG) + EX_PRINTF_XW(ex_printf_v, EX_LOG_LEVEL_VERBOSE) + EX_PRINTF_XW(ex_printf_i, EX_LOG_LEVEL_INFO) + EX_PRINTF_XW(ex_printf_w, EX_LOG_LEVEL_WARN) + EX_PRINTF_XW(ex_printf_e, EX_LOG_LEVEL_ERROR) #ifdef EX_OS_WIN32 void ex_printf_e_lasterror(const char* fmt, ...) { - ExThreadSmartLock locker(g_exlog->lock); + ExThreadSmartLock locker(g_exlog->lock); - va_list valist; - va_start(valist, fmt); - g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist); - va_end(valist); + va_list valist; + va_start(valist, fmt); + g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist); + va_end(valist); - //========================================= + //========================================= - LPVOID lpMsgBuf; - DWORD dw = GetLastError(); + LPVOID lpMsgBuf; + DWORD dw = GetLastError(); - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&lpMsgBuf, 0, NULL); + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&lpMsgBuf, 0, nullptr); - ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); - LocalFree(lpMsgBuf); + ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); } void ex_printf_e_lasterror(const wchar_t* fmt, ...) { - ExThreadSmartLock locker(g_exlog->lock); + ExThreadSmartLock locker(g_exlog->lock); - va_list valist; - va_start(valist, fmt); - g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist); - va_end(valist); + va_list valist; + va_start(valist, fmt); + g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist); + va_end(valist); - //========================================= + //========================================= - LPVOID lpMsgBuf; - DWORD dw = GetLastError(); + LPVOID lpMsgBuf; + DWORD dw = GetLastError(); - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&lpMsgBuf, 0, NULL); + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&lpMsgBuf, 0, nullptr); - ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); - LocalFree(lpMsgBuf); + ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); } #endif -void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) -{ - if(NULL == g_exlog) +void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) { + if (nullptr == g_exlog) + return; + if (!g_exlog->debug_mode) return; - if (!g_exlog->debug_mode) - return; - ExThreadSmartLock locker(g_exlog->lock); + ExThreadSmartLock locker(g_exlog->lock); - - - if (NULL == fmt) + if (nullptr == fmt) return; if (0 == strlen(fmt)) return; - char szTmp[128] = { 0 }; -// size_t offset = 0; + char szTmp[128] = {0}; va_list valist; va_start(valist, fmt); @@ -307,235 +336,186 @@ void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) #endif va_end(valist); -// -// -// -// -// va_list valist; -// va_start(valist, fmt); -// g_exlog->log_a(EX_LOG_LEVEL_DEBUG, fmt, valist); -// va_end(valist); -// - ex_printf_d("%s (%d/0x%02x Bytes)\n", szTmp, bin_size, bin_size); + ex_printf_d("%s (%d/0x%02x Bytes)\n", szTmp, bin_size, bin_size); - const ex_u8* line = bin_data; - size_t thisline = 0; - size_t offset = 0; - unsigned int i = 0; + const ex_u8* line = bin_data; + size_t offset = 0; + while (offset < bin_size) { + size_t _offset = 0; + memset(szTmp, 0, 128); -// char szTmp[128] = { 0 }; - size_t _offset = 0; + snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int) offset); + _offset += 8; - while (offset < bin_size) - { - memset(szTmp, 0, 128); - _offset = 0; + size_t this_line = bin_size - offset; + if (this_line > 16) + this_line = 16; - snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int)offset); - _offset += 8; + size_t i = 0; + for (; i < this_line; i++) { + snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]); + _offset += 3; + } - thisline = bin_size - offset; - if (thisline > 16) - thisline = 16; + snprintf(szTmp + _offset, 128 - _offset, " "); + _offset += 2; - for (i = 0; i < thisline; i++) - { - snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]); - _offset += 3; - } + for (; i < 16; i++) { + snprintf(szTmp + _offset, 128 - _offset, " "); + _offset += 3; + } - snprintf(szTmp + _offset, 128 - _offset, " "); - _offset += 2; + for (i = 0; i < this_line; i++) { + snprintf(szTmp + _offset, 128 - _offset, "%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + _offset += 1; + } - for (; i < 16; i++) - { - snprintf(szTmp + _offset, 128 - _offset, " "); - _offset += 3; - } + snprintf(szTmp + _offset, 128 - _offset, "\n"); - for (i = 0; i < thisline; i++) - { - snprintf(szTmp + _offset, 128 - _offset, "%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); - _offset += 1; - } + ex_printf_d("%s", szTmp); - snprintf(szTmp + _offset, 128 - _offset, "\n"); - _offset += 1; + offset += this_line; + line += this_line; + } - ex_printf_d("%s", szTmp); - - offset += thisline; - line += thisline; - } - - fflush(stdout); + fflush(stdout); } -bool ExLogger::set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count) -{ - m_max_filesize = max_filesize; - m_max_count = max_count; +bool ExLogger::set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count) { + m_max_filesize = max_filesize; + m_max_count = max_count; - m_filename = log_name; + m_filename = log_name; - m_path = log_path; - ex_abspath(m_path); + m_path = log_path; + ex_abspath(m_path); - ex_mkdirs(m_path); + ex_mkdirs(m_path); - m_fullname = m_path; - ex_path_join(m_fullname, false, log_name.c_str(), NULL); + m_fullname = m_path; + ex_path_join(m_fullname, false, log_name.c_str(), nullptr); - return _open_file(); + return _open_file(); } - -bool ExLogger::_open_file() -{ - if (m_file) - { +bool ExLogger::_open_file() { + if (m_file) { #ifdef EX_OS_WIN32 - CloseHandle(m_file); + CloseHandle(m_file); #else - fclose(m_file); + fclose(m_file); #endif - m_file = NULL; - } + m_file = nullptr; + } #ifdef EX_OS_WIN32 - // 注意:这里必须使用 CreateFile() 来打开日志文件,使用FILE指针无法传递给动态库进行操作。 - m_file = CreateFileW(m_fullname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == m_file) - { - m_file = NULL; - return false; - } + // 注意:这里必须使用 CreateFile() 来打开日志文件,使用FILE指针无法传递给动态库进行操作。 + m_file = CreateFileW(m_fullname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (INVALID_HANDLE_VALUE == m_file) + { + m_file = nullptr; + return false; + } - SetFilePointer(m_file, 0, NULL, FILE_END); - m_filesize = GetFileSize(m_file, NULL); + SetFilePointer(m_file, 0, nullptr, FILE_END); + m_filesize = GetFileSize(m_file, nullptr); #else - ex_astr _fullname; - ex_wstr2astr(m_fullname, _fullname); - m_file = fopen(_fullname.c_str(), "a"); + ex_astr _fullname; + ex_wstr2astr(m_fullname, _fullname); + m_file = fopen(_fullname.c_str(), "a"); - if (NULL == m_file) - { - return false; - } + if (nullptr == m_file) { + return false; + } - fseek(m_file, 0, SEEK_END); - m_filesize = (ex_u32)ftell(m_file); + fseek(m_file, 0, SEEK_END); + m_filesize = (ex_u32) ftell(m_file); #endif - return _rotate_file(); + return _rotate_file(); } -bool ExLogger::_rotate_file(void) -{ - if (m_filesize < m_max_filesize) - return true; +bool ExLogger::_rotate_file() { + if (m_filesize < m_max_filesize) + return true; - if (m_file) - { + if (m_file) { #ifdef EX_OS_WIN32 - CloseHandle(m_file); + CloseHandle(m_file); #else - fclose(m_file); + fclose(m_file); #endif - m_file = NULL; - } + m_file = nullptr; + } - // make a name for backup file. - wchar_t _tmpname[64] = { 0 }; + // make a name for backup file. + wchar_t _tmpname[64] = {0}; #ifdef EX_OS_WIN32 - SYSTEMTIME st; - GetLocalTime(&st); - swprintf_s(_tmpname, 64, L"%s.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + SYSTEMTIME st; + GetLocalTime(&st); + swprintf_s(_tmpname, 64, L"%s.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); #else - time_t timep; - time(&timep); - struct tm *p = localtime(&timep); - if (p == NULL) - return false; + time_t timep; + time(&timep); + struct tm* p = localtime(&timep); + if (p == nullptr) + return false; - ex_wcsformat(_tmpname, 64, L"%ls.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + ex_wcsformat(_tmpname, 64, L"%ls.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); #endif - ex_wstr _new_fullname(m_path); - ex_path_join(_new_fullname, false, _tmpname, NULL); + ex_wstr _new_fullname(m_path); + ex_path_join(_new_fullname, false, _tmpname, nullptr); #ifdef EX_OS_WIN32 - if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) - { - EXLOGE_WIN("can not rename log file, remove old one and try again."); - DeleteFileW(_new_fullname.c_str()); - if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) - return false; - } + if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) + { + EXLOGE_WIN("can not rename log file, remove old one and try again."); + DeleteFileW(_new_fullname.c_str()); + if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) + return false; + } #else - ex_astr _a_fullname; - ex_astr _a_new_fullname; - ex_wstr2astr(m_fullname, _a_fullname); - ex_wstr2astr(_new_fullname, _a_new_fullname); + ex_astr _a_fullname; + ex_astr _a_new_fullname; + ex_wstr2astr(m_fullname, _a_fullname); + ex_wstr2astr(_new_fullname, _a_new_fullname); - if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0) - { - remove(_a_new_fullname.c_str()); - if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str()))) - return false; - } + if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0) { + remove(_a_new_fullname.c_str()); + if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str()))) + return false; + } #endif - return _open_file(); + return _open_file(); } -bool ExLogger::write_a(const char* buf) -{ - if (NULL == m_file) - return false; +bool ExLogger::write_a(const char* buf) { + if (nullptr == m_file) + return false; - size_t len = strlen(buf); + size_t len = strlen(buf); - if (len > EX_LOG_CONTENT_MAX_LEN) - return false; + if (len > EX_LOG_CONTENT_MAX_LEN) + return false; - char szTime[100] = { 0 }; #ifdef EX_OS_WIN32 - SYSTEMTIME st; - GetLocalTime(&st); - sprintf_s(szTime, 100, "[%04d-%02d-%02d %02d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); - - int lenTime = strlen(szTime); - DWORD dwWritten = 0; - WriteFile(m_file, szTime, lenTime, &dwWritten, NULL); - m_filesize += lenTime; - WriteFile(m_file, buf, len, &dwWritten, NULL); - m_filesize += len; - FlushFileBuffers(m_file); + WriteFile(m_file, buf, len, &dwWritten, nullptr); + m_filesize += len; + FlushFileBuffers(m_file); #else - time_t timep; - struct tm *p; - time(&timep); - p = localtime(&timep); - if (p == NULL) - return false; - sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); - - size_t lenTime = strlen(szTime); - fwrite(szTime, lenTime, 1, m_file); - m_filesize += lenTime; - fwrite(buf, len, 1, m_file); - m_filesize += len; + fwrite(buf, len, 1, m_file); + m_filesize += len; fflush(m_file); #endif - return _rotate_file(); + return _rotate_file(); } -bool ExLogger::write_w(const wchar_t* buf) -{ - ex_astr _buf; - ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8); - return write_a(_buf.c_str()); +bool ExLogger::write_w(const wchar_t* buf) { + ex_astr _buf; + ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8); + return write_a(_buf.c_str()); } diff --git a/common/libex/src/ex_thread.cpp b/common/libex/src/ex_thread.cpp index a6c8d02..b261211 100644 --- a/common/libex/src/ex_thread.cpp +++ b/common/libex/src/ex_thread.cpp @@ -214,11 +214,17 @@ int ex_atomic_dec(volatile int *pt) { #endif } - -ex_u64 ex_get_thread_id() { -#ifdef EX_OS_WIN32 - return GetCurrentThreadId(); +uint64_t ex_get_thread_id() +{ +#if defined(EX_OS_WIN32) + return (uint64_t)GetCurrentThreadId(); +#elif defined(EX_OS_LINUX) + return pthread_self(); +#elif defined(EX_OS_MACOS) + uint64_t tid = 0; + pthread_threadid_np(nullptr, &tid); + return tid; #else - return (ex_u64) pthread_self(); +# error "unsupport platform." #endif } diff --git a/common/libex/src/ex_util.cpp b/common/libex/src/ex_util.cpp index c4daeba..48b16de 100644 --- a/common/libex/src/ex_util.cpp +++ b/common/libex/src/ex_util.cpp @@ -3,19 +3,20 @@ #include #include -EX_BOOL ex_initialize(const char *lc_ctype) { +EX_BOOL ex_initialize(const char *lc_ctype) +{ #ifdef EX_OS_UNIX const char *_lc_default = "en_US.UTF-8"; - const char *_lc_ctype = NULL; - char *_loc = NULL; - if (NULL == lc_ctype) + const char *_lc_ctype = nullptr; + char *_loc = nullptr; + if (nullptr == lc_ctype) _lc_ctype = _lc_default; else _lc_ctype = lc_ctype; _loc = setlocale(LC_CTYPE, _lc_ctype); - if (NULL == _loc) + if (nullptr == _loc) return EX_FALSE; // if(0 != strcmp(_loc, _lc_ctype)) // return EX_FALSE; @@ -27,50 +28,61 @@ EX_BOOL ex_initialize(const char *lc_ctype) { } -void ex_free(void *buffer) { - if (NULL == buffer) +void ex_free(void *buffer) +{ + if (nullptr == buffer) return; free(buffer); } -const ex_u8 *ex_memmem(const ex_u8 *haystack, size_t haystacklen, const ex_u8 *needle, size_t needlelen) { - const ex_u8 *cursor = NULL; +const ex_u8 *ex_memmem(const ex_u8 *haystack, size_t haystacklen, const ex_u8 *needle, size_t needlelen) +{ + const ex_u8 *cursor = nullptr; const ex_u8 *last_possible_needle_location = haystack + haystacklen - needlelen; /** Easy answers */ - if (needlelen > haystacklen) return (NULL); - if (needle == NULL) return (NULL); - if (haystack == NULL) return (NULL); - if (needlelen == 0) return (NULL); - if (haystacklen == 0) return (NULL); + if (needlelen > haystacklen) + return (nullptr); + if (needle == nullptr) + return (nullptr); + if (haystack == nullptr) + return (nullptr); + if (needlelen == 0) + return (nullptr); + if (haystacklen == 0) + return (nullptr); - for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) { + for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) + { if (memcmp(needle, cursor, needlelen) == 0) return cursor; } - return (NULL); + return (nullptr); } -void ex_mem_reverse(ex_u8 *p, size_t l) { - ex_u8 temp = 0; - size_t i = 0, j = 0; +void ex_mem_reverse(ex_u8 *p, size_t l) +{ + ex_u8 temp = 0; + size_t i = 0, j = 0; - for (i = 0, j = l - 1; i < j; i++, j--) { + for (i = 0, j = l - 1; i < j; i++, j--) + { temp = p[i]; p[i] = p[j]; p[j] = temp; } } -void ex_printf(const char *fmt, ...) { - if (NULL == fmt || 0 == strlen(fmt)) +void ex_printf(const char *fmt, ...) +{ + if (nullptr == fmt || 0 == strlen(fmt)) return; va_list valist; va_start(valist, fmt); //_ts_printf_a(TS_COLOR_GRAY, TS_COLOR_BLACK, fmt, valist); - char _tmp[4096] = {0}; + char _tmp[4096] = { 0 }; #ifdef EX_OS_WIN32 vsnprintf_s(_tmp, 4096, 4095, fmt, valist); printf_s("%s", _tmp); @@ -84,14 +96,15 @@ void ex_printf(const char *fmt, ...) { va_end(valist); } -void ex_wprintf(const wchar_t *fmt, ...) { - if (NULL == fmt || 0 == wcslen(fmt)) +void ex_wprintf(const wchar_t *fmt, ...) +{ + if (nullptr == fmt || 0 == wcslen(fmt)) return; va_list valist; va_start(valist, fmt); - wchar_t _tmp[4096] = {0}; + wchar_t _tmp[4096] = { 0 }; #ifdef EX_OS_WIN32 _vsnwprintf_s(_tmp, 4096, 4095, fmt, valist); wprintf_s(L"%s", _tmp); @@ -109,7 +122,8 @@ void ex_wprintf(const wchar_t *fmt, ...) { va_end(valist); } -ex_u64 ex_get_tick_count(void) { +ex_u64 ex_get_tick_count(void) +{ #ifdef EX_OS_WIN32 # if (_WIN32_WINNT >= 0x0600) return GetTickCount64(); @@ -132,7 +146,8 @@ ex_u64 ex_get_tick_count(void) { #endif } -void ex_sleep_ms(int ms) { +void ex_sleep_ms(int ms) +{ #ifdef EX_OS_WIN32 Sleep(ms); #else @@ -140,8 +155,9 @@ void ex_sleep_ms(int ms) { #endif } -EX_BOOL ex_localtime_now(int *t, struct tm *dt) { -// if (NULL == dt) +EX_BOOL ex_localtime_now(int *t, struct tm *dt) +{ +// if (nullptr == dt) // return EX_FALSE; //struct tm *_tmp; @@ -152,34 +168,35 @@ EX_BOOL ex_localtime_now(int *t, struct tm *dt) { _time32(&timep); if (0 != _localtime32_s(&_tmp, &timep)) return EX_FALSE; - if(NULL != dt) + if(nullptr != dt) memcpy(dt, &_tmp, sizeof(struct tm)); #else struct tm *_tmp; - time_t timep; + time_t timep; time(&timep); _tmp = localtime(&timep); //get server's time - if (_tmp == NULL) + if (_tmp == nullptr) return EX_FALSE; - if (NULL != dt) + if (nullptr != dt) memcpy(dt, _tmp, sizeof(struct tm)); #endif - if (NULL != t) + if (nullptr != t) *t = (int) timep; return EX_TRUE; } -FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) { - FILE *f = NULL; +FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) +{ + FILE *f = nullptr; #ifdef EX_OS_WIN32 errno_t err = 0; err = _wfopen_s(&f, filename.c_str(), mode); if (0 == err) return f; else - return NULL; + return nullptr; #else ex_astr _fname; ex_wstr2astr(filename, _fname); @@ -190,32 +207,35 @@ FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) { #endif } -FILE* ex_fopen(const ex_astr& filename, const char* mode) { - FILE *f = NULL; +FILE *ex_fopen(const ex_astr &filename, const char *mode) +{ + FILE *f = nullptr; #ifdef EX_OS_WIN32 - errno_t err = 0; - err = fopen_s(&f, filename.c_str(), mode); - if (0 == err) - return f; - else - return NULL; + errno_t err = 0; + err = fopen_s(&f, filename.c_str(), mode); + if (0 == err) + return f; + else + return nullptr; #else - f = fopen(filename.c_str(), mode); - return f; + f = fopen(filename.c_str(), mode); + return f; #endif } -bool ex_read_text_file(const ex_wstr &strFileName, ex_astr& file_content) { +bool ex_read_text_file(const ex_wstr &strFileName, ex_astr &file_content) +{ std::vector tmp; FILE *f = ex_fopen(strFileName, L"rb"); - if (f == NULL) + if (f == nullptr) return false; fseek(f, 0L, SEEK_END); unsigned long ulFileSize = (unsigned long) ftell(f); - if (-1 == ulFileSize) { + if (-1 == ulFileSize) + { fclose(f); return false; } @@ -230,22 +250,27 @@ bool ex_read_text_file(const ex_wstr &strFileName, ex_astr& file_content) { fclose(f); - if(ulRead != ulFileSize) { + if (ulRead != ulFileSize) + { return false; } - if ((ulFileSize > 3) && (0 == memcmp(&tmp[0], "\xEF\xBB\xBF", 3))) { + if ((ulFileSize > 3) && (0 == memcmp(&tmp[0], "\xEF\xBB\xBF", 3))) + { file_content = &tmp[3]; - } else { + } + else + { file_content = &tmp[0]; } return true; } -bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr& file_content) { +bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr &file_content) +{ FILE *f = ex_fopen(strFileName, L"wb"); - if (f == NULL) + if (f == nullptr) return false; unsigned long ulWrite = fwrite(file_content.c_str(), 1, file_content.length(), f); @@ -254,35 +279,39 @@ bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr& file_content) return ulWrite == file_content.length(); } -EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path) { - EX_DYLIB_HANDLE handle = NULL; +EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path) +{ + EX_DYLIB_HANDLE handle = nullptr; #ifdef EX_OS_WIN32 - handle = LoadLibraryExW(dylib_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (NULL == handle) + handle = LoadLibraryExW(dylib_path, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); + if (nullptr == handle) { EXLOGE_WIN(L"LoadLibraryEx('%ls') failed.\n", dylib_path); - return NULL; + return nullptr; } #else ex_astr path; - if (!ex_wstr2astr(dylib_path, path, EX_CODEPAGE_UTF8)) { + if (!ex_wstr2astr(dylib_path, path, EX_CODEPAGE_UTF8)) + { EXLOGE("convert dylib_path failed.\n"); - return NULL; + return nullptr; } handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL); - if (NULL == handle) { + if (nullptr == handle) + { EXLOGE("dlopen() failed: %s.\n", dlerror()); - return NULL; + return nullptr; } #endif return handle; } -void ex_dlclose(EX_DYLIB_HANDLE dylib) { +void ex_dlclose(EX_DYLIB_HANDLE dylib) +{ #ifdef EX_OS_WIN32 FreeLibrary(dylib); #else @@ -294,7 +323,7 @@ void ex_dlclose(EX_DYLIB_HANDLE dylib) { // static const char fmt[] = "%u.%u.%u.%u"; // char tmp[32]; // int l; -// +// // l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); // if (l <= 0 || (size_t) l >= size) { // return -1; @@ -303,178 +332,193 @@ void ex_dlclose(EX_DYLIB_HANDLE dylib) { // dst[size - 1] = '\0'; // return 0; // } -// +// // int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size) { // return _inet_ntop4((const unsigned char *) &(src->sin_addr), dst, size); // } -// -static const char * _inet_ntop_v4(const void *src, char *dst, size_t size) +// +static const char *_inet_ntop_v4(const void *src, char *dst, size_t size) { - const char digits[] = "0123456789"; - int i; - struct in_addr *addr = (struct in_addr *)src; - u_long a = ntohl(addr->s_addr); - const char *orig_dst = dst; + const char digits[] = "0123456789"; + int i; + struct in_addr *addr = (struct in_addr *) src; + u_long a = ntohl(addr->s_addr); + const char *orig_dst = dst; - if (size < EX_IPV4_NAME_LEN) { - //errno = ENOSPC; - return NULL; - } - for (i = 0; i < 4; ++i) { - int n = (a >> (24 - i * 8)) & 0xFF; - int non_zerop = 0; + if (size < EX_IPV4_NAME_LEN) + { + //errno = ENOSPC; + return nullptr; + } + for (i = 0; i < 4; ++i) + { + int n = (a >> (24 - i * 8)) & 0xFF; + int non_zerop = 0; - if (non_zerop || n / 100 > 0) { - *dst++ = digits[n / 100]; - n %= 100; - non_zerop = 1; - } - if (non_zerop || n / 10 > 0) { - *dst++ = digits[n / 10]; - n %= 10; - non_zerop = 1; - } - *dst++ = digits[n]; - if (i != 3) - *dst++ = '.'; - } - *dst++ = '\0'; - return orig_dst; + if (non_zerop || n / 100 > 0) + { + *dst++ = digits[n / 100]; + n %= 100; + non_zerop = 1; + } + if (non_zerop || n / 10 > 0) + { + *dst++ = digits[n / 10]; + n %= 10; + non_zerop = 1; + } + *dst++ = digits[n]; + if (i != 3) + *dst++ = '.'; + } + *dst++ = '\0'; + return orig_dst; } -#define IN6ADDRSZ 16 +#define IN6ADDRSZ 16 #define INT16SZ 2 -static const char * _inet_ntop_v6(const ex_u8 *src, char *dst, size_t size) + +static const char *_inet_ntop_v6(const ex_u8 *src, char *dst, size_t size) { - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[EX_IPV6_NAME_LEN]; - char *tp; - struct { - long base; - long len; - } best, cur; - u_long words[IN6ADDRSZ / INT16SZ]; - int i; + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[EX_IPV6_NAME_LEN]; + char *tp; + struct + { + long base; + long len; + } best, cur; + u_long words[IN6ADDRSZ / INT16SZ]; + int i; - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, 0, sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + /* Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, 0, sizeof(words)); + for (i = 0; i < IN6ADDRSZ; i++) + { + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + } - best.base = -1; - cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) { + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + if (words[i] == 0) + { + if (cur.base == -1) + { cur.base = i; - cur.len = 1; + cur.len = 1; } - else{ + else + { cur.len++; } - } - else if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if (best.base != -1 && best.len < 2) - best.base = -1; + } + else if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) + best = cur; + if (best.base != -1 && best.len < 2) + best.base = -1; - /* Format the result. - */ - tp = tmp; - size_t tmp_size = 0; - size_t offset = 0; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if (best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if (i == best.base) { - *tp++ = ':'; - offset += 1; - } - continue; - } + /* Format the result. + */ + tp = tmp; + size_t tmp_size = 0; + size_t offset = 0; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + /* Are we inside the best run of 0x00's? + */ + if (best.base != -1 && i >= best.base && i < (best.base + best.len)) + { + if (i == best.base) + { + *tp++ = ':'; + offset += 1; + } + continue; + } - /* Are we following an initial run of 0x00s or any real hex? - */ - if (i != 0) { - *tp++ = ':'; - offset += 1; - } + /* Are we following an initial run of 0x00s or any real hex? + */ + if (i != 0) + { + *tp++ = ':'; + offset += 1; + } - /* Is this address an encapsulated IPv4? - */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp))) - { - //errno = ENOSPC; - return (NULL); - } - tmp_size = strlen(tp); - tp += tmp_size; - offset += tmp_size; - break; - } - //tp += ex_strformat(tp, "%lX", words[i]); - tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN-offset, "%lX", words[i]); - tp += tmp_size; - offset += tmp_size; - } + /* Is this address an encapsulated IPv4? + */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) + { + if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp))) + { + //errno = ENOSPC; + return (nullptr); + } + tmp_size = strlen(tp); + tp += tmp_size; + offset += tmp_size; + break; + } + //tp += ex_strformat(tp, "%lX", words[i]); + tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN - offset, "%lX", words[i]); + tp += tmp_size; + offset += tmp_size; + } - /* Was it a trailing run of 0x00's? - */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; + /* Was it a trailing run of 0x00's? + */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; - /* Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) - { - //errno = ENOSPC; - return (NULL); - } - //return strcpy(dst, tmp); - return ex_strcpy(dst, size, tmp); - //return (NULL); + /* Check for overflow, copy, and we're done. + */ + if ((size_t) (tp - tmp) > size) + { + //errno = ENOSPC; + return (nullptr); + } + //return strcpy(dst, tmp); + return ex_strcpy(dst, size, tmp); + //return (nullptr); } -const char* ex_inet_ntop(int af, const void *src, char *dst, size_t size) { - switch (af) { - case AF_INET: - return _inet_ntop_v4(src, dst, size); - case AF_INET6: - return _inet_ntop_v6((const ex_u8*)src, dst, size); - default: - errno = EAFNOSUPPORT; - return NULL; - } +const char *ex_inet_ntop(int af, const void *src, char *dst, size_t size) +{ + switch (af) + { + case AF_INET: + return _inet_ntop_v4(src, dst, size); + case AF_INET6: + return _inet_ntop_v6((const ex_u8 *) src, dst, size); + default: + errno = EAFNOSUPPORT; + return nullptr; + } } -int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size) { - if (NULL == _inet_ntop_v4((const unsigned char *)&(src->sin_addr), dst, size)) - return -1; - return 0; +int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size) +{ + if (nullptr == _inet_ntop_v4((const unsigned char *) &(src->sin_addr), dst, size)) + return -1; + return 0; } diff --git a/common/teleport/teleport_const.h b/common/teleport/teleport_const.h index df55075..2807e2d 100644 --- a/common/teleport/teleport_const.h +++ b/common/teleport/teleport_const.h @@ -11,142 +11,143 @@ //======================================================= // Urlprotocol相关 //======================================================= -#define TP_URLPROTO_APP_NAME "teleport" +#define TP_URLPROTO_APP_NAME "teleport" //======================================================= // 远程连接认证方式 //======================================================= -#define TP_AUTH_TYPE_NONE 0 -#define TP_AUTH_TYPE_PASSWORD 1 -#define TP_AUTH_TYPE_PRIVATE_KEY 2 +#define TP_AUTH_TYPE_NONE 0 +#define TP_AUTH_TYPE_PASSWORD 1 +#define TP_AUTH_TYPE_PRIVATE_KEY 2 //======================================================= // 远程连接协议 //======================================================= -#define TP_PROTOCOL_TYPE_RDP 1 -#define TP_PROTOCOL_TYPE_SSH 2 -#define TP_PROTOCOL_TYPE_TELNET 3 +#define TP_PROTOCOL_TYPE_RDP 1 +#define TP_PROTOCOL_TYPE_SSH 2 +#define TP_PROTOCOL_TYPE_TELNET 3 //======================================================= // 远程连接子协议 //======================================================= -#define TP_PROTOCOL_TYPE_RDP_DESKTOP 100 -#define TP_PROTOCOL_TYPE_SSH_SHELL 200 -#define TP_PROTOCOL_TYPE_SSH_SFTP 201 -#define TP_PROTOCOL_TYPE_TELNET_SHELL 300 +#define TP_PROTOCOL_TYPE_RDP_DESKTOP 100 +#define TP_PROTOCOL_TYPE_SSH_SHELL 200 +#define TP_PROTOCOL_TYPE_SSH_SFTP 201 +#define TP_PROTOCOL_TYPE_TELNET_SHELL 300 //======================================================= // 远程主机操作系统 //======================================================= -#define TP_OS_TYPE_WINDOWS 1 -#define TP_OS_TYPE_LINUX 2 +#define TP_OS_TYPE_WINDOWS 1 +#define TP_OS_TYPE_LINUX 2 //======================================================= // 远程连接会话状态 //======================================================= -#define TP_SESS_STAT_RUNNING 0 // 会话开始了,正在连接 -#define TP_SESS_STAT_END 9999 // 会话成功结束 -#define TP_SESS_STAT_ERR_AUTH_DENIED 1 // 会话结束,因为认证失败 -#define TP_SESS_STAT_ERR_CONNECT 2 // 会话结束,因为无法连接到远程主机 -#define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束,因为无法识别SSH私钥 -#define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误 -#define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP) -#define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文 -#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_RUNNING 0 // 会话开始了,正在连接 +#define TP_SESS_STAT_ERR_AUTH_DENIED 1 // 会话结束,因为认证失败 +#define TP_SESS_STAT_ERR_CONNECT 2 // 会话结束,因为无法连接到远程主机 +#define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束,因为无法识别SSH私钥 +#define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误 +#define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP) +#define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文 +#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_ERR_CREATE_CHANNEL 11 // 会话结束,因为创建通道失败 + #define TP_SESS_STAT_STARTED 100 // 已经连接成功了,开始记录录像了 #define TP_SESS_STAT_ERR_START_INTERNAL 104 // 会话结束,因为内部错误 #define TP_SESS_STAT_ERR_START_BAD_PKG 106 // 会话结束,因为收到错误的报文 #define TP_SESS_STAT_ERR_START_RESET 107 // 会话结束,因为teleport核心服务重置了 #define TP_SESS_STAT_ERR_START_IO 108 // 会话结束,因为网络中断 +#define TP_SESS_STAT_END 9999 // 会话成功结束 //======================================================= // 授权标记 //======================================================= -#define TP_FLAG_ALL 0xFFFFFFFF +#define TP_FLAG_ALL 0xFFFFFFFF // 会话记录相关 -#define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放) -#define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控 +#define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放) +#define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控 // RDP相关 -#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面 -#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板 -#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射 -#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP(尚未实现) -#define TP_FLAG_RDP_CONSOLE 0x00001000 //允许连接到管理员会话(RDP的console选项) +#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面 +#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板 +#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射 +#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP(尚未实现) +#define TP_FLAG_RDP_CONSOLE 0x00001000 // 允许连接到管理员会话(RDP的console选项) // SSH相关 -#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL -#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP -#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发(尚未实现) -#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令(尚未实现) -#define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.) +#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL +#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP +#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发(尚未实现) +#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令(尚未实现) +#define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.) //======================================================= // 错误值 //======================================================= -#define TPE_OK 0 // 成功 +#define TPE_OK 0 // 成功 //------------------------------------------------------- // 通用错误值 //------------------------------------------------------- -#define TPE_NEED_MORE_DATA 1 // 需要更多数据(不一定是错误) -#define TPE_NEED_LOGIN 2 // 需要登录 -#define TPE_PRIVILEGE 3 // 没有操作权限 -#define TPE_NOT_IMPLEMENT 7 // 功能尚未实现 -#define TPE_EXISTS 8 // 目标已经存在 -#define TPE_NOT_EXISTS 9 // 目标不存在 +#define TPE_NEED_MORE_DATA 1 // 需要更多数据(不一定是错误) +#define TPE_NEED_LOGIN 2 // 需要登录 +#define TPE_PRIVILEGE 3 // 没有操作权限 +#define TPE_NOT_IMPLEMENT 7 // 功能尚未实现 +#define TPE_EXISTS 8 // 目标已经存在 +#define TPE_NOT_EXISTS 9 // 目标不存在 // 100~299是通用错误值 -#define TPE_FAILED 100 // 内部错误 -#define TPE_NETWORK 101 // 网络错误 -#define TPE_DATABASE 102 // 数据库操作失败 +#define TPE_FAILED 100 // 内部错误 +#define TPE_NETWORK 101 // 网络错误 +#define TPE_DATABASE 102 // 数据库操作失败 // HTTP请求相关错误 -#define TPE_HTTP_METHOD 120 // 无效的请求方法(不是GET/POST等),或者错误的请求方法(例如需要POST,却使用GET方式请求) -#define TPE_HTTP_URL_ENCODE 121 // URL编码错误(无法解码) -//#define TPE_HTTP_URI 122 // 无效的URI +#define TPE_HTTP_METHOD 120 // 无效的请求方法(不是GET/POST等),或者错误的请求方法(例如需要POST,却使用GET方式请求) +#define TPE_HTTP_URL_ENCODE 121 // URL编码错误(无法解码) +//#define TPE_HTTP_URI 122 // 无效的URI -#define TPE_UNKNOWN_CMD 124 // 未知的命令 -#define TPE_JSON_FORMAT 125 // 错误的JSON格式(需要JSON格式数据,但是却无法按JSON格式解码) -#define TPE_PARAM 126 // 参数错误 -#define TPE_INVALID_DATA 127 // 数据错误 -#define TPE_UNEXPECTED_DATA 128 // 不是期望的数据 +#define TPE_UNKNOWN_CMD 124 // 未知的命令 +#define TPE_JSON_FORMAT 125 // 错误的JSON格式(需要JSON格式数据,但是却无法按JSON格式解码) +#define TPE_PARAM 126 // 参数错误 +#define TPE_INVALID_DATA 127 // 数据错误 +#define TPE_UNEXPECTED_DATA 128 // 不是期望的数据 -// #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件 -// #define TPE_GETTEMPPATH_ERROR 0x1007 -#define TPE_OPENFILE 300 +// #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件 +// #define TPE_GETTEMPPATH_ERROR 0x1007 +#define TPE_OPENFILE 300 //------------------------------------------------------- // WEB服务专用错误值 //------------------------------------------------------- -#define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期 -#define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误 -#define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误 -#define TPE_SYS_MAINTENANCE 10003 // 系统维护中 +#define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期 +#define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误 +#define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误 +#define TPE_SYS_MAINTENANCE 10003 // 系统维护中 -#define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码) -#define TPE_USER_DISABLED 10101 // 用户已经被禁用 -#define TPE_USER_AUTH 10102 // 身份验证失败 +#define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码) +#define TPE_USER_DISABLED 10101 // 用户已经被禁用 +#define TPE_USER_AUTH 10102 // 身份验证失败 //------------------------------------------------------- // 助手程序专用错误值 //------------------------------------------------------- -#define TPE_NO_ASSIST 100000 // 未能检测到助手程序 -#define TPE_OLD_ASSIST 100001 // 助手程序版本太低 -#define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程) +#define TPE_NO_ASSIST 100000 // 未能检测到助手程序 +#define TPE_OLD_ASSIST 100001 // 助手程序版本太低 +#define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程) //------------------------------------------------------- // 核心服务专用错误值 //------------------------------------------------------- -#define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务 - +#define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务 #endif // __TELEPORT_CONST_H__ diff --git a/server/tp_core/common/base_env.cpp b/server/tp_core/common/base_env.cpp index 34f8c07..513d9b1 100644 --- a/server/tp_core/common/base_env.cpp +++ b/server/tp_core/common/base_env.cpp @@ -1,48 +1,46 @@ #include "base_env.h" -TppEnvBase::TppEnvBase() -{} +TppEnvBase::TppEnvBase() : + get_connect_info(nullptr), + free_connect_info(nullptr), + session_begin(nullptr), + session_update(nullptr), + session_end(nullptr) {} -TppEnvBase::~TppEnvBase() -{} +TppEnvBase::~TppEnvBase() = default; -bool TppEnvBase::init(TPP_INIT_ARGS* args) -{ - if (NULL == args) - { - EXLOGE("invalid init args(1).\n"); - return false; - } +bool TppEnvBase::init(TPP_INIT_ARGS* args) { + if (nullptr == args) { + EXLOGE("invalid init args(1).\n"); + return false; + } - EXLOG_USE_LOGGER(args->logger); + EXLOG_USE_LOGGER(args->logger); - exec_path = args->exec_path; - etc_path = args->etc_path; - replay_path = args->replay_path; + exec_path = args->exec_path; + etc_path = args->etc_path; + replay_path = args->replay_path; - get_connect_info = args->func_get_connect_info; - free_connect_info = args->func_free_connect_info; - session_begin = args->func_session_begin; - session_update = args->func_session_update; - session_end = args->func_session_end; + get_connect_info = args->func_get_connect_info; + free_connect_info = args->func_free_connect_info; + session_begin = args->func_session_begin; + session_update = args->func_session_update; + session_end = args->func_session_end; - if (NULL == get_connect_info || NULL == free_connect_info || NULL == session_begin || NULL == session_update || NULL == session_end) - { - EXLOGE("invalid init args(2).\n"); - return false; - } + if (!get_connect_info || !free_connect_info || !session_begin || !session_update || !session_end) { + EXLOGE("invalid init args(2).\n"); + return false; + } - if (NULL == args->cfg) - { - EXLOGE("invalid init args(3).\n"); - return false; - } + if (nullptr == args->cfg) { + EXLOGE("invalid init args(3).\n"); + return false; + } - if (!_on_init(args)) - { - EXLOGE("invalid init args(4).\n"); - return false; - } + if (!_on_init(args)) { + EXLOGE("invalid init args(4).\n"); + return false; + } - return true; + return true; } diff --git a/server/tp_core/common/base_env.h b/server/tp_core/common/base_env.h index 316216d..fea1879 100644 --- a/server/tp_core/common/base_env.h +++ b/server/tp_core/common/base_env.h @@ -3,27 +3,27 @@ #include "protocol_interface.h" -class TppEnvBase -{ +class TppEnvBase { public: - TppEnvBase(); - virtual ~TppEnvBase(); + TppEnvBase(); - bool init(TPP_INIT_ARGS* args); + virtual ~TppEnvBase(); + + bool init(TPP_INIT_ARGS* args); public: - ex_wstr exec_path; - ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径 - ex_wstr replay_path; + ex_wstr exec_path; + ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径 + ex_wstr replay_path; - TPP_GET_CONNNECT_INFO_FUNC get_connect_info; - TPP_FREE_CONNECT_INFO_FUNC free_connect_info; - TPP_SESSION_BEGIN_FUNC session_begin; - TPP_SESSION_UPDATE_FUNC session_update; - TPP_SESSION_END_FUNC session_end; + TPP_GET_CONNECT_INFO_FUNC get_connect_info; + TPP_FREE_CONNECT_INFO_FUNC free_connect_info; + TPP_SESSION_BEGIN_FUNC session_begin; + TPP_SESSION_UPDATE_FUNC session_update; + TPP_SESSION_END_FUNC session_end; protected: - virtual bool _on_init(TPP_INIT_ARGS* args) = 0; + virtual bool _on_init(TPP_INIT_ARGS* args) = 0; }; #endif // __TS_BASE_ENV_H__ diff --git a/server/tp_core/common/protocol_interface.h b/server/tp_core/common/protocol_interface.h index bc201ec..4e80d1c 100644 --- a/server/tp_core/common/protocol_interface.h +++ b/server/tp_core/common/protocol_interface.h @@ -14,87 +14,87 @@ # define TPP_API #endif -#define TPP_CMD_INIT 0x00000000 -#define TPP_CMD_SET_RUNTIME_CFG 0x00000005 -#define TPP_CMD_KILL_SESSIONS 0x00000006 +#define TPP_CMD_INIT 0x00000000 +#define TPP_CMD_SET_RUNTIME_CFG 0x00000005 +#define TPP_CMD_KILL_SESSIONS 0x00000006 -typedef struct TPP_CONNECT_INFO -{ - char* sid; +typedef struct TPP_CONNECT_INFO { + char* sid; - // 与此连接信息相关的三个要素的ID - int user_id; - int host_id; - int acc_id; + // 与此连接信息相关的三个要素的ID + int user_id; + int host_id; + int acc_id; - char* user_username; // 申请本次连接的用户名 + char* user_username; // 申请本次连接的用户名 - char* host_ip; // 真正的远程主机IP(如果是直接连接模式,则与remote_host_ip相同) - char* conn_ip; // 要连接的远程主机的IP(如果是端口映射模式,则为路由主机的IP) - int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口) - char* client_ip; + char* host_ip; // 真正的远程主机IP(如果是直接连接模式,则与remote_host_ip相同) + char* conn_ip; // 要连接的远程主机的IP(如果是端口映射模式,则为路由主机的IP) + int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口) + char* client_ip; - char* acc_username; // 远程主机的账号 - char* acc_secret; // 远程主机账号的密码(或者私钥) - char* username_prompt; // for telnet - char* password_prompt; // for telnet + char* acc_username; // 远程主机的账号 + char* acc_secret; // 远程主机账号的密码(或者私钥) + char* username_prompt; // for telnet + char* password_prompt; // for telnet - int protocol_type; - int protocol_sub_type; - int protocol_flag; - int record_flag; - int auth_type; -}TPP_CONNECT_INFO; + int protocol_type; + int protocol_sub_type; + int protocol_flag; + int record_flag; + int auth_type; +} TPP_CONNECT_INFO; -typedef TPP_CONNECT_INFO* (*TPP_GET_CONNNECT_INFO_FUNC)(const char* sid); -typedef void(*TPP_FREE_CONNECT_INFO_FUNC)(TPP_CONNECT_INFO* info); -typedef bool(*TPP_SESSION_BEGIN_FUNC)(const TPP_CONNECT_INFO* info, int* db_id); -typedef bool(*TPP_SESSION_UPDATE_FUNC)(int db_id, int protocol_sub_type, int state); -typedef bool(*TPP_SESSION_END_FUNC)(const char* sid, int db_id, int ret); +typedef TPP_CONNECT_INFO* (* TPP_GET_CONNECT_INFO_FUNC)(const char* sid); + +typedef void(* TPP_FREE_CONNECT_INFO_FUNC)(TPP_CONNECT_INFO* info); + +typedef bool(* TPP_SESSION_BEGIN_FUNC)(const TPP_CONNECT_INFO* info, int* db_id); + +typedef bool(* TPP_SESSION_UPDATE_FUNC)(int db_id, int protocol_sub_type, int state); + +typedef bool(* TPP_SESSION_END_FUNC)(const char* sid, int db_id, int ret); -typedef struct TPP_INIT_ARGS -{ - ExLogger* logger; - ex_wstr exec_path; - ex_wstr etc_path; - ex_wstr replay_path; - ExIniFile* cfg; +typedef struct TPP_INIT_ARGS { + ExLogger* logger; + ex_wstr exec_path; + ex_wstr etc_path; + ex_wstr replay_path; + ExIniFile* cfg; - TPP_GET_CONNNECT_INFO_FUNC func_get_connect_info; - TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info; - TPP_SESSION_BEGIN_FUNC func_session_begin; - TPP_SESSION_UPDATE_FUNC func_session_update; - TPP_SESSION_END_FUNC func_session_end; -}TPP_INIT_ARGS; - -// typedef struct TPP_SET_CFG_ARGS { -// ex_u32 noop_timeout; // as second. -// }TPP_SET_CFG_ARGS; + TPP_GET_CONNECT_INFO_FUNC func_get_connect_info; + TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info; + TPP_SESSION_BEGIN_FUNC func_session_begin; + TPP_SESSION_UPDATE_FUNC func_session_update; + TPP_SESSION_END_FUNC func_session_end; +} TPP_INIT_ARGS; #ifdef __cplusplus extern "C" { #endif - TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args); - TPP_API ex_rv tpp_start(void); - TPP_API ex_rv tpp_stop(void); - TPP_API void tpp_timer(void); -// TPP_API void tpp_set_cfg(TPP_SET_CFG_ARGS* cfg_args); +TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args); +TPP_API ex_rv tpp_start(void); +TPP_API ex_rv tpp_stop(void); +TPP_API void tpp_timer(void); - TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param); +TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param); #ifdef __cplusplus } #endif -typedef ex_rv (*TPP_INIT_FUNC)(TPP_INIT_ARGS* init_args); -typedef ex_rv (*TPP_START_FUNC)(void); -typedef ex_rv(*TPP_STOP_FUNC)(void); -typedef void(*TPP_TIMER_FUNC)(void); -// typedef void(*TPP_SET_CFG_FUNC)(TPP_SET_CFG_ARGS* cfg_args); +typedef ex_rv (* TPP_INIT_FUNC)(TPP_INIT_ARGS* init_args); -typedef ex_rv(*TPP_COMMAND_FUNC)(ex_u32 cmd, const char* param); // param is a JSON formatted string. +typedef ex_rv (* TPP_START_FUNC)(void); + +typedef ex_rv(* TPP_STOP_FUNC)(void); + +typedef void(* TPP_TIMER_FUNC)(void); + +// param: a JSON formatted string. +typedef ex_rv(* TPP_COMMAND_FUNC)(ex_u32 cmd, const char* param); #endif // __TP_PROTOCOL_INTERFACE_H__ diff --git a/server/tp_core/core/main.cpp b/server/tp_core/core/main.cpp index acc8ea7..3c8a3bd 100644 --- a/server/tp_core/core/main.cpp +++ b/server/tp_core/core/main.cpp @@ -28,7 +28,7 @@ static ex_u8 g_run_type = RUN_UNKNOWN; #define EOM_CORE_SERVICE_NAME L"Teleport Core Service" -static bool _run_daemon(void); +static bool _run_daemon(); #ifdef EX_OS_WIN32 static int service_install() @@ -113,7 +113,7 @@ static bool _process_cmd_line(int argc, wchar_t** argv) } -static int _main_loop(void) +static int _main_loop() { if (g_run_type == RUN_CORE) return ts_main(); @@ -163,7 +163,7 @@ int _app_main(int argc, wchar_t** argv) if (g_run_type == RUN_STOP) { char url[1024] = {0}; - ex_strformat(url, 1023, "http://%s:%d/rpc?{\"method\":\"exit\"}", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port); + ex_strformat(url, 1023, R"(http://%s:%d/rpc?{"method":"exit"})", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port); ex_astr body; ts_http_get(url, body); ex_printf("%s\n", body.c_str()); @@ -195,8 +195,8 @@ int _app_main(int argc, wchar_t** argv) #endif static SERVICE_STATUS g_ServiceStatus = { 0 }; -static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = NULL; -HANDLE g_hWorkerThread = NULL; +static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = nullptr; +HANDLE g_hWorkerThread = nullptr; VOID WINAPI service_main(DWORD argc, wchar_t** argv); void WINAPI service_handler(DWORD fdwControl); @@ -212,9 +212,9 @@ int main() wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //вַ ret = _app_main(_argc, _argv); - + LocalFree(_argv); - _argv = NULL; + _argv = nullptr; return ret; } @@ -224,8 +224,8 @@ static bool _run_daemon(void) SERVICE_TABLE_ENTRY DispatchTable[2]; DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME; DispatchTable[0].lpServiceProc = service_main; - DispatchTable[1].lpServiceName = NULL; - DispatchTable[1].lpServiceProc = NULL; + DispatchTable[1].lpServiceName = nullptr; + DispatchTable[1].lpServiceProc = nullptr; if (!StartServiceCtrlDispatcher(DispatchTable)) { @@ -262,7 +262,7 @@ static void WINAPI service_handler(DWORD fdwControl) if (g_hWorkerThread) { // TerminateThread(g_hWorkerThread, 1); - // g_hWorkerThread = NULL; + // g_hWorkerThread = nullptr; g_exit_flag = true; g_ServiceStatus.dwWin32ExitCode = 0; @@ -307,8 +307,8 @@ VOID WINAPI service_main(DWORD argc, wchar_t** argv) } DWORD tid = 0; - g_hWorkerThread = CreateThread(NULL, 0, service_thread_func, NULL, 0, &tid); - if (NULL == g_hWorkerThread) + g_hWorkerThread = CreateThread(nullptr, 0, service_thread_func, nullptr, 0, &tid); + if (nullptr == g_hWorkerThread) { EXLOGE_WIN("CreateThread()"); @@ -345,7 +345,7 @@ int main(int argc, char** argv) memset(&act, 0, sizeof(act)); act.sa_sigaction = _sig_handler; act.sa_flags = SA_SIGINFO; - sigaction(SIGINT, &act, NULL); + sigaction(SIGINT, &act, nullptr); wchar_t** wargv = ex_make_wargv(argc, argv); int ret = _app_main(argc, wargv); @@ -359,12 +359,12 @@ void _sig_handler(int signum, siginfo_t* info, void* ptr) { if (signum == SIGINT || signum == SIGTERM) { - EXLOGW("\n[core] received signal SIGINT, exit now.\n"); + EXLOGW("[core] received signal SIGINT, exit now.\n"); g_exit_flag = true; } } -static bool _run_daemon(void) +static bool _run_daemon() { pid_t pid = fork(); if (pid < 0) @@ -382,7 +382,7 @@ static bool _run_daemon(void) { EXLOGE("[core] setsid() failed.\n"); assert(0); - exit(EXIT_FAILURE); + // exit(EXIT_FAILURE); } umask(0); @@ -399,14 +399,14 @@ static bool _run_daemon(void) } // now I'm second children. - int ret = chdir("/"); + chdir("/"); close(STDIN_FILENO); - int stdfd = open("/dev/null", O_RDWR); + int std_fd = open("/dev/null", O_RDWR); close(STDOUT_FILENO); close(STDERR_FILENO); - dup2(stdfd, STDOUT_FILENO); - dup2(stdfd, STDERR_FILENO); + dup2(std_fd, STDOUT_FILENO); + dup2(std_fd, STDERR_FILENO); return true; } diff --git a/server/tp_core/core/tp_tpp_mgr.cpp b/server/tp_core/core/tp_tpp_mgr.cpp index 6c2a392..6908d10 100644 --- a/server/tp_core/core/tp_tpp_mgr.cpp +++ b/server/tp_core/core/tp_tpp_mgr.cpp @@ -1,126 +1,108 @@ #include "tp_tpp_mgr.h" #include "ts_main.h" -// #include "ts_session.h" -// #include "ts_http_rpc.h" -// #include "ts_web_rpc.h" #include "ts_env.h" -// #include -// #include - TppManager g_tpp_mgr; extern ExLogger g_ex_logger; -bool TppManager::load_tpp(const ex_wstr& libname) -{ - ex_wstr filename; +bool TppManager::load_tpp(const ex_wstr& libname) { + ex_wstr filename; #ifdef EX_OS_WIN32 - filename = libname + L".dll"; + filename = libname + L".dll"; #elif defined (EX_OS_LINUX) filename = L"lib"; filename += libname; - filename += L".so"; + filename += L".so"; #elif defined (EX_OS_MACOS) - filename = L"lib"; + filename = L"lib"; filename += libname; - filename += L".dylib"; + filename += L".dylib"; #endif - ex_wstr libfile = g_env.m_exec_path; - ex_path_join(libfile, false, filename.c_str(), NULL); - EXLOGV(L"[core] load protocol lib: %ls\n", libfile.c_str()); + ex_wstr lib_file = g_env.m_exec_path; + ex_path_join(lib_file, false, filename.c_str(), nullptr); + EXLOGI(L"[core] load protocol lib: %ls\n", lib_file.c_str()); - TPP_LIB* lib = new TPP_LIB; + auto lib = new TPP_LIB; - lib->dylib = ex_dlopen(libfile.c_str()); - if (NULL == lib->dylib) - { - EXLOGE(L"[core] load dylib `%ls` failed.\n", libfile.c_str()); - delete lib; - return false; - } + lib->dylib = ex_dlopen(lib_file.c_str()); + if (nullptr == lib->dylib) { + EXLOGE(L"[core] load dylib `%ls` failed.\n", lib_file.c_str()); + delete lib; + return false; + } #ifdef EX_OS_WIN32 - lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init"); - lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start"); - lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop"); - lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer"); -// lib->set_cfg = (TPP_SET_CFG_FUNC)GetProcAddress(lib->dylib, "tpp_set_cfg"); - lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command"); + lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init"); + lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start"); + lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop"); + lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer"); + lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command"); #else - lib->init = (TPP_INIT_FUNC)dlsym(lib->dylib, "tpp_init"); - lib->start = (TPP_START_FUNC)dlsym(lib->dylib, "tpp_start"); - lib->stop = (TPP_STOP_FUNC)dlsym(lib->dylib, "tpp_stop"); - lib->timer = (TPP_TIMER_FUNC)dlsym(lib->dylib, "tpp_timer"); -// lib->set_cfg = (TPP_SET_CFG_FUNC)dlsym(lib->dylib, "tpp_set_cfg"); - lib->command = (TPP_COMMAND_FUNC)dlsym(lib->dylib, "tpp_command"); + lib->init = (TPP_INIT_FUNC) dlsym(lib->dylib, "tpp_init"); + lib->start = (TPP_START_FUNC) dlsym(lib->dylib, "tpp_start"); + lib->stop = (TPP_STOP_FUNC) dlsym(lib->dylib, "tpp_stop"); + lib->timer = (TPP_TIMER_FUNC) dlsym(lib->dylib, "tpp_timer"); + lib->command = (TPP_COMMAND_FUNC) dlsym(lib->dylib, "tpp_command"); #endif - if ( - lib->init == NULL - || lib->start == NULL - || lib->stop == NULL - || lib->timer == NULL - //|| lib->set_cfg == NULL - || lib->command == NULL - ) - { - EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", libfile.c_str()); - delete lib; - return false; - } + if ( + lib->init == nullptr + || lib->start == nullptr + || lib->stop == nullptr + || lib->timer == nullptr + || lib->command == nullptr + ) { + EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", lib_file.c_str()); + delete lib; + return false; + } - TPP_INIT_ARGS init_args; - init_args.logger = &g_ex_logger; - init_args.exec_path = g_env.m_exec_path; - init_args.etc_path = g_env.m_etc_path; - init_args.replay_path = g_env.m_replay_path; - init_args.cfg = &g_env.get_ini(); - init_args.func_get_connect_info = tpp_get_connect_info; - init_args.func_free_connect_info = tpp_free_connect_info; - init_args.func_session_begin = tpp_session_begin; - init_args.func_session_update = tpp_session_update; - init_args.func_session_end = tpp_session_end; + TPP_INIT_ARGS init_args; + init_args.logger = &g_ex_logger; + init_args.exec_path = g_env.m_exec_path; + init_args.etc_path = g_env.m_etc_path; + init_args.replay_path = g_env.m_replay_path; + init_args.cfg = &g_env.get_ini(); + init_args.func_get_connect_info = tpp_get_connect_info; + init_args.func_free_connect_info = tpp_free_connect_info; + init_args.func_session_begin = tpp_session_begin; + init_args.func_session_update = tpp_session_update; + init_args.func_session_end = tpp_session_end; - if (EXRV_OK != lib->init(&init_args)) - { - EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str()); - delete lib; - return false; - } - if (EXRV_OK != lib->start()) - { - EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str()); - delete lib; - return false; - } + if (EXRV_OK != lib->init(&init_args)) { + EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str()); + delete lib; + return false; + } + if (EXRV_OK != lib->start()) { + EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str()); + delete lib; + return false; + } - m_libs.push_back(lib); - return true; + m_libs.push_back(lib); + return true; } -void TppManager::stop_all(void) { - tpp_libs::iterator it = m_libs.begin(); - for (; it != m_libs.end(); ++it) - { - (*it)->stop(); - } +void TppManager::stop_all() { + for (auto& lib : m_libs) { + lib->stop(); + } } -void TppManager::timer(void) { - tpp_libs::iterator it = m_libs.begin(); - for (; it != m_libs.end(); ++it) - { - (*it)->timer(); - } +void TppManager::timer() { + for (auto& lib : m_libs) { + lib->timer(); + } } // void TppManager::set_config(int noop_timeout) { -// +// // TPP_SET_CFG_ARGS args; // args.noop_timeout = noop_timeout; -// +// // tpp_libs::iterator it = m_libs.begin(); // for (; it != m_libs.end(); ++it) // { @@ -129,16 +111,13 @@ void TppManager::timer(void) { // } void TppManager::set_runtime_config(const ex_astr& sp) { - tpp_libs::iterator it = m_libs.begin(); - for (; it != m_libs.end(); ++it) { - (*it)->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str()); - } + for (auto& lib : m_libs) { + lib->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str()); + } } void TppManager::kill_sessions(const ex_astr& sp) { - tpp_libs::iterator it = m_libs.begin(); - for (; it != m_libs.end(); ++it) { - (*it)->command(TPP_CMD_KILL_SESSIONS, sp.c_str()); - } + for (auto& lib : m_libs) { + lib->command(TPP_CMD_KILL_SESSIONS, sp.c_str()); + } } - diff --git a/server/tp_core/core/tp_tpp_mgr.h b/server/tp_core/core/tp_tpp_mgr.h index 47819a6..e741e2b 100644 --- a/server/tp_core/core/tp_tpp_mgr.h +++ b/server/tp_core/core/tp_tpp_mgr.h @@ -1,65 +1,65 @@ -#ifndef __TP_TPP_MGR_H__ -#define __TP_TPP_MGR_H__ - -#include "../common/protocol_interface.h" - -#include - -typedef struct TPP_LIB -{ - TPP_LIB() - { - dylib = NULL; - init = NULL; - } - ~TPP_LIB() - { - if (NULL != dylib) - ex_dlclose(dylib); - dylib = NULL; - } +#ifndef __TP_TPP_MGR_H__ +#define __TP_TPP_MGR_H__ - EX_DYLIB_HANDLE dylib; - TPP_INIT_FUNC init; - TPP_START_FUNC start; - TPP_STOP_FUNC stop; - TPP_TIMER_FUNC timer; -// TPP_SET_CFG_FUNC set_cfg; +#include "../common/protocol_interface.h" - TPP_COMMAND_FUNC command; -}TPP_LIB; +#include + +typedef struct TPP_LIB { + TPP_LIB() : + dylib(nullptr), + init(nullptr), + start(nullptr), + stop(nullptr), + timer(nullptr), + command(nullptr) { + } + + ~TPP_LIB() { + if (nullptr != dylib) + ex_dlclose(dylib); + dylib = nullptr; + } + + EX_DYLIB_HANDLE dylib; + TPP_INIT_FUNC init; + TPP_START_FUNC start; + TPP_STOP_FUNC stop; + TPP_TIMER_FUNC timer; + TPP_COMMAND_FUNC command; +} TPP_LIB; typedef std::list tpp_libs; -class TppManager -{ +class TppManager { public: - TppManager() - { - } - ~TppManager() - { - tpp_libs::iterator it = m_libs.begin(); - for (; it != m_libs.end(); ++it) - { - delete (*it); - } - m_libs.clear(); - } + TppManager() = default; - bool load_tpp(const ex_wstr& libfile); - void stop_all(void); - void timer(void); // Լ1һ - int count(void) { return m_libs.size(); } + ~TppManager() { + for (auto lib : m_libs) { + delete lib; + } + m_libs.clear(); + } - void set_config(int noop_timeout); - void set_runtime_config(const ex_astr& sp); - void kill_sessions(const ex_astr& sp); + bool load_tpp(const ex_wstr& lib_file); + + void stop_all(); + + void timer(); // Լ1һ + + int count() { + return m_libs.size(); + } + + void set_runtime_config(const ex_astr& sp); + + void kill_sessions(const ex_astr& sp); private: - tpp_libs m_libs; + tpp_libs m_libs; }; extern TppManager g_tpp_mgr; -#endif // __TP_TPP_MGR_H__ +#endif // __TP_TPP_MGR_H__ diff --git a/server/tp_core/core/ts_main.cpp b/server/tp_core/core/ts_main.cpp index 1d7e8b6..ea890ce 100644 --- a/server/tp_core/core/ts_main.cpp +++ b/server/tp_core/core/ts_main.cpp @@ -6,52 +6,53 @@ #include "tp_tpp_mgr.h" #include -#include +// #include bool g_exit_flag = false; -TPP_CONNECT_INFO *tpp_get_connect_info(const char *sid) { - TS_CONNECT_INFO sinfo; - bool ret = g_session_mgr.get_connect_info(sid, sinfo); +TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid) { + TS_CONNECT_INFO connect_info; + + bool ret = g_session_mgr.get_connect_info(sid, connect_info); if (!ret) - return NULL; + return nullptr; - TPP_CONNECT_INFO *info = (TPP_CONNECT_INFO *) calloc(1, sizeof(TPP_CONNECT_INFO)); + auto info = (TPP_CONNECT_INFO*) calloc(1, sizeof(TPP_CONNECT_INFO)); - info->sid = (char *) calloc(1, sinfo.sid.length() + 1); - ex_strcpy(info->sid, sinfo.sid.length() + 1, sinfo.sid.c_str()); - info->user_username = (char *) calloc(1, sinfo.user_username.length() + 1); - ex_strcpy(info->user_username, sinfo.user_username.length() + 1, sinfo.user_username.c_str()); - info->host_ip = (char *) calloc(1, sinfo.host_ip.length() + 1); - ex_strcpy(info->host_ip, sinfo.host_ip.length() + 1, sinfo.host_ip.c_str()); - info->conn_ip = (char *) calloc(1, sinfo.conn_ip.length() + 1); - ex_strcpy(info->conn_ip, sinfo.conn_ip.length() + 1, sinfo.conn_ip.c_str()); - info->client_ip = (char *) calloc(1, sinfo.client_ip.length() + 1); - ex_strcpy(info->client_ip, sinfo.client_ip.length() + 1, sinfo.client_ip.c_str()); - info->acc_username = (char *) calloc(1, sinfo.acc_username.length() + 1); - ex_strcpy(info->acc_username, sinfo.acc_username.length() + 1, sinfo.acc_username.c_str()); - info->acc_secret = (char *) calloc(1, sinfo.acc_secret.length() + 1); - ex_strcpy(info->acc_secret, sinfo.acc_secret.length() + 1, sinfo.acc_secret.c_str()); - info->username_prompt = (char *) calloc(1, sinfo.username_prompt.length() + 1); - ex_strcpy(info->username_prompt, sinfo.username_prompt.length() + 1, sinfo.username_prompt.c_str()); - info->password_prompt = (char *) calloc(1, sinfo.password_prompt.length() + 1); - ex_strcpy(info->password_prompt, sinfo.password_prompt.length() + 1, sinfo.password_prompt.c_str()); + info->sid = (char*) calloc(1, connect_info.sid.length() + 1); + ex_strcpy(info->sid, connect_info.sid.length() + 1, connect_info.sid.c_str()); + info->user_username = (char*) calloc(1, connect_info.user_username.length() + 1); + ex_strcpy(info->user_username, connect_info.user_username.length() + 1, connect_info.user_username.c_str()); + info->host_ip = (char*) calloc(1, connect_info.host_ip.length() + 1); + ex_strcpy(info->host_ip, connect_info.host_ip.length() + 1, connect_info.host_ip.c_str()); + info->conn_ip = (char*) calloc(1, connect_info.conn_ip.length() + 1); + ex_strcpy(info->conn_ip, connect_info.conn_ip.length() + 1, connect_info.conn_ip.c_str()); + info->client_ip = (char*) calloc(1, connect_info.client_ip.length() + 1); + ex_strcpy(info->client_ip, connect_info.client_ip.length() + 1, connect_info.client_ip.c_str()); + info->acc_username = (char*) calloc(1, connect_info.acc_username.length() + 1); + ex_strcpy(info->acc_username, connect_info.acc_username.length() + 1, connect_info.acc_username.c_str()); + info->acc_secret = (char*) calloc(1, connect_info.acc_secret.length() + 1); + ex_strcpy(info->acc_secret, connect_info.acc_secret.length() + 1, connect_info.acc_secret.c_str()); + info->username_prompt = (char*) calloc(1, connect_info.username_prompt.length() + 1); + ex_strcpy(info->username_prompt, connect_info.username_prompt.length() + 1, connect_info.username_prompt.c_str()); + info->password_prompt = (char*) calloc(1, connect_info.password_prompt.length() + 1); + ex_strcpy(info->password_prompt, connect_info.password_prompt.length() + 1, connect_info.password_prompt.c_str()); - info->user_id = sinfo.user_id; - info->host_id = sinfo.host_id; - info->acc_id = sinfo.acc_id; - info->conn_port = sinfo.conn_port; - info->protocol_type = sinfo.protocol_type; - info->protocol_sub_type = sinfo.protocol_sub_type; - info->protocol_flag = sinfo.protocol_flag; - info->record_flag = sinfo.record_flag; - info->auth_type = sinfo.auth_type; + info->user_id = connect_info.user_id; + info->host_id = connect_info.host_id; + info->acc_id = connect_info.acc_id; + info->conn_port = connect_info.conn_port; + info->protocol_type = connect_info.protocol_type; + info->protocol_sub_type = connect_info.protocol_sub_type; + info->protocol_flag = connect_info.protocol_flag; + info->record_flag = connect_info.record_flag; + info->auth_type = connect_info.auth_type; return info; } -void tpp_free_connect_info(TPP_CONNECT_INFO *info) { - if (NULL == info) +void tpp_free_connect_info(TPP_CONNECT_INFO* info) { + if (nullptr == info) return; g_session_mgr.free_connect_info(info->sid); @@ -68,190 +69,46 @@ void tpp_free_connect_info(TPP_CONNECT_INFO *info) { free(info); } -bool tpp_session_begin(const TPP_CONNECT_INFO *info, int *db_id) { - if (NULL == info || NULL == db_id) +bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id) { + if (nullptr == info || nullptr == db_id) return false; - TS_CONNECT_INFO sinfo; - sinfo.sid = info->sid; - sinfo.user_id = info->user_id; - sinfo.host_id = info->host_id; - sinfo.acc_id = info->acc_id; - sinfo.user_username = info->user_username; - sinfo.host_ip = info->host_ip; - sinfo.conn_ip = info->conn_ip; - sinfo.client_ip = info->client_ip; - sinfo.acc_username = info->acc_username; + TS_CONNECT_INFO connect_info; + connect_info.sid = info->sid; + connect_info.user_id = info->user_id; + connect_info.host_id = info->host_id; + connect_info.acc_id = info->acc_id; + connect_info.user_username = info->user_username; + connect_info.host_ip = info->host_ip; + connect_info.conn_ip = info->conn_ip; + connect_info.client_ip = info->client_ip; + connect_info.acc_username = info->acc_username; - sinfo.conn_port = info->conn_port; - sinfo.protocol_type = info->protocol_type; - sinfo.protocol_sub_type = info->protocol_sub_type; - sinfo.auth_type = info->auth_type; + connect_info.conn_port = info->conn_port; + connect_info.protocol_type = info->protocol_type; + connect_info.protocol_sub_type = info->protocol_sub_type; + connect_info.auth_type = info->auth_type; - return ts_web_rpc_session_begin(sinfo, *db_id); + return ts_web_rpc_session_begin(connect_info, *db_id); } bool tpp_session_update(int db_id, int protocol_sub_type, int state) { return ts_web_rpc_session_update(db_id, protocol_sub_type, state); } -bool tpp_session_end(const char *sid, int db_id, int ret) { +bool tpp_session_end(const char* sid, int db_id, int ret) { return ts_web_rpc_session_end(sid, db_id, ret); } -// typedef struct TPP_LIB -// { -// TPP_LIB() -// { -// dylib = NULL; -// init = NULL; -// } -// ~TPP_LIB() -// { -// if (NULL != dylib) -// ex_dlclose(dylib); -// dylib = NULL; -// } -// -// EX_DYLIB_HANDLE dylib; -// TPP_INIT_FUNC init; -// TPP_START_FUNC start; -// TPP_STOP_FUNC stop; -// TPP_TIMER_FUNC timer; -// }TPP_LIB; -// -// typedef std::list tpp_libs; -// -// class TppManager -// { -// public: -// TppManager() -// { -// } -// ~TppManager() -// { -// tpp_libs::iterator it = m_libs.begin(); -// for (; it != m_libs.end(); ++it) -// { -// delete (*it); -// } -// m_libs.clear(); -// } -// -// bool load_tpp(const ex_wstr& libfile); -// void stop_all(void); -// void timer(void); // Լ1һ -// int count(void) { return m_libs.size(); } -// -// private: -// tpp_libs m_libs; -// }; -// -// static TppManager g_tpp_mgr; -// extern ExLogger g_ex_logger; -// -// bool TppManager::load_tpp(const ex_wstr& libname) -// { -// ex_wstr filename; -// #ifdef EX_OS_WIN32 -// filename = libname + L".dll"; -// #elif defined (EX_OS_LINUX) -// filename = L"lib"; -// filename += libname; -// filename += L".so"; -// #elif defined (EX_OS_MACOS) -// filename = L"lib"; -// filename += libname; -// filename += L".dylib"; -// #endif -// -// ex_wstr libfile = g_env.m_exec_path; -// ex_path_join(libfile, false, filename.c_str(), NULL); -// EXLOGV(L"[core] load protocol lib: %ls\n", libfile.c_str()); -// -// TPP_LIB* lib = new TPP_LIB; -// -// lib->dylib = ex_dlopen(libfile.c_str()); -// if (NULL == lib->dylib) -// { -// EXLOGE(L"[core] load dylib `%ls` failed.\n", libfile.c_str()); -// delete lib; -// return false; -// } -// -// #ifdef EX_OS_WIN32 -// lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init"); -// lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start"); -// lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop"); -// lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer"); -// #else -// lib->init = (TPP_INIT_FUNC)dlsym(lib->dylib, "tpp_init"); -// lib->start = (TPP_START_FUNC)dlsym(lib->dylib, "tpp_start"); -// lib->stop = (TPP_STOP_FUNC)dlsym(lib->dylib, "tpp_stop"); -// lib->timer = (TPP_TIMER_FUNC)dlsym(lib->dylib, "tpp_timer"); -// #endif -// -// if (lib->init == NULL || lib->start == NULL || lib->stop == NULL || lib->timer == NULL) -// { -// EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", libfile.c_str()); -// delete lib; -// return false; -// } -// -// TPP_INIT_ARGS init_args; -// init_args.logger = &g_ex_logger; -// init_args.exec_path = g_env.m_exec_path; -// init_args.etc_path = g_env.m_etc_path; -// init_args.replay_path = g_env.m_replay_path; -// init_args.cfg = &g_env.get_ini(); -// init_args.func_get_connect_info = tpp_get_connect_info; -// init_args.func_free_connect_info = tpp_free_connect_info; -// init_args.func_session_begin = tpp_session_begin; -// init_args.func_session_update = tpp_session_update; -// init_args.func_session_end = tpp_session_end; -// -// if (EXRV_OK != lib->init(&init_args)) -// { -// EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str()); -// delete lib; -// return false; -// } -// if (EXRV_OK != lib->start()) -// { -// EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str()); -// delete lib; -// return false; -// } -// -// m_libs.push_back(lib); -// return true; -// } -// -// void TppManager::stop_all(void) { -// tpp_libs::iterator it = m_libs.begin(); -// for (; it != m_libs.end(); ++it) -// { -// (*it)->stop(); -// } -// } -// -// void TppManager::timer(void) { -// tpp_libs::iterator it = m_libs.begin(); -// for (; it != m_libs.end(); ++it) -// { -// (*it)->timer(); -// } -// } +int ts_main() { + ExIniFile& ini = g_env.get_ini(); -int ts_main(void) { - ExIniFile &ini = g_env.get_ini(); - - EXLOGI(L"\n"); - EXLOGI(L"###############################################################\n"); + EXLOGI("\n"); + EXLOGI("###############################################################\n"); EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str()); - EXLOGI(L"Teleport Core Server starting ...\n"); + EXLOGI("Teleport Core Server starting ...\n"); - ex_ini_sections &secs = ini.GetAllSections(); + ex_ini_sections& secs = ini.GetAllSections(); TsHttpRpc rpc; // öļе[protocol-xxx]СڣضӦЭ鶯̬ @@ -259,18 +116,18 @@ int ts_main(void) { do { if (!g_session_mgr.start()) { - EXLOGE(L"[core] failed to start session-id manager.\n"); + EXLOGE("[core] failed to start session-id manager.\n"); all_ok = false; break; } if (!rpc.init() || !rpc.start()) { - EXLOGE(L"[core] rpc init/start failed.\n"); + EXLOGE("[core] rpc init/start failed.\n"); all_ok = false; break; } - ex_ini_sections::iterator it = secs.begin(); + auto it = secs.begin(); for (; it != secs.end(); ++it) { if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) { ex_wstr libname; @@ -280,7 +137,7 @@ int ts_main(void) { bool enabled = false; it->second->GetBool(L"enabled", enabled, false); if (!enabled) { - EXLOGV(L"[core] `%ls` not enabled.\n", libname.c_str()); + EXLOGW(L"[core] `%ls` not enabled.\n", libname.c_str()); continue; } @@ -291,7 +148,7 @@ int ts_main(void) { } } - } while (0); + } while (false); if (0 == g_tpp_mgr.count()) { all_ok = false; @@ -304,17 +161,19 @@ int ts_main(void) { if (!g_exit_flag) { ts_web_rpc_register_core(); - EXLOGV("[core] ---- initialized, ready for service ----\n"); + EXLOGI("[core] ---- initialized, ready for service ----\n"); while (!g_exit_flag) { ex_sleep_ms(1000); g_tpp_mgr.timer(); } } - EXLOGW("[core] try to stop all thread and exit.\n"); + EXLOGI("[core] try to stop all thread and exit.\n"); g_tpp_mgr.stop_all(); rpc.stop(); g_session_mgr.stop(); + EXLOGI("[core] done.\n"); + return 0; } diff --git a/server/tp_core/core/ts_main.h b/server/tp_core/core/ts_main.h index a5a6588..9aee8e3 100644 --- a/server/tp_core/core/ts_main.h +++ b/server/tp_core/core/ts_main.h @@ -3,13 +3,13 @@ #include "../common/protocol_interface.h" -int ts_main(void); +int ts_main(); -TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid); -void tpp_free_connect_info(TPP_CONNECT_INFO* info); -bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id); -bool tpp_session_update(int db_id, int protocol_sub_type, int state); -bool tpp_session_end(const char* sid, int db_id, int ret); +TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid); +void tpp_free_connect_info(TPP_CONNECT_INFO* info); +bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id); +bool tpp_session_update(int db_id, int protocol_sub_type, int state); +bool tpp_session_end(const char* sid, int db_id, int ret); #endif // __TS_MAIN_H__ diff --git a/server/tp_core/core/ts_session.cpp b/server/tp_core/core/ts_session.cpp index ae6ca97..ccc125d 100644 --- a/server/tp_core/core/ts_session.cpp +++ b/server/tp_core/core/ts_session.cpp @@ -11,7 +11,7 @@ TsSessionManager::TsSessionManager() : } TsSessionManager::~TsSessionManager() { - ts_connections::iterator it_conn = m_connections.begin(); + auto it_conn = m_connections.begin(); for (; it_conn != m_connections.end(); ++it_conn) { EXLOGD("[core] m_connections not clean: %s, %s\n", it_conn->first.c_str(), it_conn->second->acc_username.c_str()); delete it_conn->second; @@ -19,7 +19,7 @@ TsSessionManager::~TsSessionManager() { m_connections.clear(); } -void TsSessionManager::_thread_loop(void) { +void TsSessionManager::_thread_loop() { for (;;) { ex_sleep_ms(1000); if (m_need_stop) @@ -28,13 +28,13 @@ void TsSessionManager::_thread_loop(void) { } } -void TsSessionManager::_remove_expired_connect_info(void) { +void TsSessionManager::_remove_expired_connect_info() { // 超过15秒未进行连接的connect-info会被移除 ExThreadSmartLock locker(m_lock); ex_u64 _now = ex_get_tick_count(); - ts_connections::iterator it = m_connections.begin(); + auto it = m_connections.begin(); for (; it != m_connections.end();) { //EXLOGD("[core] check expired connect info: [%s] %d, %d %d %d\n", it->first.c_str(), it->second->ref_count, int(_now), int(it->second->ticket_start), int(_now - it->second->ticket_start)); if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start) { @@ -42,16 +42,17 @@ void TsSessionManager::_remove_expired_connect_info(void) { delete it->second; m_connections.erase(it++); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); - } else { + } + else { ++it; } } } -bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &info) { +bool TsSessionManager::get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info) { ExThreadSmartLock locker(m_lock); - ts_connections::iterator it = m_connections.find(sid); + auto it = m_connections.find(sid); if (it == m_connections.end()) return false; @@ -79,10 +80,10 @@ bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &inf return true; } -bool TsSessionManager::free_connect_info(const ex_astr &sid) { +bool TsSessionManager::free_connect_info(const ex_astr& sid) { ExThreadSmartLock locker(m_lock); - ts_connections::iterator it = m_connections.find(sid); + auto it = m_connections.find(sid); if (it == m_connections.end()) return false; @@ -97,7 +98,8 @@ bool TsSessionManager::free_connect_info(const ex_astr &sid) { m_connections.erase(it); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); } - } else { + } + else { if (it->second->ref_count == 1) it->second->ref_count = 0; it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒,这样如果没有发生RDP的第二次连接,这个连接信息就会在一分钟后被清除。 @@ -107,11 +109,14 @@ bool TsSessionManager::free_connect_info(const ex_astr &sid) { return true; } -bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) { +bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info) { ExThreadSmartLock locker(m_lock); - EXLOGD("[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", info->acc_username.c_str(), - info->protocol_type, info->auth_type); + EXLOGD( + "[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", + info->acc_username.c_str(), + info->protocol_type, info->auth_type + ); ex_astr _sid; int retried = 0; @@ -143,7 +148,7 @@ bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) { return true; } -void TsSessionManager::_gen_session_id(ex_astr &sid, const TS_CONNECT_INFO *info, int len) { +void TsSessionManager::_gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len) { mbedtls_sha1_context sha; ex_u8 sha_digist[20] = {0}; @@ -152,11 +157,11 @@ void TsSessionManager::_gen_session_id(ex_astr &sid, const TS_CONNECT_INFO *info mbedtls_sha1_init(&sha); mbedtls_sha1_starts(&sha); - mbedtls_sha1_update(&sha, (const unsigned char *) &_tick, sizeof(ex_u64)); - mbedtls_sha1_update(&sha, (const unsigned char *) &_tid, sizeof(ex_u64)); - mbedtls_sha1_update(&sha, (const unsigned char *) info->conn_ip.c_str(), info->conn_ip.length()); - mbedtls_sha1_update(&sha, (const unsigned char *) info->client_ip.c_str(), info->client_ip.length()); - mbedtls_sha1_update(&sha, (const unsigned char *) info->acc_username.c_str(), info->acc_username.length()); + mbedtls_sha1_update(&sha, (const unsigned char*) &_tick, sizeof(ex_u64)); + mbedtls_sha1_update(&sha, (const unsigned char*) &_tid, sizeof(ex_u64)); + mbedtls_sha1_update(&sha, (const unsigned char*) info->conn_ip.c_str(), info->conn_ip.length()); + mbedtls_sha1_update(&sha, (const unsigned char*) info->client_ip.c_str(), info->client_ip.length()); + mbedtls_sha1_update(&sha, (const unsigned char*) info->acc_username.c_str(), info->acc_username.length()); mbedtls_sha1_finish(&sha, sha_digist); mbedtls_sha1_free(&sha); diff --git a/server/tp_core/core/ts_session.h b/server/tp_core/core/ts_session.h index e227351..1e82a0b 100644 --- a/server/tp_core/core/ts_session.h +++ b/server/tp_core/core/ts_session.h @@ -6,68 +6,65 @@ #include -typedef struct TS_CONNECT_INFO -{ - // TODO: - //TPP_CONNECT_INFO conn; +typedef struct TS_CONNECT_INFO { + ex_astr sid; - ex_astr sid; + // ϢصҪصID + int user_id; + int host_id; + int acc_id; - // ϢصҪصID - int user_id; - int host_id; - int acc_id; + ex_astr user_username;// 뱾ӵû - ex_astr user_username;// 뱾ӵû + ex_astr host_ip;// ԶIPֱģʽremote_host_ipͬ + ex_astr conn_ip;// ҪӵԶIPǶ˿ӳģʽΪ·IP + int conn_port;// ҪӵԶĶ˿ڣǶ˿ӳģʽΪ·Ķ˿ڣ + ex_astr client_ip; - ex_astr host_ip;// ԶIPֱģʽremote_host_ipͬ - ex_astr conn_ip;// ҪӵԶIPǶ˿ӳģʽΪ·IP - int conn_port;// ҪӵԶĶ˿ڣǶ˿ӳģʽΪ·Ķ˿ڣ - ex_astr client_ip; + ex_astr acc_username; // Զ˺ + ex_astr acc_secret; // Զ˺ŵ루˽Կ + ex_astr username_prompt;// for telnet + ex_astr password_prompt;// for telnet - ex_astr acc_username; // Զ˺ - ex_astr acc_secret; // Զ˺ŵ루˽Կ - ex_astr username_prompt;// for telnet - ex_astr password_prompt;// for telnet + int protocol_type; + int protocol_sub_type; + int protocol_flag; + int record_flag; + int auth_type; - int protocol_type; - int protocol_sub_type; - int protocol_flag; - int record_flag; - int auth_type; - - int ref_count;// ϢüϢδʹã򳬹30Զ - ex_u64 ticket_start;// ϢĴʱ䣨ڳʱδʹþٵĹܣ -}TS_CONNECT_INFO; + int ref_count;// ϢüϢδʹã򳬹30Զ + ex_u64 ticket_start;// ϢĴʱ䣨ڳʱδʹþٵĹܣ +} TS_CONNECT_INFO; typedef std::map ts_connections; // sid -> TS_CONNECT_INFO -class TsSessionManager : public ExThreadBase -{ +class TsSessionManager : public ExThreadBase { public: - TsSessionManager(); - ~TsSessionManager(); + TsSessionManager(); - // generate a sid for connection info. - bool request_session(ex_astr& sid, TS_CONNECT_INFO* info); + ~TsSessionManager() override; - // sidõϢü - bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info); - // üüΪ0ʱɾ֮ - bool free_connect_info(const ex_astr& sid); + // generate a sid for connection info. + bool request_session(ex_astr& sid, TS_CONNECT_INFO* info); + + // sidõϢü + bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info); + + // üüΪ0ʱɾ֮ + bool free_connect_info(const ex_astr& sid); protected: - void _thread_loop(void); + void _thread_loop() override; private: - void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len); + void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len); - // ʱ飬30δӵconnect-infoᱻƳ - void _remove_expired_connect_info(void); + // ʱ飬30δӵconnect-infoᱻƳ + void _remove_expired_connect_info(); private: - ExThreadLock m_lock; - ts_connections m_connections; + ExThreadLock m_lock; + ts_connections m_connections; }; extern TsSessionManager g_session_mgr; diff --git a/server/tp_core/core/ts_web_rpc.cpp b/server/tp_core/core/ts_web_rpc.cpp index 1ec813a..096d722 100644 --- a/server/tp_core/core/ts_web_rpc.cpp +++ b/server/tp_core/core/ts_web_rpc.cpp @@ -148,7 +148,7 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info) EXLOGE("got connection info from web-server, but not all info valid.\n"); return TPE_PARAM; } - + int user_id; int host_id; int acc_id; @@ -253,7 +253,6 @@ bool ts_web_rpc_session_begin(TS_CONNECT_INFO& info, int& record_id) jreq["param"]["protocol_sub_type"] = info.protocol_sub_type; ex_astr json_param; - //json_param = json_writer.write(jreq); Json::StreamWriterBuilder jwb; std::unique_ptr jwriter(jwb.newStreamWriter()); ex_aoss os; @@ -276,16 +275,13 @@ bool ts_web_rpc_session_begin(TS_CONNECT_INFO& info, int& record_id) return false; } - //Json::Reader jreader; Json::Value jret; - //if (!jreader.parse(body.c_str(), jret)) Json::CharReaderBuilder jcrb; std::unique_ptr const jreader(jcrb.newCharReader()); const char *str_json_begin = body.c_str(); ex_astr err; - //if (!jreader.parse(func_args.c_str(), jsRoot)) { if (!jreader->parse(str_json_begin, str_json_begin + body.length(), &jret, &err)) return false; if (!jret.isObject()) @@ -346,7 +342,7 @@ bool ts_web_rpc_session_end(const char* sid, int record_id, int ret_code) ex_aoss os; jwriter->write(jreq, &os); json_param = os.str(); - + ex_astr param; ts_url_encode(json_param.c_str(), param); diff --git a/server/tp_core/protocol/ssh/ssh_channel_pair.cpp b/server/tp_core/protocol/ssh/ssh_channel_pair.cpp index 14b9467..3d405bd 100644 --- a/server/tp_core/protocol/ssh/ssh_channel_pair.cpp +++ b/server/tp_core/protocol/ssh/ssh_channel_pair.cpp @@ -4,78 +4,66 @@ #include -SshChannelPair::SshChannelPair(SshSession *_owner, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) : - m_owner(_owner), - rsc_tp2cli(_rsc_tp2cli), - rsc_tp2srv(_rsc_tp2srv) -{ +SshChannelPair::SshChannelPair(SshSession* _owner, uint32_t dbg_id, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) : + m_owner(_owner), + m_dbg_id(dbg_id), + type(TS_SSH_CHANNEL_TYPE_UNKNOWN), + win_width(0), + rsc_tp2cli(_rsc_tp2cli), + rsc_tp2srv(_rsc_tp2srv) { last_access_timestamp = (ex_u32) time(nullptr); + ex_strformat(m_dbg_name, 128, "%s-%d", m_owner->dbg_name().c_str(), dbg_id); - state = TP_SESS_STAT_RUNNING; - db_id = 0; - channel_id = 0; + state = TP_SESS_STAT_RUNNING; + db_id = 0; - win_width = 0; is_first_server_data = true; - need_close = false; - - m_is_cmd_mode = false; - m_recv_prompt = false; - m_client_last_char = 0; + need_close = false; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; } -SshChannelPair::~SshChannelPair() -{ -} +SshChannelPair::~SshChannelPair() = default; -void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t len) -{ +void SshChannelPair::process_pty_data_from_client(const uint8_t* data, uint32_t len) { if (data == nullptr || len == 0) return; - if (len == 1) - { - if (data[0] == 0x0d) - { + if (len == 1) { + if (data[0] == 0x0d) { // 0x0d 回车键 - if (!m_cmd.empty()) - EXLOGD("[%s] CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str()); + if (!m_cmd.empty()) { + // EXLOGD("[%s] CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str()); + rec.record_command(0, m_cmd.str()); + } m_cmd.reset(); m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input single RETURN.\n"); return; } - else if (data[0] == 0x03) - { + else if (data[0] == 0x03) { // 0x03 Ctrl-C m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input Ctrl-C.\n"); return; } - else if (data[0] == 0x09) - { + else if (data[0] == 0x09) { // 0x09 TAB键 - if (m_pty_stat == PTY_STAT_WAIT_CLIENT_INPUT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_PRESSED) - { + if (m_pty_stat == PTY_STAT_WAIT_CLIENT_INPUT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_PRESSED) { m_pty_stat = PTY_STAT_TAB_PRESSED; // EXLOGD("------ turn to PTY_STAT_TAB_PRESSED, input TAB.\n"); return; } } - else if (data[0] == 0x7f) - { + else if (data[0] == 0x7f) { // 7f backspace 回删键 m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input BACKSPACE.\n"); return; } } - else if (len == 3) - { - if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44)) - { + else if (len == 3) { + if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44)) { // 1b 5b 41 (上箭头) // 1b 5b 42 (下箭头) // 1b 5b 43 (右箭头) @@ -85,10 +73,8 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t return; } } - else if (len == 4) - { - if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e) - { + else if (len == 4) { + if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e) { // 1b 5b 33 7e (删除一个字符) m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input DEL.\n"); @@ -96,44 +82,36 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t } } - if (len >= 512) - { - if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) - { + if (len >= 512) { + if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) { m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input too large.\n"); } return; } - int return_count = 0; - bool valid_input = true; + int return_count = 0; + bool valid_input = true; - int offset = 0; + int offset = 0; int last_return_pos = 0; - for (; offset < len;) - { + for (; offset < len;) { uint8_t ch = data[offset]; - switch (ch) - { + switch (ch) { case 0x1b: - if (offset + 1 < len) - { - if (data[offset + 1] == 0x5b) - { + if (offset + 1 < len) { + if (data[offset + 1] == 0x5b) { valid_input = false; break; } } break; - case 0x0d: - return_count++; + case 0x0d:return_count++; last_return_pos = offset; break; - default: - break; + default:break; } if (!valid_input) @@ -142,33 +120,29 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t offset++; } - if (!valid_input) - { - if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) - { + if (!valid_input) { + if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) { m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input invalid.\n"); } return; } - if (return_count > 0) - { - std::string tmp_cmd((const char *) data, last_return_pos + 1); + if (return_count > 0) { + std::string tmp_cmd((const char*) data, last_return_pos + 1); EXLOGD("[%s] Paste CMD=[%s]\n", m_owner->dbg_name().c_str(), tmp_cmd.c_str()); + rec.record_command(1, tmp_cmd); m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, maybe paste.\n"); } - else - { + else { m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input something.\n"); } } -void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t len) -{ +void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t len) { if (data == nullptr || len == 0) return; @@ -176,32 +150,26 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT - || m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) - { - if (_contains_cmd_prompt(data, len)) - { + || m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) { + if (_contains_cmd_prompt(data, len)) { contains_prompt = true; - if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT) - { + if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT) { // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after exec.\n"); m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; return; } - else if (m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT) - { + else if (m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT) { // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after TAB.\n"); m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; return; } - else if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) - { + else if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) { // EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv prompt while multi-exec.\n"); m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; return; } - else if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) - { + else if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) { // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt while wait echo.\n"); m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; m_cmd.reset(); @@ -210,46 +178,39 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t } } - if (!contains_prompt) - { + if (!contains_prompt) { if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT - || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) - { + || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) { return; } } if (!( - m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO - || m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD - || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT - || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT - || m_pty_stat == PTY_STAT_TAB_PRESSED - )) - { + m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO + || m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD + || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT + || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT + || m_pty_stat == PTY_STAT_TAB_PRESSED + )) { // EXLOGD("------ keep PTY_STAT, recv but not in ECHO or multi-cmd mode.\n"); return; } - if (len > 512) - { + if (len > 512) { // EXLOGD("------ keep PTY_STAT, recv too large.\n"); return; } // 处理输入回显,合成最终的命令行字符串 - int offset = 0; + int offset = 0; bool esc_mode = false; - int esc_arg = 0; - for (; offset < len;) - { + int esc_arg = 0; + for (; offset < len;) { uint8_t ch = data[offset]; - if (esc_mode) - { - switch (ch) - { + if (esc_mode) { + switch (ch) { case '0': case '1': case '2': @@ -259,30 +220,24 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t case '6': case '7': case '8': - case '9': - esc_arg = esc_arg * 10 + (ch - '0'); + case '9':esc_arg = esc_arg * 10 + (ch - '0'); break; case 0x3f: case ';': - case '>': - m_cmd.reset(); + case '>':m_cmd.reset(); return; - case 0x4b: - { // 'K' - if (0 == esc_arg) - { + case 0x4b: { // 'K' + if (0 == esc_arg) { // 删除光标到行尾的字符串 m_cmd.erase_to_end(); } - else if (1 == esc_arg) - { + else if (1 == esc_arg) { // 删除从开始到光标处的字符串 m_cmd.erase_to_begin(); } - else if (2 == esc_arg) - { + else if (2 == esc_arg) { // 删除整行 m_cmd.reset(); } @@ -290,8 +245,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t esc_mode = false; break; } - case 0x43: - {// ^[C + case 0x43: {// ^[C // 光标右移 if (esc_arg == 0) esc_arg = 1; @@ -299,8 +253,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t esc_mode = false; break; } - case 0x44: - { // ^[D + case 0x44: { // ^[D // 光标左移 if (esc_arg == 0) esc_arg = 1; @@ -309,8 +262,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t break; } - case 0x50: - { + case 0x50: { // 'P' 删除指定数量的字符 if (esc_arg == 0) esc_arg = 1; @@ -319,8 +271,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t break; } - case 0x40: - { // '@' 插入指定数量的空白字符 + case 0x40: { // '@' 插入指定数量的空白字符 if (esc_arg == 0) esc_arg = 1; m_cmd.insert_white_space(esc_arg); @@ -328,8 +279,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t break; } - default: - esc_mode = false; + default:esc_mode = false; break; } @@ -337,25 +287,20 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t continue; } - switch (ch) - { + switch (ch) { case 0x07: // 响铃 break; - case 0x08: - { + case 0x08: { // 光标左移 m_cmd.cursor_move_left(1); break; } - case 0x1b: - { - if (offset + 1 < len) - { - if (data[offset + 1] == 0x5b) - { + case 0x1b: { + if (offset + 1 < len) { + if (data[offset + 1] == 0x5b) { esc_mode = true; - esc_arg = 0; + esc_arg = 0; offset += 1; } @@ -363,12 +308,9 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t break; } - case 0x0d: - { - if (offset + 1 < len && data[offset + 1] == 0x0a) - { - if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD) - { + case 0x0d: { + if (offset + 1 < len && data[offset + 1] == 0x0a) { + if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD) { if (!m_cmd.empty()) EXLOGD("[%s] one of multi-cmd, CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str()); m_cmd.reset(); @@ -376,14 +318,12 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t m_pty_stat = PTY_STAT_MULTI_CMD_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv 0x0d0a after multi-exec.\n"); - if (_contains_cmd_prompt(data, len)) - { + if (_contains_cmd_prompt(data, len)) { m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt after multi-exec.\n"); } } - else if (m_pty_stat == PTY_STAT_TAB_PRESSED) - { + else if (m_pty_stat == PTY_STAT_TAB_PRESSED) { m_pty_stat = PTY_STAT_TAB_WAIT_PROMPT; // EXLOGD("------ turn to PTY_STAT_TAB_WAIT_PROMPT, recv 0d0a after TAB pressed.\n"); } @@ -392,10 +332,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t break; } - default: - m_cmd.replace(ch); - if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) - { + default:m_cmd.replace(ch); + if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) { m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n"); } @@ -405,15 +343,13 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t offset++; } - if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT && contains_prompt) - { + if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT && contains_prompt) { m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt.\n"); } } -bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) -{ +bool SshChannelPair::_contains_cmd_prompt(const uint8_t* data, uint32_t len) { // 正常情况下,收到的服务端数据(一包数据不会太大,可以考虑限定在512字节范围内),从后向前查找 0x07,它的位置 // 应该位于倒数256字节范围内(这之后的数据可能是命令行提示符的内容了,不会太长的)。继续向前找,应该能够找到正 // 序为 1b 5d 30/31/32/33 3b ... 直到刚才的 07。满足这样格式的,99%可能处于命令行模式了,还有1%可能是Mac @@ -434,21 +370,19 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) bool found_0x07 = false; bool found_0x3b = false; - bool found_Ps = false; + bool found_Ps = false; bool found_0x5d = false; int offset = static_cast(len) - 1; - for (int i = 0; offset >= 0; i++) - { + for (int i = 0; offset >= 0; i++) { if (i > 256) return false; if (found_0x5d) return (data[offset] == 0x1b); - if (found_Ps) - { + if (found_Ps) { found_0x5d = (data[offset] == 0x5d); if (!found_0x5d) return false; @@ -456,8 +390,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) continue; } - if (found_0x3b) - { + if (found_0x3b) { found_Ps = (data[offset] == 0x30 || data[offset] == 0x31 || data[offset] == 0x32); if (!found_Ps) return false; @@ -465,8 +398,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) continue; } - if (!found_0x07) - { + if (!found_0x07) { found_0x07 = (data[offset] == 0x07); offset--; continue; @@ -479,8 +411,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) return false; } -void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, uint32_t len) -{ +void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t* data, uint32_t len) { // SFTP protocol: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 // EXLOG_BIN(data, len, "[sftp] client channel data"); @@ -502,8 +433,7 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u ex_u8 sftp_cmd = data[4]; - if (sftp_cmd == 0x01) - { + if (sftp_cmd == 0x01) { // 0x01 = 1 = SSH_FXP_INIT rec.record_command(0, "SFTP INITIALIZE\r\n"); EXLOGD("[sftp-%s] SFTP INITIALIZE\n", m_owner->dbg_name().c_str()); @@ -516,16 +446,15 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u 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]); + 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 = nullptr;// (ex_u8*)data + 13; - int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]); + ex_u8* str2_ptr = nullptr;// (ex_u8*)data + 13; + int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]); - switch (sftp_cmd) - { + switch (sftp_cmd) { case 0x03: // 0x03 = 3 = SSH_FXP_OPEN EXLOGD("[sftp-%s] SSH_FXP_OPEN\n", m_owner->dbg_name().c_str()); @@ -560,8 +489,7 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u str2_len = (int) ((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]); EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str()); break; - default: - return; + default:return; } int total_len = 5 + str1_len + 4; @@ -570,16 +498,14 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u if (total_len > pkg_len) return; - char msg[2048] = { 0 }; - if (str2_len == 0) - { - ex_astr str1((char *) ((ex_u8 *) data + 13), str1_len); + char msg[2048] = {0}; + if (str2_len == 0) { + ex_astr str1((char*) ((ex_u8*) data + 13), str1_len); ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str()); } - else - { - ex_astr str1((char *) (str1_ptr + 4), str1_len); - ex_astr str2((char *) (str2_ptr + 4), str2_len); + else { + ex_astr str1((char*) (str1_ptr + 4), str1_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()); } @@ -587,21 +513,20 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u rec.record_command(0, msg); } -bool SshChannelPair::record_begin(const TPP_CONNECT_INFO *conn_info) -{ +bool SshChannelPair::record_begin(const TPP_CONNECT_INFO* conn_info) { #ifndef TEST_SSH_SESSION_000000 if (!g_ssh_env.session_begin(conn_info, &db_id)) { - EXLOGE("[ssh] can not save to database, channel begin failed.\n"); + EXLOGE("[%s] can not save to database, channel begin failed.\n", m_dbg_name.c_str()); return false; } - else { - channel_id = db_id; - // EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id); - } + // else { + // channel_id = db_id; + // // EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id); + // } if (!g_ssh_env.session_update(db_id, conn_info->protocol_sub_type, TP_SESS_STAT_STARTED)) { - EXLOGE("[ssh] [channel:%d] can not update state, cannel begin failed.\n", channel_id); + EXLOGE("[%s] can not update state, cannel begin failed.\n", m_dbg_name.c_str()); return false; } @@ -611,11 +536,10 @@ bool SshChannelPair::record_begin(const TPP_CONNECT_INFO *conn_info) return true; } -void SshChannelPair::record_end() -{ +void SshChannelPair::record_end() { #ifndef TEST_SSH_SESSION_000000 if (db_id > 0) { - // EXLOGD("[ssh] [channel:%d] channel end with code: %d\n", cp->channel_id, cp->state); + EXLOGD("[%s] channel end with code: %d\n", m_dbg_name.c_str(), state); // 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值 if (state == TP_SESS_STAT_RUNNING || state == TP_SESS_STAT_STARTED) @@ -626,7 +550,7 @@ void SshChannelPair::record_end() db_id = 0; } else { - // EXLOGD("[ssh] [channel:%d] when channel end, no db-id.\n", cp->channel_id); + EXLOGD("[%s] when channel end, no db-id.\n", m_dbg_name.c_str()); } #endif } @@ -636,17 +560,13 @@ void SshChannelPair::record_end() // SshCommand // ================================================== -SshCommand::SshCommand() -{ +SshCommand::SshCommand() { m_cmd.clear(); m_pos = m_cmd.begin(); } -SshCommand::~SshCommand() -{ -} +SshCommand::~SshCommand() = default; -void SshCommand::_dump(const char *msg) -{ +void SshCommand::_dump(const char* msg) { // EXLOGD("CMD-BUFFER: %s [%s]\n", msg, str().c_str()); } diff --git a/server/tp_core/protocol/ssh/ssh_channel_pair.h b/server/tp_core/protocol/ssh/ssh_channel_pair.h index 0d4ac0d..d410903 100644 --- a/server/tp_core/protocol/ssh/ssh_channel_pair.h +++ b/server/tp_core/protocol/ssh/ssh_channel_pair.h @@ -8,53 +8,46 @@ class SshSession; -class SshCommand -{ +class SshCommand { public: SshCommand(); + virtual ~SshCommand(); - void reset() - { + void reset() { m_cmd.clear(); m_pos = m_cmd.end(); _dump("reset"); } - std::string str() - { + std::string str() { if (empty()) return ""; else return std::string(m_cmd.begin(), m_cmd.end()); } - bool empty() const - { + bool empty() const { return m_cmd.empty(); } - void erase_to_end() - { + void erase_to_end() { // 删除光标到行尾的字符串 m_cmd.erase(m_pos, m_cmd.end()); m_pos = m_cmd.end(); _dump("erase to end"); } - void erase_to_begin() - { + void erase_to_begin() { // 删除从开始到光标处的字符串 m_cmd.erase(m_cmd.begin(), m_pos); m_pos = m_cmd.begin(); _dump("erase to begin"); } - void cursor_move_right(int count) - { + void cursor_move_right(int count) { // 光标右移 - for (int i = 0; i < count; ++i) - { + for (int i = 0; i < count; ++i) { if (m_pos != m_cmd.end()) m_pos++; else @@ -63,11 +56,9 @@ public: _dump("cursor move right"); } - void cursor_move_left(int count) - { + void cursor_move_left(int count) { // 光标左移 - for (int i = 0; i < count; ++i) - { + for (int i = 0; i < count; ++i) { if (m_pos != m_cmd.begin()) m_pos--; else @@ -76,11 +67,9 @@ public: _dump("cursor move left"); } - void erase_chars(int count) - { + void erase_chars(int count) { // 删除指定数量的字符 - for (int i = 0; i < count; ++i) - { + for (int i = 0; i < count; ++i) { if (m_pos != m_cmd.end()) m_pos = m_cmd.erase(m_pos); else @@ -89,26 +78,21 @@ public: _dump("erase char"); } - void insert_white_space(int count) - { + void insert_white_space(int count) { // 插入指定数量的空白字符 - for (int i = 0; i < count; ++i) - { + for (int i = 0; i < count; ++i) { m_pos = m_cmd.insert(m_pos, ' '); } _dump("insert white space"); } - void replace(uint8_t ch) - { - if (m_pos != m_cmd.end()) - { + void replace(uint8_t ch) { + if (m_pos != m_cmd.end()) { m_pos = m_cmd.erase(m_pos); m_pos = m_cmd.insert(m_pos, ch); m_pos++; } - else - { + else { m_cmd.push_back(ch); //cmd_char_pos = cmd_char_list.end(); m_pos = m_cmd.end(); @@ -116,17 +100,13 @@ public: _dump("replace char"); } - void insert(const uint8_t *data, int len) - { - for (int i = 0; i < len; ++i) - { - if (m_pos == m_cmd.end()) - { + void insert(const uint8_t* data, int len) { + for (int i = 0; i < len; ++i) { + if (m_pos == m_cmd.end()) { m_cmd.push_back(data[i]); m_pos = m_cmd.end(); } - else - { + else { m_pos = m_cmd.insert(m_pos, data[i]); m_pos++; } @@ -134,15 +114,12 @@ public: _dump("insert chars"); } - void insert(uint8_t ch) - { - if (m_pos == m_cmd.end()) - { + void insert(uint8_t ch) { + if (m_pos == m_cmd.end()) { m_cmd.push_back(ch); m_pos = m_cmd.end(); } - else - { + else { m_pos = m_cmd.insert(m_pos, ch); m_pos++; } @@ -150,16 +127,15 @@ public: } protected: - void _dump(const char *msg); + void _dump(const char* msg); private: - std::list m_cmd; + std::list m_cmd; std::list::iterator m_pos; }; // SSH命令解析,有限状态机状态值 -enum PTY_STAT -{ +enum PTY_STAT { PTY_STAT_NORMAL_WAIT_PROMPT = 0, PTY_STAT_MULTI_CMD_WAIT_PROMPT, PTY_STAT_TAB_PRESSED, @@ -170,35 +146,37 @@ enum PTY_STAT }; -class SshChannelPair -{ +class SshChannelPair { friend class SshSession; public: - SshChannelPair(SshSession *owner, ssh_channel rsc_tp2cli, ssh_channel rsc_tp2srv); + SshChannelPair(SshSession* owner, uint32_t dbg_id, ssh_channel rsc_tp2cli, ssh_channel rsc_tp2srv); virtual ~SshChannelPair(); - void process_pty_data_from_client(const uint8_t *data, uint32_t len); - void process_pty_data_from_server(const uint8_t *data, uint32_t len); + void process_pty_data_from_client(const uint8_t* data, uint32_t len); + + void process_pty_data_from_server(const uint8_t* data, uint32_t len); - void process_sftp_command(ssh_channel ch, const uint8_t *data, uint32_t len); + void process_sftp_command(ssh_channel ch, const uint8_t* data, uint32_t len); // when client<->server channel created, start to record. - bool record_begin(const TPP_CONNECT_INFO *conn_info); + bool record_begin(const TPP_CONNECT_INFO* conn_info); // stop record because channel closed. void record_end(); protected: - bool _contains_cmd_prompt(const uint8_t *data, uint32_t len); + bool _contains_cmd_prompt(const uint8_t* data, uint32_t len); protected: - SshSession *m_owner; + SshSession* m_owner; + uint32_t m_dbg_id; + std::string m_dbg_name; - int win_width; // window width, in char count. int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP + int win_width; // window width, in char count. ssh_channel rsc_tp2cli; ssh_channel rsc_tp2srv; @@ -206,28 +184,18 @@ protected: uint32_t last_access_timestamp; TppSshRec rec; - int db_id; - + int db_id; int state; - int channel_id; // for debug only. bool is_first_server_data; bool need_close; - // 是否处于命令行输入模式 - bool m_is_cmd_mode; - bool m_recv_prompt; - uint8_t m_client_last_char; SshCommand m_cmd; -// uint32_t m_input_flag; - -// std::vector m_last_input; - PTY_STAT m_pty_stat; }; -typedef std::list TPChannelPairs; -typedef std::map channel_map; +typedef std::list TPChannelPairs; +typedef std::map channel_map; #endif //__SSH_CHANNEL_PAIR_H__ diff --git a/server/tp_core/protocol/ssh/ssh_proxy.cpp b/server/tp_core/protocol/ssh/ssh_proxy.cpp index 6790ac1..12b2d3b 100644 --- a/server/tp_core/protocol/ssh/ssh_proxy.cpp +++ b/server/tp_core/protocol/ssh/ssh_proxy.cpp @@ -4,46 +4,39 @@ SshProxy g_ssh_proxy; SshProxy::SshProxy() noexcept: - ExThreadBase("ssh-proxy-thread"), - m_bind(nullptr), - m_host_port(0) -{ + ExThreadBase("ssh-proxy-thread"), + m_bind(nullptr), + m_host_port(0) { m_timer_counter_check_noop = 0; m_timer_counter_keep_alive = 0; - m_noop_timeout_sec = 0;//900; // default to 15 minutes. - m_listener_running = false; - m_dbg_id = 0; + m_noop_timeout_sec = 0;//900; // default to 15 minutes. + m_listener_running = false; + m_dbg_id = 0; } -SshProxy::~SshProxy() -{ - if (m_bind) - { +SshProxy::~SshProxy() { + if (m_bind) { ssh_bind_free(m_bind); m_bind = nullptr; } } -bool SshProxy::init() -{ - m_host_ip = g_ssh_env.bind_ip; +bool SshProxy::init() { + m_host_ip = g_ssh_env.bind_ip; m_host_port = g_ssh_env.bind_port; m_bind = ssh_bind_new(); - if (!m_bind) - { + if (!m_bind) { EXLOGE("[ssh] can not create bind.\n"); 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"); 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"); return false; } @@ -53,15 +46,13 @@ bool SshProxy::init() ex_astr key_file; ex_wstr2astr(_key_file, key_file); - 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())) - { + EXLOGI("[ssh] loading 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())) { EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n"); return false; } - if (ssh_bind_listen(m_bind) < 0) - { + if (ssh_bind_listen(m_bind) < 0) { EXLOGE("[ssh] can not listen on port %d: %s\n", m_host_port, ssh_get_error(m_bind)); return false; } @@ -69,8 +60,7 @@ bool SshProxy::init() return true; } -void SshProxy::timer() -{ +void SshProxy::timer() { // timer() will be called per one second by tp_core main thread. m_timer_counter_check_noop++; @@ -78,18 +68,15 @@ void SshProxy::timer() { ExThreadSmartLock locker(m_lock); - for (auto it = m_sessions.begin(); it != m_sessions.end();) - { + for (auto it = m_sessions.begin(); it != m_sessions.end();) { // 检查通道是否已经关闭 it->first->check_channels(); // 检查会话是否已经关闭,如果会话已经完全关闭,则销毁之 - if (it->first->closed()) - { + if (it->first->closed()) { delete it->first; m_sessions.erase(it++); } - else - { + else { ++it; } } @@ -99,15 +86,13 @@ void SshProxy::timer() } // check no-op per 5 seconds. - if (m_timer_counter_check_noop >= 5) - { + if (m_timer_counter_check_noop >= 5) { auto t_now = (ex_u32) time(nullptr); m_timer_counter_check_noop = 0; ExThreadSmartLock locker(m_lock); - for (auto &session : m_sessions) - { + for (auto& session : m_sessions) { session.first->save_record(); if (0 != m_noop_timeout_sec) session.first->check_noop_timeout(t_now, m_noop_timeout_sec); @@ -115,21 +100,16 @@ void SshProxy::timer() } } -void SshProxy::set_cfg(ex_u32 noop_timeout) -{ +void SshProxy::set_cfg(ex_u32 noop_timeout) { m_noop_timeout_sec = noop_timeout; } -void SshProxy::kill_sessions(const ex_astrs &sessions) -{ +void SshProxy::kill_sessions(const ex_astrs& sessions) { ExThreadSmartLock locker(m_lock); - for (auto &session : m_sessions) - { - for (const auto &sid : sessions) - { - if (session.first->sid() == sid) - { + for (auto& session : m_sessions) { + for (const auto& sid : sessions) { + if (session.first->sid() == sid) { EXLOGW("[ssh] kill session %s\n", sid.c_str()); session.first->check_noop_timeout(0, 0); // 立即结束 break; @@ -138,14 +118,12 @@ 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); m_listener_running = true; - for (;;) - { + for (;;) { ssh_session rs_tp2cli = ssh_new(); // #ifdef EX_DEBUG @@ -153,39 +131,36 @@ void SshProxy::_thread_loop() // ssh_options_set(rs_tp2cli, SSH_OPTIONS_LOG_VERBOSITY, &flag); // #endif - if (ssh_bind_accept(m_bind, rs_tp2cli) != SSH_OK) - { + if (ssh_bind_accept(m_bind, rs_tp2cli) != SSH_OK) { EXLOGE("[ssh] accepting a connection failed: %s.\n", ssh_get_error(m_bind)); continue; } EXLOGD("[ssh] ssh_bind_accept() returned...\n"); - if (m_need_stop) - { + if (m_need_stop) { ssh_free(rs_tp2cli); break; } struct sockaddr_storage sock_client{}; - char ip[32] = { 0 }; - int len = sizeof(ip); + char ip[32] = {0}; + int len = sizeof(ip); #ifdef EX_OS_WIN32 getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, &len); #else - getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, (unsigned int *) &len); + getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr*) &sock_client, (unsigned int*) &len); #endif - auto addr = (sockaddr_in *) &sock_client; + auto addr = (sockaddr_in*) &sock_client; - if (0 != ex_ip4_name(addr, ip, sizeof(ip))) - { + if (0 != ex_ip4_name(addr, ip, sizeof(ip))) { EXLOGW("[ssh] can not parse client address into IP and port.\n"); } - uint32_t dbg_id = m_dbg_id++; - auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port); + uint32_t dbg_id = m_dbg_id++; + auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port); EXLOGW("[ssh] ------ NEW SSH SESSION [%s from %s:%d] ------\n", session->dbg_name().c_str(), ip, addr->sin_port); { @@ -201,15 +176,13 @@ void SshProxy::_thread_loop() ExThreadSmartLock locker(m_lock); - for (auto &session : m_sessions) - { + for (auto& session : m_sessions) { session.first->check_noop_timeout(0, 0); } } // 等待所有session完成关闭清理操作,工作线程退出 - for (;;) - { + for (;;) { // tp_core退出时会先停止timer线程,所以这里需要自己调用timer()来进行session状态检查 timer(); @@ -225,12 +198,10 @@ void SshProxy::_thread_loop() EXLOGV("[ssh] main-loop end.\n"); } -void SshProxy::_on_stop() -{ +void SshProxy::_on_stop() { ExThreadBase::_on_stop(); - if (m_is_running) - { + if (m_is_running) { // 用一个变通的方式来结束阻塞中的监听,就是连接一下它。 ex_astr host_ip = m_host_ip; if (host_ip == "0.0.0.0") @@ -250,8 +221,7 @@ void SshProxy::_on_stop() ex_sleep_ms(500); } - while (m_listener_running) - { + while (m_listener_running) { ex_sleep_ms(1000); } } diff --git a/server/tp_core/protocol/ssh/ssh_recorder.cpp b/server/tp_core/protocol/ssh/ssh_recorder.cpp index 0190493..6b6e0f0 100644 --- a/server/tp_core/protocol/ssh/ssh_recorder.cpp +++ b/server/tp_core/protocol/ssh/ssh_recorder.cpp @@ -7,15 +7,15 @@ TppSshRec::TppSshRec() { m_cmd_cache.reserve(MAX_SIZE_PER_FILE); memset(&m_head, 0, sizeof(TS_RECORD_HEADER)); - memcpy((ex_u8 *) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32)); + memcpy((ex_u8*) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32)); m_head.info.ver = 0x04; m_head.info.type = TS_TPPR_TYPE_SSH; m_header_changed = false; m_save_full_header = false; - m_file_info = NULL; - m_file_data = NULL; - m_file_cmd = NULL; + m_file_info = nullptr; + m_file_data = nullptr; + m_file_cmd = nullptr; } @@ -23,10 +23,10 @@ TppSshRec::~TppSshRec() { end(); } -bool TppSshRec::_on_begin(const TPP_CONNECT_INFO *info) { - if (NULL == info) +bool TppSshRec::_on_begin(const TPP_CONNECT_INFO* info) { + if (nullptr == info) return false; - m_head.basic.timestamp = (ex_u64) time(NULL); + m_head.basic.timestamp = (ex_u64) time(nullptr); m_head.basic.protocol_type = (ex_u16) info->protocol_type; m_head.basic.protocol_sub_type = (ex_u16) info->protocol_sub_type; m_head.basic.conn_port = (ex_u16) info->conn_port; @@ -44,11 +44,11 @@ bool TppSshRec::_on_end() { // 如果还有剩下未写入的数据,写入文件中。 save_record(); - if (m_file_info != NULL) + if (m_file_info != nullptr) fclose(m_file_info); - if (m_file_data != NULL) + if (m_file_data != nullptr) fclose(m_file_data); - if (m_file_cmd != NULL) + if (m_file_cmd != nullptr) fclose(m_file_cmd); return true; @@ -59,8 +59,8 @@ void TppSshRec::save_record() { _save_to_cmd_file(); } -void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) { - if (data == NULL || 0 == size) +void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) { + if (data == nullptr || 0 == size) return; if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE) @@ -77,7 +77,7 @@ void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) { m_header_changed = true; } - m_cache.append((ex_u8 *) &pkg, sizeof(TS_RECORD_PKG)); + m_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG)); m_cache.append(data, size); //m_head.info.packages++; @@ -94,11 +94,11 @@ void TppSshRec::record_win_size_change(int width, int height) { TS_RECORD_WIN_SIZE pkg = {0}; pkg.width = (ex_u16) width; pkg.height = (ex_u16) height; - record(TS_RECORD_TYPE_SSH_TERM_SIZE, (ex_u8 *) &pkg, sizeof(TS_RECORD_WIN_SIZE)); + record(TS_RECORD_TYPE_SSH_TERM_SIZE, (ex_u8*) &pkg, sizeof(TS_RECORD_WIN_SIZE)); } // 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。 -void TppSshRec::record_command(int flag, const ex_astr &cmd) { +void TppSshRec::record_command(int flag, const ex_astr& cmd) { char szTime[100] = {0}; #ifdef EX_OS_WIN32 // SYSTEMTIME st; @@ -109,7 +109,7 @@ void TppSshRec::record_command(int flag, const ex_astr &cmd) { // struct tm *p; // time(&timep); // p = localtime(&timep); -// if (p == NULL) +// if (p == nullptr) // return; // sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag); #endif @@ -120,23 +120,23 @@ void TppSshRec::record_command(int flag, const ex_astr &cmd) { if (m_cmd_cache.size() + cmd.length() + lenTime > MAX_SIZE_PER_FILE) _save_to_cmd_file(); - m_cmd_cache.append((ex_u8 *) szTime, lenTime); - m_cmd_cache.append((ex_u8 *) cmd.c_str(), cmd.length()); - m_cmd_cache.append((ex_u8 *) "\r\n", 2); + m_cmd_cache.append((ex_u8*) szTime, lenTime); + m_cmd_cache.append((ex_u8*) cmd.c_str(), cmd.length()); + m_cmd_cache.append((ex_u8*) "\r\n", 2); } bool TppSshRec::_save_to_info_file() { if (!m_header_changed) return true; - if (m_file_info == NULL) { + if (m_file_info == nullptr) { ex_wstr fname = m_base_path; - if(!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) + if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr)) return false; fname += L".tpr"; m_file_info = ex_fopen(fname, L"wb"); - if (NULL == m_file_info) { + if (nullptr == m_file_info) { EXLOGE("[ssh] can not open record info-file for write.\n"); return false; } @@ -150,7 +150,8 @@ bool TppSshRec::_save_to_info_file() { fwrite(&m_head, ts_record_header_size, 1, m_file_info); fflush(m_file_info); m_save_full_header = false; - } else { + } + else { fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info); fflush(m_file_info); } @@ -162,14 +163,14 @@ bool TppSshRec::_save_to_data_file() { if (m_cache.size() == 0) return true; - if (m_file_data == NULL) { + if (m_file_data == nullptr) { ex_wstr fname = m_base_path; - if(!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) + if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr)) return false; fname += L".dat"; m_file_data = ex_fopen(fname, L"wb"); - if (NULL == m_file_data) { + if (nullptr == m_file_data) { EXLOGE("[ssh] can not open record data-file for write.\n"); return false; } @@ -188,14 +189,14 @@ bool TppSshRec::_save_to_cmd_file() { if (m_cmd_cache.size() == 0) return true; - if (NULL == m_file_cmd) { + if (nullptr == m_file_cmd) { ex_wstr fname = m_base_path; - if (!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) + if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr)) return false; fname += L"-cmd.txt"; m_file_cmd = ex_fopen(fname, L"wb"); - if (NULL == m_file_cmd) { + if (nullptr == m_file_cmd) { EXLOGE("[ssh] can not open record cmd-file for write.\n"); return false; } diff --git a/server/tp_core/protocol/ssh/ssh_session.cpp b/server/tp_core/protocol/ssh/ssh_session.cpp index 01c0560..66e5d12 100644 --- a/server/tp_core/protocol/ssh/ssh_session.cpp +++ b/server/tp_core/protocol/ssh/ssh_session.cpp @@ -5,28 +5,29 @@ #include #include -SshSession::SshSession(SshProxy *proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char *client_ip, uint16_t client_port) : - ExThreadBase("ssh-session-thread"), - m_proxy(proxy), - m_state(SSH_SESSION_STATE_STARTING), - m_rs_tp2cli(rs_tp2cli), - m_rs_tp2srv(nullptr), - m_dbg_id(dbg_id), - m_conn_info(nullptr), - m_conn_port(0), - m_flags(0), - m_auth_type(TP_AUTH_TYPE_NONE), - m_allow_user_input_password(false) -{ +SshSession::SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char* client_ip, uint16_t client_port) : + ExThreadBase("ssh-session-thread"), + m_proxy(proxy), + m_state(SSH_SESSION_STATE_STARTING), + m_rs_tp2cli(rs_tp2cli), + m_rs_tp2srv(nullptr), + m_dbg_id(dbg_id), + m_conn_info(nullptr), + m_conn_port(0), + m_flags(0), + m_auth_type(TP_AUTH_TYPE_NONE), + m_allow_user_input_password(false) { ex_strformat(m_dbg_name, 128, "ssh-%d", dbg_id); ex_strformat(m_dbg_client, 128, "%s:%d", client_ip, client_port); - m_first_auth = true; - m_auth_passed = false; - m_fault = false; + m_first_auth = true; + m_auth_passed = false; + m_fault = false; m_need_send_keepalive = false; - m_recving_from_srv = false; - m_recving_from_cli = false; + // m_recving_from_srv = false; + // m_recving_from_cli = false; + + m_pair_id = 0; memset(&m_srv_cb, 0, sizeof(m_srv_cb)); ssh_callbacks_init(&m_srv_cb) @@ -41,10 +42,8 @@ SshSession::SshSession(SshProxy *proxy, ssh_session rs_tp2cli, uint32_t dbg_id, m_srv_channel_cb.userdata = this; } -SshSession::~SshSession() -{ - if (m_conn_info) - { +SshSession::~SshSession() { + if (m_conn_info) { #ifdef TEST_SSH_SESSION_000000 delete m_conn_info; #else @@ -56,37 +55,31 @@ SshSession::~SshSession() EXLOGD("[%s] session %s destroy.\n", m_dbg_name.c_str(), m_sid.c_str()); } -void SshSession::_on_stop() -{ +void SshSession::_on_stop() { ExThreadBase::_on_stop(); _close_channels(); - if (m_rs_tp2cli) - { + if (m_rs_tp2cli) { ssh_disconnect(m_rs_tp2cli); ssh_free(m_rs_tp2cli); m_rs_tp2cli = nullptr; } - if (m_rs_tp2srv) - { + if (m_rs_tp2srv) { ssh_disconnect(m_rs_tp2srv); ssh_free(m_rs_tp2srv); m_rs_tp2srv = nullptr; } - if (m_conn_info) - { + if (m_conn_info) { g_ssh_env.free_connect_info(m_conn_info); } } -void SshSession::_on_stopped() -{ +void SshSession::_on_stopped() { } -void SshSession::_set_last_error(int err_code) -{ +void SshSession::_set_last_error(int err_code) { #ifndef TEST_SSH_SESSION_000000 int db_id = 0; if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0) @@ -100,49 +93,40 @@ void SshSession::_set_last_error(int err_code) } -void SshSession::_close_channels() -{ +void SshSession::_close_channels() { ExThreadSmartLock locker(m_lock); - for (auto &pair : m_pairs) - { + for (auto& pair : m_pairs) { pair->need_close = true; } } -void SshSession::check_channels() -{ +void SshSession::check_channels() { if (!(m_state == SSH_SESSION_STATE_CLOSING || m_state == SSH_SESSION_STATE_RUNNING)) return; ExThreadSmartLock locker(m_lock); - for (auto it = m_pairs.begin(); it != m_pairs.end();) - { + for (auto it = m_pairs.begin(); it != m_pairs.end();) { ssh_channel ch_tp2cli = (*it)->rsc_tp2cli; ssh_channel ch_tp2srv = (*it)->rsc_tp2srv; // 判断是否需要关闭通道: // 如果通道一侧打开过,但现在已经关闭了,则需要关闭另外一侧。 bool need_close = (*it)->need_close; - if (!need_close) - { + if (!need_close) { if (ch_tp2cli != nullptr && ssh_channel_is_closed(ch_tp2cli)) need_close = true; if (ch_tp2srv != nullptr && ssh_channel_is_closed(ch_tp2srv)) need_close = true; } - if (need_close) - { - if (ch_tp2cli != nullptr) - { - if (!ssh_channel_is_closed(ch_tp2cli)) - { + if (need_close) { + if (ch_tp2cli != nullptr) { + if (!ssh_channel_is_closed(ch_tp2cli)) { ssh_channel_close(ch_tp2cli); } - else - { + else { auto it_map = m_channel_map.find(ch_tp2cli); if (it_map != m_channel_map.end()) m_channel_map.erase(it_map); @@ -150,14 +134,11 @@ void SshSession::check_channels() } } - if (ch_tp2srv != nullptr) - { - if (!ssh_channel_is_closed(ch_tp2srv)) - { + if (ch_tp2srv != nullptr) { + if (!ssh_channel_is_closed(ch_tp2srv)) { ssh_channel_close(ch_tp2srv); } - else - { + else { auto it_map = m_channel_map.find(ch_tp2srv); if (it_map != m_channel_map.end()) m_channel_map.erase(it_map); @@ -166,39 +147,35 @@ void SshSession::check_channels() } } - if (ch_tp2cli == nullptr && ch_tp2srv == nullptr) - { + if (ch_tp2cli == nullptr && ch_tp2srv == nullptr) { (*it)->record_end(); delete (*it); m_pairs.erase(it++); } - else - { + else { ++it; } } - if (m_pairs.empty()) - { + if (m_pairs.empty()) { EXLOGV("[%s] all channels closed, should close and destroy this session.\n", m_dbg_name.c_str()); m_fault = true; } } -void SshSession::_thread_loop() -{ - m_srv_cb.auth_password_function = _on_auth_password_request; +void SshSession::_thread_loop() { + m_srv_cb.auth_password_function = _on_auth_password_request; m_srv_cb.channel_open_request_session_function = _on_new_channel_request; - m_srv_channel_cb.channel_data_function = _on_server_channel_data; + m_srv_channel_cb.channel_data_function = _on_server_channel_data; m_srv_channel_cb.channel_close_function = _on_server_channel_close; - m_cli_channel_cb.channel_data_function = _on_client_channel_data; - m_cli_channel_cb.channel_close_function = _on_client_channel_close; - m_cli_channel_cb.channel_pty_request_function = _on_client_pty_request; - m_cli_channel_cb.channel_shell_request_function = _on_client_shell_request; + m_cli_channel_cb.channel_data_function = _on_client_channel_data; + m_cli_channel_cb.channel_close_function = _on_client_channel_close; + m_cli_channel_cb.channel_pty_request_function = _on_client_pty_request; + m_cli_channel_cb.channel_shell_request_function = _on_client_shell_request; m_cli_channel_cb.channel_pty_window_change_function = _on_client_pty_win_change; - m_cli_channel_cb.channel_exec_request_function = _on_client_channel_exec_request; + m_cli_channel_cb.channel_exec_request_function = _on_client_channel_exec_request; m_cli_channel_cb.channel_subsystem_request_function = _on_client_channel_subsystem_request; // there are some other channel callbacks not implemented yet: // channel_eof_function @@ -215,8 +192,7 @@ void SshSession::_thread_loop() // 安全连接(密钥交换) err = ssh_handle_key_exchange(m_rs_tp2cli); - if (err != SSH_OK) - { + if (err != SSH_OK) { EXLOGE("[%s] key exchange with client failed: %s\n", m_dbg_name.c_str(), ssh_get_error(m_rs_tp2cli)); return; } @@ -229,14 +205,12 @@ void SshSession::_thread_loop() ssh_set_blocking(m_rs_tp2cli, 0); ssh_event event_loop = ssh_event_new(); - if (!event_loop) - { + if (!event_loop) { EXLOGE("[%s] can not create event loop.\n", m_dbg_name.c_str()); return; } err = ssh_event_add_session(event_loop, m_rs_tp2cli); - if (err != SSH_OK) - { + if (err != SSH_OK) { EXLOGE("[%s] can not add client-session into event loop.\n", m_dbg_name.c_str()); return; } @@ -244,28 +218,23 @@ void SshSession::_thread_loop() m_state = SSH_SESSION_STATE_AUTHING; // 认证,并打开一个通道 - do - { + do { err = ssh_event_dopoll(event_loop, 500); - if (err == SSH_AGAIN) - { + if (err == SSH_AGAIN) { continue; } - else if (err != SSH_OK) - { + else if (err != SSH_OK) { EXLOGE("[%s] error when event poll: %s\n", m_dbg_name.c_str(), ssh_get_error(m_rs_tp2cli)); m_fault = true; } - if (m_fault) - { + if (m_fault) { EXLOGE("[%s] error when event poll, fault.\n", m_dbg_name.c_str()); break; } } while (!(m_state == SSH_SESSION_STATE_AUTH_END && !m_pairs.empty())); - if (m_fault) - { + if (m_fault) { ssh_event_remove_session(event_loop, m_rs_tp2cli); ssh_event_free(event_loop); EXLOGE("[%s] Error, exiting loop.\n", m_dbg_name.c_str()); @@ -277,16 +246,14 @@ void SshSession::_thread_loop() // 现在双方的连接已经建立好了,开始转发 ssh_event_add_session(event_loop, m_rs_tp2srv); - do - { + do { err = ssh_event_dopoll(event_loop, 500); if (m_fault) break; if (err == SSH_OK || err == SSH_AGAIN) continue; - if (err == SSH_ERROR) - { + if (err == SSH_ERROR) { EXLOGE("[%s] event poll failed. [cli] %s. [srv] %s\n", m_dbg_name.c_str(), ssh_get_error(m_rs_tp2cli), ssh_get_error(m_rs_tp2srv)); m_fault = true; } @@ -304,34 +271,28 @@ void SshSession::_thread_loop() EXLOGV("[%s] session event loop end.\n", m_dbg_name.c_str()); } -void SshSession::save_record() -{ +void SshSession::save_record() { ExThreadSmartLock locker(m_lock); - for (auto &pair : m_pairs) - { + for (auto& pair : m_pairs) { pair->rec.save_record(); } } -void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) -{ +void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) { ExThreadSmartLock locker(m_lock); - for (auto &pair : m_pairs) - { + for (auto& pair : m_pairs) { if (pair->need_close) continue; bool need_close = false; - if (t_now == 0) - { + if (t_now == 0) { EXLOGW("[%s] try close channel by kill.\n", m_dbg_name.c_str()); need_close = true; } - if (t_now - pair->last_access_timestamp > timeout) - { + if (t_now - pair->last_access_timestamp > timeout) { EXLOGW("[%s] try close channel by timeout.\n", m_dbg_name.c_str()); need_close = true; } @@ -340,10 +301,8 @@ void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) } } -bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv) -{ - if (!ch_tp2cli || !ch_tp2srv) - { +bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv) { + if (!ch_tp2cli || !ch_tp2srv) { EXLOGE("[%s] can not make channel pair with null channel.\n", m_dbg_name.c_str()); return false; } @@ -351,19 +310,24 @@ bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv) ExThreadSmartLock locker(m_lock); auto it = m_channel_map.find(ch_tp2cli); - if (it != m_channel_map.end()) - { + if (it != m_channel_map.end()) { EXLOGE("[%s] can not make channel pair, channel to client already exists.\n", m_dbg_name.c_str()); return false; } it = m_channel_map.find(ch_tp2srv); - if (it != m_channel_map.end()) - { + if (it != m_channel_map.end()) { EXLOGE("[%s] can not make channel pair, channel to server already exists.\n", m_dbg_name.c_str()); return false; } - auto _pair = new SshChannelPair(this, ch_tp2cli, ch_tp2srv); + uint32_t dbg_id = m_pair_id++; + auto _pair = new SshChannelPair(this, dbg_id, ch_tp2cli, ch_tp2srv); + + if(!_pair->record_begin(m_conn_info)) { + delete _pair; + return false; + } + m_pairs.push_back(_pair); m_channel_map.insert(std::make_pair(ch_tp2cli, _pair)); @@ -375,8 +339,7 @@ bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv) return true; } -SshChannelPair *SshSession::get_channel_pair(ssh_channel ch) -{ +SshChannelPair* SshSession::get_channel_pair(ssh_channel ch) { ExThreadSmartLock locker(m_lock); auto it = m_channel_map.find(ch); @@ -387,13 +350,11 @@ SshChannelPair *SshSession::get_channel_pair(ssh_channel ch) return it->second; } -void SshSession::set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv) -{ +void SshSession::set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv) { ssh_set_channel_callbacks(ch_tp2srv, &m_srv_channel_cb); } -void SshSession::keep_alive() -{ +void SshSession::keep_alive() { m_need_send_keepalive = true; // EXLOGD("[ssh] keep-alive.\n"); // if(m_srv_session) @@ -402,17 +363,15 @@ void SshSession::keep_alive() // ssh_send_keepalive(m_cli_session); } -int SshSession::_on_auth_password_request(ssh_session /*session*/, const char *user, const char *password, void *userdata) -{ - auto *_this = (SshSession *) userdata; +int SshSession::_on_auth_password_request(ssh_session /*session*/, const char* user, const char* password, void* userdata) { + auto* _this = (SshSession*) userdata; int ret = _this->_do_auth(user, password); _this->m_first_auth = false; return ret; } -int SshSession::_do_auth(const char *user, const char *secret) -{ +int SshSession::_do_auth(const char* user, const char* secret) { EXLOGD("[%s] authenticating, user: %s\n", m_dbg_name.c_str(), user); // v3.6.0 @@ -445,17 +404,14 @@ int SshSession::_do_auth(const char *user, const char *secret) // Linux系统中,用户名通常长度不超过8个字符,并且由大小写字母和/或数字组成。登录名中不能有冒号(,因为冒号在这里是分隔符。为了兼容 // 起见,登录名中最好不要包含点字符(.),并且不使用连字符(-)和加号(+)打头。 - if (m_first_auth) - { + if (m_first_auth) { std::string _name; std::string _sid; std::string tmp(user); std::string::size_type tmp_pos = tmp.rfind("--"); - if (tmp_pos == std::string::npos) - { - //_set_last_error(TP_SESS_STAT_ERR_SESSION); - //return SSH_AUTH_SUCCESS; + if (tmp_pos == std::string::npos) { + // 向下兼容 _name = "TP"; m_sid = tmp; } @@ -472,59 +428,60 @@ int SshSession::_do_auth(const char *user, const char *secret) #ifdef TEST_SSH_SESSION_000000 m_conn_info = new TPP_CONNECT_INFO; - m_conn_info->sid = "000000"; - m_conn_info->user_id = 1; - m_conn_info->host_id = 1; - m_conn_info->acc_id = 1; - m_conn_info->user_username = "apex.liu"; // 申请本次连接的用户名 - m_conn_info->client_ip = "127.0.0.1"; - m_conn_info->username_prompt = ""; // for telnet - m_conn_info->password_prompt = ""; // for telnet - m_conn_info->protocol_type = TP_PROTOCOL_TYPE_SSH; + m_conn_info->sid = "000000"; + m_conn_info->user_id = 1; + m_conn_info->host_id = 1; + m_conn_info->acc_id = 1; + m_conn_info->user_username = "apex.liu"; // 申请本次连接的用户名 + m_conn_info->client_ip = "127.0.0.1"; + m_conn_info->username_prompt = ""; // for telnet + m_conn_info->password_prompt = ""; // for telnet + m_conn_info->protocol_type = TP_PROTOCOL_TYPE_SSH; m_conn_info->protocol_sub_type = TP_PROTOCOL_TYPE_SSH_SHELL; - m_conn_info->protocol_flag = TP_FLAG_ALL; - m_conn_info->record_flag = TP_FLAG_ALL; - m_conn_info->auth_type = TP_AUTH_TYPE_PASSWORD; + m_conn_info->protocol_flag = TP_FLAG_ALL; + m_conn_info->record_flag = TP_FLAG_ALL; + m_conn_info->auth_type = TP_AUTH_TYPE_PASSWORD; - if (m_sid == "000000") - { - m_conn_info->host_ip = "39.97.125.170"; - m_conn_info->conn_ip = "39.97.125.170"; - m_conn_info->conn_port = 22; + if (m_sid == "000000") { + m_conn_info->host_ip = "39.97.125.170"; + m_conn_info->conn_ip = "39.97.125.170"; + m_conn_info->conn_port = 22; m_conn_info->acc_username = "root"; - m_conn_info->acc_secret = "123456"; + m_conn_info->acc_secret = "*******"; // m_conn_info->acc_username = "INTERACTIVE_USER"; // m_conn_info->acc_secret = ""; - } - else - { - m_conn_info->host_ip = "127.0.0.1"; - m_conn_info->conn_ip = "127.0.0.1"; - m_conn_info->conn_port = 22; - m_conn_info->acc_username = "apex"; - m_conn_info->acc_secret = "123456"; - } + // m_conn_info->host_ip = "47.99.60.237"; + // m_conn_info->conn_ip = "47.99.60.237"; + // m_conn_info->conn_port = 40022; + // m_conn_info->acc_username = "trops"; + // m_conn_info->acc_secret = "******"; + } + else { + m_conn_info->host_ip = "127.0.0.1"; + m_conn_info->conn_ip = "127.0.0.1"; + m_conn_info->conn_port = 22; + m_conn_info->acc_username = "apex"; + m_conn_info->acc_secret = "********"; + } #else m_conn_info = g_ssh_env.get_connect_info(m_sid.c_str()); #endif - if (!m_conn_info) - { + if (!m_conn_info) { EXLOGE("[%s] no such session id: %s\n", m_dbg_name.c_str(), m_sid.c_str()); _set_last_error(TP_SESS_STAT_ERR_SESSION); return SSH_AUTH_SUCCESS; } - m_conn_ip = m_conn_info->conn_ip; - m_conn_port = m_conn_info->conn_port; - m_auth_type = m_conn_info->auth_type; + m_conn_ip = m_conn_info->conn_ip; + m_conn_port = m_conn_info->conn_port; + m_auth_type = m_conn_info->auth_type; // m_acc_name = m_conn_info->acc_username; m_acc_secret = m_conn_info->acc_secret; - m_flags = m_conn_info->protocol_flag; + m_flags = m_conn_info->protocol_flag; - if (m_conn_info->protocol_type != TP_PROTOCOL_TYPE_SSH) - { + if (m_conn_info->protocol_type != TP_PROTOCOL_TYPE_SSH) { EXLOGE("[ssh] session '%s' is not for SSH.\n", m_sid.c_str()); _set_last_error(TP_SESS_STAT_ERR_INTERNAL); return SSH_AUTH_SUCCESS; @@ -532,8 +489,7 @@ int SshSession::_do_auth(const char *user, const char *secret) _name = m_conn_info->acc_username; if ((m_acc_name.empty() && _name == "INTERACTIVE_USER") - || (!m_acc_name.empty() && _name != "INTERACTIVE_USER")) - { + || (!m_acc_name.empty() && _name != "INTERACTIVE_USER")) { EXLOGE("[%s] conflict account info.\n", m_dbg_name.c_str()); _set_last_error(TP_SESS_STAT_ERR_SESSION); return SSH_AUTH_SUCCESS; @@ -541,8 +497,7 @@ int SshSession::_do_auth(const char *user, const char *secret) if (m_acc_name.empty()) m_acc_name = _name; - if (m_acc_secret.empty()) - { + if (m_acc_secret.empty()) { // 如果TP中未设置远程账号密码,表示允许用户自行输入密码 m_allow_user_input_password = true; @@ -555,8 +510,7 @@ int SshSession::_do_auth(const char *user, const char *secret) m_acc_secret = secret; } } - else - { + else { // 允许用户自行输入密码的情况下,第二次认证,参数secret就是用户自己输入的密码了。 m_acc_secret = secret; } @@ -565,8 +519,7 @@ int SshSession::_do_auth(const char *user, const char *secret) ex_strformat(m_dbg_server, 128, "%s:%d", m_conn_ip.c_str(), m_conn_port); EXLOGV("[%s] try to connect to real SSH server %s\n", m_dbg_name.c_str(), m_dbg_server.c_str()); - if (m_rs_tp2srv) - { + if (m_rs_tp2srv) { ssh_free(m_rs_tp2srv); m_rs_tp2srv = nullptr; } @@ -593,8 +546,7 @@ int SshSession::_do_auth(const char *user, const char *secret) ssh_options_set(m_rs_tp2srv, SSH_OPTIONS_TIMEOUT, &_timeout); int rc = ssh_connect(m_rs_tp2srv); - if (rc != SSH_OK) - { + if (rc != SSH_OK) { EXLOGE("[%s] can not connect to real SSH server %s. %s\n", m_dbg_name.c_str(), m_dbg_server.c_str(), ssh_get_error(m_rs_tp2srv)); _set_last_error(TP_SESS_STAT_ERR_CONNECT); return SSH_AUTH_SUCCESS; @@ -611,38 +563,32 @@ int SshSession::_do_auth(const char *user, const char *secret) // _this->m_ssh_ver = ssh_get_version(_this->m_rs_tp2srv); // EXLOGW("[ssh] real host is SSHv%d\n", _this->m_ssh_ver); - const char *banner = ssh_get_issue_banner(m_rs_tp2srv); - if (banner) - { + const char* banner = ssh_get_issue_banner(m_rs_tp2srv); + if (banner) { EXLOGE("[%s] remote host issue banner: %s\n", m_dbg_name.c_str(), banner); } int auth_methods = 0; rc = ssh_userauth_none(m_rs_tp2srv, nullptr); - while (rc == SSH_AUTH_AGAIN) - { + while (rc == SSH_AUTH_AGAIN) { ex_sleep_ms(20); rc = ssh_userauth_none(m_rs_tp2srv, nullptr); } - if (SSH_AUTH_ERROR != rc) - { + if (SSH_AUTH_ERROR != rc) { auth_methods = ssh_userauth_list(m_rs_tp2srv, nullptr); EXLOGV("[%s] allowed auth method: 0x%08x\n", m_dbg_name.c_str(), auth_methods); } // some host does not give us the auth methods list, so we need try each one. - if (auth_methods == 0) - { + if (auth_methods == 0) { auth_methods = SSH_AUTH_METHOD_INTERACTIVE | SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY; EXLOGW("[%s] can not get allowed auth method, try each method we can.\n", m_dbg_name.c_str()); } - if (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 (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))) { EXLOGE("[%s] configure to auth by password, but remote host not allow such auth mode.\n", m_dbg_name.c_str()); _set_last_error(TP_SESS_STAT_ERR_AUTH_TYPE); return SSH_AUTH_SUCCESS; @@ -651,20 +597,16 @@ int SshSession::_do_auth(const char *user, const char *secret) int retry_count = 0; // 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) { rc = ssh_userauth_kbdint(m_rs_tp2srv, nullptr, nullptr); - for (;;) - { - if (rc == SSH_AUTH_SUCCESS) - { + for (;;) { + if (rc == SSH_AUTH_SUCCESS) { EXLOGW("[%s] login with interactive mode succeeded.\n", m_dbg_name.c_str()); m_auth_passed = true; return SSH_AUTH_SUCCESS; } - if (rc == SSH_AUTH_AGAIN) - { + if (rc == SSH_AUTH_AGAIN) { retry_count += 1; if (retry_count >= 5) break; @@ -677,16 +619,14 @@ int SshSession::_do_auth(const char *user, const char *secret) break; int prompts = ssh_userauth_kbdint_getnprompts(m_rs_tp2srv); - if (0 == prompts) - { + if (0 == prompts) { rc = ssh_userauth_kbdint(m_rs_tp2srv, nullptr, nullptr); continue; } - for (int i = 0; i < prompts; ++i) - { - char echo = 0; - const char *prompt = ssh_userauth_kbdint_getprompt(m_rs_tp2srv, i, &echo); + for (int i = 0; i < prompts; ++i) { + char echo = 0; + const char* prompt = ssh_userauth_kbdint_getprompt(m_rs_tp2srv, i, &echo); // about 'echo': // This is an optional variable. You can obtain a boolean if the user input should be echoed or @@ -697,8 +637,7 @@ int SshSession::_do_auth(const char *user, const char *secret) continue; rc = ssh_userauth_kbdint_setanswer(m_rs_tp2srv, i, m_acc_secret.c_str()); - if (rc < 0) - { + if (rc < 0) { EXLOGE("[%s] invalid password for interactive mode to login to remote host %s.\n", m_dbg_name.c_str(), m_dbg_server.c_str()); _set_last_error(TP_SESS_STAT_ERR_AUTH_DENIED); return SSH_AUTH_SUCCESS; @@ -710,19 +649,15 @@ int SshSession::_do_auth(const char *user, const char *secret) } // 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) { rc = ssh_userauth_password(m_rs_tp2srv, nullptr, m_acc_secret.c_str()); - for (;;) - { - if (rc == SSH_AUTH_SUCCESS) - { + for (;;) { + if (rc == SSH_AUTH_SUCCESS) { EXLOGW("[%s] login with password mode succeeded.\n", m_dbg_name.c_str()); m_auth_passed = true; return SSH_AUTH_SUCCESS; } - else if (rc == SSH_AUTH_AGAIN) - { + else if (rc == SSH_AUTH_AGAIN) { retry_count += 1; if (retry_count >= 3) break; @@ -740,18 +675,15 @@ int SshSession::_do_auth(const char *user, const char *secret) _set_last_error(TP_SESS_STAT_ERR_AUTH_DENIED); return SSH_AUTH_SUCCESS; } - else if (m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) - { - if ((auth_methods & SSH_AUTH_METHOD_PUBLICKEY) != SSH_AUTH_METHOD_PUBLICKEY) - { + else if (m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) { + if ((auth_methods & SSH_AUTH_METHOD_PUBLICKEY) != SSH_AUTH_METHOD_PUBLICKEY) { EXLOGE("[%s] configure to use public-key auth, but remote host not allow such auth mode.\n", m_dbg_name.c_str()); _set_last_error(TP_SESS_STAT_ERR_AUTH_TYPE); return SSH_AUTH_SUCCESS; } ssh_key key = nullptr; - if (SSH_OK != ssh_pki_import_privkey_base64(m_acc_secret.c_str(), nullptr, nullptr, nullptr, &key)) - { + if (SSH_OK != ssh_pki_import_privkey_base64(m_acc_secret.c_str(), nullptr, nullptr, nullptr, &key)) { EXLOGE("[%s] can not import private-key for auth.\n", m_dbg_name.c_str()); _set_last_error(TP_SESS_STAT_ERR_BAD_SSH_KEY); return SSH_AUTH_SUCCESS; @@ -760,8 +692,7 @@ int SshSession::_do_auth(const char *user, const char *secret) rc = ssh_userauth_publickey(m_rs_tp2srv, nullptr, key); ssh_key_free(key); - if (rc == SSH_AUTH_SUCCESS) - { + if (rc == SSH_AUTH_SUCCESS) { EXLOGW("[%s] login with public-key mode succeeded.\n", m_dbg_name.c_str()); m_auth_passed = true; return SSH_AUTH_SUCCESS; @@ -771,41 +702,37 @@ int SshSession::_do_auth(const char *user, const char *secret) _set_last_error(TP_SESS_STAT_ERR_AUTH_DENIED); return SSH_AUTH_SUCCESS; } - else if (m_auth_type == TP_AUTH_TYPE_NONE) - { + else if (m_auth_type == TP_AUTH_TYPE_NONE) { EXLOGE("[%s] configure to login without auth, not allowed.\n", m_dbg_name.c_str()); _set_last_error(TP_SESS_STAT_ERR_AUTH_DENIED); return SSH_AUTH_SUCCESS; } - else - { + else { EXLOGE("[%s] unknown auth mode: %d.\n", m_dbg_name.c_str(), m_auth_type); _set_last_error(TP_SESS_STAT_ERR_AUTH_DENIED); return SSH_AUTH_SUCCESS; } } -ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userdata) -{ +ssh_channel SshSession::_on_new_channel_request(ssh_session session, void* userdata) { // 客户端尝试打开一个通道(然后才能通过这个通道发控制命令或者收发数据) - auto _this = (SshSession *) userdata; + auto _this = (SshSession*) userdata; EXLOGV("[%s] client open channel.\n", _this->m_dbg_name.c_str()); if (_this->m_state == SSH_SESSION_STATE_AUTHING) _this->m_state = SSH_SESSION_STATE_AUTH_END; // 如果认证过程中已经发生了不可继续的错误,这里返回null,中断连接 - if (!_this->m_auth_passed) - { + if (!_this->m_auth_passed) { _this->m_fault = true; EXLOGE("[%s] fault before request channel.\n", _this->m_dbg_name.c_str()); return nullptr; } ssh_channel rc_tp2cli = ssh_channel_new(session); - if (!rc_tp2cli) - { + if (!rc_tp2cli) { EXLOGE("[%s] can not create channel for client.\n", _this->m_dbg_name.c_str()); + _this->_set_last_error(TP_SESS_STAT_ERR_CREATE_CHANNEL); return nullptr; } ssh_set_channel_callbacks(rc_tp2cli, &_this->m_cli_channel_cb); @@ -813,32 +740,31 @@ ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userd // 我们也要向真正的服务器申请打开一个通道,来进行转发 ssh_channel rc_tp2srv = ssh_channel_new(_this->m_rs_tp2srv); - if (!rc_tp2srv) - { + if (!rc_tp2srv) { EXLOGE("[%s] can not create channel for server.\n", _this->m_dbg_name.c_str()); + _this->_set_last_error(TP_SESS_STAT_ERR_CREATE_CHANNEL); return nullptr; } int rc = ssh_channel_open_session(rc_tp2srv); - while (rc == SSH_AGAIN) - { + while (rc == SSH_AGAIN) { ex_sleep_ms(20); rc = ssh_channel_open_session(rc_tp2srv); } - if (SSH_OK != rc) - { + if (SSH_OK != rc) { EXLOGE("[%s] error opening channel to real server: %s\n", _this->m_dbg_name.c_str(), ssh_get_error(_this->m_rs_tp2srv)); ssh_channel_free(rc_tp2cli); + _this->_set_last_error(TP_SESS_STAT_ERR_CREATE_CHANNEL); return nullptr; } EXLOGD("[%s] channel to real server opened.\n", _this->m_dbg_name.c_str()); ssh_set_channel_callbacks(rc_tp2srv, &_this->m_srv_channel_cb); - if (!_this->make_channel_pair(rc_tp2cli, rc_tp2srv)) - { + if (!_this->make_channel_pair(rc_tp2cli, rc_tp2srv)) { EXLOGE("[%s] can not make channel pair.\n", _this->m_dbg_name.c_str()); + _this->_set_last_error(TP_SESS_STAT_ERR_INTERNAL); ssh_channel_close(rc_tp2cli); ssh_channel_close(rc_tp2srv); return nullptr; @@ -847,48 +773,42 @@ ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userd return rc_tp2cli; } -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) -{ - auto _this = (SshSession *) userdata; +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) { + auto _this = (SshSession*) userdata; EXLOGD("[%s] client request pty: %s, (%d, %d) / (%d, %d)\n", _this->m_dbg_name.c_str(), term, x, y, px, py); auto cp = _this->get_channel_pair(channel); - if (!cp) - { + if (!cp) { EXLOGE("[%s] when client request pty, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } cp->win_width = x; + cp->rec.record_win_size_change(x, y); int rc = ssh_channel_request_pty_size(cp->rsc_tp2srv, term, x, y); - while (rc == SSH_AGAIN) - { + while (rc == SSH_AGAIN) { ex_sleep_ms(20); rc = ssh_channel_request_pty_size(cp->rsc_tp2srv, term, x, y); } - if (rc != SSH_OK) - { + if (rc != SSH_OK) { EXLOGE("[%s] request pty from server failed, %s\n", _this->m_dbg_name.c_str(), ssh_get_error(_this->m_rs_tp2srv)); } return rc; } -int SshSession::_on_client_shell_request(ssh_session /*session*/, ssh_channel channel, void *userdata) -{ - auto _this = (SshSession *) userdata; +int SshSession::_on_client_shell_request(ssh_session /*session*/, ssh_channel channel, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGD("[%s] client request shell\n", _this->m_dbg_name.c_str()); - 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("[%s] ssh-shell disabled by ops-policy.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } auto cp = _this->get_channel_pair(channel); - if (!cp) - { + if (!cp) { EXLOGE("[%s] when client request shell, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } @@ -897,34 +817,29 @@ int SshSession::_on_client_shell_request(ssh_session /*session*/, ssh_channel ch g_ssh_env.session_update(cp->db_id, TP_PROTOCOL_TYPE_SSH_SHELL, TP_SESS_STAT_STARTED); int rc = ssh_channel_request_shell(cp->rsc_tp2srv); - while (rc == SSH_AGAIN) - { + while (rc == SSH_AGAIN) { ex_sleep_ms(20); rc = ssh_channel_request_shell(cp->rsc_tp2srv); } - if (rc != SSH_OK) - { + if (rc != SSH_OK) { EXLOGE("[%s] request shell from server failed, %s\n", _this->m_dbg_name.c_str(), ssh_get_error(_this->m_rs_tp2srv)); } return rc; } -void SshSession::_on_client_channel_close(ssh_session /*session*/, ssh_channel /*channel*/, void *userdata) -{ - auto _this = (SshSession *) userdata; +void SshSession::_on_client_channel_close(ssh_session /*session*/, ssh_channel /*channel*/, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGV("[%s] client channel (from %s) closed.\n", _this->m_dbg_name.c_str(), _this->m_dbg_client.c_str()); } -int SshSession::_on_client_pty_win_change(ssh_session /*session*/, ssh_channel channel, int width, int height, int /*px_width*/, int /*pw_height*/, void *userdata) -{ - auto _this = (SshSession *) userdata; +int SshSession::_on_client_pty_win_change(ssh_session /*session*/, ssh_channel channel, int width, int height, int /*px_width*/, int /*pw_height*/, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGD("[%s] client pty win size change to: (%d, %d)\n", _this->m_dbg_name.c_str(), width, height); auto cp = _this->get_channel_pair(channel); - if (!cp) - { + if (!cp) { EXLOGE("[%s] when client pty win change, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } @@ -933,41 +848,35 @@ int SshSession::_on_client_pty_win_change(ssh_session /*session*/, ssh_channel c cp->rec.record_win_size_change(width, height); int rc = ssh_channel_change_pty_size(cp->rsc_tp2srv, width, height); - while (rc == SSH_AGAIN) - { + while (rc == SSH_AGAIN) { ex_sleep_ms(20); rc = ssh_channel_change_pty_size(cp->rsc_tp2srv, width, height); } - if (rc != SSH_OK) - { + if (rc != SSH_OK) { EXLOGE("[%s] request shell from server failed, %s\n", _this->m_dbg_name.c_str(), ssh_get_error(_this->m_rs_tp2srv)); } return rc; } -int SshSession::_on_client_channel_subsystem_request(ssh_session /*session*/, ssh_channel channel, const char *subsystem, void *userdata) -{ - auto _this = (SshSession *) userdata; +int SshSession::_on_client_channel_subsystem_request(ssh_session /*session*/, ssh_channel channel, const char* subsystem, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGD("[%s] on_client_channel_subsystem_request(): %s\n", _this->m_dbg_name.c_str(), subsystem); auto cp = _this->get_channel_pair(channel); - if (!cp) - { + if (!cp) { EXLOGE("[%s] when request channel subsystem, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } // 目前只支持SFTP子系统 - if (strcmp(subsystem, "sftp") != 0) - { + if (strcmp(subsystem, "sftp") != 0) { EXLOGE("[%s] support `sftp` subsystem only, but got `%s`.\n", _this->m_dbg_name.c_str(), subsystem); cp->state = TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL; 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("[%s] ssh-sftp disabled by ops-policy.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } @@ -976,96 +885,79 @@ int SshSession::_on_client_channel_subsystem_request(ssh_session /*session*/, ss g_ssh_env.session_update(cp->db_id, TP_PROTOCOL_TYPE_SSH_SFTP, TP_SESS_STAT_STARTED); int rc = ssh_channel_request_subsystem(cp->rsc_tp2srv, subsystem); - while (rc == SSH_AGAIN) - { + while (rc == SSH_AGAIN) { ex_sleep_ms(20); rc = ssh_channel_request_subsystem(cp->rsc_tp2srv, subsystem); } - if (rc != SSH_OK) - { + if (rc != SSH_OK) { EXLOGE("[%s] request shell from server failed, %s\n", _this->m_dbg_name.c_str(), ssh_get_error(_this->m_rs_tp2srv)); } return rc; } -int SshSession::_on_client_channel_exec_request(ssh_session /*session*/, ssh_channel /*channel*/, const char *command, void *userdata) -{ - auto _this = (SshSession *) userdata; +int SshSession::_on_client_channel_exec_request(ssh_session /*session*/, ssh_channel /*channel*/, const char* command, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGW("[%s] ssh exec not supported. command: %s\n", _this->m_dbg_name.c_str(), command); return SSH_ERROR; } -void SshSession::_on_server_channel_close(ssh_session /*session*/, ssh_channel /*channel*/, void *userdata) -{ - auto _this = (SshSession *) userdata; +void SshSession::_on_server_channel_close(ssh_session /*session*/, ssh_channel /*channel*/, void* userdata) { + auto _this = (SshSession*) userdata; EXLOGV("[%s] server channel (to %s) closed.\n", _this->m_dbg_name.c_str(), _this->m_dbg_server.c_str()); } -bool SshSession::_send(ssh_channel channel_to, int is_stderr, void *data, uint32_t len) -{ +bool SshSession::_send(ssh_channel channel_to, int is_stderr, void* data, uint32_t len) { uint32_t sent_len = 0; - for (;;) - { + for (;;) { int ret; if (is_stderr) ret = ssh_channel_write_stderr(channel_to, data, len - sent_len); else ret = ssh_channel_write(channel_to, data, len - sent_len); - if (ret < 0) - { - if (ret == SSH_AGAIN) - { + if (ret < 0) { + if (ret == SSH_AGAIN) { ex_sleep_ms(1); continue; } - else - { + else { EXLOGE("[%s] send data failed: %d\n", m_dbg_name.c_str(), ret); return false; } } - if (ret > 0) - { + if (ret > 0) { sent_len += ret; - if (sent_len >= len) - { + if (sent_len >= len) { return true; } } } } -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); // EXLOGD(" ---> recv from client %d B\n", len); - auto _this = (SshSession *) userdata; - auto cp = _this->get_channel_pair(channel); - if (!cp) - { + auto _this = (SshSession*) userdata; + auto cp = _this->get_channel_pair(channel); + if (!cp) { EXLOGE("[%s] when receive client channel data, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } - if (!is_stderr) - { - if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL) - { - cp->process_pty_data_from_client(static_cast(data), len); + if (!is_stderr) { + if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL) { + cp->process_pty_data_from_client(static_cast(data), len); } - else - { - cp->process_sftp_command(channel, (ex_u8*)data, len); + else { + cp->process_sftp_command(channel, (ex_u8*) data, len); } } - if (!_this->_send(cp->rsc_tp2srv, is_stderr, data, len)) - { + if (!_this->_send(cp->rsc_tp2srv, is_stderr, data, len)) { cp->need_close = true; return SSH_ERROR; } @@ -1073,43 +965,36 @@ int SshSession::_on_client_channel_data(ssh_session /*session*/, ssh_channel cha return static_cast(len); } -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); // EXLOGD(" <--- recv from server %d B\n", len); - auto _this = (SshSession *) userdata; + auto _this = (SshSession*) userdata; auto cp = _this->get_channel_pair(channel); - if (!cp) - { + if (!cp) { EXLOGE("[%s] when receive server channel data, channel pair not found.\n", _this->m_dbg_name.c_str()); return SSH_ERROR; } - if (!is_stderr) - { - if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL) - { - cp->process_pty_data_from_server(static_cast(data), len); - cp->rec.record(TS_RECORD_TYPE_SSH_DATA, static_cast(data), len); + if (!is_stderr) { + if (cp->type == TS_SSH_CHANNEL_TYPE_SHELL) { + cp->process_pty_data_from_server(static_cast(data), len); + cp->rec.record(TS_RECORD_TYPE_SSH_DATA, static_cast(data), len); } - else - { + else { // cp->process_sftp_command(channel, (ex_u8*)data, len); } } // 收到第一包服务端返回的数据时,在输出数据之前显示一些自定义的信息 - if (!is_stderr && cp->is_first_server_data) - { + if (!is_stderr && cp->is_first_server_data) { cp->is_first_server_data = false; - if (cp->type != TS_SSH_CHANNEL_TYPE_SFTP) - { - char buf[512] = { 0 }; + if (cp->type != TS_SSH_CHANNEL_TYPE_SFTP) { + char buf[512] = {0}; - const char *auth_mode; + const char* auth_mode; if (_this->m_auth_type == TP_AUTH_TYPE_PASSWORD) auth_mode = "password"; else if (_this->m_auth_type == TP_AUTH_TYPE_PRIVATE_KEY) @@ -1117,11 +1002,11 @@ int SshSession::_on_server_channel_data(ssh_session /*session*/, ssh_channel cha else auth_mode = "unknown"; - int w = MIN(cp->win_width, 64); + int w = MIN(cp->win_width, 64); ex_astr line(w, '='); snprintf( - buf, sizeof(buf), "\r\n"\ + buf, sizeof(buf), "\r\n"\ "%s\r\n"\ "Teleport SSH Bastion Server...\r\n"\ " - teleport to %s:%d\r\n"\ @@ -1130,16 +1015,14 @@ int SshSession::_on_server_channel_data(ssh_session /*session*/, ssh_channel cha "\r\n\r\n", line.c_str(), _this->m_conn_ip.c_str(), _this->m_conn_port, auth_mode, line.c_str() ); - if (!_this->_send(cp->rsc_tp2cli, 0, buf, strlen(buf))) - { + if (!_this->_send(cp->rsc_tp2cli, 0, buf, strlen(buf))) { cp->need_close = true; return SSH_ERROR; } } } - if (!_this->_send(cp->rsc_tp2cli, is_stderr, data, len)) - { + if (!_this->_send(cp->rsc_tp2cli, is_stderr, data, len)) { cp->need_close = true; return SSH_ERROR; } diff --git a/server/tp_core/protocol/ssh/ssh_session.h b/server/tp_core/protocol/ssh/ssh_session.h index 5c6d5ed..8535da6 100644 --- a/server/tp_core/protocol/ssh/ssh_session.h +++ b/server/tp_core/protocol/ssh/ssh_session.h @@ -14,14 +14,13 @@ #include "ssh_channel_pair.h" -#define TEST_SSH_SESSION_000000 +// #define TEST_SSH_SESSION_000000 #define TS_SSH_CHANNEL_TYPE_UNKNOWN 0 #define TS_SSH_CHANNEL_TYPE_SHELL 1 #define TS_SSH_CHANNEL_TYPE_SFTP 2 -enum SSH_SESSION_STATUS -{ +enum SSH_SESSION_STATUS { SSH_SESSION_STATE_CLOSED = 0, SSH_SESSION_STATE_STARTING, SSH_SESSION_STATE_AUTHING, @@ -35,35 +34,25 @@ class SshProxy; class SshSession; class SshSession : - public ExThreadBase -{ + public ExThreadBase { public: - SshSession(SshProxy *proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char *client_ip, uint16_t client_port); + SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char* client_ip, uint16_t client_port); virtual ~SshSession(); -// uint32_t dbg_id() const -// { -// return m_dbg_id; -// } - - const std::string &dbg_name() const - { + const std::string& dbg_name() const { return m_dbg_name; } - const std::string &dbg_client() const - { + const std::string& dbg_client() const { return m_dbg_client; } - const std::string &dbg_server() const - { + const std::string& dbg_server() const { return m_dbg_server; } - const std::string &sid() - { + const std::string& sid() { return m_sid; } @@ -76,13 +65,11 @@ public: void keep_alive(); - bool closed() const - { + bool closed() const { return m_state == SSH_SESSION_STATE_CLOSED; } - ssh_session get_peer_raw_session(ssh_session session) - { + ssh_session get_peer_raw_session(ssh_session session) { if (session == m_rs_tp2cli) return m_rs_tp2srv; else if (session == m_rs_tp2srv) @@ -95,9 +82,11 @@ public: // 通道管理 // -------------------------- void set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv); + bool make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv); - SshChannelPair *get_channel_pair(ssh_channel ch); + SshChannelPair* get_channel_pair(ssh_channel ch); + void check_channels(); protected: @@ -113,57 +102,57 @@ protected: private: void _close_channels(); - int _do_auth(const char *user, const char *secret); + int _do_auth(const char* user, const char* secret); void _set_last_error(int err_code); - bool _send(ssh_channel channel_to, int is_stderr, void *data, uint32_t len); + bool _send(ssh_channel channel_to, int is_stderr, void* data, uint32_t len); - static int _on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata); + 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 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); + 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); - static int _on_client_shell_request(ssh_session session, ssh_channel channel, void *userdata); + static int _on_client_shell_request(ssh_session session, ssh_channel channel, void* userdata); - static void _on_client_channel_close(ssh_session session, ssh_channel channel, void *userdata); + static void _on_client_channel_close(ssh_session session, ssh_channel channel, void* userdata); - static int _on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); + static int _on_client_channel_data(ssh_session session, ssh_channel channel, void* data, unsigned int len, int is_stderr, void* userdata); - static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void *userdata); + static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void* userdata); - static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata); + static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char* subsystem, void* userdata); - static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char *command, void *userdata); + static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char* command, void* userdata); - static int _on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); + static int _on_server_channel_data(ssh_session session, ssh_channel channel, void* data, unsigned int len, int is_stderr, void* userdata); - 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: - SshProxy *m_proxy; + SshProxy* m_proxy; SSH_SESSION_STATUS m_state; - ssh_session m_rs_tp2cli; - ssh_session m_rs_tp2srv; + ssh_session m_rs_tp2cli; + ssh_session m_rs_tp2srv; ExThreadLock m_lock; - uint32_t m_dbg_id; + uint32_t m_dbg_id; std::string m_dbg_name; std::string m_dbg_client; std::string m_dbg_server; - TPP_CONNECT_INFO *m_conn_info; + TPP_CONNECT_INFO* m_conn_info; std::string m_sid; std::string m_conn_ip; - uint16_t m_conn_port; + uint16_t m_conn_port; std::string m_acc_name; std::string m_acc_secret; - uint32_t m_flags; - int m_auth_type; - bool m_allow_user_input_password; + uint32_t m_flags; + int m_auth_type; + bool m_allow_user_input_password; bool m_first_auth; // 远程主机认证是否通过 @@ -171,25 +160,17 @@ private: // 发生了不可逆的错误,需要关闭整个会话(包括所有的通道) bool m_fault; - // int m_ssh_ver; - - // 一个ssh_session中可以打开多个ssh_channel - // tp_channels m_channels; - // 管理两端的通道对 - TPChannelPairs m_pairs; + uint32_t m_pair_id; // for debug. + TPChannelPairs m_pairs; // 用于快速查找 - channel_map m_channel_map; + channel_map m_channel_map; // 本会话中的所有通道(无论哪一端的) std::list m_channels; - bool m_need_send_keepalive; - bool m_recving_from_srv; // 是否正在从服务器接收数据? - bool m_recving_from_cli; // 是否正在从客户端接收数据? - - struct ssh_server_callbacks_struct m_srv_cb; + 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; }; diff --git a/server/tp_core/protocol/ssh/tpp_env.cpp b/server/tp_core/protocol/ssh/tpp_env.cpp index b15a40d..1bbd81f 100644 --- a/server/tp_core/protocol/ssh/tpp_env.cpp +++ b/server/tp_core/protocol/ssh/tpp_env.cpp @@ -2,37 +2,30 @@ TppSshEnv g_ssh_env; -TppSshEnv::TppSshEnv() -{ +TppSshEnv::TppSshEnv() noexcept: + bind_port(0) { } -TppSshEnv::~TppSshEnv() -{ -} +TppSshEnv::~TppSshEnv() = default; -bool TppSshEnv::_on_init(TPP_INIT_ARGS *args) -{ +bool TppSshEnv::_on_init(TPP_INIT_ARGS* args) { ex_path_join(replay_path, false, L"ssh", NULL); auto ps = args->cfg->GetSection(L"protocol-ssh"); - if (!ps) - { + if (!ps) { EXLOGE("[ssh] invalid config(2).\n"); return false; } ex_wstr tmp; - if (!ps->GetStr(L"bind-ip", tmp)) - { + if (!ps->GetStr(L"bind-ip", tmp)) { bind_ip = TS_SSH_PROXY_HOST; } - else - { + else { ex_wstr2astr(tmp, bind_ip); } - if (!ps->GetInt(L"bind-port", bind_port)) - { + if (!ps->GetInt(L"bind-port", bind_port)) { bind_port = TS_SSH_PROXY_PORT; } diff --git a/server/tp_core/protocol/ssh/tpp_env.h b/server/tp_core/protocol/ssh/tpp_env.h index b461b42..3fb6d81 100644 --- a/server/tp_core/protocol/ssh/tpp_env.h +++ b/server/tp_core/protocol/ssh/tpp_env.h @@ -3,18 +3,18 @@ #include "../../common/base_env.h" -class TppSshEnv : public TppEnvBase -{ +class TppSshEnv : public TppEnvBase { public: - TppSshEnv(); - ~TppSshEnv(); + TppSshEnv() noexcept; + + ~TppSshEnv() override; public: ex_astr bind_ip; - int bind_port; + int bind_port; private: - bool _on_init(TPP_INIT_ARGS *args); + bool _on_init(TPP_INIT_ARGS* args) override; }; extern TppSshEnv g_ssh_env; diff --git a/server/tp_core/protocol/ssh/tpssh.cpp b/server/tp_core/protocol/ssh/tpssh.cpp index 1200863..2220bc4 100644 --- a/server/tp_core/protocol/ssh/tpssh.cpp +++ b/server/tp_core/protocol/ssh/tpssh.cpp @@ -4,8 +4,7 @@ #include #include -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 ssh_threads_set_callbacks(ssh_threads_get_pthread()); ssh_init(); @@ -19,8 +18,7 @@ TPP_API ex_rv tpp_init(TPP_INIT_ARGS *init_args) return 0; } -TPP_API ex_rv tpp_start(void) -{ +TPP_API ex_rv tpp_start(void) { if (!g_ssh_proxy.init()) return TPE_FAILED; if (!g_ssh_proxy.start()) @@ -29,26 +27,23 @@ TPP_API ex_rv tpp_start(void) return 0; } -TPP_API ex_rv tpp_stop(void) -{ +TPP_API ex_rv tpp_stop(void) { g_ssh_proxy.stop(); ssh_finalize(); return 0; } -TPP_API void tpp_timer(void) -{ +TPP_API void tpp_timer(void) { // be called per one second. g_ssh_proxy.timer(); } -static ex_rv tpp_cmd_set_runtime_config(const char *param) -{ - Json::Value jp; - Json::CharReaderBuilder jcrb; +static ex_rv tpp_cmd_set_runtime_config(const char* param) { + Json::Value jp; + Json::CharReaderBuilder jcrb; std::unique_ptr const jreader(jcrb.newCharReader()); - const char *str_json_begin = param; - ex_astr err; + const char* str_json_begin = param; + ex_astr err; if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err)) return TPE_JSON_FORMAT; @@ -68,12 +63,11 @@ static ex_rv tpp_cmd_set_runtime_config(const char *param) return TPE_PARAM; } -static ex_rv tpp_cmd_kill_sessions(const char *param) -{ - Json::Value jp; +static ex_rv tpp_cmd_kill_sessions(const char* param) { + Json::Value jp; Json::CharReaderBuilder reader_builder; - const char *str_json_begin = param; - ex_astr err; + const char* str_json_begin = param; + ex_astr err; std::unique_ptr const json_reader(reader_builder.newCharReader()); if (!json_reader->parse(str_json_begin, param + strlen(param), &jp, &err)) @@ -84,10 +78,8 @@ static ex_rv tpp_cmd_kill_sessions(const char *param) ex_astrs ss; - for (const auto &item : jp) - { - if (!item.isString()) - { + for (const auto& item : jp) { + if (!item.isString()) { return TPE_PARAM; } @@ -99,18 +91,13 @@ static ex_rv tpp_cmd_kill_sessions(const char *param) return TPE_PARAM; } -TPP_API ex_rv tpp_command(ex_u32 cmd, const char *param) -{ +TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) { if (!param || strlen(param) == 0) return TPE_PARAM; - switch (cmd) - { - case TPP_CMD_SET_RUNTIME_CFG: - return tpp_cmd_set_runtime_config(param); - case TPP_CMD_KILL_SESSIONS: - return tpp_cmd_kill_sessions(param); - default: - return TPE_UNKNOWN_CMD; + switch (cmd) { + case TPP_CMD_SET_RUNTIME_CFG:return tpp_cmd_set_runtime_config(param); + case TPP_CMD_KILL_SESSIONS:return tpp_cmd_kill_sessions(param); + default:return TPE_UNKNOWN_CMD; } } diff --git a/server/www/teleport/static/js/audit/record-list.js b/server/www/teleport/static/js/audit/record-list.js index 1a82f64..a336107 100644 --- a/server/www/teleport/static/js/audit/record-list.js +++ b/server/www/teleport/static/js/audit/record-list.js @@ -313,6 +313,9 @@ $app.on_table_host_render_created = function (render) { case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL: msg = '协议不支持'; break; + case TP_SESS_STAT_ERR_CREATE_CHANNEL: + msg = '无法创建数据通道'; + break; case TP_SESS_STAT_ERR_BAD_PKG: case TP_SESS_STAT_ERR_START_BAD_PKG: msg = '数据格式错误'; diff --git a/server/www/teleport/static/js/ops/session-list.js b/server/www/teleport/static/js/ops/session-list.js index 098e6be..a64895d 100644 --- a/server/www/teleport/static/js/ops/session-list.js +++ b/server/www/teleport/static/js/ops/session-list.js @@ -324,6 +324,9 @@ $app.on_table_session_render_created = function (render) { case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL: msg = '协议不支持'; break; + case TP_SESS_STAT_ERR_CREATE_CHANNEL: + msg = '无法创建数据通道'; + break; case TP_SESS_STAT_ERR_BAD_PKG: case TP_SESS_STAT_ERR_START_BAD_PKG: msg = '数据格式错误'; diff --git a/server/www/teleport/static/js/tp-const.js b/server/www/teleport/static/js/tp-const.js index 6bf9e10..6c7e1a9 100755 --- a/server/www/teleport/static/js/tp-const.js +++ b/server/www/teleport/static/js/tp-const.js @@ -38,23 +38,26 @@ var TP_OS_TYPE_LINUX = 2; // ======================================================= // 远程连接会话状态 // ======================================================= -var TP_SESS_STAT_RUNNING = 0; // 会话开始了,尚未结束,还在连接过程中 -var TP_SESS_STAT_END = 9999; // 会话成功结束 -var TP_SESS_STAT_ERR_AUTH_DENIED = 1; // 会话结束,因为认证失败 -var TP_SESS_STAT_ERR_CONNECT = 2; // 会话结束,因为无法连接到远程主机 -var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束,因为无法识别SSH私钥 -var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误 -var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP) -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; // 会话结束,因为收到错误的报文 -var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束,因为teleport核心服务重置了 -var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断 +var TP_SESS_STAT_RUNNING = 0; // 会话开始了,尚未结束,还在连接过程中 +var TP_SESS_STAT_ERR_AUTH_DENIED = 1; // 会话结束,因为认证失败 +var TP_SESS_STAT_ERR_CONNECT = 2; // 会话结束,因为无法连接到远程主机 +var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束,因为无法识别SSH私钥 +var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误 +var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP) +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_ERR_CREATE_CHANNEL = 11; // 会话结束,因为创建通道失败 + +var TP_SESS_STAT_STARTED = 100; // 已经连接成功了,开始记录录像了 +var TP_SESS_STAT_ERR_START_INTERNAL = 104; // 会话结束,因为内部错误 +var TP_SESS_STAT_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文 +var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束,因为teleport核心服务重置了 +var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断 + +var TP_SESS_STAT_END = 9999; // 会话成功结束 // ========================================================================== // 对象类型 @@ -332,7 +335,7 @@ function tp_error_msg(error_code, message) { case TPE_SYS_MAINTENANCE: msg = '系统维护中'; break; - + case TPE_OATH_ALREADY_BIND: msg = '该账号已经绑定了身份验证器,如无法使用,请联系管理员重置密码或更换登录方式'; break; diff --git a/server/www/teleport/webroot/app/base/logger.py b/server/www/teleport/webroot/app/base/logger.py index 14ffddb..9fcccc1 100644 --- a/server/www/teleport/webroot/app/base/logger.py +++ b/server/www/teleport/webroot/app/base/logger.py @@ -7,6 +7,7 @@ import sys import threading import time import traceback +import builtins __all__ = ['log'] @@ -14,6 +15,7 @@ USE_TPWEB_LOG = False try: import tpweb + USE_TPWEB_LOG = True except ImportError: pass @@ -627,6 +629,4 @@ del Logger # log._test() # print('test built-in `print` function.') -import builtins - builtins.__dict__['print'] = log.log_print diff --git a/server/www/teleport/webroot/app/const.py b/server/www/teleport/webroot/app/const.py index bad80e6..f97c432 100755 --- a/server/www/teleport/webroot/app/const.py +++ b/server/www/teleport/webroot/app/const.py @@ -2,11 +2,11 @@ from enum import IntEnum, unique -TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行) -TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码 -TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码 -TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH -TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH +TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行) +TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码 +TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码 +TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH +TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH APP_MODE_NORMAL = 1 APP_MODE_MAINTENANCE = 2 @@ -67,7 +67,7 @@ TP_OS_TYPE_LINUX = 2 # 远程连接会话状态 # ======================================================= TP_SESS_STAT_RUNNING = 0 # 会话开始了,尚未结束 -TP_SESS_STAT_END = 9999 # 会话成功结束 + TP_SESS_STAT_ERR_AUTH_DENIED = 1 # 会话结束,因为认证失败 TP_SESS_STAT_ERR_CONNECT = 2 # 会话结束,因为无法连接到远程主机 TP_SESS_STAT_ERR_BAD_SSH_KEY = 3 # 会话结束,因为无法识别SSH私钥 @@ -77,12 +77,18 @@ TP_SESS_STAT_ERR_BAD_PKG = 6 # 会话结束,因为收到错误的报文 TP_SESS_STAT_ERR_RESET = 7 # 会话结束,因为teleport核心服务重置了 TP_SESS_STAT_ERR_IO = 8 # 会话结束,因为网络中断 TP_SESS_STAT_ERR_SESSION = 9 # 会话结束,因为无效的会话ID +TP_SESS_STAT_ERR_AUTH_TYPE = 10 # 会话结束,因为服务端不支持此认证方式 +TP_SESS_STAT_ERR_CREATE_CHANNEL = 11 # 会话结束,因为创建通道失败 + TP_SESS_STAT_STARTED = 100 # 已经连接成功了,开始记录录像了 + TP_SESS_STAT_ERR_START_INTERNAL = 104 # 会话结束,因为内部错误 TP_SESS_STAT_ERR_START_BAD_PKG = 106 # 会话结束,因为收到错误的报文 TP_SESS_STAT_ERR_START_RESET = 107 # 会话结束,因为teleport核心服务重置了 TP_SESS_STAT_ERR_START_IO = 108 # 会话结束,因为网络中断 +TP_SESS_STAT_END = 9999 # 会话成功结束 + # ========================================================================== # 分组类型 # ========================================================================== @@ -228,7 +234,7 @@ TPE_CAPTCHA_EXPIRED = 10000 TPE_CAPTCHA_MISMATCH = 10001 TPE_OATH_MISMATCH = 10002 TPE_SYS_MAINTENANCE = 10003 -TPE_OATH_ALREADY_BIND = 10004 +TPE_OATH_ALREADY_BIND = 10004 TPE_USER_LOCKED = 10100 TPE_USER_DISABLED = 10101