From 4ee850c83ec9c4fd7a7e9a265753e8d4e0a3d794 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Fri, 7 Apr 2017 15:05:29 +0800 Subject: [PATCH] temp. --- build/builder/build-server.py | 16 +- client/tp_assist/tp_assist.vs2015.vcxproj | 368 ++-- client/tp_assist/ts_http_rpc.cpp | 40 +- common/teleport/teleport_const.h | 2 +- server/tp_core/common/ts_const.h | 134 +- server/tp_core/core/tp_core.vs2015.vcxproj | 456 ++-- .../teleport/app/eom_app/controller/host.py | 1954 ++++++++--------- 7 files changed, 1490 insertions(+), 1480 deletions(-) diff --git a/build/builder/build-server.py b/build/builder/build-server.py index 3848c43..a0dcf4d 100644 --- a/build/builder/build-server.py +++ b/build/builder/build-server.py @@ -25,12 +25,16 @@ class BuilderWin(BuilderBase): def build_server(self): cc.n('build web server ...') - sln_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'tp_web.vs2015.sln') - out_file = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, ctx.target_path, 'tp_web.exe') - if os.path.exists(out_file): - utils.remove(out_file) - utils.msvc_build(sln_file, 'tp_web', ctx.target_path, ctx.bits_path, False) - utils.ensure_file_exists(out_file) + # notice: now we can not build debug version of tp_web.exe + if ctx.target_path == 'debug': + cc.w('cannot build debug version of tp_web, skip.') + else: + sln_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'tp_web.vs2015.sln') + out_file = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, ctx.target_path, 'tp_web.exe') + if os.path.exists(out_file): + utils.remove(out_file) + utils.msvc_build(sln_file, 'tp_web', ctx.target_path, ctx.bits_path, False) + utils.ensure_file_exists(out_file) cc.n('build core server ...') sln_file = os.path.join(env.root_path, 'server', 'tp_core', 'core', 'tp_core.vs2015.sln') diff --git a/client/tp_assist/tp_assist.vs2015.vcxproj b/client/tp_assist/tp_assist.vs2015.vcxproj index a7293a5..cdfceab 100644 --- a/client/tp_assist/tp_assist.vs2015.vcxproj +++ b/client/tp_assist/tp_assist.vs2015.vcxproj @@ -1,185 +1,185 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {63B7A8F2-9722-487C-A92A-3DB5D8CA1473} - Win32Proj - tp_assist - tp_assist - 8.1 - - - - Application - true - v140_xp - Unicode - - - Application - false - v140_xp - true - Unicode - false - - - - - - - - - - - - - true - ..\..\out\client\$(PlatformTarget)\$(Configuration)\ - ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - D:\apps\vld\include;$(IncludePath) - D:\apps\vld\lib\Win32;$(LibraryPath) - - - false - ..\..\out\client\$(PlatformTarget)\$(Configuration)\ - ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) - true - ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 - - - Windows - true - ..\..\external\openssl\out32\ssleay32.lib;..\..\external\openssl\out32\libeay32.lib;%(AdditionalDependencies) - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) - true - ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 - MultiThreaded - - - Windows - true - true - true - ..\..\external\openssl\out32\ssleay32.lib;..\..\external\openssl\out32\libeay32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - NotUsing - NotUsing - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {63B7A8F2-9722-487C-A92A-3DB5D8CA1473} + Win32Proj + tp_assist + tp_assist + 8.1 + + + + Application + true + v140_xp + Unicode + + + Application + false + v140_xp + true + Unicode + false + + + + + + + + + + + + + true + ..\..\out\client\$(PlatformTarget)\$(Configuration)\ + ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath) + C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(LibraryPath) + + + false + ..\..\out\client\$(PlatformTarget)\$(Configuration)\ + ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) + true + ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 + + + Windows + true + ..\..\external\openssl\out32\ssleay32.lib;..\..\external\openssl\out32\libeay32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) + true + ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 + MultiThreaded + + + Windows + true + true + true + ..\..\external\openssl\out32\ssleay32.lib;..\..\external\openssl\out32\libeay32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/tp_assist/ts_http_rpc.cpp b/client/tp_assist/ts_http_rpc.cpp index f7622dc..c017e7e 100644 --- a/client/tp_assist/ts_http_rpc.cpp +++ b/client/tp_assist/ts_http_rpc.cpp @@ -44,8 +44,12 @@ End Sub ֹˣubuntuԣ֪Ƿܹ֧еLinuxSecureCRTԴ˱ʾԡ */ +#define RDP_CLIENT_SYSTEM_BUILTIN +// #define RDP_CLIENT_SYSTEM_ACTIVE_CONTROL +// #define RDP_CLIENT_FREERDP -#if 0 + +#ifdef RDP_CLIENT_SYSTEM_BUILTIN std::string rdp_content = "\ connect to console:i:%d\n\ screen mode id:i:%d\n\ @@ -64,7 +68,7 @@ audiocapturemode:i:0\n\ negotiate security layer:i:1\n\ videoplaybackmode:i:1\n\ connection type:i:2\n\ -prompt for credentials on client:i:1\r\n\ +prompt for credentials on client:i:1\n\ displayconnectionbar:i:1\n\ disable wallpaper:i:1\n\ allow font smoothing:i:0\n\ @@ -116,7 +120,6 @@ void http_rpc_stop(void) g_http_interface.stop(); } - #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) @@ -582,9 +585,9 @@ void TsHttpRpc::_rpc_func_create_ts_client(const ex_astr& func_args, ex_astr& bu //============================================== // RDP //============================================== -#if 1 +//#if 1 -#if 0 +#if defined(RDP_CLIENT_SYSTEM_ACTIVE_CONTROL) int split_pos = session_id.length() - 2; std::string real_s_id = session_id.substr(0, split_pos); std::string str_pwd_len = session_id.substr(split_pos, session_id.length()); @@ -624,7 +627,7 @@ void TsHttpRpc::_rpc_func_create_ts_client(const ex_astr& func_args, ex_astr& bu w_exe_path += w_szCommandLine; //BOOL bRet = DeleteFile(w_sz_file_name.c_str()); -#else +#elif defined(RDP_CLIENT_FREERDP) wchar_t* w_screen = NULL; switch (windows_size) @@ -677,9 +680,9 @@ void TsHttpRpc::_rpc_func_create_ts_client(const ex_astr& func_args, ex_astr& bu w_exe_path += w_szCommandLine; -#endif +//#endif -#else +#elif defined(RDP_CLIENT_SYSTEM_BUILTIN) int width = 800; int higth = 600; int cx = 0; @@ -755,29 +758,32 @@ void TsHttpRpc::_rpc_func_create_ts_client(const ex_astr& func_args, ex_astr& bu if (ret <= 0) { printf("fopen failed (%d).\n", GetLastError()); - _create_json_ret(buf, TSR_GETTEMPPATH_ERROR); + _create_json_ret(buf, TPE_FAILED); return; } ex_wstr w_s_id; - ex_astr2str(real_sid, w_s_id); + ex_astr2wstr(real_sid, w_s_id); - ex_astr temp_host_ip = replace_all_distinct(real_host_ip, ("."), "-"); + ex_astr temp_host_ip = real_host_ip;// replace_all_distinct(real_host_ip, ("."), "-"); + ex_replace_all(temp_host_ip, ".", "-"); - sprintf_s(sz_file_name, ("%s\\%s.rdp"), temp_path, temp_host_ip.c_str()); - FILE* f = fopen(sz_file_name, ("wt")); - if (f == NULL) + sprintf_s(sz_file_name, ("%s%s.rdp"), temp_path, temp_host_ip.c_str()); + //FILE* f = fopen(sz_file_name, ("wt")); + //if (f == NULL) + FILE* f = NULL; + if(fopen_s(&f, sz_file_name, "wt") != 0) { printf("fopen failed (%d).\n", GetLastError()); - _create_json_ret(buf, TSR_OPENFILE_ERROR); + _create_json_ret(buf, TPE_OPENFILE); return; } // Write a string into the file. fwrite(sz_rdp_file_content, strlen(sz_rdp_file_content), 1, f); fclose(f); ex_wstr w_sz_file_name; - ex_astr2str(sz_file_name, w_sz_file_name); + ex_astr2wstr(sz_file_name, w_sz_file_name); - swprintf_s(w_szCommandLine, _T("mstsc %s"), w_sz_file_name.c_str()); + swprintf_s(w_szCommandLine, _T("mstsc \"%s\""), w_sz_file_name.c_str()); w_exe_path = w_szCommandLine; //BOOL bRet = DeleteFile(w_sz_file_name.c_str()); #endif diff --git a/common/teleport/teleport_const.h b/common/teleport/teleport_const.h index 852d887..4fdf8f8 100644 --- a/common/teleport/teleport_const.h +++ b/common/teleport/teleport_const.h @@ -35,7 +35,7 @@ // #define TPE_OPENFILE_ERROR 0x1007 // ޷ļ // #define TPE_GETTEMPPATH_ERROR 0x1007 - +#define TPE_OPENFILE 300 //------------------------------------------------------- // ֳרôֵ diff --git a/server/tp_core/common/ts_const.h b/server/tp_core/common/ts_const.h index daf5398..bca8089 100644 --- a/server/tp_core/common/ts_const.h +++ b/server/tp_core/common/ts_const.h @@ -1,67 +1,67 @@ -#ifndef __TS_ERRNO_H__ -#define __TS_ERRNO_H__ - -//#include "ts_types.h" - -// #define TS_RDP_PROXY_PORT 3389 -// #define TS_RDP_PROXY_HOST "0.0.0.0" - -#define TS_SSH_PROXY_PORT 22 -#define TS_SSH_PROXY_HOST "0.0.0.0" -// -// #define TS_TELNET_PROXY_PORT 23 -// #define TS_TELNET_PROXY_HOST "0.0.0.0" - -#define TS_HTTP_RPC_PORT 52080 -//#define TS_HTTP_RPC_HOST "127.0.0.1" -#define TS_HTTP_RPC_HOST "0.0.0.0" - - -#define TS_RDP_PROTOCOL_RDP 0 -#define TS_RDP_PROTOCOL_SSL 1 -#define TS_RDP_PROTOCOL_HYBRID 2 -#define TS_RDP_PROTOCOL_HYBRID_EX 8 - -#define TS_AUTH_MODE_NONE 0 -#define TS_AUTH_MODE_PASSWORD 1 -#define TS_AUTH_MODE_PRIVATE_KEY 2 - -#define TS_PROXY_PROTOCOL_RDP 1 -#define TS_PROXY_PROTOCOL_SSH 2 -#define TS_PROXY_PROTOCOL_TELNET 3 - -//typedef ex_u32 ts_rv; - -#define TSR_OK 0x0000 -#define TSR_INVALID_DATA 0x0001 -#define TSR_SEND_ERROR 0x0002 -#define TSR_NEED_MORE_DATA 0x0005 -#define TSR_FAILED 0x0006 -#define TSR_DATA_LEN_ZERO 0x0007 - -#define TSR_MAX_CONN_REACHED 0x0010 -#define TSR_MAX_HOST_REACHED 0x0011 - -#define TSR_INVALID_REQUEST 0x1000 -#define TSR_INVALID_URI 0x1001 -#define TSR_INVALID_URL_ENCODE 0x1002 -#define TSR_NO_SUCH_METHOD 0x1003 -#define TSR_INVALID_JSON_FORMAT 0x1004 -#define TSR_INVALID_JSON_PARAM 0x1005 -#define TSR_GETAUTH_INFO_ERROR 0x1006 -#define TSR_HOST_LOCK_ERROR 0x1007 -#define TSR_ACCOUNT_LOCK_ERROR 0x1008 - -//================================================ -#define SESS_STAT_RUNNING 0 // Ựʼˣδ -#define SESS_STAT_END 9999 // Ựɹ -#define SESS_STAT_ERR_AUTH_DENIED 1 // ỰΪ֤ʧ -#define SESS_STAT_ERR_CONNECT 2 // ỰΪ޷ӵԶ -#define SESS_STAT_ERR_BAD_SSH_KEY 3 // ỰΪ޷ʶSSH˽Կ -#define SESS_STAT_ERR_INTERNAL 4 // ỰΪڲ -#define SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // ỰΪЭ鲻֧(RDP) -#define SESS_STAT_ERR_BAD_PKG 6 // ỰΪյı -#define SESS_STAT_ERR_RESET 7 // ỰΪteleportķ - - -#endif // __TS_ERRNO_H__ +#ifndef __TS_ERRNO_H__ +#define __TS_ERRNO_H__ + +//#include "ts_types.h" + +#define TS_RDP_PROXY_PORT 3389 +#define TS_RDP_PROXY_HOST "0.0.0.0" + +#define TS_SSH_PROXY_PORT 22 +#define TS_SSH_PROXY_HOST "0.0.0.0" + +#define TS_TELNET_PROXY_PORT 23 +#define TS_TELNET_PROXY_HOST "0.0.0.0" + +#define TS_HTTP_RPC_PORT 52080 +#define TS_HTTP_RPC_HOST "127.0.0.1" +//#define TS_HTTP_RPC_HOST "0.0.0.0" + + +#define TS_RDP_PROTOCOL_RDP 0 +#define TS_RDP_PROTOCOL_SSL 1 +#define TS_RDP_PROTOCOL_HYBRID 2 +#define TS_RDP_PROTOCOL_HYBRID_EX 8 + +#define TS_AUTH_MODE_NONE 0 +#define TS_AUTH_MODE_PASSWORD 1 +#define TS_AUTH_MODE_PRIVATE_KEY 2 + +#define TS_PROXY_PROTOCOL_RDP 1 +#define TS_PROXY_PROTOCOL_SSH 2 +#define TS_PROXY_PROTOCOL_TELNET 3 + +//typedef ex_u32 ts_rv; + +#define TSR_OK 0x0000 +#define TSR_INVALID_DATA 0x0001 +#define TSR_SEND_ERROR 0x0002 +#define TSR_NEED_MORE_DATA 0x0005 +#define TSR_FAILED 0x0006 +#define TSR_DATA_LEN_ZERO 0x0007 + +#define TSR_MAX_CONN_REACHED 0x0010 +#define TSR_MAX_HOST_REACHED 0x0011 + +#define TSR_INVALID_REQUEST 0x1000 +#define TSR_INVALID_URI 0x1001 +#define TSR_INVALID_URL_ENCODE 0x1002 +#define TSR_NO_SUCH_METHOD 0x1003 +#define TSR_INVALID_JSON_FORMAT 0x1004 +#define TSR_INVALID_JSON_PARAM 0x1005 +#define TSR_GETAUTH_INFO_ERROR 0x1006 +#define TSR_HOST_LOCK_ERROR 0x1007 +#define TSR_ACCOUNT_LOCK_ERROR 0x1008 + +//================================================ +#define SESS_STAT_RUNNING 0 // Ựʼˣδ +#define SESS_STAT_END 9999 // Ựɹ +#define SESS_STAT_ERR_AUTH_DENIED 1 // ỰΪ֤ʧ +#define SESS_STAT_ERR_CONNECT 2 // ỰΪ޷ӵԶ +#define SESS_STAT_ERR_BAD_SSH_KEY 3 // ỰΪ޷ʶSSH˽Կ +#define SESS_STAT_ERR_INTERNAL 4 // ỰΪڲ +#define SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // ỰΪЭ鲻֧(RDP) +#define SESS_STAT_ERR_BAD_PKG 6 // ỰΪյı +#define SESS_STAT_ERR_RESET 7 // ỰΪteleportķ + + +#endif // __TS_ERRNO_H__ diff --git a/server/tp_core/core/tp_core.vs2015.vcxproj b/server/tp_core/core/tp_core.vs2015.vcxproj index 0a42984..08568d1 100644 --- a/server/tp_core/core/tp_core.vs2015.vcxproj +++ b/server/tp_core/core/tp_core.vs2015.vcxproj @@ -1,229 +1,229 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {6548CB1D-A7BA-4A68-9B3F-A5129F77868B} - Win32Proj - tp_core - 8.1 - tp_core - - - - Application - true - v140_xp - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - ..\..\..\out\server\$(PlatformTarget)\$(Configuration)\ - ..\..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - D:\apps\vld\include;$(IncludePath) - D:\apps\vld\lib\Win32;$(LibraryPath) - - - true - ..\..\out\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - - - false - ..\..\..\out\server\$(PlatformTarget)\$(Configuration)\ - ..\..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - - - false - ..\..\out\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) - true - ../../../common/libex/include;../../../external/jsoncpp/include;../../../external/mbedtls/include;../../../external/mongoose - MultiThreadedDebug - - - Console - - - libcmt.lib - Debug - - - - - - - Level3 - Disabled - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - ../../external/windows/libuv/include;../../external/windows/openssl/include;../../external/windows/zlib/include;../../external/windows/mbedtls/include;../../external/windows/libssh/include;../../external/common/jsoncpp/include;../../external/common/sqlite;d:/apps/vld/include - - - Windows - true - ../../external/windows/openssl/lib;../../external/windows/zlib/lib;../../external/windows/libssh/lib - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) - true - ../../../common/libex/include;../../../external/jsoncpp/include;../../../external/mbedtls/include;../../../external/mongoose - MultiThreaded - - - Console - true - true - - - - - - - Level3 - - - MaxSpeed - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - ../../external/windows/libuv/include;../../external/windows/openssl/include;../../external/windows/zlib/include;../../external/windows/mbedtls/include;../../external/windows/libssh/include;../../external/common/jsoncpp/include;../../external/common/sqlite - - - Windows - true - true - true - ../../external/windows/openssl/lib;../../external/windows/zlib/lib;../../external/windows/libssh/lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {6548CB1D-A7BA-4A68-9B3F-A5129F77868B} + Win32Proj + tp_core + 8.1 + tp_core + + + + Application + true + v140_xp + Unicode + + + Application + false + v140_xp + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + ..\..\..\out\server\$(PlatformTarget)\$(Configuration)\ + ..\..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath) + C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(LibraryPath) + + + true + ..\..\out\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + + + false + ..\..\..\out\server\$(PlatformTarget)\$(Configuration)\ + ..\..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + + + false + ..\..\out\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + ..\..\out\_tmp_\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) + true + ../../../common/libex/include;../../../external/jsoncpp/include;../../../external/mbedtls/include;../../../external/mongoose + MultiThreadedDebug + + + Console + + + libcmt.lib + Debug + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ../../external/windows/libuv/include;../../external/windows/openssl/include;../../external/windows/zlib/include;../../external/windows/mbedtls/include;../../external/windows/libssh/include;../../external/common/jsoncpp/include;../../external/common/sqlite;d:/apps/vld/include + + + Windows + true + ../../external/windows/openssl/lib;../../external/windows/zlib/lib;../../external/windows/libssh/lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) + true + ../../../common/libex/include;../../../external/jsoncpp/include;../../../external/mbedtls/include;../../../external/mongoose + MultiThreaded + + + Console + true + true + + + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ../../external/windows/libuv/include;../../external/windows/openssl/include;../../external/windows/zlib/include;../../external/windows/mbedtls/include;../../external/windows/libssh/include;../../external/common/jsoncpp/include;../../external/common/sqlite + + + Windows + true + true + true + ../../external/windows/openssl/lib;../../external/windows/zlib/lib;../../external/windows/libssh/lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/www/teleport/app/eom_app/controller/host.py b/server/www/teleport/app/eom_app/controller/host.py index 449484e..de39949 100644 --- a/server/www/teleport/app/eom_app/controller/host.py +++ b/server/www/teleport/app/eom_app/controller/host.py @@ -1,977 +1,977 @@ -# -*- coding: utf-8 -*- - -import time -import csv -import os -import json -import threading -import tornado.gen -import tornado.httpclient - -from eom_app.app.configs import app_cfg -from eom_app.app.util import * -from eom_app.module import host -from eom_common.eomcore.logger import * -from eom_app.app.session import web_session -from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseUserAuthJsonHandler, TPBaseAdminAuthJsonHandler - -cfg = app_cfg() - -# 临时认证ID的基数,每次使用时均递减 -tmp_auth_id_base = -1 -tmp_auth_id_lock = threading.RLock() - - -class IndexHandler(TPBaseUserAuthHandler): - def get(self): - _user = self.get_session('user') - if _user is None: - return self.write(-1) - - param = dict() - - param['core'] = { - 'ssh_port': cfg.core.ssh.port, - 'rdp_port': cfg.core.telnet.port, - 'telnet_port': cfg.core.telnet.port - } - - param['group_list'] = host.get_group_list() - - if _user['type'] >= 100: - param['cert_list'] = host.get_cert_list() - self.render('host/admin_index.mako', page_param=json.dumps(param)) - else: - self.render('host/common_index.mako', page_param=json.dumps(param)) - - -class UploadAndImportHandler(TPBaseAdminAuthJsonHandler): - # TODO: 导入操作可能会比较耗时,应该分离导入和获取导入状态两个过程,在页面上可以呈现导入进度,并列出导出成功/失败的项 - - @tornado.gen.coroutine - def post(self): - """ - csv导入规则: - 每一行的数据格式: 分组ID,操作系统,IP地址,端口,系统用户,系统密码,协议,密钥ID,状态,认证类型,描述 - 因为主机的唯一性在于 `IP地址 + 端口`,且允许一个 `IP地址 + 端口` 对应多个系统用户,因此,每一行的数据几乎没有限制。 - 在导入时: - 1. 对每一个第一次遇到的 `IP地址 + 端口` 组合,就在 ts_host_info 表中加一个条目,并在 ts_auth_info 表中加入一个用户。 - 2. 对于非第一次遇到的 `IP地址 + 端口` 组合,则仅仅在 ts_auth_info 表中加一个用户,不更改 ts_host_info 表中的现有数据。 - 3. `IP地址 + 端口 + 用户` 的组合不能重复。 - 4. 空行跳过,数据格式不正确的跳过。 - """ - ret = dict() - ret['code'] = 0 - ret['msg'] = list() # 记录跳过的行(格式不正确,或者数据重复等) - csv_filename = '' - - try: - # upload_path = os.path.join(os.path.dirname(__file__), 'csv-files') # 文件的暂存路径 - upload_path = os.path.join(cfg.data_path, 'tmp') # 文件的暂存路径 - if not os.path.exists(upload_path): - os.mkdir(upload_path) - file_metas = self.request.files['csvfile'] # 提取表单中‘name’为‘file’的文件元数据 - for meta in file_metas: - now = time.localtime(time.time()) - tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.csv'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec) - csv_filename = os.path.join(upload_path, tmp_name) - with open(csv_filename, 'wb') as up: - up.write(meta['body']) - - # file encode maybe utf8 or gbk... check it out. - file_encode = None - with open(csv_filename, encoding='gbk') as up: - try: - up.readlines() - file_encode = 'gbk' - except: - log.e('open file:{} -1\n'.format(csv_filename)) - - if file_encode is None: - with open(csv_filename, encoding='utf8') as up: - try: - up.readlines() - file_encode = 'utf8' - except: - log.e('open file:{} -2\n'.format(csv_filename)) - - if file_encode is None: - os.remove(csv_filename) - self.write_json(-2) - log.e('file {} unknown encode.\n'.format(csv_filename)) - return - - with open(csv_filename, encoding=file_encode) as up: - csv_reader = csv.reader(up) - is_first_line = True - for csv_recorder in csv_reader: - # 跳过第一行,那是格式说明 - if is_first_line: - is_first_line = False - continue - - # 空行则忽略 - if len(csv_recorder) <= 1: - continue - - # 格式错误则记录在案,然后继续 - if len(csv_recorder) != 13: - ret['msg'].append({'reason': '格式错误', 'line': ', '.join(csv_recorder)}) - continue - - # pro_type = int(line[6]) - # host_port = int(line[3]) - - host_args = dict() - user_args = dict() - # 分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密,附加参数, 密钥ID, 认证类型 - - host_args['group_id'] = int(csv_recorder[0]) - host_args['host_sys_type'] = int(csv_recorder[1]) - host_args['host_ip'] = csv_recorder[2] - host_args['host_port'] = csv_recorder[3] - host_args['protocol'] = csv_recorder[4] - host_args['host_lock'] = csv_recorder[5] - host_args['host_desc'] = csv_recorder[6] - # 加入一个主机(如果已经存在,则直接返回已存在的条目的host_id) - host_id = host.add_host(host_args, must_not_exists=False) - if host_id < 0: - ret['msg'].append({'reason': '添加主机失败,操作数据库失败', 'line': ', '.join(csv_recorder)}) - continue - - user_args['host_id'] = host_id - user_args['user_name'] = csv_recorder[7] - user_pswd = csv_recorder[8] - is_encrpty = int(csv_recorder[9]) - user_args['user_param'] = csv_recorder[10].replace('\\n', '\n') - user_args['cert_id'] = int(csv_recorder[11]) - auth_mode = int(csv_recorder[12]) - user_args['auth_mode'] = auth_mode - user_args['user_pswd'] = '' - ret_code = 0 - if auth_mode == 0: - pass - elif auth_mode == 1: - try: - if is_encrpty == 0: - # ret_code, tmp_pswd = get_enc_data(user_pswd) - _yr = async_enc(user_pswd) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - tmp_pswd = return_data['data'] - - else: - tmp_pswd = user_pswd - - user_args['user_pswd'] = tmp_pswd - - except Exception: - ret_code = -1 - log.e('get_enc_data() failed.\n') - - if 0 != ret_code: - ret['msg'].append({'reason': '加密用户密码失败,可能原因:Teleport核心服务未启动', 'line': ', '.join(csv_recorder)}) - log.e('get_enc_data() failed, error={}\n'.format(ret_code)) - continue - - elif auth_mode == 2: - pass - # user_args['cert_id'] = int(csv_recorder[7]) - else: - ret['msg'].append({'reason': '未知的认证模式', 'line': ', '.join(csv_recorder)}) - log.e('auth_mode unknown\n') - continue - - uid = host.sys_user_add(user_args) - if uid < 0: - if uid == -100: - ret['msg'].append({'reason': '添加登录账号失败,账号已存在', 'line': ', '.join(csv_recorder)}) - else: - ret['msg'].append({'reason': '添加登录账号失败,操作数据库失败', 'line': ', '.join(csv_recorder)}) - # log.e('sys_user_add() failed.\n') - - ret = json.dumps(ret).encode('utf8') - self.write(ret) - except: - log.e('error\n') - ret['code'] = -1 - ret = json.dumps(ret).encode('utf8') - self.write(ret) - - finally: - if os.path.exists(csv_filename): - os.remove(csv_filename) - - -class GetListHandler(TPBaseUserAuthJsonHandler): - def post(self): - _user = self.get_session('user') - if _user is None: - return self.write(-1) - - _type = _user['type'] - _uname = _user['name'] - - filter = dict() - user = self.get_current_user() - order = dict() - order['name'] = 'host_id' - order['asc'] = True - limit = dict() - limit['page_index'] = 0 - limit['per_page'] = 25 - - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - - tmp = list() - _filter = args['filter'] - for i in _filter: - if i == 'host_sys_type' and _filter[i] == 0: - tmp.append(i) - continue - if i == 'host_group' and _filter[i] == 0: - tmp.append(i) - continue - if i == 'search': - _x = _filter[i].strip() - if len(_x) == 0: - tmp.append(i) - continue - - for i in tmp: - del _filter[i] - - filter.update(_filter) - - _limit = args['limit'] - if _limit['page_index'] < 0: - _limit['page_index'] = 0 - if _limit['per_page'] < 10: - _limit['per_page'] = 10 - if _limit['per_page'] > 100: - _limit['per_page'] = 100 - - limit.update(_limit) - - _order = args['order'] - if _order is not None: - order['name'] = _order['k'] - order['asc'] = _order['v'] - if _type == 100: - _total, _hosts = host.get_all_host_info_list(filter, order, limit) - else: - filter['account_name'] = _uname - _total, _hosts = host.get_host_info_list_by_user(filter, order, limit) - # print(_hosts) - - ret = dict() - ret['page_index'] = limit['page_index'] - ret['total'] = _total - ret['data'] = _hosts - self.write_json(0, data=ret) - # self.write(json_encode(data)) - - -class GetGrouplist(TPBaseUserAuthJsonHandler): - def post(self): - group_list = host.get_group_list() - self.write_json(0, data=group_list) - - -class UpdateHandler(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - - if 'host_id' not in args or 'kv' not in args: - # ret = {'code':-2} - self.write_json(-2) - return - - # _host_id = args['host_id'] - - _ret = host.update(args['host_id'], args['kv']) - - if _ret: - self.write_json(0) - else: - self.write_json(-1) - - -class AddHost(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - - try: - ret = host.add_host(args) - if ret > 0: - self.write_json(0) - else: - self.write_json(ret) - return - except: - self.write_json(-1) - return - - -class LockHost(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - - host_id = args['host_id'] - lock = args['lock'] - try: - ret = host.lock_host(host_id, lock) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class DeleteHost(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - host_list = args['host_list'] - try: - ret = host.delete_host(host_list) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class ExportHostHandler(TPBaseAdminAuthHandler): - def get(self): - self.set_header('Content-Type', 'application/octet-stream') - self.set_header('Content-Disposition', 'attachment; filename=teleport-host-export.csv') - - order = dict() - order['name'] = 'host_id' - order['asc'] = True - limit = dict() - limit['page_index'] = 0 - limit['per_page'] = 999999 - _total, _hosts = host.get_all_host_info_list(dict(), order, limit, True) - - self.write("分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密, 附加参数, 密钥ID, 认证类型\n".encode('gbk')) - - try: - - for h in _hosts: - auth_list = h['auth_list'] - # 分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密,附加参数, 密钥ID, 认证类型 - for j in auth_list: - row_string = '' - # row_string = str(h['host_id']) - # row_string += ',' - row_string += str(h['group_id']) - row_string += ',' - row_string += str(h['host_sys_type']) - row_string += ',' - row_string += h['host_ip'] - row_string += ',' - row_string += str(h['host_port']) - row_string += ',' - row_string += str(h['protocol']) - row_string += ',' - row_string += str(h['host_lock']) - row_string += ',' - row_string += h['host_desc'] - row_string += ',' - - # row_string += str(j['host_auth_id']) - # row_string += ',' - row_string += j['user_name'] - row_string += ',' - row_string += j['user_pswd'] - row_string += ',' - row_string += '1' - row_string += ',' - user_param = j['user_param'] - if len(user_param) > 0: - user_param = user_param.replace('\n', '\\n') - row_string += user_param - row_string += ',' - row_string += str(j['cert_id']) - row_string += ',' - row_string += str(j['auth_mode']) - - self.write(row_string.encode('gbk')) - self.write('\n') - - except IndexError: - self.write('**********************************************\n'.encode('gbk')) - self.write('!!错误!!\n'.encode('gbk')) - self.write('导出过程中发生了错误!!\n'.encode('gbk')) - self.write('**********************************************\n'.encode('gbk')) - log.e('') - - self.finish() - - -class GetCertList(TPBaseUserAuthJsonHandler): - def post(self): - # args = self.get_argument('args', None) - # if args is not None: - # args = json.loads(args) - # # print('args', args) - # else: - # # ret = {'code':-1} - # self.write_json(-1) - # return - _certs = host.get_cert_list() - if _certs is None: - self.write_json(-1) - return - else: - self.write_json(0, data=_certs) - return - - -class AddCert(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - self.write_json(-1) - return - - cert_pub = args['cert_pub'] - cert_pri = args['cert_pri'] - cert_name = args['cert_name'] - - if len(cert_pri) == 0: - self.write_json(-1) - return - - _yr = async_enc(cert_pri) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - cert_pri = return_data['data'] - - try: - ret = host.add_cert(cert_pub, cert_pri, cert_name) - if ret: - return self.write_json(0) - else: - return self.write_json(-1) - except: - return self.write_json(-1) - - -class DeleteCert(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - cert_id = args['cert_id'] - try: - ret = host.delete_cert(cert_id) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class UpdateCert(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - cert_id = args['cert_id'] - cert_pub = args['cert_pub'] - cert_pri = args['cert_pri'] - cert_name = args['cert_name'] - - if len(cert_pri) > 0: - _yr = async_enc(cert_pri) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - cert_pri = return_data['data'] - - try: - ret = host.update_cert(cert_id, cert_pub, cert_pri, cert_name) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class AddGroup(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - group_name = args['group_name'] - try: - ret = host.add_group(group_name) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class UpdateGroup(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - group_id = args['group_id'] - group_name = args['group_name'] - try: - ret = host.update_group(group_id, group_name) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class DeleteGroup(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - group_id = args['group_id'] - try: - ret = host.delete_group(group_id) - if ret == 0: - self.write_json(0) - else: - self.write_json(ret) - return - except: - self.write_json(-1) - return - - -class AddHostToGroup(TPBaseUserAuthJsonHandler): - def post(self): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - host_list = args['host_list'] - group_id = args['group_id'] - try: - ret = host.add_host_to_group(host_list, group_id) - if ret: - self.write_json(0) - else: - self.write_json(-1) - return - except: - self.write_json(-1) - return - - -class GetSessionId(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - # print('args', args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - if 'auth_id' not in args: - self.write_json(-1) - return - auth_id = args['auth_id'] - - req = {'method': 'request_session', 'param': {'authid': auth_id}} - _yr = async_post_http(req) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data: - return self.write_json(-1) - - _code = return_data['code'] - if _code != 0: - return self.write_json(_code) - - try: - session_id = return_data['data']['sid'] - except IndexError: - return self.write_json(-1) - - data = dict() - data['session_id'] = session_id - - return self.write_json(0, data=data) - - -class AdminGetSessionId(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - self.write_json(-1) - return - - if 'host_auth_id' not in args: - self.write_json(-1) - return - - _host_auth_id = int(args['host_auth_id']) - - user = self.get_current_user() - - # host_auth_id 对应的是 ts_auth_info 表中的某个条目,含有具体的认证数据,因为管理员无需授权即可访问所有远程主机,因此 - # 直接给出 host_auth_id,且account直接指明是当前登录用户(其必然是管理员) - - tmp_auth_info = host.get_host_auth_info(_host_auth_id) - if tmp_auth_info is None: - self.write_json(-1) - return - - tmp_auth_info['account_lock'] = 0 - tmp_auth_info['account_name'] = user['name'] - - with tmp_auth_id_lock: - global tmp_auth_id_base - tmp_auth_id_base -= 1 - auth_id = tmp_auth_id_base - - # 将这个临时认证信息放到session中备后续查找使用(10秒内有效) - web_session().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10) - - req = {'method': 'request_session', 'param': {'authid': auth_id}} - _yr = async_post_http(req) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data: - return self.write_json(-1) - - _code = return_data['code'] - if _code != 0: - return self.write_json(_code) - - try: - session_id = return_data['data']['sid'] - except IndexError: - return self.write_json(-1) - - data = dict() - data['session_id'] = session_id - - return self.write_json(0, data=data) - - -class AdminFastGetSessionId(TPBaseAdminAuthJsonHandler): - @tornado.gen.coroutine - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - self.write_json(-1) - return - - user = self.get_current_user() - - tmp_auth_info = dict() - - try: - _host_auth_id = int(args['host_auth_id']) - _user_pswd = args['user_pswd'] - _cert_id = int(args['cert_id']) - - tmp_auth_info['host_ip'] = args['host_ip'] - tmp_auth_info['host_port'] = int(args['host_port']) - tmp_auth_info['sys_type'] = int(args['sys_type']) - tmp_auth_info['protocol'] = int(args['protocol']) - tmp_auth_info['user_name'] = args['user_name'] - tmp_auth_info['auth_mode'] = int(args['auth_mode']) - tmp_auth_info['user_param'] = args['user_param'] - tmp_auth_info['encrypt'] = 1 - tmp_auth_info['account_lock'] = 0 - tmp_auth_info['account_name'] = user['name'] - except IndexError: - self.write_json(-2) - return - - if tmp_auth_info['auth_mode'] == 1: - if len(_user_pswd) == 0: # 修改登录用户信息时可能不会修改密码,因此页面上可能不会传来密码,需要从数据库中直接读取 - h = host.get_host_auth_info(_host_auth_id) - tmp_auth_info['user_auth'] = h['user_auth'] - else: # 如果页面上修改了密码或者新建账号时设定了密码,那么需要先交给core服务进行加密 - req = {'method': 'enc', 'param': {'p': _user_pswd}} - _yr = async_post_http(req) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - tmp_auth_info['user_auth'] = return_data['data']['c'] - - elif tmp_auth_info['auth_mode'] == 2: - tmp_auth_info['user_auth'] = host.get_cert_info(_cert_id) - if tmp_auth_info['user_auth'] is None: - self.write_json(-100) - return - elif tmp_auth_info['auth_mode'] == 0: - tmp_auth_info['user_auth'] = '' - else: - self.write_json(-101) - return - - with tmp_auth_id_lock: - global tmp_auth_id_base - tmp_auth_id_base -= 1 - auth_id = tmp_auth_id_base - - web_session().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10) - - req = {'method': 'request_session', 'param': {'authid': auth_id}} - _yr = async_post_http(req) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data: - return self.write_json(-1) - - _code = return_data['code'] - if _code != 0: - return self.write_json(_code) - - try: - session_id = return_data['data']['sid'] - except IndexError: - return self.write_json(-1) - - data = dict() - data['session_id'] = session_id - - return self.write_json(0, data=data) - - -class SysUserList(TPBaseUserAuthJsonHandler): - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - self.write_json(-1) - return - try: - host_id = args['host_id'] - except Exception as e: - self.write_json(-2) - return - - data = host.sys_user_list(host_id) - return self.write_json(0, data=data) - - -class SysUserAdd(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - return self.write_json(-1) - - try: - auth_mode = args['auth_mode'] - user_pswd = args['user_pswd'] - cert_id = args['cert_id'] - except IndexError: - return self.write_json(-2) - - if auth_mode == 1: - if 0 == len(args['user_pswd']): - return self.write_json(-1) - - _yr = async_enc(user_pswd) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - args['user_pswd'] = return_data['data'] - - if host.sys_user_add(args) < 0: - return self.write_json(-1) - - return self.write_json(0) - - -class SysUserUpdate(TPBaseUserAuthJsonHandler): - @tornado.gen.coroutine - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - # ret = {'code':-1} - self.write_json(-1) - return - - if 'host_auth_id' not in args or 'kv' not in args: - # ret = {'code':-2} - self.write_json(-2) - return - - kv = args['kv'] - if 'auth_mode' not in kv or 'user_pswd' not in kv or 'cert_id' not in kv: - self.write_json(-3) - return - - auth_mode = kv['auth_mode'] - if 'user_pswd' in kv: - user_pswd = kv['user_pswd'] - if 0 == len(user_pswd): - args['kv'].pop('user_pswd') - user_pswd = None - else: - user_pswd = None - - cert_id = kv['cert_id'] - if auth_mode == 1 and user_pswd is not None: - _yr = async_enc(user_pswd) - return_data = yield _yr - if return_data is None: - return self.write_json(-1) - - if 'code' not in return_data or return_data['code'] != 0: - return self.write_json(-1) - - args['kv']['user_pswd'] = return_data['data'] - - if host.sys_user_update(args['host_auth_id'], args['kv']): - return self.write_json(0) - - return self.write_json(-1) - - -class SysUserDelete(TPBaseUserAuthJsonHandler): - def post(self, *args, **kwargs): - args = self.get_argument('args', None) - if args is not None: - args = json.loads(args) - else: - self.write_json(-2) - return - try: - host_auth_id = args['host_auth_id'] - except IndexError: - self.write_json(-2) - return - - if host.sys_user_delete(host_auth_id): - return self.write_json(0) - - return self.write_json(-1) +# -*- coding: utf-8 -*- + +import time +import csv +import os +import json +import threading +import tornado.gen +import tornado.httpclient + +from eom_app.app.configs import app_cfg +from eom_app.app.util import * +from eom_app.module import host +from eom_common.eomcore.logger import * +from eom_app.app.session import web_session +from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseUserAuthJsonHandler, TPBaseAdminAuthJsonHandler + +cfg = app_cfg() + +# 临时认证ID的基数,每次使用时均递减 +tmp_auth_id_base = -1 +tmp_auth_id_lock = threading.RLock() + + +class IndexHandler(TPBaseUserAuthHandler): + def get(self): + _user = self.get_session('user') + if _user is None: + return self.write(-1) + + param = dict() + + param['core'] = { + 'ssh_port': cfg.core.ssh.port, + 'rdp_port': cfg.core.rdp.port, + 'telnet_port': cfg.core.telnet.port + } + + param['group_list'] = host.get_group_list() + + if _user['type'] >= 100: + param['cert_list'] = host.get_cert_list() + self.render('host/admin_index.mako', page_param=json.dumps(param)) + else: + self.render('host/common_index.mako', page_param=json.dumps(param)) + + +class UploadAndImportHandler(TPBaseAdminAuthJsonHandler): + # TODO: 导入操作可能会比较耗时,应该分离导入和获取导入状态两个过程,在页面上可以呈现导入进度,并列出导出成功/失败的项 + + @tornado.gen.coroutine + def post(self): + """ + csv导入规则: + 每一行的数据格式: 分组ID,操作系统,IP地址,端口,系统用户,系统密码,协议,密钥ID,状态,认证类型,描述 + 因为主机的唯一性在于 `IP地址 + 端口`,且允许一个 `IP地址 + 端口` 对应多个系统用户,因此,每一行的数据几乎没有限制。 + 在导入时: + 1. 对每一个第一次遇到的 `IP地址 + 端口` 组合,就在 ts_host_info 表中加一个条目,并在 ts_auth_info 表中加入一个用户。 + 2. 对于非第一次遇到的 `IP地址 + 端口` 组合,则仅仅在 ts_auth_info 表中加一个用户,不更改 ts_host_info 表中的现有数据。 + 3. `IP地址 + 端口 + 用户` 的组合不能重复。 + 4. 空行跳过,数据格式不正确的跳过。 + """ + ret = dict() + ret['code'] = 0 + ret['msg'] = list() # 记录跳过的行(格式不正确,或者数据重复等) + csv_filename = '' + + try: + # upload_path = os.path.join(os.path.dirname(__file__), 'csv-files') # 文件的暂存路径 + upload_path = os.path.join(cfg.data_path, 'tmp') # 文件的暂存路径 + if not os.path.exists(upload_path): + os.mkdir(upload_path) + file_metas = self.request.files['csvfile'] # 提取表单中‘name’为‘file’的文件元数据 + for meta in file_metas: + now = time.localtime(time.time()) + tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.csv'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec) + csv_filename = os.path.join(upload_path, tmp_name) + with open(csv_filename, 'wb') as up: + up.write(meta['body']) + + # file encode maybe utf8 or gbk... check it out. + file_encode = None + with open(csv_filename, encoding='gbk') as up: + try: + up.readlines() + file_encode = 'gbk' + except: + log.e('open file:{} -1\n'.format(csv_filename)) + + if file_encode is None: + with open(csv_filename, encoding='utf8') as up: + try: + up.readlines() + file_encode = 'utf8' + except: + log.e('open file:{} -2\n'.format(csv_filename)) + + if file_encode is None: + os.remove(csv_filename) + self.write_json(-2) + log.e('file {} unknown encode.\n'.format(csv_filename)) + return + + with open(csv_filename, encoding=file_encode) as up: + csv_reader = csv.reader(up) + is_first_line = True + for csv_recorder in csv_reader: + # 跳过第一行,那是格式说明 + if is_first_line: + is_first_line = False + continue + + # 空行则忽略 + if len(csv_recorder) <= 1: + continue + + # 格式错误则记录在案,然后继续 + if len(csv_recorder) != 13: + ret['msg'].append({'reason': '格式错误', 'line': ', '.join(csv_recorder)}) + continue + + # pro_type = int(line[6]) + # host_port = int(line[3]) + + host_args = dict() + user_args = dict() + # 分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密,附加参数, 密钥ID, 认证类型 + + host_args['group_id'] = int(csv_recorder[0]) + host_args['host_sys_type'] = int(csv_recorder[1]) + host_args['host_ip'] = csv_recorder[2] + host_args['host_port'] = csv_recorder[3] + host_args['protocol'] = csv_recorder[4] + host_args['host_lock'] = csv_recorder[5] + host_args['host_desc'] = csv_recorder[6] + # 加入一个主机(如果已经存在,则直接返回已存在的条目的host_id) + host_id = host.add_host(host_args, must_not_exists=False) + if host_id < 0: + ret['msg'].append({'reason': '添加主机失败,操作数据库失败', 'line': ', '.join(csv_recorder)}) + continue + + user_args['host_id'] = host_id + user_args['user_name'] = csv_recorder[7] + user_pswd = csv_recorder[8] + is_encrpty = int(csv_recorder[9]) + user_args['user_param'] = csv_recorder[10].replace('\\n', '\n') + user_args['cert_id'] = int(csv_recorder[11]) + auth_mode = int(csv_recorder[12]) + user_args['auth_mode'] = auth_mode + user_args['user_pswd'] = '' + ret_code = 0 + if auth_mode == 0: + pass + elif auth_mode == 1: + try: + if is_encrpty == 0: + # ret_code, tmp_pswd = get_enc_data(user_pswd) + _yr = async_enc(user_pswd) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + tmp_pswd = return_data['data'] + + else: + tmp_pswd = user_pswd + + user_args['user_pswd'] = tmp_pswd + + except Exception: + ret_code = -1 + log.e('get_enc_data() failed.\n') + + if 0 != ret_code: + ret['msg'].append({'reason': '加密用户密码失败,可能原因:Teleport核心服务未启动', 'line': ', '.join(csv_recorder)}) + log.e('get_enc_data() failed, error={}\n'.format(ret_code)) + continue + + elif auth_mode == 2: + pass + # user_args['cert_id'] = int(csv_recorder[7]) + else: + ret['msg'].append({'reason': '未知的认证模式', 'line': ', '.join(csv_recorder)}) + log.e('auth_mode unknown\n') + continue + + uid = host.sys_user_add(user_args) + if uid < 0: + if uid == -100: + ret['msg'].append({'reason': '添加登录账号失败,账号已存在', 'line': ', '.join(csv_recorder)}) + else: + ret['msg'].append({'reason': '添加登录账号失败,操作数据库失败', 'line': ', '.join(csv_recorder)}) + # log.e('sys_user_add() failed.\n') + + ret = json.dumps(ret).encode('utf8') + self.write(ret) + except: + log.e('error\n') + ret['code'] = -1 + ret = json.dumps(ret).encode('utf8') + self.write(ret) + + finally: + if os.path.exists(csv_filename): + os.remove(csv_filename) + + +class GetListHandler(TPBaseUserAuthJsonHandler): + def post(self): + _user = self.get_session('user') + if _user is None: + return self.write(-1) + + _type = _user['type'] + _uname = _user['name'] + + filter = dict() + user = self.get_current_user() + order = dict() + order['name'] = 'host_id' + order['asc'] = True + limit = dict() + limit['page_index'] = 0 + limit['per_page'] = 25 + + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + + tmp = list() + _filter = args['filter'] + for i in _filter: + if i == 'host_sys_type' and _filter[i] == 0: + tmp.append(i) + continue + if i == 'host_group' and _filter[i] == 0: + tmp.append(i) + continue + if i == 'search': + _x = _filter[i].strip() + if len(_x) == 0: + tmp.append(i) + continue + + for i in tmp: + del _filter[i] + + filter.update(_filter) + + _limit = args['limit'] + if _limit['page_index'] < 0: + _limit['page_index'] = 0 + if _limit['per_page'] < 10: + _limit['per_page'] = 10 + if _limit['per_page'] > 100: + _limit['per_page'] = 100 + + limit.update(_limit) + + _order = args['order'] + if _order is not None: + order['name'] = _order['k'] + order['asc'] = _order['v'] + if _type == 100: + _total, _hosts = host.get_all_host_info_list(filter, order, limit) + else: + filter['account_name'] = _uname + _total, _hosts = host.get_host_info_list_by_user(filter, order, limit) + # print(_hosts) + + ret = dict() + ret['page_index'] = limit['page_index'] + ret['total'] = _total + ret['data'] = _hosts + self.write_json(0, data=ret) + # self.write(json_encode(data)) + + +class GetGrouplist(TPBaseUserAuthJsonHandler): + def post(self): + group_list = host.get_group_list() + self.write_json(0, data=group_list) + + +class UpdateHandler(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + + if 'host_id' not in args or 'kv' not in args: + # ret = {'code':-2} + self.write_json(-2) + return + + # _host_id = args['host_id'] + + _ret = host.update(args['host_id'], args['kv']) + + if _ret: + self.write_json(0) + else: + self.write_json(-1) + + +class AddHost(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + + try: + ret = host.add_host(args) + if ret > 0: + self.write_json(0) + else: + self.write_json(ret) + return + except: + self.write_json(-1) + return + + +class LockHost(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + + host_id = args['host_id'] + lock = args['lock'] + try: + ret = host.lock_host(host_id, lock) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class DeleteHost(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + host_list = args['host_list'] + try: + ret = host.delete_host(host_list) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class ExportHostHandler(TPBaseAdminAuthHandler): + def get(self): + self.set_header('Content-Type', 'application/octet-stream') + self.set_header('Content-Disposition', 'attachment; filename=teleport-host-export.csv') + + order = dict() + order['name'] = 'host_id' + order['asc'] = True + limit = dict() + limit['page_index'] = 0 + limit['per_page'] = 999999 + _total, _hosts = host.get_all_host_info_list(dict(), order, limit, True) + + self.write("分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密, 附加参数, 密钥ID, 认证类型\n".encode('gbk')) + + try: + + for h in _hosts: + auth_list = h['auth_list'] + # 分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密,附加参数, 密钥ID, 认证类型 + for j in auth_list: + row_string = '' + # row_string = str(h['host_id']) + # row_string += ',' + row_string += str(h['group_id']) + row_string += ',' + row_string += str(h['host_sys_type']) + row_string += ',' + row_string += h['host_ip'] + row_string += ',' + row_string += str(h['host_port']) + row_string += ',' + row_string += str(h['protocol']) + row_string += ',' + row_string += str(h['host_lock']) + row_string += ',' + row_string += h['host_desc'] + row_string += ',' + + # row_string += str(j['host_auth_id']) + # row_string += ',' + row_string += j['user_name'] + row_string += ',' + row_string += j['user_pswd'] + row_string += ',' + row_string += '1' + row_string += ',' + user_param = j['user_param'] + if len(user_param) > 0: + user_param = user_param.replace('\n', '\\n') + row_string += user_param + row_string += ',' + row_string += str(j['cert_id']) + row_string += ',' + row_string += str(j['auth_mode']) + + self.write(row_string.encode('gbk')) + self.write('\n') + + except IndexError: + self.write('**********************************************\n'.encode('gbk')) + self.write('!!错误!!\n'.encode('gbk')) + self.write('导出过程中发生了错误!!\n'.encode('gbk')) + self.write('**********************************************\n'.encode('gbk')) + log.e('') + + self.finish() + + +class GetCertList(TPBaseUserAuthJsonHandler): + def post(self): + # args = self.get_argument('args', None) + # if args is not None: + # args = json.loads(args) + # # print('args', args) + # else: + # # ret = {'code':-1} + # self.write_json(-1) + # return + _certs = host.get_cert_list() + if _certs is None: + self.write_json(-1) + return + else: + self.write_json(0, data=_certs) + return + + +class AddCert(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + self.write_json(-1) + return + + cert_pub = args['cert_pub'] + cert_pri = args['cert_pri'] + cert_name = args['cert_name'] + + if len(cert_pri) == 0: + self.write_json(-1) + return + + _yr = async_enc(cert_pri) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + cert_pri = return_data['data'] + + try: + ret = host.add_cert(cert_pub, cert_pri, cert_name) + if ret: + return self.write_json(0) + else: + return self.write_json(-1) + except: + return self.write_json(-1) + + +class DeleteCert(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + cert_id = args['cert_id'] + try: + ret = host.delete_cert(cert_id) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class UpdateCert(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + cert_id = args['cert_id'] + cert_pub = args['cert_pub'] + cert_pri = args['cert_pri'] + cert_name = args['cert_name'] + + if len(cert_pri) > 0: + _yr = async_enc(cert_pri) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + cert_pri = return_data['data'] + + try: + ret = host.update_cert(cert_id, cert_pub, cert_pri, cert_name) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class AddGroup(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + group_name = args['group_name'] + try: + ret = host.add_group(group_name) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class UpdateGroup(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + group_id = args['group_id'] + group_name = args['group_name'] + try: + ret = host.update_group(group_id, group_name) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class DeleteGroup(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + group_id = args['group_id'] + try: + ret = host.delete_group(group_id) + if ret == 0: + self.write_json(0) + else: + self.write_json(ret) + return + except: + self.write_json(-1) + return + + +class AddHostToGroup(TPBaseUserAuthJsonHandler): + def post(self): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + host_list = args['host_list'] + group_id = args['group_id'] + try: + ret = host.add_host_to_group(host_list, group_id) + if ret: + self.write_json(0) + else: + self.write_json(-1) + return + except: + self.write_json(-1) + return + + +class GetSessionId(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + # print('args', args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + if 'auth_id' not in args: + self.write_json(-1) + return + auth_id = args['auth_id'] + + req = {'method': 'request_session', 'param': {'authid': auth_id}} + _yr = async_post_http(req) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data: + return self.write_json(-1) + + _code = return_data['code'] + if _code != 0: + return self.write_json(_code) + + try: + session_id = return_data['data']['sid'] + except IndexError: + return self.write_json(-1) + + data = dict() + data['session_id'] = session_id + + return self.write_json(0, data=data) + + +class AdminGetSessionId(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + self.write_json(-1) + return + + if 'host_auth_id' not in args: + self.write_json(-1) + return + + _host_auth_id = int(args['host_auth_id']) + + user = self.get_current_user() + + # host_auth_id 对应的是 ts_auth_info 表中的某个条目,含有具体的认证数据,因为管理员无需授权即可访问所有远程主机,因此 + # 直接给出 host_auth_id,且account直接指明是当前登录用户(其必然是管理员) + + tmp_auth_info = host.get_host_auth_info(_host_auth_id) + if tmp_auth_info is None: + self.write_json(-1) + return + + tmp_auth_info['account_lock'] = 0 + tmp_auth_info['account_name'] = user['name'] + + with tmp_auth_id_lock: + global tmp_auth_id_base + tmp_auth_id_base -= 1 + auth_id = tmp_auth_id_base + + # 将这个临时认证信息放到session中备后续查找使用(10秒内有效) + web_session().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10) + + req = {'method': 'request_session', 'param': {'authid': auth_id}} + _yr = async_post_http(req) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data: + return self.write_json(-1) + + _code = return_data['code'] + if _code != 0: + return self.write_json(_code) + + try: + session_id = return_data['data']['sid'] + except IndexError: + return self.write_json(-1) + + data = dict() + data['session_id'] = session_id + + return self.write_json(0, data=data) + + +class AdminFastGetSessionId(TPBaseAdminAuthJsonHandler): + @tornado.gen.coroutine + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + self.write_json(-1) + return + + user = self.get_current_user() + + tmp_auth_info = dict() + + try: + _host_auth_id = int(args['host_auth_id']) + _user_pswd = args['user_pswd'] + _cert_id = int(args['cert_id']) + + tmp_auth_info['host_ip'] = args['host_ip'] + tmp_auth_info['host_port'] = int(args['host_port']) + tmp_auth_info['sys_type'] = int(args['sys_type']) + tmp_auth_info['protocol'] = int(args['protocol']) + tmp_auth_info['user_name'] = args['user_name'] + tmp_auth_info['auth_mode'] = int(args['auth_mode']) + tmp_auth_info['user_param'] = args['user_param'] + tmp_auth_info['encrypt'] = 1 + tmp_auth_info['account_lock'] = 0 + tmp_auth_info['account_name'] = user['name'] + except IndexError: + self.write_json(-2) + return + + if tmp_auth_info['auth_mode'] == 1: + if len(_user_pswd) == 0: # 修改登录用户信息时可能不会修改密码,因此页面上可能不会传来密码,需要从数据库中直接读取 + h = host.get_host_auth_info(_host_auth_id) + tmp_auth_info['user_auth'] = h['user_auth'] + else: # 如果页面上修改了密码或者新建账号时设定了密码,那么需要先交给core服务进行加密 + req = {'method': 'enc', 'param': {'p': _user_pswd}} + _yr = async_post_http(req) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + tmp_auth_info['user_auth'] = return_data['data']['c'] + + elif tmp_auth_info['auth_mode'] == 2: + tmp_auth_info['user_auth'] = host.get_cert_info(_cert_id) + if tmp_auth_info['user_auth'] is None: + self.write_json(-100) + return + elif tmp_auth_info['auth_mode'] == 0: + tmp_auth_info['user_auth'] = '' + else: + self.write_json(-101) + return + + with tmp_auth_id_lock: + global tmp_auth_id_base + tmp_auth_id_base -= 1 + auth_id = tmp_auth_id_base + + web_session().set('tmp-auth-info-{}'.format(auth_id), tmp_auth_info, 10) + + req = {'method': 'request_session', 'param': {'authid': auth_id}} + _yr = async_post_http(req) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data: + return self.write_json(-1) + + _code = return_data['code'] + if _code != 0: + return self.write_json(_code) + + try: + session_id = return_data['data']['sid'] + except IndexError: + return self.write_json(-1) + + data = dict() + data['session_id'] = session_id + + return self.write_json(0, data=data) + + +class SysUserList(TPBaseUserAuthJsonHandler): + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + self.write_json(-1) + return + try: + host_id = args['host_id'] + except Exception as e: + self.write_json(-2) + return + + data = host.sys_user_list(host_id) + return self.write_json(0, data=data) + + +class SysUserAdd(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + return self.write_json(-1) + + try: + auth_mode = args['auth_mode'] + user_pswd = args['user_pswd'] + cert_id = args['cert_id'] + except IndexError: + return self.write_json(-2) + + if auth_mode == 1: + if 0 == len(args['user_pswd']): + return self.write_json(-1) + + _yr = async_enc(user_pswd) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + args['user_pswd'] = return_data['data'] + + if host.sys_user_add(args) < 0: + return self.write_json(-1) + + return self.write_json(0) + + +class SysUserUpdate(TPBaseUserAuthJsonHandler): + @tornado.gen.coroutine + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + # ret = {'code':-1} + self.write_json(-1) + return + + if 'host_auth_id' not in args or 'kv' not in args: + # ret = {'code':-2} + self.write_json(-2) + return + + kv = args['kv'] + if 'auth_mode' not in kv or 'user_pswd' not in kv or 'cert_id' not in kv: + self.write_json(-3) + return + + auth_mode = kv['auth_mode'] + if 'user_pswd' in kv: + user_pswd = kv['user_pswd'] + if 0 == len(user_pswd): + args['kv'].pop('user_pswd') + user_pswd = None + else: + user_pswd = None + + cert_id = kv['cert_id'] + if auth_mode == 1 and user_pswd is not None: + _yr = async_enc(user_pswd) + return_data = yield _yr + if return_data is None: + return self.write_json(-1) + + if 'code' not in return_data or return_data['code'] != 0: + return self.write_json(-1) + + args['kv']['user_pswd'] = return_data['data'] + + if host.sys_user_update(args['host_auth_id'], args['kv']): + return self.write_json(0) + + return self.write_json(-1) + + +class SysUserDelete(TPBaseUserAuthJsonHandler): + def post(self, *args, **kwargs): + args = self.get_argument('args', None) + if args is not None: + args = json.loads(args) + else: + self.write_json(-2) + return + try: + host_auth_id = args['host_auth_id'] + except IndexError: + self.write_json(-2) + return + + if host.sys_user_delete(host_auth_id): + return self.write_json(0) + + return self.write_json(-1)