diff --git a/client/tp-player/record_format.h b/client/tp-player/record_format.h index 42b8ff3..aa7b3e9 100644 --- a/client/tp-player/record_format.h +++ b/client/tp-player/record_format.h @@ -28,7 +28,6 @@ typedef struct TS_RECORD_HEADER_INFO { // uint32_t packages; // 总包数 uint32_t time_ms; // 总耗时(毫秒) uint32_t dat_file_count; // 数据文件数量 - uint8_t _reserve[64-4-2-2-4-4]; }TS_RECORD_HEADER_INFO; #define ts_record_header_info_size sizeof(TS_RECORD_HEADER_INFO) @@ -50,15 +49,14 @@ typedef struct TS_RECORD_HEADER_BASIC { // // RDP专有 // uint8_t rdp_security; // 0 = RDP, 1 = TLS - -// uint8_t _reserve[512 - 2 - 2 - 8 - 2 - 2 - 64 - 64 - 40 - 40 - 2 - 40 - 1 - ts_record_header_info_size]; - uint8_t _reserve[512 - 2 - 2 - 8 - 2 - 2 - 64 - 64 - 40 - 40 - 2 - 40 - ts_record_header_info_size]; }TS_RECORD_HEADER_BASIC; #define ts_record_header_basic_size sizeof(TS_RECORD_HEADER_BASIC) typedef struct TS_RECORD_HEADER { - TS_RECORD_HEADER_INFO info; - TS_RECORD_HEADER_BASIC basic; + TS_RECORD_HEADER_INFO info; + ex_u8 _reserve1[64 - ts_record_header_info_size]; + TS_RECORD_HEADER_BASIC basic; + ex_u8 _reserve2[512 - 64 - ts_record_header_basic_size]; }TS_RECORD_HEADER; // header部分(header-info + header-basic) = 512B @@ -67,10 +65,9 @@ typedef struct TS_RECORD_HEADER { // 一个数据包的头 typedef struct TS_RECORD_PKG { uint8_t type; // 包的数据类型 - uint8_t _reserve[3]; // 保留 uint32_t size; // 这个包的总大小(不含包头) uint32_t time_ms; // 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天) - // uint32_t index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) + uint8_t _reserve[3]; // 保留 }TS_RECORD_PKG; diff --git a/server/tp_core/common/base_record.h b/server/tp_core/common/base_record.h index f4ac222..4e614d1 100644 --- a/server/tp_core/common/base_record.h +++ b/server/tp_core/common/base_record.h @@ -39,7 +39,6 @@ typedef struct TS_RECORD_HEADER_INFO { // ex_u32 packages; // 总包数 ex_u32 time_ms; // 总耗时(毫秒) ex_u32 dat_file_count; // 数据文件数量 - ex_u8 _reserve[64-4-2-2-4-4]; }TS_RECORD_HEADER_INFO; #define ts_record_header_info_size sizeof(TS_RECORD_HEADER_INFO) @@ -62,13 +61,14 @@ typedef struct TS_RECORD_HEADER_BASIC { // // RDP专有 - v3.5.0废弃并移除 // ex_u8 rdp_security; // 0 = RDP, 1 = TLS - ex_u8 _reserve[512 - ts_record_header_info_size - 2 - 2 - 8 - 2 - 2 - 64 - 64 - 40 - 40 - 2 - 40]; }TS_RECORD_HEADER_BASIC; #define ts_record_header_basic_size sizeof(TS_RECORD_HEADER_BASIC) typedef struct TS_RECORD_HEADER { TS_RECORD_HEADER_INFO info; + ex_u8 _reserve1[64 - ts_record_header_info_size]; TS_RECORD_HEADER_BASIC basic; + ex_u8 _reserve2[512 - 64 - ts_record_header_basic_size]; }TS_RECORD_HEADER; // header部分(header-info + header-basic) = 512B @@ -77,10 +77,9 @@ typedef struct TS_RECORD_HEADER { // 一个数据包的头 typedef struct TS_RECORD_PKG { ex_u8 type; // 包的数据类型 - ex_u8 _reserve[3]; // 保留 ex_u32 size; // 这个包的总大小(不含包头) ex_u32 time_ms; // 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天) - //ex_u32 index; // 这个包的序号(最后一个包的序号与TS_RECORD_HEADER_INFO::packages数量匹配) + ex_u8 _reserve[3]; // 保留 }TS_RECORD_PKG; #pragma pack(pop) diff --git a/server/tp_core/protocol/ssh/ssh_recorder.cpp b/server/tp_core/protocol/ssh/ssh_recorder.cpp index 9d66b86..0190493 100644 --- a/server/tp_core/protocol/ssh/ssh_recorder.cpp +++ b/server/tp_core/protocol/ssh/ssh_recorder.cpp @@ -1,4 +1,4 @@ -#include "ssh_recorder.h" +#include "ssh_recorder.h" //#include static ex_u8 TPP_RECORD_MAGIC[4] = {'T', 'P', 'P', 'R'}; @@ -8,7 +8,8 @@ TppSshRec::TppSshRec() { memset(&m_head, 0, sizeof(TS_RECORD_HEADER)); memcpy((ex_u8 *) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32)); - m_head.info.ver = 0x03; + m_head.info.ver = 0x04; + m_head.info.type = TS_TPPR_TYPE_SSH; m_header_changed = false; m_save_full_header = false; @@ -40,7 +41,7 @@ bool TppSshRec::_on_begin(const TPP_CONNECT_INFO *info) { } bool TppSshRec::_on_end() { - // ʣδдݣдļС + // 如果还有剩下未写入的数据,写入文件中。 save_record(); if (m_file_info != NULL) @@ -73,13 +74,14 @@ void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) { if (m_start_time > 0) { pkg.time_ms = (ex_u32) (ex_get_tick_count() - m_start_time); m_head.info.time_ms = pkg.time_ms; + m_header_changed = true; } m_cache.append((ex_u8 *) &pkg, sizeof(TS_RECORD_PKG)); m_cache.append(data, size); - m_head.info.packages++; - m_header_changed = true; + //m_head.info.packages++; + //m_header_changed = true; } void TppSshRec::record_win_size_startup(int width, int height) { @@ -95,7 +97,7 @@ void TppSshRec::record_win_size_change(int width, int height) { record(TS_RECORD_TYPE_SSH_TERM_SIZE, (ex_u8 *) &pkg, sizeof(TS_RECORD_WIN_SIZE)); } -// Ϊ¼طźʷܹӦֱ¼ĶӦʱ㣩¼ݰķʽ¼ʱƫƣǾʱ䡣 +// 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。 void TppSshRec::record_command(int flag, const ex_astr &cmd) { char szTime[100] = {0}; #ifdef EX_OS_WIN32 diff --git a/server/tp_core/protocol/ssh/stdafx.cpp b/server/tp_core/protocol/ssh/stdafx.cpp index 46afe00..faf90a3 100644 --- a/server/tp_core/protocol/ssh/stdafx.cpp +++ b/server/tp_core/protocol/ssh/stdafx.cpp @@ -1,4 +1,4 @@ -// stdafx.cpp : source file that includes just the standard includes +// stdafx.cpp : source file that includes just the standard includes // tpssh.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information @@ -11,11 +11,17 @@ #ifdef EX_OS_WIN32 # ifdef EX_DEBUG -# pragma comment(lib, "debug/ssh.lib") +# pragma comment(lib, "debug/ssh.lib") +# pragma comment(lib, "libcrypto32MTd.lib") +# pragma comment(lib, "libssl32MTd.lib") # else -# pragma comment(lib, "release/ssh.lib") +# pragma comment(lib, "release/ssh.lib") +# pragma comment(lib, "libcrypto32MT.lib") +# pragma comment(lib, "libssl32MT.lib") # endif -# pragma comment(lib, "libeay32.lib") +// # pragma comment(lib, "libcrypto.lib") +// # pragma comment(lib, "libeay32.lib") # pragma comment(lib, "ws2_32.lib") +# pragma comment(lib, "crypt32.lib") #endif diff --git a/server/tp_core/protocol/ssh/tpssh.cpp b/server/tp_core/protocol/ssh/tpssh.cpp index 5bfa7d1..a605635 100644 --- a/server/tp_core/protocol/ssh/tpssh.cpp +++ b/server/tp_core/protocol/ssh/tpssh.cpp @@ -1,4 +1,4 @@ -#include "ssh_proxy.h" +#include "ssh_proxy.h" #include "tpp_env.h" #include @@ -46,10 +46,15 @@ TPP_API void tpp_timer(void) { static ex_rv _set_runtime_config(const char* param) { Json::Value jp; - Json::Reader jreader; + //Json::Reader jreader; + Json::CharReaderBuilder jcrb; + std::unique_ptr const jreader(jcrb.newCharReader()); + const char *str_json_begin = param; + ex_astr err; - if (!jreader.parse(param, jp)) - return TPE_JSON_FORMAT; + //if (!jreader.parse(param, jp)) + if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err)) + return TPE_JSON_FORMAT; if (!jp.isObject()) return TPE_PARAM; @@ -68,10 +73,16 @@ static ex_rv _set_runtime_config(const char* param) { static ex_rv _kill_sessions(const char* param) { Json::Value jp; - Json::Reader jreader; +// Json::Reader jreader; +// if (!jreader.parse(param, jp)) + Json::CharReaderBuilder jcrb; + std::unique_ptr const jreader(jcrb.newCharReader()); + const char *str_json_begin = param; + ex_astr err; - if (!jreader.parse(param, jp)) - return TPE_JSON_FORMAT; + //if (!jreader.parse(param, jp)) + if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err)) + return TPE_JSON_FORMAT; if (!jp.isArray()) return TPE_PARAM; diff --git a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj index c2c091e..cd5eb27 100644 --- a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj +++ b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj @@ -66,7 +66,7 @@ Windows Debug - ..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories) + ..\..\..\..\external\libssh\build\src;..\..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories) @@ -86,7 +86,7 @@ true true true - ..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories) + ..\..\..\..\external\libssh\build\src;..\..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories) diff --git a/server/tp_core/testssh/stdafx.cpp b/server/tp_core/testssh/stdafx.cpp index 846b803..d6b01d0 100644 --- a/server/tp_core/testssh/stdafx.cpp +++ b/server/tp_core/testssh/stdafx.cpp @@ -1,17 +1,23 @@ -// stdafx.cpp : source file that includes just the standard includes -// testssh.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file - -#ifdef _DEBUG -# pragma comment(lib, "debug/ssh.lib") -#else -# pragma comment(lib, "release/ssh.lib") -#endif -#pragma comment(lib, "libeay32.lib") -#pragma comment(lib, "ws2_32.lib") - +// stdafx.cpp : source file that includes just the standard includes +// testssh.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file + +#ifdef _DEBUG +# pragma comment(lib, "debug/ssh.lib") +# pragma comment(lib, "libcrypto32MTd.lib") +# pragma comment(lib, "libssl32MTd.lib") +#else +# pragma comment(lib, "release/ssh.lib") +# pragma comment(lib, "libcrypto32MT.lib") +# pragma comment(lib, "libssl32MT.lib") +#endif +// #pragma comment(lib, "libeay32.lib") +// #pragma comment(lib, "libcrypto.lib") +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "crypt32.lib") + diff --git a/server/tp_core/testssh/testssh.cpp b/server/tp_core/testssh/testssh.cpp index 231bed4..2f934a6 100644 --- a/server/tp_core/testssh/testssh.cpp +++ b/server/tp_core/testssh/testssh.cpp @@ -1,172 +1,172 @@ -// testssh.cpp : Defines the entry point for the console application. -// - -//#include "stdafx.h" - -#include -#include - -void show_usage() { - printf("Usage:\n"); - printf(" testssh USERNAME PASSWORD IP PORT\n"); -} - -int main(int argc, char** argv) -{ - if (argc != 5) { - show_usage(); - return -1; - } - - ssh_init(); - - ssh_session sess = ssh_new(); - ssh_set_blocking(sess, 1); - - char* username = argv[1]; - char* password = argv[2]; - - char* ip = argv[3]; - ssh_options_set(sess, SSH_OPTIONS_HOST, ip); - - int port = atoi(argv[4]); - ssh_options_set(sess, SSH_OPTIONS_PORT, &port); - - int flag = SSH_LOG_FUNCTIONS; - ssh_options_set(sess, SSH_OPTIONS_LOG_VERBOSITY, &flag); - - int val = 0; - ssh_options_set(sess, SSH_OPTIONS_STRICTHOSTKEYCHECK, &val); - - ssh_options_set(sess, SSH_OPTIONS_USER, username); - - int _timeout = 120; // 60 sec. - ssh_options_set(sess, SSH_OPTIONS_TIMEOUT, &_timeout); - - // connect to real SSH host. - int rc = 0; - rc = ssh_connect(sess); - if (rc != SSH_OK) { - printf("[ERROR] can not connect to SSH server %s:%d. [%d] %s\n", ip, port, rc, ssh_get_error(sess)); - ssh_free(sess); - return -1; - } - - _timeout = 120; // 60 sec. - ssh_options_set(sess, SSH_OPTIONS_TIMEOUT, &_timeout); - - // get version of SSH server. - int ver = ssh_get_version(sess); - printf("[INFO] host is SSHv%d\n", ver); - - // get supported auth-type of SSH server. - //ssh_userauth_none(sess, username); - rc = ssh_userauth_none(sess, NULL); - if (rc == SSH_AUTH_ERROR) { - printf("[ERROR] can not got auth type supported by SSH server.\n"); - ssh_free(sess); - return -1; - } - - int auth_methods = ssh_userauth_list(sess, username); - printf("[INFO] supported auth-type: 0x%08x\n", auth_methods); - if(auth_methods == SSH_AUTH_METHOD_UNKNOWN) { -// auth_methods = SSH_AUTH_METHOD_PASSWORD|SSH_AUTH_METHOD_INTERACTIVE; -// printf("[WRN] unknown auth-type, try PASSWORD and INTERACTIVE\n"); - auth_methods = SSH_AUTH_METHOD_PASSWORD; - printf("[WRN] unknown auth-type, try PASSWORD mode.\n"); - } - - // get banner. - const char* banner = ssh_get_issue_banner(sess); - if (banner != NULL) { - printf("[INFO] server issue banner: %s\n", banner); - } - - // try auth. - bool ok = false; - int retry_count = 0; - - // first try interactive login mode if server allow. - if (!ok && (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) { - retry_count = 0; - rc = ssh_userauth_kbdint(sess, NULL, NULL); - for (;;) { - if (rc == SSH_AUTH_SUCCESS) { - ok = true; - break; - } - - if (rc == SSH_AUTH_AGAIN) { - retry_count += 1; - if (retry_count >= 5) - break; - ex_sleep_ms(500); - // Sleep(500); - rc = ssh_userauth_kbdint(sess, NULL, NULL); - continue; - } - - if (rc != SSH_AUTH_INFO) - break; - - int nprompts = ssh_userauth_kbdint_getnprompts(sess); - if (0 == nprompts) { - rc = ssh_userauth_kbdint(sess, NULL, NULL); - continue; - } - - for (int iprompt = 0; iprompt < nprompts; ++iprompt) { - char echo = 0; - const char *prompt = ssh_userauth_kbdint_getprompt(sess, iprompt, &echo); - printf("[INFO] interactive login prompt: %s\n", prompt); - - rc = ssh_userauth_kbdint_setanswer(sess, iprompt, password); - if (rc < 0) { - printf("[ERROR] invalid password for interactive mode to login to SSH server.\n"); - ssh_free(sess); - return -1; - } - } - - rc = ssh_userauth_kbdint(sess, NULL, NULL); - } - } - - // and then try password login mode if server allow. - if (!ok && (auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD) { - retry_count = 0; - rc = ssh_userauth_password(sess, NULL, password); - for (;;) { - if (rc == SSH_AUTH_AGAIN) { - retry_count += 1; - if (retry_count >= 3) - break; - ex_sleep_ms(100); - // Sleep(100); - rc = ssh_userauth_password(sess, NULL, password); - continue; - } - if (rc == SSH_AUTH_SUCCESS) { - ok = true; - printf("[INFO] login with password mode OK.\n"); - break; - } else { - printf("[ERROR] failed to login with password mode, got %d.\n", rc); - break; - } - } - } - - if (!ok) { - printf("[ERROR] can not use password mode or interactive mode to login to SSH server.\n"); - } - else { - printf("[INFO] login success.\n"); - } - - ssh_disconnect(sess); - ssh_free(sess); - return 0; -} - +// testssh.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +#include +#include + +void show_usage() { + printf("Usage:\n"); + printf(" testssh USERNAME PASSWORD IP PORT\n"); +} + +int main(int argc, char** argv) +{ + if (argc != 5) { + show_usage(); + return -1; + } + + ssh_init(); + + ssh_session sess = ssh_new(); + ssh_set_blocking(sess, 1); + + char* username = argv[1]; + char* password = argv[2]; + + char* ip = argv[3]; + ssh_options_set(sess, SSH_OPTIONS_HOST, ip); + + int port = atoi(argv[4]); + ssh_options_set(sess, SSH_OPTIONS_PORT, &port); + + int flag = SSH_LOG_FUNCTIONS; + ssh_options_set(sess, SSH_OPTIONS_LOG_VERBOSITY, &flag); + + int val = 0; + ssh_options_set(sess, SSH_OPTIONS_STRICTHOSTKEYCHECK, &val); + + ssh_options_set(sess, SSH_OPTIONS_USER, username); + + int _timeout = 120; // 60 sec. + ssh_options_set(sess, SSH_OPTIONS_TIMEOUT, &_timeout); + + // connect to real SSH host. + int rc = 0; + rc = ssh_connect(sess); + if (rc != SSH_OK) { + printf("[ERROR] can not connect to SSH server %s:%d. [%d] %s\n", ip, port, rc, ssh_get_error(sess)); + ssh_free(sess); + return -1; + } + + _timeout = 120; // 60 sec. + ssh_options_set(sess, SSH_OPTIONS_TIMEOUT, &_timeout); + + // get version of SSH server. + int ver = ssh_get_version(sess); + printf("[INFO] host is SSHv%d\n", ver); + + // get supported auth-type of SSH server. + //ssh_userauth_none(sess, username); + rc = ssh_userauth_none(sess, NULL); + if (rc == SSH_AUTH_ERROR) { + printf("[ERROR] can not got auth type supported by SSH server.\n"); + ssh_free(sess); + return -1; + } + + int auth_methods = ssh_userauth_list(sess, username); + printf("[INFO] supported auth-type: 0x%08x\n", auth_methods); + if(auth_methods == SSH_AUTH_METHOD_UNKNOWN) { +// auth_methods = SSH_AUTH_METHOD_PASSWORD|SSH_AUTH_METHOD_INTERACTIVE; +// printf("[WRN] unknown auth-type, try PASSWORD and INTERACTIVE\n"); + auth_methods = SSH_AUTH_METHOD_PASSWORD; + printf("[WRN] unknown auth-type, try PASSWORD mode.\n"); + } + + // get banner. + const char* banner = ssh_get_issue_banner(sess); + if (banner != NULL) { + printf("[INFO] server issue banner: %s\n", banner); + } + + // try auth. + bool ok = false; + int retry_count = 0; + + // first try interactive login mode if server allow. + if (!ok && (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) { + retry_count = 0; + rc = ssh_userauth_kbdint(sess, NULL, NULL); + for (;;) { + if (rc == SSH_AUTH_SUCCESS) { + ok = true; + break; + } + + if (rc == SSH_AUTH_AGAIN) { + retry_count += 1; + if (retry_count >= 5) + break; + ex_sleep_ms(500); + // Sleep(500); + rc = ssh_userauth_kbdint(sess, NULL, NULL); + continue; + } + + if (rc != SSH_AUTH_INFO) + break; + + int nprompts = ssh_userauth_kbdint_getnprompts(sess); + if (0 == nprompts) { + rc = ssh_userauth_kbdint(sess, NULL, NULL); + continue; + } + + for (int iprompt = 0; iprompt < nprompts; ++iprompt) { + char echo = 0; + const char *prompt = ssh_userauth_kbdint_getprompt(sess, iprompt, &echo); + printf("[INFO] interactive login prompt: %s\n", prompt); + + rc = ssh_userauth_kbdint_setanswer(sess, iprompt, password); + if (rc < 0) { + printf("[ERROR] invalid password for interactive mode to login to SSH server.\n"); + ssh_free(sess); + return -1; + } + } + + rc = ssh_userauth_kbdint(sess, NULL, NULL); + } + } + + // and then try password login mode if server allow. + if (!ok && (auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD) { + retry_count = 0; + rc = ssh_userauth_password(sess, NULL, password); + for (;;) { + if (rc == SSH_AUTH_AGAIN) { + retry_count += 1; + if (retry_count >= 3) + break; + ex_sleep_ms(100); + // Sleep(100); + rc = ssh_userauth_password(sess, NULL, password); + continue; + } + if (rc == SSH_AUTH_SUCCESS) { + ok = true; + printf("[INFO] login with password mode OK.\n"); + break; + } else { + printf("[ERROR] failed to login with password mode, got %d.\n", rc); + break; + } + } + } + + if (!ok) { + printf("[ERROR] can not use password mode or interactive mode to login to SSH server.\n"); + } + else { + printf("[INFO] login success.\n"); + } + + ssh_disconnect(sess); + ssh_free(sess); + return 0; +} + diff --git a/server/tp_core/testssh/testssh.vcxproj b/server/tp_core/testssh/testssh.vcxproj index fb14cbc..d6e2ed7 100644 --- a/server/tp_core/testssh/testssh.vcxproj +++ b/server/tp_core/testssh/testssh.vcxproj @@ -55,13 +55,13 @@ Disabled WIN32;_DEBUG;_CONSOLE;LIBSSH_STATIC;%(PreprocessorDefinitions) true - ..\..\..\external\libssh\include;%(AdditionalIncludeDirectories) + ..\..\..\external\libssh\include;..\..\..\common\libex\include;%(AdditionalIncludeDirectories) MultiThreadedDebug Console true - ..\..\..\external\libssh\build\src\static;..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories) + ..\..\..\external\libssh\build\src;..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories) @@ -73,7 +73,7 @@ true WIN32;NDEBUG;_CONSOLE;LIBSSH_STATIC;%(PreprocessorDefinitions) true - ..\..\..\external\libssh\include;C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories) + ..\..\..\external\libssh\include;..\..\..\common\libex\include;%(AdditionalIncludeDirectories) MultiThreaded @@ -92,6 +92,26 @@ + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + Create Create diff --git a/server/tp_core/testssh/testssh.vcxproj.filters b/server/tp_core/testssh/testssh.vcxproj.filters index ac6addb..0388b1a 100644 --- a/server/tp_core/testssh/testssh.vcxproj.filters +++ b/server/tp_core/testssh/testssh.vcxproj.filters @@ -13,6 +13,9 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {d9087583-83c7-4d47-bba3-fd86b0cb3901} + @@ -32,5 +35,20 @@ Source Files + + libex + + + libex + + + libex + + + libex + + + libex + \ No newline at end of file diff --git a/server/www/teleport/static/js/audit/replay-ssh.js b/server/www/teleport/static/js/audit/replay-ssh.js index 0e82d68..a7f5104 100644 --- a/server/www/teleport/static/js/audit/replay-ssh.js +++ b/server/www/teleport/static/js/audit/replay-ssh.js @@ -56,7 +56,7 @@ $app.on_init = function (cb_stack) { $app.record_hdr.height = 24; console.log('header', $app.record_hdr); - $('#recorder-info').html(tp_format_datetime($app.record_hdr.start) + ': ' + $app.record_hdr.user_name + '@' + $app.record_hdr.client_ip + ' 访问 ' + $app.record_hdr.account + '@' + $app.record_hdr.conn_ip + ':' + $app.record_hdr.conn_port); + $('#recorder-info').html(tp_format_datetime($app.record_hdr.start) + ',用户' + $app.record_hdr.user_name + '(来自' + $app.record_hdr.client_ip + ') 访问远程主机 ' + $app.record_hdr.account + '@' + $app.record_hdr.conn_ip + ':' + $app.record_hdr.conn_port); $app.req_record_data(record_id, 0); @@ -163,12 +163,13 @@ $app.on_init = function (cb_stack) { $app.req_record_data = function (record_id, offset) { $tp.ajax_post_json('/audit/get-record-data', {protocol: TP_PROTOCOL_TYPE_SSH, id: record_id, offset: offset}, function (ret) { - if (ret.code === TPE_OK) { - // console.log('data', ret.data); + if (ret.code === TPE_OK || ret.code === TPE_NO_MORE_DATA) { + console.log('data', ret.data); $app.record_data = $app.record_data.concat(ret.data.data_list); $app.record_data_offset += ret.data.data_size; - if ($app.record_data.length < $app.record_hdr.pkg_count) { + //if ($app.record_data.length < $app.record_hdr.pkg_count) { + if(ret.code === TPE_OK) { $app.req_record_data(record_id, $app.record_data_offset); } } else { @@ -252,7 +253,8 @@ $app.do_play = function() { $app.player_console_term.write(tp_base64_decode(play_data.d)); } - if (($app.played_pkg_count + 1) === $app.record_hdr.pkg_count) { + //if (($app.played_pkg_count + 1) === $app.record_hdr.pkg_count) { + if (($app.played_pkg_count + 1) === $app.record_data.length) { $app.dom.progress.val(100); $app.dom.status.text('播放完成'); $app.dom.time.text(parseInt($app.record_hdr.time_used / 1000) + '秒'); @@ -287,7 +289,8 @@ $app.do_play = function() { $app.dom.time.text(temp + '/' + parseInt($app.record_hdr.time_used / 1000) + '秒'); // if all packages played - if ($app.played_pkg_count >= $app.record_hdr.pkg_count) { + // if ($app.played_pkg_count >= $app.record_hdr.pkg_count) { + if ($app.played_pkg_count >= $app.record_data.length) { $app.dom.progress.val(100); $app.dom.status.text('播放完成'); $app.dom.time.text(parseInt($app.record_hdr.time_used / 1000) + '秒'); diff --git a/server/www/teleport/static/js/tp-const.js b/server/www/teleport/static/js/tp-const.js index d0e90c0..6bf9e10 100755 --- a/server/www/teleport/static/js/tp-const.js +++ b/server/www/teleport/static/js/tp-const.js @@ -195,6 +195,8 @@ var TPE_PRIVILEGE = 3; var TPE_NOT_IMPLEMENT = 7; // 尚未实现 var TPE_EXISTS = 8; var TPE_NOT_EXISTS = 9; +var TPE_NO_MORE_DATA = 10; // 没有更多的数据了(不一定是错误) +var TPE_INCOMPATIBLE_VERSION = 11; // 版本不兼容 // 100~299是通用错误值 diff --git a/server/www/teleport/webroot/app/const.py b/server/www/teleport/webroot/app/const.py index 492d26f..3c343a7 100755 --- a/server/www/teleport/webroot/app/const.py +++ b/server/www/teleport/webroot/app/const.py @@ -183,6 +183,8 @@ TPE_PRIVILEGE = 3 TPE_NOT_IMPLEMENT = 7 TPE_EXISTS = 8 TPE_NOT_EXISTS = 9 +TPE_NO_MORE_DATA = 10 +TPE_INCOMPATIBLE_VERSION = 11 TPE_FAILED = 100 TPE_NETWORK = 101 diff --git a/server/www/teleport/webroot/app/model/record.py b/server/www/teleport/webroot/app/model/record.py index 2fdeb52..4739be2 100644 --- a/server/www/teleport/webroot/app/model/record.py +++ b/server/www/teleport/webroot/app/model/record.py @@ -149,30 +149,36 @@ def read_record_head(protocol_type, record_id): data = file.read() offset = 0 - magic, = struct.unpack_from('I', data, offset) # magic must be 1381126228, 'TPPR' - offset += 4 - ver, = struct.unpack_from('H', data, offset) - offset += 2 - pkg_count, = struct.unpack_from('I', data, offset) - offset += 4 - time_used, = struct.unpack_from('I', data, offset) - offset += 4 + # 读取 `TPPR` 标记(1380995156) 和录像文件版本、录像类型 + magic, ver, = struct.unpack_from('=IH', data, offset) + offset += 6 + if magic != 1380995156: + return None, TPE_DATA + if ver != 4: # 从v3.5.0开始录像文件版本为版本4 + return None, TPE_INCOMPATIBLE_VERSION - protocol_type, = struct.unpack_from('H', data, offset) - offset += 2 - protocol_sub_type, = struct.unpack_from('H', data, offset) - offset += 2 - time_start, = struct.unpack_from('Q', data, offset) - offset += 8 - width, = struct.unpack_from('H', data, offset) - offset += 2 - height, = struct.unpack_from('H', data, offset) - offset += 2 + rec_type, time_used, dat_file_count, = struct.unpack_from('=HII', data, offset) + offset += 10 + log.w('yyy: {}, {}, {}\n'.format(rec_type, time_used, dat_file_count)) - # file_count, = struct.unpack_from('H', data, offset) + # TS_RECORD_HEADER_INFO 共计64字节,前面有用的数据读取后,跳过后面补齐用的字节,从第64字节 + # 开始解析 TS_RECORD_HEADER_BASIC + offset = 64 + + # protocol_type, = struct.unpack_from('H', data, offset) # offset += 2 - # total_size, = struct.unpack_from('I', data, offset) - # offset += 4 + # protocol_sub_type, = struct.unpack_from('H', data, offset) + # offset += 2 + # time_start, = struct.unpack_from('Q', data, offset) + # offset += 8 + # width, = struct.unpack_from('H', data, offset) + # offset += 2 + # height, = struct.unpack_from('H', data, offset) + # offset += 2 + + protocol_type, protocol_sub_type, time_start, width, height = struct.unpack_from('=HHQHH', data, offset) + offset += 16 + log.w('xxx: {}, {}, {}, {}, {}\n'.format(protocol_type, protocol_sub_type, time_start, width, height)) user_name, = struct.unpack_from('64s', data, offset) user_name = _remove_padding_space(user_name).decode() @@ -202,7 +208,7 @@ def read_record_head(protocol_type, record_id): header = dict() header['start'] = time_start - header['pkg_count'] = pkg_count + # header['pkg_count'] = pkg_count header['time_used'] = time_used header['width'] = width header['height'] = height @@ -212,6 +218,7 @@ def read_record_head(protocol_type, record_id): header['conn_ip'] = conn_ip header['conn_port'] = conn_port header['client_ip'] = client_ip + log.d('header:', header, '\n') return header, TPE_OK @@ -305,10 +312,11 @@ def read_ssh_record_data(record_id, offset): data_list = list() data_size = 0 file = None + err = TPE_OK try: file_size = os.path.getsize(file_data) if offset >= file_size: - return None, 0, TPE_FAILED + return None, 0, TPE_NO_MORE_DATA file = open(file_data, 'rb') if offset > 0: @@ -356,6 +364,7 @@ def read_ssh_record_data(record_id, offset): data_list.append(temp) if offset + data_size == file_size: + err = TPE_NO_MORE_DATA break except Exception: @@ -365,7 +374,7 @@ def read_ssh_record_data(record_id, offset): if file is not None: file.close() - return data_list, data_size, TPE_OK + return data_list, data_size, err def read_telnet_record_data(record_id, offset):