1. 调整rdp日志输出;2. 优化当SSH连接时会话ID无效的处理;3. 部分代码格式化;

feature/assist-websocket
Apex Liu 2022-05-25 01:19:27 +08:00
parent 21c2432f29
commit 3409a2fd57
16 changed files with 765 additions and 755 deletions

View File

@ -19,174 +19,175 @@ ExLogger g_ex_logger;
bool g_is_debug = false; bool g_is_debug = false;
extern bool g_exit_flag; extern bool g_exit_flag;
#define RUN_UNKNOWN 0 #define RUN_UNKNOWN 0
#define RUN_CORE 1 #define RUN_CORE 1
#define RUN_INSTALL_SRV 2 #define RUN_INSTALL_SRV 2
#define RUN_UNINST_SRV 3 #define RUN_UNINST_SRV 3
#define RUN_STOP 4 #define RUN_STOP 4
static ex_u8 g_run_type = RUN_UNKNOWN; static ex_u8 g_run_type = RUN_UNKNOWN;
#define EOM_CORE_SERVICE_NAME L"Teleport Core Service" #define EOM_CORE_SERVICE_NAME L"Teleport Core Service"
static bool run_daemon_(); static bool run_daemon_();
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
static int service_install() static int service_install()
{ {
ex_wstr exec_file(g_env.m_exec_file); ex_wstr exec_file(g_env.m_exec_file);
exec_file += L" start"; exec_file += L" start";
if (EXRV_OK == ex_winsrv_install(EOM_CORE_SERVICE_NAME, EOM_CORE_SERVICE_NAME, exec_file)) if (EXRV_OK == ex_winsrv_install(EOM_CORE_SERVICE_NAME, EOM_CORE_SERVICE_NAME, exec_file))
return 0; return 0;
else else
return 1; return 1;
} }
static int service_uninstall() static int service_uninstall()
{ {
if (EXRV_OK != ex_winsrv_stop(EOM_CORE_SERVICE_NAME)) if (EXRV_OK != ex_winsrv_stop(EOM_CORE_SERVICE_NAME))
return 1; return 1;
if (EXRV_OK != ex_winsrv_uninstall(EOM_CORE_SERVICE_NAME)) if (EXRV_OK != ex_winsrv_uninstall(EOM_CORE_SERVICE_NAME))
return 2; return 2;
return 0; return 0;
} }
#endif #endif
static bool process_cmd_line_(int argc, wchar_t** argv) static bool process_cmd_line_(int argc, wchar_t** argv)
{ {
if (argc <= 1) if (argc <= 1)
{ {
EXLOGE("nothing to do.\n\n"); EXLOGE("nothing to do.\n\n");
return false; return false;
} }
g_run_type = RUN_UNKNOWN; g_run_type = RUN_UNKNOWN;
if (0 == wcscmp(argv[1], L"--version")) if (0 == wcscmp(argv[1], L"--version"))
{ {
EXLOGI("\nTeleport Server, version %ls.\n\n", TP_SERVER_VER); EXLOGI("\nTeleport Server, version %ls.\n\n", TP_SERVER_VER);
return false; return false;
} }
else if (0 == wcscmp(argv[1], L"-i")) else if (0 == wcscmp(argv[1], L"-i"))
{ {
g_run_type = RUN_INSTALL_SRV; g_run_type = RUN_INSTALL_SRV;
} }
else if (0 == wcscmp(argv[1], L"-u")) else if (0 == wcscmp(argv[1], L"-u"))
{ {
g_run_type = RUN_UNINST_SRV; g_run_type = RUN_UNINST_SRV;
} }
else else
{ {
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
if (0 == wcscmp(argv[i], L"start")) if (0 == wcscmp(argv[i], L"start"))
{ {
g_run_type = RUN_CORE; g_run_type = RUN_CORE;
continue; continue;
} }
else if (0 == wcscmp(argv[i], L"stop")) { else if (0 == wcscmp(argv[i], L"stop"))
g_run_type = RUN_STOP; {
continue; g_run_type = RUN_STOP;
} continue;
}
if (0 == wcscmp(argv[i], L"-d")) if (0 == wcscmp(argv[i], L"-d"))
{ {
g_is_debug = true; g_is_debug = true;
continue; continue;
} }
EXLOGE(L"unknown option: %ls\n", argv[i]); EXLOGE(L"unknown option: %ls\n", argv[i]);
return false; return false;
} }
} }
if (g_run_type == RUN_UNKNOWN) if (g_run_type == RUN_UNKNOWN)
{ {
EXLOGE("nothing to do.\n\n"); EXLOGE("nothing to do.\n\n");
return false; return false;
} }
return true; return true;
} }
static int main_loop_() static int main_loop_()
{ {
if (g_run_type == RUN_CORE) if (g_run_type == RUN_CORE)
return ts_main(); return ts_main();
else else
return 1; return 1;
} }
int app_main_(int argc, wchar_t** argv) int app_main_(int argc, wchar_t** argv)
{ {
EXLOG_USE_LOGGER(&g_ex_logger); EXLOG_USE_LOGGER(&g_ex_logger);
if (!process_cmd_line_(argc, argv)) if (!process_cmd_line_(argc, argv))
return 1; return 1;
#ifdef EX_DEBUG #ifdef EX_DEBUG
EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG); EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG);
#endif #endif
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
if (g_run_type == RUN_INSTALL_SRV) if (g_run_type == RUN_INSTALL_SRV)
{ {
if (!g_env.init(false)) if (!g_env.init(false))
{ {
EXLOGE("[core] env init failed.\n"); EXLOGE("[core] env init failed.\n");
return 1; return 1;
} }
return service_install(); return service_install();
} }
else if (g_run_type == RUN_UNINST_SRV) else if (g_run_type == RUN_UNINST_SRV)
{ {
if (!g_env.init(false)) if (!g_env.init(false))
{ {
EXLOGE("[core] env init failed.\n"); EXLOGE("[core] env init failed.\n");
return 1; return 1;
} }
return service_uninstall(); return service_uninstall();
} }
#endif #endif
if (!g_env.init(true)) if (!g_env.init(true))
{ {
EXLOGE("[core] env init failed.\n"); EXLOGE("[core] env init failed.\n");
return 1; return 1;
} }
if (g_run_type == RUN_STOP) { if (g_run_type == RUN_STOP)
char url[1024] = {0}; {
ex_strformat(url, 1023, R"(http://%s:%d/rpc?{"method":"exit"})", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port); char url[1024] = {0};
ex_astr body; ex_strformat(url, 1023, R"(http://%s:%d/rpc?{"method":"exit"})", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port);
ts_http_get(url, body); ex_astr body;
ex_printf("%s\n", body.c_str()); ts_http_get(url, body);
return 0; ex_printf("%s\n", body.c_str());
} return 0;
}
if (!g_is_debug) if (!g_is_debug)
{ {
if (!run_daemon_()) if (!run_daemon_())
{ {
EXLOGE("[core] can not run in daemon mode.\n"); EXLOGE("[core] can not run in daemon mode.\n");
return 1; return 1;
} }
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
return 0; return 0;
#endif #endif
} }
return main_loop_(); return main_loop_();
} }
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
#ifdef EX_DEBUG #ifdef EX_DEBUG
@ -204,131 +205,131 @@ static DWORD WINAPI service_thread_func(LPVOID lpParam);
int main() int main()
{ {
int ret = 0; int ret = 0;
LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数; LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数;
int _argc = 0; int _argc = 0;
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串; wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
ret = app_main_(_argc, _argv); ret = app_main_(_argc, _argv);
LocalFree(_argv); LocalFree(_argv);
_argv = nullptr; _argv = nullptr;
return ret; return ret;
} }
static bool run_daemon_(void) static bool run_daemon_(void)
{ {
SERVICE_TABLE_ENTRY DispatchTable[2]; SERVICE_TABLE_ENTRY DispatchTable[2];
DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME; DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME;
DispatchTable[0].lpServiceProc = service_main; DispatchTable[0].lpServiceProc = service_main;
DispatchTable[1].lpServiceName = nullptr; DispatchTable[1].lpServiceName = nullptr;
DispatchTable[1].lpServiceProc = nullptr; DispatchTable[1].lpServiceProc = nullptr;
if (!StartServiceCtrlDispatcher(DispatchTable)) if (!StartServiceCtrlDispatcher(DispatchTable))
{ {
EXLOGE_WIN("StartServiceCtrlDispatcher()"); EXLOGE_WIN("StartServiceCtrlDispatcher()");
return false; return false;
} }
return true; return true;
} }
static DWORD WINAPI service_thread_func(LPVOID lpParam) static DWORD WINAPI service_thread_func(LPVOID lpParam)
{ {
int ret = main_loop_(); int ret = main_loop_();
// 更新服务状态(如果服务还在运行,将其设置为停止状态) // 更新服务状态(如果服务还在运行,将其设置为停止状态)
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0; g_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus)) if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus))
EXLOGE_WIN("SetServiceStatus()"); EXLOGE_WIN("SetServiceStatus()");
return ret; return ret;
} }
static void WINAPI service_handler(DWORD fdwControl) static void WINAPI service_handler(DWORD fdwControl)
{ {
switch (fdwControl) switch (fdwControl)
{ {
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_SHUTDOWN:
{ {
if (g_hWorkerThread) if (g_hWorkerThread)
{ {
// TerminateThread(g_hWorkerThread, 1); // TerminateThread(g_hWorkerThread, 1);
// g_hWorkerThread = nullptr; // g_hWorkerThread = nullptr;
g_exit_flag = true; g_exit_flag = true;
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0; g_ServiceStatus.dwWaitHint = 0;
} }
else { else {
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0; g_ServiceStatus.dwWaitHint = 0;
} }
}break; }break;
default: default:
return; return;
}; };
if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus)) if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus))
{ {
EXLOGE_WIN("SetServiceStatus(STOP)"); EXLOGE_WIN("SetServiceStatus(STOP)");
return; return;
} }
} }
VOID WINAPI service_main(DWORD argc, wchar_t** argv) VOID WINAPI service_main(DWORD argc, wchar_t** argv)
{ {
g_ServiceStatus.dwServiceType = SERVICE_WIN32; g_ServiceStatus.dwServiceType = SERVICE_WIN32;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0; g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0; g_ServiceStatus.dwWaitHint = 0;
g_hServiceStatusHandle = RegisterServiceCtrlHandler(EOM_CORE_SERVICE_NAME, service_handler); g_hServiceStatusHandle = RegisterServiceCtrlHandler(EOM_CORE_SERVICE_NAME, service_handler);
if (g_hServiceStatusHandle == 0) if (g_hServiceStatusHandle == 0)
{ {
EXLOGE_WIN("RegisterServiceCtrlHandler()"); EXLOGE_WIN("RegisterServiceCtrlHandler()");
return; return;
} }
DWORD tid = 0; DWORD tid = 0;
g_hWorkerThread = CreateThread(nullptr, 0, service_thread_func, nullptr, 0, &tid); g_hWorkerThread = CreateThread(nullptr, 0, service_thread_func, nullptr, 0, &tid);
if (nullptr == g_hWorkerThread) if (nullptr == g_hWorkerThread)
{ {
EXLOGE_WIN("CreateThread()"); EXLOGE_WIN("CreateThread()");
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0; g_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus)) if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus))
EXLOGE_WIN("SetServiceStatus()"); EXLOGE_WIN("SetServiceStatus()");
return; return;
} }
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 9000; g_ServiceStatus.dwWaitHint = 9000;
if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus)) if (!SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus))
{ {
EXLOGE_WIN("SetServiceStatus()"); EXLOGE_WIN("SetServiceStatus()");
return; return;
} }
} }
#else #else
@ -340,74 +341,74 @@ static void sig_handler_(int signum, siginfo_t* info, void* ptr);
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
struct sigaction act{}; struct sigaction act{};
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_sigaction = sig_handler_; act.sa_sigaction = sig_handler_;
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &act, nullptr); sigaction(SIGINT, &act, nullptr);
wchar_t** wargv = ex_make_wargv(argc, argv); wchar_t** wargv = ex_make_wargv(argc, argv);
int ret = app_main_(argc, wargv); int ret = app_main_(argc, wargv);
ex_free_wargv(argc, wargv); ex_free_wargv(argc, wargv);
return ret; return ret;
} }
void sig_handler_(int signum, siginfo_t* info, void* ptr) void sig_handler_(int signum, siginfo_t* info, void* ptr)
{ {
if (signum == SIGINT || signum == SIGTERM) if (signum == SIGINT || signum == SIGTERM)
{ {
EXLOGW("[core] received signal SIGINT, exit now.\n"); EXLOGW("[core] received signal SIGINT, exit now.\n");
g_exit_flag = true; g_exit_flag = true;
} }
} }
static bool run_daemon_() static bool run_daemon_()
{ {
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) if (pid < 0)
{ {
EXLOGE("[core] can not fork daemon.\n"); EXLOGE("[core] can not fork daemon.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
else if (pid > 0) else if (pid > 0)
{ {
exit(EXIT_SUCCESS); // parent exit. exit(EXIT_SUCCESS); // parent exit.
} }
// now I'm first children. // now I'm first children.
if (setsid() == -1) if (setsid() == -1)
{ {
EXLOGE("[core] setsid() failed.\n"); EXLOGE("[core] setsid() failed.\n");
assert(0); assert(0);
// exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
} }
umask(0); umask(0);
pid = fork(); pid = fork();
if (pid < 0) if (pid < 0)
{ {
EXLOGE("[core] can not fork daemon.\n"); EXLOGE("[core] can not fork daemon.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
else if (pid > 0) else if (pid > 0)
{ {
exit(0); // first children exit. exit(0); // first children exit.
} }
// now I'm second children. // now I'm second children.
chdir("/"); chdir("/");
close(STDIN_FILENO); close(STDIN_FILENO);
int std_fd = open("/dev/null", O_RDWR); int std_fd = open("/dev/null", O_RDWR);
close(STDOUT_FILENO); close(STDOUT_FILENO);
close(STDERR_FILENO); close(STDERR_FILENO);
dup2(std_fd, STDOUT_FILENO); dup2(std_fd, STDOUT_FILENO);
dup2(std_fd, STDERR_FILENO); dup2(std_fd, STDERR_FILENO);
return true; return true;
} }
#endif #endif

View File

@ -6,7 +6,8 @@ TppManager g_tpp_mgr;
extern ExLogger g_ex_logger; extern ExLogger g_ex_logger;
bool TppManager::load_tpp(const ex_wstr& libname) { bool TppManager::load_tpp(const ex_wstr& libname)
{
ex_wstr filename; ex_wstr filename;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
filename = libname + L".dll"; filename = libname + L".dll";
@ -27,7 +28,8 @@ bool TppManager::load_tpp(const ex_wstr& libname) {
auto lib = new TPP_LIB; auto lib = new TPP_LIB;
lib->dylib = ex_dlopen(lib_file.c_str()); lib->dylib = ex_dlopen(lib_file.c_str());
if (nullptr == lib->dylib) { if (nullptr == lib->dylib)
{
EXLOGE(L"[core] load dylib `%ls` failed.\n", lib_file.c_str()); EXLOGE(L"[core] load dylib `%ls` failed.\n", lib_file.c_str());
delete lib; delete lib;
return false; return false;
@ -40,11 +42,11 @@ bool TppManager::load_tpp(const ex_wstr& libname) {
lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer"); lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer");
lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command"); lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command");
#else #else
lib->init = (TPP_INIT_FUNC) dlsym(lib->dylib, "tpp_init"); lib->init = (TPP_INIT_FUNC)dlsym(lib->dylib, "tpp_init");
lib->start = (TPP_START_FUNC) dlsym(lib->dylib, "tpp_start"); lib->start = (TPP_START_FUNC)dlsym(lib->dylib, "tpp_start");
lib->stop = (TPP_STOP_FUNC) dlsym(lib->dylib, "tpp_stop"); lib->stop = (TPP_STOP_FUNC)dlsym(lib->dylib, "tpp_stop");
lib->timer = (TPP_TIMER_FUNC) dlsym(lib->dylib, "tpp_timer"); lib->timer = (TPP_TIMER_FUNC)dlsym(lib->dylib, "tpp_timer");
lib->command = (TPP_COMMAND_FUNC) dlsym(lib->dylib, "tpp_command"); lib->command = (TPP_COMMAND_FUNC)dlsym(lib->dylib, "tpp_command");
#endif #endif
if ( if (
@ -53,7 +55,8 @@ bool TppManager::load_tpp(const ex_wstr& libname) {
|| lib->stop == nullptr || lib->stop == nullptr
|| lib->timer == nullptr || lib->timer == nullptr
|| lib->command == nullptr || lib->command == nullptr
) { )
{
EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", lib_file.c_str()); EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", lib_file.c_str());
delete lib; delete lib;
return false; return false;
@ -71,12 +74,14 @@ bool TppManager::load_tpp(const ex_wstr& libname) {
init_args.func_session_update = tpp_session_update; init_args.func_session_update = tpp_session_update;
init_args.func_session_end = tpp_session_end; init_args.func_session_end = tpp_session_end;
if (EXRV_OK != lib->init(&init_args)) { if (EXRV_OK != lib->init(&init_args))
{
EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str()); EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str());
delete lib; delete lib;
return false; return false;
} }
if (EXRV_OK != lib->start()) { if (EXRV_OK != lib->start())
{
EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str()); EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str());
delete lib; delete lib;
return false; return false;
@ -86,14 +91,18 @@ bool TppManager::load_tpp(const ex_wstr& libname) {
return true; return true;
} }
void TppManager::stop_all() { void TppManager::stop_all()
for (auto& lib : m_libs) { {
for (auto& lib: m_libs)
{
lib->stop(); lib->stop();
} }
} }
void TppManager::timer() { void TppManager::timer()
for (auto& lib : m_libs) { {
for (auto& lib: m_libs)
{
lib->timer(); lib->timer();
} }
} }
@ -110,14 +119,18 @@ void TppManager::timer() {
// } // }
// } // }
void TppManager::set_runtime_config(const ex_astr& sp) { void TppManager::set_runtime_config(const ex_astr& sp)
for (auto& lib : m_libs) { {
for (auto& lib: m_libs)
{
lib->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str()); lib->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str());
} }
} }
void TppManager::kill_sessions(const ex_astr& sp) { void TppManager::kill_sessions(const ex_astr& sp)
for (auto& lib : m_libs) { {
for (auto& lib: m_libs)
{
lib->command(TPP_CMD_KILL_SESSIONS, sp.c_str()); lib->command(TPP_CMD_KILL_SESSIONS, sp.c_str());
} }
} }

View File

@ -5,17 +5,20 @@
#include <ex.h> #include <ex.h>
typedef struct TPP_LIB { typedef struct TPP_LIB
{
TPP_LIB() : TPP_LIB() :
dylib(nullptr), dylib(nullptr),
init(nullptr), init(nullptr),
start(nullptr), start(nullptr),
stop(nullptr), stop(nullptr),
timer(nullptr), timer(nullptr),
command(nullptr) { command(nullptr)
{
} }
~TPP_LIB() { ~TPP_LIB()
{
if (nullptr != dylib) if (nullptr != dylib)
ex_dlclose(dylib); ex_dlclose(dylib);
dylib = nullptr; dylib = nullptr;
@ -31,12 +34,15 @@ typedef struct TPP_LIB {
typedef std::list<TPP_LIB*> tpp_libs; typedef std::list<TPP_LIB*> tpp_libs;
class TppManager { class TppManager
{
public: public:
TppManager() = default; TppManager() = default;
~TppManager() { ~TppManager()
for (auto lib : m_libs) { {
for (auto lib: m_libs)
{
delete lib; delete lib;
} }
m_libs.clear(); m_libs.clear();
@ -48,7 +54,8 @@ public:
void timer(); // 大约1秒调用一次 void timer(); // 大约1秒调用一次
int count() { size_t count()
{
return m_libs.size(); return m_libs.size();
} }

View File

@ -9,172 +9,172 @@
*/ */
static ex_u8 g_db_field_aes_key[32] = { static ex_u8 g_db_field_aes_key[32] = {
0xd6, 0xb6, 0x6e, 0x3b, 0x41, 0xc4, 0x33, 0x13, 0xaa, 0x61, 0xc9, 0x47, 0x82, 0xfc, 0x84, 0x50, 0xd6, 0xb6, 0x6e, 0x3b, 0x41, 0xc4, 0x33, 0x13, 0xaa, 0x61, 0xc9, 0x47, 0x82, 0xfc, 0x84, 0x50,
0x85, 0x53, 0x3a, 0x01, 0x97, 0x2d, 0xca, 0xba, 0x87, 0xbc, 0x27, 0x20, 0x29, 0xde, 0x87, 0x67, 0x85, 0x53, 0x3a, 0x01, 0x97, 0x2d, 0xca, 0xba, 0x87, 0xbc, 0x27, 0x20, 0x29, 0xde, 0x87, 0x67,
}; };
bool ts_db_field_encrypt(const ex_astr& str_dec, ex_astr& str_enc) bool ts_db_field_encrypt(const ex_astr& str_dec, ex_astr& str_enc)
{ {
ex_bin bin_dec; ex_bin bin_dec;
bin_dec.resize(str_dec.length()); bin_dec.resize(str_dec.length());
memset(&bin_dec[0], 0, bin_dec.size()); memset(&bin_dec[0], 0, bin_dec.size());
memcpy(&bin_dec[0], str_dec.c_str(), bin_dec.size()); memcpy(&bin_dec[0], str_dec.c_str(), bin_dec.size());
return ts_db_field_encrypt(bin_dec, str_enc); return ts_db_field_encrypt(bin_dec, str_enc);
} }
bool ts_db_field_decrypt(const ex_astr& str_enc, ex_astr& str_dec) bool ts_db_field_decrypt(const ex_astr& str_enc, ex_astr& str_dec)
{ {
ex_bin bin_dec; ex_bin bin_dec;
if (!ts_db_field_decrypt(str_enc, bin_dec)) if (!ts_db_field_decrypt(str_enc, bin_dec))
return false; return false;
if (bin_dec[bin_dec.size() - 1] != 0) if (bin_dec[bin_dec.size() - 1] != 0)
{ {
bin_dec.resize(bin_dec.size() + 1); bin_dec.resize(bin_dec.size() + 1);
bin_dec[bin_dec.size() - 1] = 0; bin_dec[bin_dec.size() - 1] = 0;
} }
str_dec = (char*)&bin_dec[0]; str_dec = (char*)&bin_dec[0];
return true; return true;
} }
bool ts_db_field_encrypt(const ex_bin& bin_dec, ex_astr& str_enc) bool ts_db_field_encrypt(const ex_bin& bin_dec, ex_astr& str_enc)
{ {
int i = 0; int i = 0;
int offset = 0; int offset = 0;
// 随机数种子发生器(注意多线程的问题) // 随机数种子发生器(注意多线程的问题)
ex_u64 _tick = ex_get_tick_count(); ex_u64 _tick = ex_get_tick_count();
ex_u64 _seed_tmp = ex_get_thread_id() + _tick; ex_u64 _seed_tmp = ex_get_thread_id() + _tick;
ex_u32 _seed = ((ex_u32*)&_seed_tmp)[0] + ((ex_u32*)&_seed_tmp)[1]; ex_u32 _seed = ((ex_u32*)&_seed_tmp)[0] + ((ex_u32*)&_seed_tmp)[1];
srand(_seed); srand(_seed);
// 计算密文大小 // 计算密文大小
int pad = 16 - bin_dec.size() % 16; int pad = 16 - bin_dec.size() % 16;
int enc_size = bin_dec.size() + pad + 16; // 追加16字节是为了额外填充的随机数 int enc_size = bin_dec.size() + pad + 16; // 追加16字节是为了额外填充的随机数
// 准备被加密数据16字节随机数+明文+补齐填充) // 准备被加密数据16字节随机数+明文+补齐填充)
ex_bin bin_be_enc; ex_bin bin_be_enc;
bin_be_enc.resize(enc_size); bin_be_enc.resize(enc_size);
memset(&bin_be_enc[0], 0, bin_be_enc.size()); memset(&bin_be_enc[0], 0, bin_be_enc.size());
offset = 0; offset = 0;
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
{ {
bin_be_enc[offset] = (unsigned char)(rand() % 0xFF); bin_be_enc[offset] = (unsigned char)(rand() % 0xFF);
offset++; offset++;
} }
memcpy(&bin_be_enc[offset], &bin_dec[0], bin_dec.size()); memcpy(&bin_be_enc[offset], &bin_dec[0], bin_dec.size());
offset += bin_dec.size(); offset += bin_dec.size();
for (i = 0; i < pad; ++i) for (i = 0; i < pad; ++i)
{ {
bin_be_enc[offset] = (unsigned char)pad; bin_be_enc[offset] = (unsigned char)pad;
offset++; offset++;
} }
// 准备密文缓冲区 // 准备密文缓冲区
ex_bin bin_enc; ex_bin bin_enc;
bin_enc.resize(enc_size); bin_enc.resize(enc_size);
memset(&bin_enc[0], 0, bin_enc.size()); memset(&bin_enc[0], 0, bin_enc.size());
// 准备加密算法 // 准备加密算法
mbedtls_aes_context ctx; mbedtls_aes_context ctx;
mbedtls_aes_init(&ctx); mbedtls_aes_init(&ctx);
if (0 != mbedtls_aes_setkey_enc(&ctx, g_db_field_aes_key, 256)) if (0 != mbedtls_aes_setkey_enc(&ctx, g_db_field_aes_key, 256))
{ {
EXLOGE("[core] invalid AES key.\n"); EXLOGE("[core] invalid AES key.\n");
return false; return false;
} }
// 加密 // 加密
unsigned char iv[16] = { 0 }; unsigned char iv[16] = {0};
memset(iv, 0, 16); memset(iv, 0, 16);
if (0 != mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, enc_size, iv, &bin_be_enc[0], &bin_enc[0])) if (0 != mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, enc_size, iv, &bin_be_enc[0], &bin_enc[0]))
{ {
EXLOGE("[core] AES-CBC encrypt failed.\n"); EXLOGE("[core] AES-CBC encrypt failed.\n");
mbedtls_aes_free(&ctx); mbedtls_aes_free(&ctx);
return false; return false;
} }
mbedtls_aes_free(&ctx); mbedtls_aes_free(&ctx);
// 将加密结果进行base64编码 // 将加密结果进行base64编码
ex_bin enc_b64; ex_bin enc_b64;
enc_b64.resize(enc_size * 2); enc_b64.resize(enc_size * 2);
memset(&enc_b64[0], 0, enc_size * 2); memset(&enc_b64[0], 0, enc_size * 2);
size_t olen = 0; size_t olen = 0;
if (0 != mbedtls_base64_encode(&enc_b64[0], enc_size * 2, &olen, &bin_enc[0], enc_size)) if (0 != mbedtls_base64_encode(&enc_b64[0], enc_size * 2, &olen, &bin_enc[0], enc_size))
{ {
EXLOGE("[core] BASE64 encode failed.\n"); EXLOGE("[core] BASE64 encode failed.\n");
return false; return false;
} }
enc_b64[olen] = 0; enc_b64[olen] = 0;
str_enc = (char*)&enc_b64[0]; str_enc = (char*)&enc_b64[0];
return true; return true;
} }
bool ts_db_field_decrypt(const ex_astr& str_enc, ex_bin& bin_dec) bool ts_db_field_decrypt(const ex_astr& str_enc, ex_bin& bin_dec)
{ {
ex_bin bin_enc; ex_bin bin_enc;
bin_enc.resize(str_enc.length()); bin_enc.resize(str_enc.length());
memset(&bin_enc[0], 0, bin_enc.size()); memset(&bin_enc[0], 0, bin_enc.size());
// base64解码 // base64解码
size_t enc_size = 0; size_t enc_size = 0;
if (0 != mbedtls_base64_decode(&bin_enc[0], bin_enc.size(), &enc_size, (const unsigned char*)str_enc.c_str(), str_enc.length())) if (0 != mbedtls_base64_decode(&bin_enc[0], bin_enc.size(), &enc_size, (const unsigned char*)str_enc.c_str(), str_enc.length()))
{ {
EXLOGE("[core] BASE64 decode failed.\n"); EXLOGE("[core] BASE64 decode failed.\n");
return false; return false;
} }
bin_enc.resize(enc_size); bin_enc.resize(enc_size);
if (bin_enc.size() % 16 != 0) if (bin_enc.size() % 16 != 0)
{ {
EXLOGE("[core] invalid cipher-data.\n"); EXLOGE("[core] invalid cipher-data.\n");
return false; return false;
} }
// 准备明文缓冲区 // 准备明文缓冲区
ex_bin bin_tmp; ex_bin bin_tmp;
bin_tmp.resize(enc_size); bin_tmp.resize(enc_size);
memset(&bin_tmp[0], 0, bin_tmp.size()); memset(&bin_tmp[0], 0, bin_tmp.size());
// 准备解密算法 // 准备解密算法
mbedtls_aes_context ctx; mbedtls_aes_context ctx;
mbedtls_aes_init(&ctx); mbedtls_aes_init(&ctx);
if (0 != mbedtls_aes_setkey_dec(&ctx, g_db_field_aes_key, 256)) if (0 != mbedtls_aes_setkey_dec(&ctx, g_db_field_aes_key, 256))
{ {
EXLOGE("[core] invalid AES key.\n"); EXLOGE("[core] invalid AES key.\n");
return false; return false;
} }
// 解密 // 解密
unsigned char iv[16] = { 0 }; unsigned char iv[16] = {0};
memset(iv, 0, 16); memset(iv, 0, 16);
if (0 != mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, enc_size, iv, &bin_enc[0], &bin_tmp[0])) if (0 != mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, enc_size, iv, &bin_enc[0], &bin_tmp[0]))
{ {
EXLOGE("[core] AES-CBC decrypt failed.\n"); EXLOGE("[core] AES-CBC decrypt failed.\n");
mbedtls_aes_free(&ctx); mbedtls_aes_free(&ctx);
return false; return false;
} }
mbedtls_aes_free(&ctx); mbedtls_aes_free(&ctx);
// 去除padding // 去除padding
unsigned char pad = bin_tmp[bin_tmp.size() - 1]; unsigned char pad = bin_tmp[bin_tmp.size() - 1];
if (pad == 0 || pad > 16) if (pad == 0 || pad > 16)
{ {
EXLOGE("[core] invalid padding.\n"); EXLOGE("[core] invalid padding.\n");
return false; return false;
} }
bin_tmp.resize(bin_tmp.size() - pad); bin_tmp.resize(bin_tmp.size() - pad);
if (bin_tmp.size() < 16) if (bin_tmp.size() < 16)
{ {
EXLOGE("[core] invalid decrypted data.\n"); EXLOGE("[core] invalid decrypted data.\n");
return false; return false;
} }
// 将最终结果复制到返回缓冲区需要抛弃前面的16字节随机数 // 将最终结果复制到返回缓冲区需要抛弃前面的16字节随机数
bin_dec.resize(bin_tmp.size() - 16); bin_dec.resize(bin_tmp.size() - 16);
memcpy(&bin_dec[0], &bin_tmp[16], bin_dec.size()); memcpy(&bin_dec[0], &bin_tmp[16], bin_dec.size());
return true; return true;
} }

View File

@ -5,9 +5,11 @@
// 用于数据库字段的加密/解密使用内置密钥加密结果为base64编码的字符串 // 用于数据库字段的加密/解密使用内置密钥加密结果为base64编码的字符串
bool ts_db_field_encrypt(const ex_bin& bin_dec, ex_astr& str_enc); bool ts_db_field_encrypt(const ex_bin& bin_dec, ex_astr& str_enc);
bool ts_db_field_decrypt(const ex_astr& str_enc, ex_bin& bin_dec); bool ts_db_field_decrypt(const ex_astr& str_enc, ex_bin& bin_dec);
bool ts_db_field_encrypt(const ex_astr& str_dec, ex_astr& str_enc); bool ts_db_field_encrypt(const ex_astr& str_dec, ex_astr& str_enc);
bool ts_db_field_decrypt(const ex_astr& str_enc, ex_astr& str_dec); bool ts_db_field_decrypt(const ex_astr& str_enc, ex_astr& str_dec);

View File

@ -3,145 +3,144 @@
TsEnv g_env; TsEnv g_env;
TsEnv::TsEnv() TsEnv::TsEnv() {}
{}
TsEnv::~TsEnv() TsEnv::~TsEnv() {}
{}
bool TsEnv::init(bool load_config) bool TsEnv::init(bool load_config)
{ {
EXLOG_LEVEL(EX_LOG_LEVEL_INFO); EXLOG_LEVEL(EX_LOG_LEVEL_INFO);
ex_exec_file(m_exec_file); ex_exec_file(m_exec_file);
m_exec_path = m_exec_file; m_exec_path = m_exec_file;
ex_dirname(m_exec_path); ex_dirname(m_exec_path);
if(!load_config) if (!load_config)
return true; return true;
// check development flag file, if exists, run in development mode for trace and debug. // check development flag file, if exists, run in development mode for trace and debug.
ex_wstr dev_flag_file = m_exec_path; ex_wstr dev_flag_file = m_exec_path;
ex_path_join(dev_flag_file, false, L"dev_mode", NULL); ex_path_join(dev_flag_file, false, L"dev_mode", NULL);
ex_wstr base_path = m_exec_path; ex_wstr base_path = m_exec_path;
ex_wstr log_path; ex_wstr log_path;
ex_wstr conf_file; ex_wstr conf_file;
if (ex_is_file_exists(dev_flag_file.c_str())) if (ex_is_file_exists(dev_flag_file.c_str()))
{ {
EXLOGW("===== DEVELOPMENT MODE =====\n"); EXLOGW("===== DEVELOPMENT MODE =====\n");
ex_path_join(base_path, true, L"..", L"..", L"..", L"..", L"server", NULL); ex_path_join(base_path, true, L"..", L"..", L"..", L"..", L"server", NULL);
m_etc_path = base_path; m_etc_path = base_path;
ex_path_join(m_etc_path, false, L"share", L"etc", NULL); ex_path_join(m_etc_path, false, L"share", L"etc", NULL);
conf_file = m_etc_path; conf_file = m_etc_path;
ex_path_join(conf_file, false, L"core.ini", NULL); ex_path_join(conf_file, false, L"core.ini", NULL);
m_replay_path = base_path; m_replay_path = base_path;
ex_path_join(m_replay_path, false, L"share", L"replay", NULL); ex_path_join(m_replay_path, false, L"share", L"replay", NULL);
log_path = base_path; log_path = base_path;
ex_path_join(log_path, false, L"share", L"log", NULL); ex_path_join(log_path, false, L"share", L"log", NULL);
} }
else // not in development mode else // not in development mode
{ {
base_path = m_exec_path; base_path = m_exec_path;
ex_path_join(base_path, true, L"..", L"data", NULL); ex_path_join(base_path, true, L"..", L"data", NULL);
m_etc_path = base_path; m_etc_path = base_path;
ex_path_join(m_etc_path, false, L"etc", NULL); ex_path_join(m_etc_path, false, L"etc", NULL);
conf_file = m_etc_path; conf_file = m_etc_path;
ex_path_join(conf_file, false, L"core.ini", NULL); ex_path_join(conf_file, false, L"core.ini", NULL);
m_replay_path = base_path; m_replay_path = base_path;
ex_path_join(m_replay_path, false, L"replay", NULL); ex_path_join(m_replay_path, false, L"replay", NULL);
log_path = base_path; log_path = base_path;
ex_path_join(log_path, false, L"log", NULL); ex_path_join(log_path, false, L"log", NULL);
} }
if (!m_ini.LoadFromFile(conf_file)) if (!m_ini.LoadFromFile(conf_file))
{ {
EXLOGE(L"[core] can not load %ls.\n", conf_file.c_str()); EXLOGE(L"[core] can not load %ls.\n", conf_file.c_str());
return false; return false;
} }
ExIniSection* ps = m_ini.GetSection(L"common"); ExIniSection* ps = m_ini.GetSection(L"common");
if(NULL == ps) if (NULL == ps)
ps = m_ini.GetDumySection(); ps = m_ini.GetDumySection();
ex_wstr replay_path; ex_wstr replay_path;
if (ps->GetStr(L"replay-path", replay_path)) if (ps->GetStr(L"replay-path", replay_path))
{ {
m_replay_path = replay_path; m_replay_path = replay_path;
} }
ex_mkdirs(m_replay_path); ex_mkdirs(m_replay_path);
ex_wstr log_file; ex_wstr log_file;
if (!ps->GetStr(L"log-file", log_file)) if (!ps->GetStr(L"log-file", log_file))
{ {
EXLOG_FILE(L"tpcore.log", log_path.c_str()); EXLOG_FILE(L"tpcore.log", log_path.c_str());
} }
else else
{ {
ex_remove_white_space(log_file); ex_remove_white_space(log_file);
if (log_file[0] == L'"' || log_file[0] == L'\'') if (log_file[0] == L'"' || log_file[0] == L'\'')
log_file.erase(0, 1); log_file.erase(0, 1);
if (log_file[ log_file.length() - 1 ] == L'"' || log_file[log_file.length() - 1] == L'\'') if (log_file[log_file.length() - 1] == L'"' || log_file[log_file.length() - 1] == L'\'')
log_file.erase(log_file.length() - 1, 1); log_file.erase(log_file.length() - 1, 1);
log_path = log_file; log_path = log_file;
ex_dirname(log_path); ex_dirname(log_path);
ex_wstr file_name; ex_wstr file_name;
file_name.assign(log_file, log_path.length() + 1, log_file.length()); file_name.assign(log_file, log_path.length() + 1, log_file.length());
EXLOG_FILE(file_name.c_str(), log_path.c_str()); EXLOG_FILE(file_name.c_str(), log_path.c_str());
} }
int log_level = EX_LOG_LEVEL_INFO; int log_level = EX_LOG_LEVEL_INFO;
ps->GetInt(L"log-level", log_level, EX_LOG_LEVEL_INFO); ps->GetInt(L"log-level", log_level, EX_LOG_LEVEL_INFO);
EXLOG_LEVEL(log_level); EXLOG_LEVEL(log_level);
int debug_mode = 0; int debug_mode = 0;
ps->GetInt(L"debug-mode", debug_mode, 0); ps->GetInt(L"debug-mode", debug_mode, 0);
if (debug_mode == 1) { if (debug_mode == 1)
EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG); {
EXLOG_DEBUG(true); EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG);
} EXLOG_DEBUG(true);
}
ex_wstr tmp; ex_wstr tmp;
if (!ps->GetStr(L"web-server-rpc", tmp)) if (!ps->GetStr(L"web-server-rpc", tmp))
{ {
web_server_rpc = "http://localhost:7190/rpc"; web_server_rpc = "http://localhost:7190/rpc";
} }
else else
{ {
ex_wstr2astr(tmp, web_server_rpc); ex_wstr2astr(tmp, web_server_rpc);
} }
ps = m_ini.GetSection(L"rpc"); ps = m_ini.GetSection(L"rpc");
if (!ps->GetStr(L"bind-ip", tmp)) if (!ps->GetStr(L"bind-ip", tmp))
{ {
rpc_bind_ip = TS_HTTP_RPC_HOST; rpc_bind_ip = TS_HTTP_RPC_HOST;
} }
else else
{ {
ex_wstr2astr(tmp, rpc_bind_ip); ex_wstr2astr(tmp, rpc_bind_ip);
//if (rpc_bind_ip == "localhost") //if (rpc_bind_ip == "localhost")
// rpc_bind_ip = "127.0.0.1"; // rpc_bind_ip = "127.0.0.1";
} }
if (!ps->GetInt(L"bind-port", rpc_bind_port)) if (!ps->GetInt(L"bind-port", rpc_bind_port))
{ {
rpc_bind_port = TS_HTTP_RPC_PORT; rpc_bind_port = TS_HTTP_RPC_PORT;
} }
char port_str[20] = { 0 }; char port_str[20] = {0};
ex_strformat(port_str, 20, "%d", rpc_bind_port); ex_strformat(port_str, 20, "%d", rpc_bind_port);
core_server_rpc = "http://" + rpc_bind_ip + ":" + port_str + "/rpc"; core_server_rpc = "http://" + rpc_bind_ip + ":" + port_str + "/rpc";
return true; return true;
} }

View File

@ -6,27 +6,28 @@
class TsEnv class TsEnv
{ {
public: public:
TsEnv(); TsEnv();
~TsEnv();
bool init(bool load_config); ~TsEnv();
ExIniFile& get_ini() { return m_ini; } bool init(bool load_config);
ExIniFile& get_ini() { return m_ini; }
public: public:
ex_wstr m_exec_file; ex_wstr m_exec_file;
ex_wstr m_exec_path; ex_wstr m_exec_path;
ex_wstr m_etc_path; ex_wstr m_etc_path;
ex_wstr m_replay_path; ex_wstr m_replay_path;
ex_astr rpc_bind_ip; ex_astr rpc_bind_ip;
int rpc_bind_port; int rpc_bind_port;
ex_astr web_server_rpc; ex_astr web_server_rpc;
ex_astr core_server_rpc; ex_astr core_server_rpc;
private: private:
ExIniFile m_ini; ExIniFile m_ini;
}; };
extern TsEnv g_env; extern TsEnv g_env;

View File

@ -3,69 +3,73 @@
#include <ex/ex_str.h> #include <ex/ex_str.h>
void ts_url_encode(const char *src, ex_astr& out) void ts_url_encode(const char* src, ex_astr& out)
{ {
static const char *dont_escape = "._-$,;~()/"; static const char* dont_escape = "._-$,;~()/";
static const char *hex = "0123456789abcdef"; static const char* hex = "0123456789abcdef";
size_t s_len = strlen(src); size_t s_len = strlen(src);
size_t dst_len = s_len * 3 + 1; size_t dst_len = s_len * 3 + 1;
char* dst = new char[dst_len]; char* dst = new char[dst_len];
memset(dst, 0, dst_len); memset(dst, 0, dst_len);
size_t i = 0, j = 0; size_t i = 0, j = 0;
for (i = j = 0; dst_len > 0 && i < s_len && j + 2 < dst_len - 1; i++, j++) { for (i = j = 0; dst_len > 0 && i < s_len && j + 2 < dst_len - 1; i++, j++)
if (isalnum(*(const unsigned char *)(src + i)) || {
strchr(dont_escape, *(const unsigned char *)(src + i)) != NULL) { if (isalnum(*(const unsigned char*)(src + i)) ||
dst[j] = src[i]; strchr(dont_escape, *(const unsigned char*)(src + i)) != nullptr)
} {
else if (j + 3 < dst_len) { dst[j] = src[i];
dst[j] = '%'; }
dst[j + 1] = hex[(*(const unsigned char *)(src + i)) >> 4]; else if (j + 3 < dst_len)
dst[j + 2] = hex[(*(const unsigned char *)(src + i)) & 0xf]; {
j += 2; dst[j] = '%';
} dst[j + 1] = hex[(*(const unsigned char*)(src + i)) >> 4];
} dst[j + 2] = hex[(*(const unsigned char*)(src + i)) & 0xf];
j += 2;
}
}
dst[j] = '\0'; dst[j] = '\0';
out = dst; out = dst;
delete []dst; delete[]dst;
} }
typedef struct HTTP_DATA { typedef struct HTTP_DATA
bool exit_flag;
bool have_error;
ex_astr body;
}HTTP_DATA;
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data)
{ {
HTTP_DATA* hdata = (HTTP_DATA*)nc->user_data; bool exit_flag;
struct http_message *hm = (struct http_message *) ev_data; bool have_error;
ex_astr body;
} HTTP_DATA;
switch (ev) { static void ev_handler(struct mg_connection* nc, int ev, void* ev_data)
case MG_EV_CONNECT: {
if (*(int *)ev_data != 0) { auto* p_http_data = (HTTP_DATA*)nc->user_data;
hdata->exit_flag = true; auto* hm = (struct http_message*)ev_data;
hdata->have_error = true;
} switch (ev)
break; {
case MG_EV_HTTP_REPLY: case MG_EV_CONNECT:
nc->flags |= MG_F_CLOSE_IMMEDIATELY; if (*(int*)ev_data != 0)
//hdata->exit_flag = true; {
hdata->body.assign(hm->body.p, hm->body.len); p_http_data->exit_flag = true;
break; p_http_data->have_error = true;
case MG_EV_CLOSE: }
// if (s_exit_flag == 0) { break;
// printf("Server closed connection\n"); case MG_EV_HTTP_REPLY: nc->flags |= MG_F_CLOSE_IMMEDIATELY;
// s_exit_flag = 1; //p_http_data->exit_flag = true;
// } p_http_data->body.assign(hm->body.p, hm->body.len);
hdata->exit_flag = true; break;
break; case MG_EV_CLOSE:
default: // if (s_exit_flag == 0) {
break; // printf("Server closed connection\n");
} // s_exit_flag = 1;
// }
p_http_data->exit_flag = true;
break;
default: break;
}
} }
//static struct mg_mgr g_mg_mgr; //static struct mg_mgr g_mg_mgr;
@ -107,62 +111,63 @@ bool ts_http_get(const ex_astr& url, ex_astr& body)
// is_mg_mgr_initialized = true; // is_mg_mgr_initialized = true;
// } // }
mg_connection* nc = mg_connect_http(g_mg_mgr.get_mg_mgr(), ev_handler, url.c_str(), NULL, NULL); mg_connection* nc = mg_connect_http(g_mg_mgr.get_mg_mgr(), ev_handler, url.c_str(), NULL, NULL);
if (NULL == nc) if (NULL == nc)
return false; return false;
//HTTP_DATA* hdata = new HTTP_DATA; //HTTP_DATA* hdata = new HTTP_DATA;
HTTP_DATA hdata; HTTP_DATA hdata;
hdata.exit_flag = false; hdata.exit_flag = false;
hdata.have_error = false; hdata.have_error = false;
nc->user_data = &hdata; nc->user_data = &hdata;
// int count = 0; // int count = 0;
while (!hdata.exit_flag) while (!hdata.exit_flag)
{ {
mg_mgr_poll(g_mg_mgr.get_mg_mgr(), 100); mg_mgr_poll(g_mg_mgr.get_mg_mgr(), 100);
// count++; // count++;
// if (count > 2) // if (count > 2)
// break; // break;
} }
bool ret = !hdata.have_error; bool ret = !hdata.have_error;
if (ret) if (ret)
body = hdata.body; body = hdata.body;
// mg_mgr_free(&mgr); // mg_mgr_free(&mgr);
// delete hdata; // delete hdata;
return ret; return ret;
} }
#endif // if 0 #endif // if 0
bool ts_http_get(const ex_astr& url, ex_astr& body) bool ts_http_get(const ex_astr& url, ex_astr& body)
{ {
struct mg_mgr _mgr; struct mg_mgr _mgr{};
mg_mgr_init(&_mgr, NULL); mg_mgr_init(&_mgr, nullptr);
mg_connection* nc = mg_connect_http(&_mgr, ev_handler, url.c_str(), NULL, NULL); mg_connection* nc = mg_connect_http(&_mgr, ev_handler, url.c_str(), nullptr, nullptr);
if (nc == nullptr) { if (nc == nullptr)
{
mg_mgr_free(&_mgr); mg_mgr_free(&_mgr);
return false; return false;
} }
HTTP_DATA hdata; HTTP_DATA http_data;
hdata.exit_flag = false; http_data.exit_flag = false;
hdata.have_error = false; http_data.have_error = false;
nc->user_data = (void*)&hdata; nc->user_data = (void*)&http_data;
while (!hdata.exit_flag) while (!http_data.exit_flag)
{ {
mg_mgr_poll(&_mgr, 100); mg_mgr_poll(&_mgr, 100);
} }
bool ret = !hdata.have_error; bool ret = !http_data.have_error;
if (ret) if (ret)
body = hdata.body; body = http_data.body;
mg_mgr_free(&_mgr); mg_mgr_free(&_mgr);
return ret; return ret;
} }

View File

@ -3,7 +3,8 @@
#include <ex.h> #include <ex.h>
void ts_url_encode(const char *src, ex_astr& out); void ts_url_encode(const char* src, ex_astr& out);
bool ts_http_get(const ex_astr& url, ex_astr& body); bool ts_http_get(const ex_astr& url, ex_astr& body);
#endif // __TS_HTTP_CLIENT_H__ #endif // __TS_HTTP_CLIENT_H__

View File

@ -9,53 +9,9 @@
#include <teleport_const.h> #include <teleport_const.h>
#include <sstream> #include <sstream>
#if 0 TsHttpRpc::TsHttpRpc() : ExThreadBase("http-rpc-thread")
#define HEXTOI(x) (isdigit(x) ? (x) - '0' : (x) - 'W')
int ts_url_decode(const char* src, int src_len, char* dst, int dst_len, int is_form_url_encoded)
{ {
int i, j, a, b; mg_mgr_init(&m_mg_mgr, nullptr);
if(src_len == 0 || dst == nullptr || dst_len == 0)
return 0;
for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++)
{
if (src[i] == '%')
{
if (i < src_len - 2 && isxdigit(*(const unsigned char*)(src + i + 1)) &&
isxdigit(*(const unsigned char*)(src + i + 2)))
{
a = tolower(*(const unsigned char*)(src + i + 1));
b = tolower(*(const unsigned char*)(src + i + 2));
dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b));
i += 2;
}
else
{
return -1;
}
}
else if (is_form_url_encoded && src[i] == '+')
{
dst[j] = ' ';
}
else
{
dst[j] = src[i];
}
}
dst[j] = '\0'; /* Null-terminate the destination */
return i >= src_len ? j : -1;
}
#endif
TsHttpRpc::TsHttpRpc() :
ExThreadBase("http-rpc-thread")
{
mg_mgr_init(&m_mg_mgr, NULL);
} }
TsHttpRpc::~TsHttpRpc() TsHttpRpc::~TsHttpRpc()
@ -63,7 +19,7 @@ TsHttpRpc::~TsHttpRpc()
mg_mgr_free(&m_mg_mgr); mg_mgr_free(&m_mg_mgr);
} }
void TsHttpRpc::_thread_loop(void) void TsHttpRpc::_thread_loop()
{ {
EXLOGI("[core] TeleportServer-RPC ready on %s:%d\n", m_host_ip.c_str(), m_host_port); EXLOGI("[core] TeleportServer-RPC ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
@ -76,25 +32,19 @@ void TsHttpRpc::_thread_loop(void)
} }
bool TsHttpRpc::init(void) bool TsHttpRpc::init()
{ {
struct mg_connection* nc = NULL;
m_host_ip = g_env.rpc_bind_ip; m_host_ip = g_env.rpc_bind_ip;
m_host_port = g_env.rpc_bind_port; m_host_port = g_env.rpc_bind_port;
char addr[128] = {0}; char addr[128] = {0};
// if (0 == strcmp(m_host_ip.c_str(), "127.0.0.1") || 0 == strcmp(m_host_ip.c_str(), "localhost"))
// ex_strformat(addr, 128, ":%d", m_host_port);
// else
// ex_strformat(addr, 128, "%s:%d", m_host_ip.c_str(), m_host_port);
if (0 == strcmp(m_host_ip.c_str(), "0.0.0.0")) if (0 == strcmp(m_host_ip.c_str(), "0.0.0.0"))
ex_strformat(addr, 128, ":%d", m_host_port); ex_strformat(addr, 128, ":%d", m_host_port);
else else
ex_strformat(addr, 128, "%s:%d", m_host_ip.c_str(), m_host_port); ex_strformat(addr, 128, "%s:%d", m_host_ip.c_str(), m_host_port);
nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler); auto* nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler);
if (NULL == nc) if (nc == nullptr)
{ {
EXLOGE("[core] rpc listener failed to bind at %s.\n", addr); EXLOGE("[core] rpc listener failed to bind at %s.\n", addr);
return false; return false;
@ -115,10 +65,10 @@ bool TsHttpRpc::init(void)
void TsHttpRpc::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_data) void TsHttpRpc::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_data)
{ {
struct http_message* hm = (struct http_message*)ev_data; auto* hm = (struct http_message*)ev_data;
TsHttpRpc* _this = (TsHttpRpc*)nc->user_data; auto* _this = (TsHttpRpc*)nc->user_data;
if (NULL == _this) if (_this == nullptr)
{ {
EXLOGE("[core] rpc invalid http request.\n"); EXLOGE("[core] rpc invalid http request.\n");
return; return;
@ -168,7 +118,7 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_dat
ex_rv TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, Json::Value& json_param) ex_rv TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, Json::Value& json_param)
{ {
if (NULL == req) if (req == nullptr)
return TPE_PARAM; return TPE_PARAM;
bool is_get = true; bool is_get = true;
@ -203,14 +153,14 @@ ex_rv TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, Jso
ex_chars sztmp; ex_chars sztmp;
sztmp.resize(len); sztmp.resize(len);
memset(&sztmp[0], 0, len); memset(sztmp.data(), 0, len);
if (-1 == ex_url_decode(json_str.c_str(), json_str.length(), &sztmp[0], len, 0)) if (-1 == ex_url_decode(json_str.c_str(), json_str.length(), sztmp.data(), len, 0))
return TPE_HTTP_URL_ENCODE; return TPE_HTTP_URL_ENCODE;
json_str = &sztmp[0]; json_str = sztmp.data();
} }
if (0 == json_str.length()) if (json_str.empty())
return TPE_PARAM; return TPE_PARAM;
//Json::Reader jreader; //Json::Reader jreader;
@ -339,8 +289,7 @@ void TsHttpRpc::_rpc_func_get_config(const Json::Value& json_param, ex_astr& buf
ExIniFile& ini = g_env.get_ini(); ExIniFile& ini = g_env.get_ini();
ex_ini_sections& secs = ini.GetAllSections(); ex_ini_sections& secs = ini.GetAllSections();
ex_ini_sections::iterator it = secs.begin(); for (auto it = secs.begin(); it != secs.end(); ++it)
for (; it != secs.end(); ++it)
{ {
if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9))
{ {
@ -374,7 +323,6 @@ void TsHttpRpc::_rpc_func_request_session(const Json::Value& json_param, ex_astr
{ {
// https://github.com/tp4a/teleport/wiki/TELEPORT-CORE-JSON-RPC#request_session // https://github.com/tp4a/teleport/wiki/TELEPORT-CORE-JSON-RPC#request_session
int conn_id = 0;
ex_rv rv = TPE_OK; ex_rv rv = TPE_OK;
if (json_param["conn_id"].isNull()) if (json_param["conn_id"].isNull())
@ -388,14 +336,14 @@ void TsHttpRpc::_rpc_func_request_session(const Json::Value& json_param, ex_astr
return; return;
} }
conn_id = json_param["conn_id"].asInt(); int conn_id = json_param["conn_id"].asInt();
if (0 == conn_id) if (0 == conn_id)
{ {
_create_json_ret(buf, TPE_PARAM); _create_json_ret(buf, TPE_PARAM);
return; return;
} }
TS_CONNECT_INFO* info = new TS_CONNECT_INFO; auto* info = new TS_CONNECT_INFO;
if ((rv = ts_web_rpc_get_conn_info(conn_id, *info)) != TPE_OK) if ((rv = ts_web_rpc_get_conn_info(conn_id, *info)) != TPE_OK)
{ {
_create_json_ret(buf, rv); _create_json_ret(buf, rv);
@ -444,7 +392,7 @@ void TsHttpRpc::_rpc_func_kill_sessions(const Json::Value& json_param, ex_astr&
} }
Json::Value s = json_param["sessions"]; Json::Value s = json_param["sessions"];
int cnt = s.size(); int cnt = (int)s.size();
for (int i = 0; i < cnt; ++i) for (int i = 0; i < cnt; ++i)
{ {
if (!s[i].isString()) if (!s[i].isString())
@ -452,7 +400,7 @@ void TsHttpRpc::_rpc_func_kill_sessions(const Json::Value& json_param, ex_astr&
_create_json_ret(buf, TPE_PARAM); _create_json_ret(buf, TPE_PARAM);
return; return;
} }
} };
EXLOGV("[core] try to kill %d sessions.\n", cnt); EXLOGV("[core] try to kill %d sessions.\n", cnt);
ex_astr sp = s.toStyledString(); ex_astr sp = s.toStyledString();
@ -542,7 +490,7 @@ void TsHttpRpc::_rpc_func_set_config(const Json::Value& json_param, ex_astr& buf
return; return;
} }
int noop_timeout = json_param["noop_timeout"].asUInt(); int noop_timeout = json_param["noop_timeout"].asInt();
EXLOGV("[core] set run-time config:\n"); EXLOGV("[core] set run-time config:\n");
EXLOGV("[core] noop_timeout = %dm\n", noop_timeout); EXLOGV("[core] noop_timeout = %dm\n", noop_timeout);

View File

@ -12,43 +12,51 @@
class TsHttpRpc : public ExThreadBase class TsHttpRpc : public ExThreadBase
{ {
public: public:
TsHttpRpc(); TsHttpRpc();
~TsHttpRpc();
bool init(void); ~TsHttpRpc();
bool init();
protected: protected:
void _thread_loop(void); void _thread_loop();
private: private:
ex_rv _parse_request(struct http_message* req, ex_astr& func_cmd, Json::Value& json_param); ex_rv _parse_request(struct http_message* req, ex_astr& func_cmd, Json::Value& json_param);
void _process_request(const ex_astr& func_cmd, const Json::Value& json_param, ex_astr& buf);
//void _create_json_ret(ex_astr& buf, Json::Value& jr_root); void _process_request(const ex_astr& func_cmd, const Json::Value& json_param, ex_astr& buf);
void _create_json_ret(ex_astr& buf, int errcode, const Json::Value& jr_data);
void _create_json_ret(ex_astr& buf, int errcode);
void _create_json_ret(ex_astr& buf, int errcode, const char* message);
// 获取core服务的配置信息主要是支持的各个协议是否启用以及其端口号等 void _create_json_ret(ex_astr& buf, int errcode, const Json::Value& jr_data);
void _rpc_func_get_config(const Json::Value& json_param, ex_astr& buf);
// set run-time configuration, like no-op-timeout.
void _rpc_func_set_config(const Json::Value& json_param, ex_astr& buf);
// 请求一个会话ID
void _rpc_func_request_session(const Json::Value& json_param, ex_astr& buf);
// 强行终止会话
void _rpc_func_kill_sessions(const Json::Value& json_param, ex_astr& buf);
// 加密一个字符串返回的是密文的BASE64编码
void _rpc_func_enc(const Json::Value& json_param, ex_astr& buf);
// 要求整个核心服务退出
void _rpc_func_exit(const Json::Value& json_param, ex_astr& buf);
static void _mg_event_handler(struct mg_connection *nc, int ev, void *ev_data); static void _create_json_ret(ex_astr& buf, int errcode);
void _create_json_ret(ex_astr& buf, int errcode, const char* message);
// 获取core服务的配置信息主要是支持的各个协议是否启用以及其端口号等
void _rpc_func_get_config(const Json::Value& json_param, ex_astr& buf);
// set run-time configuration, like no-op-timeout.
void _rpc_func_set_config(const Json::Value& json_param, ex_astr& buf);
// 请求一个会话ID
void _rpc_func_request_session(const Json::Value& json_param, ex_astr& buf);
// 强行终止会话
void _rpc_func_kill_sessions(const Json::Value& json_param, ex_astr& buf);
// 加密一个字符串返回的是密文的BASE64编码
void _rpc_func_enc(const Json::Value& json_param, ex_astr& buf);
// 要求整个核心服务退出
void _rpc_func_exit(const Json::Value& json_param, ex_astr& buf);
static void _mg_event_handler(struct mg_connection* nc, int ev, void* ev_data);
private: private:
ex_astr m_host_ip; ex_astr m_host_ip;
int m_host_port; int m_host_port;
struct mg_mgr m_mg_mgr; struct mg_mgr m_mg_mgr;
}; };
#endif // __TS_HTTP_RPC_H__ #endif // __TS_HTTP_RPC_H__

View File

@ -3,6 +3,7 @@
#include "ts_http_rpc.h" #include "ts_http_rpc.h"
#include "ts_web_rpc.h" #include "ts_web_rpc.h"
#include "ts_env.h" #include "ts_env.h"
#include "ts_ver.h"
#include "tp_tpp_mgr.h" #include "tp_tpp_mgr.h"
#include <mbedtls/platform.h> #include <mbedtls/platform.h>
@ -103,10 +104,10 @@ bool tpp_session_end(const char* sid, int db_id, int ret) {
int ts_main() { int ts_main() {
ExIniFile& ini = g_env.get_ini(); ExIniFile& ini = g_env.get_ini();
EXLOGI("\n"); EXLOGW("\n");
EXLOGI("###############################################################\n"); EXLOGW("###############################################################\n");
EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str()); EXLOGW(L"Teleport Core Server v%ls starting ...\n", TP_SERVER_VER);
EXLOGI("Teleport Core Server starting ...\n"); EXLOGW(L"Load config file: %ls.\n", ini.get_filename().c_str());
ex_ini_sections& secs = ini.GetAllSections(); ex_ini_sections& secs = ini.GetAllSections();
TsHttpRpc rpc; TsHttpRpc rpc;

View File

@ -7,20 +7,25 @@
TsSessionManager g_session_mgr; TsSessionManager g_session_mgr;
TsSessionManager::TsSessionManager() : TsSessionManager::TsSessionManager() :
ExThreadBase("sid-mgr-thread") { ExThreadBase("sid-mgr-thread")
{
} }
TsSessionManager::~TsSessionManager() { TsSessionManager::~TsSessionManager()
{
auto it_conn = m_connections.begin(); auto it_conn = m_connections.begin();
for (; it_conn != m_connections.end(); ++it_conn) { 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()); 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; delete it_conn->second;
} }
m_connections.clear(); m_connections.clear();
} }
void TsSessionManager::_thread_loop() { void TsSessionManager::_thread_loop()
for (;;) { {
for (;;)
{
ex_sleep_ms(1000); ex_sleep_ms(1000);
if (m_need_stop) if (m_need_stop)
return; return;
@ -28,28 +33,33 @@ void TsSessionManager::_thread_loop() {
} }
} }
void TsSessionManager::_remove_expired_connect_info() { void TsSessionManager::_remove_expired_connect_info()
{
// 超过15秒未进行连接的connect-info会被移除 // 超过15秒未进行连接的connect-info会被移除
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
ex_u64 _now = ex_get_tick_count(); ex_u64 _now = ex_get_tick_count();
auto it = m_connections.begin(); auto it = m_connections.begin();
for (; it != m_connections.end();) { 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)); //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) { if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start)
{
EXLOGD("[core] remove connection info, because timeout: %s\n", it->first.c_str()); EXLOGD("[core] remove connection info, because timeout: %s\n", it->first.c_str());
delete it->second; delete it->second;
m_connections.erase(it++); m_connections.erase(it++);
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
} }
else { else
{
++it; ++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); ExThreadSmartLock locker(m_lock);
auto it = m_connections.find(sid); auto it = m_connections.find(sid);
@ -80,7 +90,8 @@ bool TsSessionManager::get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& inf
return true; return true;
} }
bool TsSessionManager::free_connect_info(const ex_astr& sid) { bool TsSessionManager::free_connect_info(const ex_astr& sid)
{
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
auto it = m_connections.find(sid); auto it = m_connections.find(sid);
@ -91,15 +102,18 @@ bool TsSessionManager::free_connect_info(const ex_astr& sid) {
// 对于RDP来说此时不要移除连接信息系统自带RDP客户端在第一次连接时进行协议协商然后马上会断开之后立即重新连接一次第二次连接之前可能会提示证书信息如果用户长时间不操作可能会导致超时 // 对于RDP来说此时不要移除连接信息系统自带RDP客户端在第一次连接时进行协议协商然后马上会断开之后立即重新连接一次第二次连接之前可能会提示证书信息如果用户长时间不操作可能会导致超时
// 因此,我们将其引用计数减低,并更新一下最后访问时间,让定时器来移除它。 // 因此,我们将其引用计数减低,并更新一下最后访问时间,让定时器来移除它。
if (it->second->protocol_type != TP_PROTOCOL_TYPE_RDP) { if (it->second->protocol_type != TP_PROTOCOL_TYPE_RDP)
if (it->second->ref_count <= 0) { {
if (it->second->ref_count <= 0)
{
EXLOGD("[core] remove connection info, because all connections closed: %s\n", it->first.c_str()); EXLOGD("[core] remove connection info, because all connections closed: %s\n", it->first.c_str());
delete it->second; delete it->second;
m_connections.erase(it); m_connections.erase(it);
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
} }
} }
else { else
{
if (it->second->ref_count == 1) if (it->second->ref_count == 1)
it->second->ref_count = 0; it->second->ref_count = 0;
it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒这样如果没有发生RDP的第二次连接这个连接信息就会在一分钟后被清除。 it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒这样如果没有发生RDP的第二次连接这个连接信息就会在一分钟后被清除。
@ -109,7 +123,8 @@ bool TsSessionManager::free_connect_info(const ex_astr& sid) {
return true; 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); ExThreadSmartLock locker(m_lock);
EXLOGD( EXLOGD(
@ -121,7 +136,8 @@ bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info) {
ex_astr _sid; ex_astr _sid;
int retried = 0; int retried = 0;
ts_connections::iterator it; ts_connections::iterator it;
for (;;) { for (;;)
{
_gen_session_id(_sid, info, 6); _gen_session_id(_sid, info, 6);
it = m_connections.find(_sid); it = m_connections.find(_sid);
if (it == m_connections.end()) if (it == m_connections.end())
@ -138,17 +154,19 @@ bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info) {
m_connections.insert(std::make_pair(_sid, info)); m_connections.insert(std::make_pair(_sid, info));
sid = _sid; sid = _sid;
if (info->protocol_type == TP_PROTOCOL_TYPE_RDP) { if (info->protocol_type == TP_PROTOCOL_TYPE_RDP)
{
info->ref_count = 1; // 因为RDP连接之前可能会有很长时间用于确认是否连接、是否信任证书所以很容易超时我们认为将引用计数+1防止因超时被清除。 info->ref_count = 1; // 因为RDP连接之前可能会有很长时间用于确认是否连接、是否信任证书所以很容易超时我们认为将引用计数+1防止因超时被清除。
char szTmp[8] = {0}; char szTmp[8] = {0};
snprintf(szTmp, 8, "%02X", (unsigned char) (info->acc_username.length() + info->acc_secret.length())); snprintf(szTmp, 8, "%02X", (unsigned char)(info->acc_username.length() + info->acc_secret.length()));
sid += szTmp; sid += szTmp;
} }
return true; 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; mbedtls_sha1_context sha;
ex_u8 sha_digist[20] = {0}; ex_u8 sha_digist[20] = {0};
@ -157,11 +175,11 @@ void TsSessionManager::_gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info
mbedtls_sha1_init(&sha); mbedtls_sha1_init(&sha);
mbedtls_sha1_starts(&sha); mbedtls_sha1_starts(&sha);
mbedtls_sha1_update(&sha, (const unsigned char*) &_tick, sizeof(ex_u64)); 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*)&_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->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->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*)info->acc_username.c_str(), info->acc_username.length());
mbedtls_sha1_finish(&sha, sha_digist); mbedtls_sha1_finish(&sha, sha_digist);
mbedtls_sha1_free(&sha); mbedtls_sha1_free(&sha);
@ -169,7 +187,8 @@ void TsSessionManager::_gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info
int _len = len / 2 + 1; int _len = len / 2 + 1;
int i = 0; int i = 0;
int offset = 0; int offset = 0;
for (i = 0; i < _len; ++i) { for (i = 0; i < _len; ++i)
{
snprintf(szTmp + offset, 64 - offset, "%02X", sha_digist[i]); snprintf(szTmp + offset, 64 - offset, "%02X", sha_digist[i]);
offset += 2; offset += 2;
} }

View File

@ -3,8 +3,6 @@
#include "ts_crypto.h" #include "ts_crypto.h"
#include "ts_http_client.h" #include "ts_http_client.h"
#include "../common/ts_const.h"
#include <ex/ex_str.h> #include <ex/ex_str.h>
#include <teleport_const.h> #include <teleport_const.h>

View File

@ -162,7 +162,7 @@ void SshProxy::_thread_loop() {
uint32_t dbg_id = m_dbg_id++; uint32_t dbg_id = m_dbg_id++;
auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port); 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); EXLOGW("[ssh] ------ NEW SSH SESSION [%s from %s] ------\n", session->dbg_name().c_str(), session->dbg_client().c_str());
{ {
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);

View File

@ -604,6 +604,13 @@ int SshSession::_do_auth(const char* user, const char* secret)
} }
else else
{ {
// 如果第一次认证时没有确定目标远程主机IP和端口例如session-id无效则不再继续后面的操作
if(m_conn_ip.empty() || m_conn_port == 0)
{
EXLOGE("[%s] second auth, user: %s, no remote host info, can not connect.\n", m_dbg_name.c_str(), user);
return SSH_AUTH_DENIED;
}
// 允许用户自行输入密码的情况下第二次认证参数secret就是用户自己输入的密码了。 // 允许用户自行输入密码的情况下第二次认证参数secret就是用户自己输入的密码了。
m_acc_secret = secret; m_acc_secret = secret;
} }