调整ssh的录像相关,未完成。

pull/236/head
Apex Liu 2019-11-20 04:09:16 +08:00
parent f579c8cb69
commit 2908a54f79
14 changed files with 328 additions and 253 deletions

View File

@ -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;

View File

@ -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)

View File

@ -1,4 +1,4 @@
#include "ssh_recorder.h"
#include "ssh_recorder.h"
//#include <teleport_const.h>
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

View File

@ -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

View File

@ -1,4 +1,4 @@
#include "ssh_proxy.h"
#include "ssh_proxy.h"
#include "tpp_env.h"
#include <teleport_const.h>
@ -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<Json::CharReader> 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<Json::CharReader> 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;

View File

@ -66,7 +66,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>Debug</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>..\..\..\..\external\libssh\build\src;..\..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -86,7 +86,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>..\..\..\..\external\libssh\build\src;..\..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@ -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")

View File

@ -1,172 +1,172 @@
// testssh.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <libssh/libssh.h>
#include <ex.h>
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 <libssh/libssh.h>
#include <ex.h>
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;
}

View File

@ -55,13 +55,13 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;LIBSSH_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\external\libssh\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\external\libssh\include;..\..\..\common\libex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\external\libssh\build\src\static;..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>..\..\..\external\libssh\build\src;..\..\..\external\openssl\lib\VC\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -73,7 +73,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;LIBSSH_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\external\libssh\include;C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\external\libssh\include;..\..\..\common\libex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
@ -92,6 +92,26 @@
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\common\libex\src\ex_log.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_path.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_str.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_thread.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_util.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

View File

@ -13,6 +13,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="libex">
<UniqueIdentifier>{d9087583-83c7-4d47-bba3-fd86b0cb3901}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
@ -32,5 +35,20 @@
<ClCompile Include="testssh.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_util.cpp">
<Filter>libex</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_str.cpp">
<Filter>libex</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_log.cpp">
<Filter>libex</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_thread.cpp">
<Filter>libex</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\libex\src\ex_path.cpp">
<Filter>libex</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -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) + '秒');

View File

@ -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是通用错误值

View File

@ -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

View File

@ -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):