telnet可以录像和播放了(还不能记录命令,不能感知客户端窗口大小变化)
parent
db9838e480
commit
21e07f7b32
|
|
@ -46,7 +46,7 @@ bind-ip=0.0.0.0
|
||||||
bind-port=52089
|
bind-port=52089
|
||||||
|
|
||||||
[protocol-telnet]
|
[protocol-telnet]
|
||||||
enabled=false
|
enabled=true
|
||||||
lib=tptelnet
|
lib=tptelnet
|
||||||
bind-ip=0.0.0.0
|
bind-ip=0.0.0.0
|
||||||
bind-port=52389
|
bind-port=52389
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ TelnetConn::TelnetConn(TelnetSession *sess, bool is_server_side) : m_session(ses
|
||||||
m_state = TELNET_CONN_STATE_FREE;
|
m_state = TELNET_CONN_STATE_FREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_is_recving = false;
|
|
||||||
|
|
||||||
m_timer_running = false;
|
m_timer_running = false;
|
||||||
|
|
||||||
uv_tcp_init(sess->get_loop(), &m_handle);
|
uv_tcp_init(sess->get_loop(), &m_handle);
|
||||||
|
|
@ -26,7 +24,6 @@ TelnetConn::~TelnetConn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TelnetConn::start_recv() {
|
bool TelnetConn::start_recv() {
|
||||||
m_is_recving = true;
|
|
||||||
int err = uv_read_start((uv_stream_t *)&m_handle, _on_alloc, _on_recv);
|
int err = uv_read_start((uv_stream_t *)&m_handle, _on_alloc, _on_recv);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
EXLOGE("[telnet] [%s] can not start to read.\n", m_name);
|
EXLOGE("[telnet] [%s] can not start to read.\n", m_name);
|
||||||
|
|
@ -34,7 +31,6 @@ bool TelnetConn::start_recv() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_is_recving = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,41 +49,12 @@ void TelnetConn::close() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_is_recving) {
|
|
||||||
m_is_recving = false;
|
|
||||||
uv_read_stop((uv_stream_t*)&m_handle);
|
uv_read_stop((uv_stream_t*)&m_handle);
|
||||||
}
|
|
||||||
|
|
||||||
// int uverr = 0;
|
|
||||||
// uv_shutdown_t *sreq = (uv_shutdown_t *)calloc(1, sizeof(uv_shutdown_t));
|
|
||||||
// sreq->data = this;
|
|
||||||
// if ((uverr = uv_shutdown(sreq, stream_handle(), _uv_on_shutdown)) != 0) {
|
|
||||||
// EXLOGW("[telnet] [%s] error when shutdown connection. %s\n", m_name, uv_strerror(uverr));
|
|
||||||
// free(sreq);
|
|
||||||
//
|
|
||||||
// m_state = TELNET_CONN_STATE_FREE;
|
|
||||||
//
|
|
||||||
// m_session->on_conn_close();
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// m_state = RDP_CONN_STATE_CLOSING;
|
|
||||||
// }
|
|
||||||
|
|
||||||
uv_close(handle() , _uv_on_closed);
|
uv_close(handle() , _uv_on_closed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// void TelnetConn::_uv_on_shutdown(uv_shutdown_t *req, int status) {
|
|
||||||
// TelnetConn *_this = (TelnetConn *)req->data;
|
|
||||||
// //EXLOGD("[telnet] [%s] .. _uv_on_shutdown, status=%d\n", _this->m_name, status);
|
|
||||||
// uv_close((uv_handle_t *)req->handle, _uv_on_closed);
|
|
||||||
// free(req);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
|
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
|
||||||
TelnetConn *_this = (TelnetConn *)handle->data;
|
TelnetConn *_this = (TelnetConn *)handle->data;
|
||||||
//EXLOGD("[telnet] [%s] .. _uv_on_closed\n", _this->m_name);
|
|
||||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||||
_this->m_session->on_conn_close();
|
_this->m_session->on_conn_close();
|
||||||
}
|
}
|
||||||
|
|
@ -101,11 +68,8 @@ void TelnetConn::_on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t
|
||||||
void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
|
void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
|
||||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||||
|
|
||||||
//ExThreadSmartLock locker(_this->m_locker_recv);
|
|
||||||
|
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
free(buf->base);
|
free(buf->base);
|
||||||
//_this->m_session->do_next(_this);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (nread < 0) {
|
else if (nread < 0) {
|
||||||
|
|
@ -128,8 +92,6 @@ void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *bu
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EXLOG_BIN((ex_u8*)buf->base, nread, "--READ-- %s", _this->m_name);
|
|
||||||
|
|
||||||
_this->m_buf_data.append((ex_u8 *) buf->base, nread);
|
_this->m_buf_data.append((ex_u8 *) buf->base, nread);
|
||||||
free(buf->base);
|
free(buf->base);
|
||||||
|
|
||||||
|
|
@ -140,17 +102,6 @@ bool TelnetConn::send(MemBuffer &mbuf) {
|
||||||
return _raw_send(mbuf.data(), mbuf.size());
|
return _raw_send(mbuf.data(), mbuf.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool TelnetConn::send(TelnetPkgBase &pkg) {
|
|
||||||
// MemBuffer mbuf;
|
|
||||||
// MemStream s(mbuf);
|
|
||||||
// if (TPE_OK != pkg.build(s)) {
|
|
||||||
// EXLOGE("[telnet] when send, can not build package to binary.\n");
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return _raw_send(mbuf.data(), mbuf.size());
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool TelnetConn::send(const ex_u8 *data, size_t size) {
|
bool TelnetConn::send(const ex_u8 *data, size_t size) {
|
||||||
return _raw_send(data, size);
|
return _raw_send(data, size);
|
||||||
}
|
}
|
||||||
|
|
@ -158,13 +109,9 @@ bool TelnetConn::send(const ex_u8 *data, size_t size) {
|
||||||
bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
|
bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
|
||||||
// #ifdef LOG_DATA
|
// #ifdef LOG_DATA
|
||||||
// if (!m_session->is_relay())
|
// if (!m_session->is_relay())
|
||||||
EXLOG_BIN(data, size, "[telnet] [%s] SEND %dB.", m_name, size);
|
// EXLOG_BIN(data, size, "[telnet] [%s] SEND %dB.", m_name, size);
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
return raw_send(data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TelnetConn::raw_send(const ex_u8 *data, size_t size) {
|
|
||||||
uv_write_t *w = (uv_write_t *) calloc(1, sizeof(uv_write_t));
|
uv_write_t *w = (uv_write_t *) calloc(1, sizeof(uv_write_t));
|
||||||
|
|
||||||
ex_u8 *_data = (ex_u8 *) calloc(1, size);
|
ex_u8 *_data = (ex_u8 *) calloc(1, size);
|
||||||
|
|
@ -252,7 +199,6 @@ void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
|
||||||
void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer)
|
void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer)
|
||||||
{
|
{
|
||||||
TelnetConn *_this = (TelnetConn *)timer->data;
|
TelnetConn *_this = (TelnetConn *)timer->data;
|
||||||
//EXLOGD("[telnet] [%s] .. _uv_on_connect_timeout.\n", _this->m_name);
|
|
||||||
|
|
||||||
if (_this->m_timer_running) {
|
if (_this->m_timer_running) {
|
||||||
_this->m_timer_running = false;
|
_this->m_timer_running = false;
|
||||||
|
|
@ -268,7 +214,6 @@ void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer)
|
||||||
|
|
||||||
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
||||||
TelnetConn *_this = (TelnetConn *)handle->data;
|
TelnetConn *_this = (TelnetConn *)handle->data;
|
||||||
//EXLOGD("[telnet] [%s] .. _uv_on_reconnect.\n", _this->m_name);
|
|
||||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||||
|
|
||||||
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
|
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
|
||||||
|
|
@ -280,7 +225,6 @@ void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
||||||
void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
|
void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
|
||||||
TelnetConn *_this = (TelnetConn *)req->data;
|
TelnetConn *_this = (TelnetConn *)req->data;
|
||||||
free(req);
|
free(req);
|
||||||
//EXLOGD("[telnet] [%s] .. _uv_on_connected: status=%d.\n", _this->m_name, status);
|
|
||||||
|
|
||||||
if (_this->m_timer_running) {
|
if (_this->m_timer_running) {
|
||||||
_this->m_timer_running = false;
|
_this->m_timer_running = false;
|
||||||
|
|
@ -308,5 +252,4 @@ void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
|
void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,8 @@
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
// typedef time_t mbedtls_time_t;
|
|
||||||
|
|
||||||
// #include <mbedtls/arc4.h>
|
|
||||||
// #include <mbedtls/ssl.h>
|
|
||||||
// #include <mbedtls/entropy.h>
|
|
||||||
// #include <mbedtls/ctr_drbg.h>
|
|
||||||
|
|
||||||
// #include "telnet_package.h"
|
|
||||||
#include "../../common/ts_membuf.h"
|
#include "../../common/ts_membuf.h"
|
||||||
#include "../../common/ts_memstream.h"
|
#include "../../common/ts_memstream.h"
|
||||||
// #include "telnet_bulk.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#define LOG_DATA
|
//#define LOG_DATA
|
||||||
|
|
||||||
|
|
@ -47,45 +36,14 @@ public:
|
||||||
MemBuffer &data() { return m_buf_data; }
|
MemBuffer &data() { return m_buf_data; }
|
||||||
|
|
||||||
bool send(MemBuffer &mbuf);
|
bool send(MemBuffer &mbuf);
|
||||||
// bool send(TelnetPkgBase &pkg);
|
|
||||||
bool send(const ex_u8 *data, size_t size);
|
bool send(const ex_u8 *data, size_t size);
|
||||||
bool raw_send(const ex_u8 *data, size_t size);
|
|
||||||
|
|
||||||
// connect to real server, for proxy-client-side only.
|
// connect to real server, for proxy-client-side only.
|
||||||
void connect(const char *server_ip, ex_u16 server_port = 3389);
|
void connect(const char *server_ip, ex_u16 server_port = 3389);
|
||||||
// try to close this connection. return current RDP_CONN_STATE_XXXX.
|
// try to close this connection. return current TELNET_CONN_STATE_XXXX.
|
||||||
void close();
|
void close();
|
||||||
bool start_recv();
|
bool start_recv();
|
||||||
|
|
||||||
|
|
||||||
// 密钥相关
|
|
||||||
// void gen_session_keys(ex_u8 *client_random, ex_u8 *server_random);
|
|
||||||
// void decrypt(ex_u8 *buf_data, size_t buf_size, bool update_counter);
|
|
||||||
// void encrypt(ex_u8 *buf_data, size_t buf_size, bool update_counter);
|
|
||||||
// ex_u32 get_dec_counter() { return m_decrypt_total; }
|
|
||||||
// ex_u32 get_enc_counter() { return m_encrypt_total; }
|
|
||||||
// void calc_mac(ex_u8 *buf_data, size_t buf_size, ex_u8 *signature, bool with_counter = false, ex_u32 counter = 0);
|
|
||||||
|
|
||||||
// RDP-SSL 相关
|
|
||||||
// bool ssl_prepare();
|
|
||||||
|
|
||||||
// mbedtls_ssl_context *ssl_context() { return &m_ssl_ctx; }
|
|
||||||
|
|
||||||
// bool ssl_is_in_handshake() { return m_ssl_ctx.state != MBEDTLS_SSL_HANDSHAKE_OVER; }
|
|
||||||
// int ssl_do_handshake();
|
|
||||||
// int ssl_do_read();
|
|
||||||
|
|
||||||
// bool ssl_send(MemBuffer &mbuf);
|
|
||||||
// bool ssl_send(TelnetPkgBase &pkg);
|
|
||||||
// bool ssl_send(const ex_u8 *data, size_t size);
|
|
||||||
|
|
||||||
// MemBuffer &ssl_data() { return m_ssl_mbuf; }
|
|
||||||
|
|
||||||
// static int on_ssl_read(void *ctx, ex_u8 *buf, size_t len);
|
|
||||||
// static int on_ssl_write(void *ctx, const ex_u8 *buf, size_t len);
|
|
||||||
|
|
||||||
//RDP_BULK* get_bulk() { return m_bulk; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
static void _on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||||
static void _on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf);
|
static void _on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf);
|
||||||
|
|
@ -93,18 +51,10 @@ private:
|
||||||
static void _uv_on_connect_timeout(uv_timer_t *timer);
|
static void _uv_on_connect_timeout(uv_timer_t *timer);
|
||||||
static void _uv_on_connected(uv_connect_t *req, int status);
|
static void _uv_on_connected(uv_connect_t *req, int status);
|
||||||
static void _uv_on_reconnect(uv_handle_t *handle);
|
static void _uv_on_reconnect(uv_handle_t *handle);
|
||||||
static void _uv_on_shutdown(uv_shutdown_t *req, int status);
|
|
||||||
static void _uv_on_closed(uv_handle_t *handle);
|
static void _uv_on_closed(uv_handle_t *handle);
|
||||||
static void _uv_on_timer_connect_timeout_closed(uv_handle_t *handle);
|
static void _uv_on_timer_connect_timeout_closed(uv_handle_t *handle);
|
||||||
|
|
||||||
// static void _sec_hash_48(ex_u8 *buf_out, ex_u8 *buf_in, ex_u8 *salt1, ex_u8 *salt2, ex_u8 salt);
|
|
||||||
// static void _sec_hash_16(ex_u8 *buf_out, ex_u8 *buf_in, ex_u8 *salt1, ex_u8 *salt2);
|
|
||||||
// void _sec_update(ex_u8 *init_key, ex_u8 *curr_key);
|
|
||||||
|
|
||||||
bool _raw_send(const ex_u8 *data, size_t size);
|
bool _raw_send(const ex_u8 *data, size_t size);
|
||||||
// bool _ssl_send(const ex_u8 *data, size_t size);
|
|
||||||
// bool _ssl_prepare_as_server();
|
|
||||||
// bool _ssl_prepare_as_client();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TelnetSession *m_session;
|
TelnetSession *m_session;
|
||||||
|
|
@ -117,46 +67,13 @@ private:
|
||||||
uv_timer_t m_timer_connect_timeout;
|
uv_timer_t m_timer_connect_timeout;
|
||||||
bool m_timer_running; // does m_timer_connect_timeout initialized and started.
|
bool m_timer_running; // does m_timer_connect_timeout initialized and started.
|
||||||
|
|
||||||
ex_u8 m_state; // RDP_CONN_STATE_XXXX
|
ex_u8 m_state; // TELNET_CONN_STATE_XXXX
|
||||||
|
|
||||||
// 作为client需要的数据(远程主机信息)
|
// 作为client需要的数据(远程主机信息)
|
||||||
std::string m_server_ip;
|
std::string m_server_ip;
|
||||||
ex_u16 m_server_port;
|
ex_u16 m_server_port;
|
||||||
bool m_is_recving; // does this connection is receiving data?
|
|
||||||
|
|
||||||
ExThreadLock m_locker_send;
|
|
||||||
ExThreadLock m_locker_recv;
|
|
||||||
MemBuffer m_buf_data;
|
MemBuffer m_buf_data;
|
||||||
|
|
||||||
|
|
||||||
// 会话密钥相关
|
|
||||||
// ex_u8 m_rc4_key_len;
|
|
||||||
// ex_u8 m_mac_key[16];
|
|
||||||
// ex_u8 m_init_enc_key[16];
|
|
||||||
// ex_u8 m_init_dec_key[16];
|
|
||||||
// ex_u8 m_curr_enc_key[16];
|
|
||||||
// ex_u8 m_curr_dec_key[16];
|
|
||||||
// mbedtls_arc4_context m_rc4_encrypt_key;
|
|
||||||
// mbedtls_arc4_context m_rc4_decrypt_key;
|
|
||||||
|
|
||||||
// ex_u32 m_encrypt_count;
|
|
||||||
// ex_u32 m_decrypt_count;
|
|
||||||
// ex_u32 m_encrypt_total;
|
|
||||||
// ex_u32 m_decrypt_total;
|
|
||||||
|
|
||||||
|
|
||||||
// RDP-SSL相关
|
|
||||||
// MemBuffer m_ssl_mbuf; // 存放接收到的数据(经过ssl解密)的缓冲区,等待处理。处理函数处理之后,应该将已经处理过的数据弹掉。
|
|
||||||
// mbedtls_ssl_context m_ssl_ctx;
|
|
||||||
// mbedtls_x509_crt m_ssl_node_cert;
|
|
||||||
// mbedtls_pk_context m_ssl_node_key;
|
|
||||||
// mbedtls_ssl_config m_ssl_conf;
|
|
||||||
// mbedtls_entropy_context m_ssl_entropy;
|
|
||||||
// mbedtls_ctr_drbg_context m_ssl_ctr_drbg;
|
|
||||||
// mbedtls_x509_crt m_ssl_ca_cert;
|
|
||||||
|
|
||||||
// 数据包解析相关
|
|
||||||
//RDP_BULK* m_bulk;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __TELNET_CONN_H__
|
#endif // __TELNET_CONN_H__
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,6 @@ void TppTelnetRec::save_record() {
|
||||||
_save_to_cmd_file();
|
_save_to_cmd_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
// void TppTelnetRec::record_time_begin(void) // 指定从此时开始计时,之前收到的包会计时为0,这样播放时会快进到此处。
|
|
||||||
// {
|
|
||||||
// m_start_time = ex_get_tick_count();
|
|
||||||
// // m_head.timestamp = time(NULL);
|
|
||||||
// m_head.basic.timestamp = (ex_u64)time(NULL);
|
|
||||||
// m_save_full_header = true;
|
|
||||||
// m_header_changed = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size)
|
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size)
|
||||||
{
|
{
|
||||||
if (data == NULL || 0 == size)
|
if (data == NULL || 0 == size)
|
||||||
|
|
@ -100,7 +91,6 @@ void TppTelnetRec::record_win_size(int width, int height)
|
||||||
m_head.basic.height = (ex_u16)height;
|
m_head.basic.height = (ex_u16)height;
|
||||||
m_save_full_header = true;
|
m_save_full_header = true;
|
||||||
m_header_changed = true;
|
m_header_changed = true;
|
||||||
//_save_to_info_file();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TppTelnetRec::_save_to_info_file() {
|
bool TppTelnetRec::_save_to_info_file() {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ public:
|
||||||
TppTelnetRec();
|
TppTelnetRec();
|
||||||
virtual ~TppTelnetRec();
|
virtual ~TppTelnetRec();
|
||||||
|
|
||||||
// void record_time_begin(void); // 指定从此时开始计时,之前收到的包会计时为0,这样播放时会快进到此处。
|
|
||||||
void record(ex_u8 type, const ex_u8* data, size_t size);
|
void record(ex_u8 type, const ex_u8* data, size_t size);
|
||||||
void record_win_size(int width, int height);
|
void record_win_size(int width, int height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ TelnetSession::TelnetSession(TelnetProxy *proxy) :
|
||||||
m_proxy(proxy),
|
m_proxy(proxy),
|
||||||
m_conn_info(NULL)
|
m_conn_info(NULL)
|
||||||
{
|
{
|
||||||
m_client_type = 0;
|
|
||||||
m_state = TP_SESS_STAT_RUNNING;
|
m_state = TP_SESS_STAT_RUNNING;
|
||||||
|
m_record_started = false;
|
||||||
m_db_id = 0;
|
m_db_id = 0;
|
||||||
m_is_relay = false;
|
m_is_relay = false;
|
||||||
m_is_closed = false;
|
m_is_closed = false;
|
||||||
|
|
@ -40,9 +40,6 @@ TelnetSession::~TelnetSession() {
|
||||||
delete m_conn_client;
|
delete m_conn_client;
|
||||||
delete m_conn_server;
|
delete m_conn_server;
|
||||||
|
|
||||||
// mbedtls_rsa_free(&m_server_pubkey);
|
|
||||||
// mbedtls_rsa_free(&m_proxy_keypair_dynamic);
|
|
||||||
|
|
||||||
if (NULL != m_conn_info) {
|
if (NULL != m_conn_info) {
|
||||||
g_telnet_env.free_connect_info(m_conn_info);
|
g_telnet_env.free_connect_info(m_conn_info);
|
||||||
}
|
}
|
||||||
|
|
@ -126,21 +123,9 @@ void TelnetSession::do_next(TelnetConn *conn) {
|
||||||
case s_negotiation_with_client:
|
case s_negotiation_with_client:
|
||||||
new_status = _do_negotiation_with_client(conn);
|
new_status = _do_negotiation_with_client(conn);
|
||||||
break;
|
break;
|
||||||
// case s_ssl_handshake_with_client: // 与客户端端进行SSL握手
|
|
||||||
// new_status = _do_ssl_handshake_with_client();
|
|
||||||
// break;
|
|
||||||
// case s_connect_server:
|
|
||||||
// new_status = _do_connect_server();
|
|
||||||
// break;
|
|
||||||
case s_server_connected:
|
case s_server_connected:
|
||||||
new_status = _do_server_connected();
|
new_status = _do_server_connected();
|
||||||
break;
|
break;
|
||||||
// case s_negotiation_with_server:
|
|
||||||
// new_status = _do_negotiation_with_server();
|
|
||||||
// break;
|
|
||||||
// case s_ssl_handshake_with_server:
|
|
||||||
// new_status = _do_ssl_handshake_with_server();
|
|
||||||
// break;
|
|
||||||
case s_relay:
|
case s_relay:
|
||||||
new_status = _do_relay(conn);
|
new_status = _do_relay(conn);
|
||||||
break;
|
break;
|
||||||
|
|
@ -164,7 +149,6 @@ void TelnetSession::do_next(TelnetConn *conn) {
|
||||||
if (m_status == s_dead) {
|
if (m_status == s_dead) {
|
||||||
EXLOGW("[telnet] try to remove session.\n");
|
EXLOGW("[telnet] try to remove session.\n");
|
||||||
_on_session_end();
|
_on_session_end();
|
||||||
//m_proxy->session_finished(this);
|
|
||||||
m_is_closed = true;
|
m_is_closed = true;
|
||||||
m_proxy->clean_session();
|
m_proxy->clean_session();
|
||||||
}
|
}
|
||||||
|
|
@ -410,9 +394,6 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn* conn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录日志,会话开始了
|
|
||||||
// set_info(sess_info);
|
|
||||||
|
|
||||||
// try to connect to real server.
|
// try to connect to real server.
|
||||||
m_conn_server->connect(m_conn_ip.c_str(), m_conn_port);
|
m_conn_server->connect(m_conn_ip.c_str(), m_conn_port);
|
||||||
|
|
||||||
|
|
@ -439,6 +420,7 @@ sess_state TelnetSession::_do_server_connected() {
|
||||||
m_conn_server->send(_d, sizeof(_d) - 1);
|
m_conn_server->send(_d, sizeof(_d) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_is_relay = true;
|
||||||
EXLOGW("[telnet] enter relay mode.\n");
|
EXLOGW("[telnet] enter relay mode.\n");
|
||||||
|
|
||||||
return s_relay;
|
return s_relay;
|
||||||
|
|
@ -451,15 +433,6 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
||||||
if (conn->is_server_side())
|
if (conn->is_server_side())
|
||||||
{
|
{
|
||||||
// 收到了客户端发来的数据
|
// 收到了客户端发来的数据
|
||||||
// if (!_this->m_is_changle_title_sent)
|
|
||||||
// {
|
|
||||||
// _this->m_is_changle_title_sent = true;
|
|
||||||
// ts_astr msg = "\033]0;TP#telnet://";
|
|
||||||
// msg += m_server_ip;
|
|
||||||
// msg += "\007\x0d\x0a";
|
|
||||||
// m_conn_client->send((ts_u8*)msg.c_str(), msg.length());
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (_this->m_is_putty_mode && !_this->m_is_putty_eat_username)
|
if (_this->m_is_putty_mode && !_this->m_is_putty_eat_username)
|
||||||
{
|
{
|
||||||
if (_this->_eat_username(m_conn_client, m_conn_server))
|
if (_this->_eat_username(m_conn_client, m_conn_server))
|
||||||
|
|
@ -482,6 +455,8 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 收到了服务端返回的数据
|
// 收到了服务端返回的数据
|
||||||
|
if(m_record_started)
|
||||||
|
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, m_conn_server->data().data(), m_conn_server->data().size());
|
||||||
|
|
||||||
if (!_this->m_username_sent && _this->m_acc_name.length() > 0)
|
if (!_this->m_username_sent && _this->m_acc_name.length() > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -497,6 +472,14 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
||||||
{
|
{
|
||||||
_this->m_password_sent = true;
|
_this->m_password_sent = true;
|
||||||
is_processed = true;
|
is_processed = true;
|
||||||
|
|
||||||
|
if (!m_record_started) {
|
||||||
|
m_record_started = true;
|
||||||
|
if (!_on_session_begin()) {
|
||||||
|
return _do_close(TP_SESS_STAT_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,54 +489,7 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
||||||
return s_relay;
|
return s_relay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 替换会导致客户端窗口标题改变的数据
|
|
||||||
//ts_u8* data = m_conn_server->data().data();
|
|
||||||
//size_t len = m_conn_server->data().size();
|
|
||||||
// if (len > 5)
|
|
||||||
// {
|
|
||||||
// const ts_u8* _begin = memmem(data, len, (const ts_u8*)"\033]0;", 4);
|
|
||||||
//
|
|
||||||
// if (NULL != _begin)
|
|
||||||
// {
|
|
||||||
// size_t len_before = _begin - data;
|
|
||||||
//
|
|
||||||
// const ts_u8* _end = memmem(_begin + 4, len - len_before, (const ts_u8*)"\007", 1);
|
|
||||||
// if (NULL != _end)
|
|
||||||
// {
|
|
||||||
// _end++;
|
|
||||||
//
|
|
||||||
// // 这个包中含有改变标题的数据,将标题换为我们想要的
|
|
||||||
// size_t len_end = len - (_end - data);
|
|
||||||
// MemBuffer mbuf;
|
|
||||||
//
|
|
||||||
// if (len_before > 0)
|
|
||||||
// mbuf.append(data, len_before);
|
|
||||||
//
|
|
||||||
// mbuf.append((ts_u8*)"\033]0;TP#ssh://", 13);
|
|
||||||
// mbuf.append((ts_u8*)_this->m_server_ip.c_str(), _this->m_server_ip.length());
|
|
||||||
// mbuf.append((ts_u8*)"\007", 1);
|
|
||||||
//
|
|
||||||
// if (len_end > 0)
|
|
||||||
// mbuf.append(_end, len_end);
|
|
||||||
//
|
|
||||||
// m_conn_client->send(mbuf.data(), mbuf.size());
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
{
|
|
||||||
m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
|
m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
|
||||||
}
|
|
||||||
|
|
||||||
m_conn_server->data().empty();
|
m_conn_server->data().empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ enum sess_state {
|
||||||
s_client_connect, // 客户端连接
|
s_client_connect, // 客户端连接
|
||||||
s_negotiation_with_client, // 与客户端进行握手,直到得到客户端发来的登录用户名(其实是SessionID)
|
s_negotiation_with_client, // 与客户端进行握手,直到得到客户端发来的登录用户名(其实是SessionID)
|
||||||
|
|
||||||
// s_connect_server, // 与服务端连接
|
|
||||||
s_server_connected, // 成功连接上服务器了
|
s_server_connected, // 成功连接上服务器了
|
||||||
|
|
||||||
s_relay, // 正常转发数据
|
s_relay, // 正常转发数据
|
||||||
|
|
@ -38,8 +37,6 @@ public:
|
||||||
TelnetConn* server() { return m_conn_server; }
|
TelnetConn* server() { return m_conn_server; }
|
||||||
uv_loop_t* get_loop();
|
uv_loop_t* get_loop();
|
||||||
|
|
||||||
//bool is_client_auth_replaced() const { return m_is_client_auth_replaced; }
|
|
||||||
|
|
||||||
void set_state(int state) { m_state = state; }
|
void set_state(int state) { m_state = state; }
|
||||||
void close(int err_code);
|
void close(int err_code);
|
||||||
void on_conn_close();
|
void on_conn_close();
|
||||||
|
|
@ -53,13 +50,9 @@ public:
|
||||||
m_rec.record(type, data, size);
|
m_rec.record(type, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static bool init_builtin_keypair();
|
|
||||||
|
|
||||||
void client_addr(const char* addr) { m_client_addr = addr; }
|
void client_addr(const char* addr) { m_client_addr = addr; }
|
||||||
const char* client_addr() const { return m_client_addr.c_str(); }
|
const char* client_addr() const { return m_client_addr.c_str(); }
|
||||||
|
|
||||||
//static void release_builtin_keys();
|
|
||||||
|
|
||||||
bool is_relay() { return m_is_relay; }
|
bool is_relay() { return m_is_relay; }
|
||||||
bool is_closed() { return m_is_closed; }
|
bool is_closed() { return m_is_closed; }
|
||||||
|
|
||||||
|
|
@ -72,26 +65,19 @@ protected:
|
||||||
private:
|
private:
|
||||||
sess_state _do_client_connect(TelnetConn* conn);
|
sess_state _do_client_connect(TelnetConn* conn);
|
||||||
sess_state _do_negotiation_with_client(TelnetConn* conn);
|
sess_state _do_negotiation_with_client(TelnetConn* conn);
|
||||||
//sess_state _do_ssl_handshake_with_client();
|
|
||||||
// sess_state _do_connect_server();
|
|
||||||
sess_state _do_server_connected();
|
sess_state _do_server_connected();
|
||||||
//sess_state _do_negotiation_with_server();
|
|
||||||
//sess_state _do_ssl_handshake_with_server();
|
|
||||||
sess_state _do_relay(TelnetConn* conn);
|
sess_state _do_relay(TelnetConn* conn);
|
||||||
//sess_state _relay_dispatch_rdp(TelnetConn* conn_from, TelnetConn* conn_to);
|
|
||||||
//sess_state _relay_dispatch_ssl(TelnetConn* conn_from, TelnetConn* conn_to);
|
|
||||||
sess_state _do_close(int err_code);
|
sess_state _do_close(int err_code);
|
||||||
sess_state _do_check_closing();
|
sess_state _do_check_closing();
|
||||||
|
|
||||||
//bool _replace_server_cert(SC_ConferenceCreateResponse& gcc);
|
|
||||||
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
|
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
|
||||||
bool _eat_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
|
bool _eat_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_state;
|
int m_state;
|
||||||
int m_client_type; // 1 = mstsc, 2=freerdp
|
|
||||||
|
|
||||||
TPP_CONNECT_INFO* m_conn_info;
|
TPP_CONNECT_INFO* m_conn_info;
|
||||||
|
bool m_record_started;
|
||||||
int m_db_id;
|
int m_db_id;
|
||||||
|
|
||||||
bool m_is_relay; // 是否进入relay模式了(只有进入relay模式才会有录像存在)
|
bool m_is_relay; // 是否进入relay模式了(只有进入relay模式才会有录像存在)
|
||||||
|
|
@ -118,7 +104,6 @@ private:
|
||||||
|
|
||||||
bool m_is_putty_mode;
|
bool m_is_putty_mode;
|
||||||
bool m_is_putty_eat_username;
|
bool m_is_putty_eat_username;
|
||||||
// bool m_is_changle_title_sent; // 连接成功后,可以给客户端发送一个特殊的字符序列,客户端会改变窗口标题(已经在PuTTY/SecureCRT测试过)
|
|
||||||
|
|
||||||
bool m_username_sent;
|
bool m_username_sent;
|
||||||
bool m_password_sent;
|
bool m_password_sent;
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@ bool TppTelnetEnv::_on_init(TPP_INIT_ARGS* args) {
|
||||||
|
|
||||||
ex_wstr tmp;
|
ex_wstr tmp;
|
||||||
if (!ps->GetStr(L"bind-ip", tmp)) {
|
if (!ps->GetStr(L"bind-ip", tmp)) {
|
||||||
bind_ip = TS_RDP_PROXY_HOST;
|
bind_ip = TS_TELNET_PROXY_HOST;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ex_wstr2astr(tmp, bind_ip);
|
ex_wstr2astr(tmp, bind_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ps->GetInt(L"bind-port", bind_port)) {
|
if (!ps->GetInt(L"bind-port", bind_port)) {
|
||||||
bind_port = TS_RDP_PROXY_PORT;
|
bind_port = TS_TELNET_PROXY_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -167,47 +167,6 @@
|
||||||
<ClCompile Include="..\..\..\..\external\libuv\src\win\util.c" />
|
<ClCompile Include="..\..\..\..\external\libuv\src\win\util.c" />
|
||||||
<ClCompile Include="..\..\..\..\external\libuv\src\win\winapi.c" />
|
<ClCompile Include="..\..\..\..\external\libuv\src\win\winapi.c" />
|
||||||
<ClCompile Include="..\..\..\..\external\libuv\src\win\winsock.c" />
|
<ClCompile Include="..\..\..\..\external\libuv\src\win\winsock.c" />
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\aes.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\arc4.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\asn1parse.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\base64.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\bignum.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\blowfish.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\certs.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\cipher.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\cipher_wrap.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ctr_drbg.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\debug.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\des.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\dhm.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\entropy.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\entropy_poll.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\error.c">
|
|
||||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)mbedtls_error.obj</ObjectFileName>
|
|
||||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)mbedtls_error.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\hmac_drbg.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md5.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md_wrap.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\oid.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pem.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pk.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkcs12.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkcs5.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkparse.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pk_wrap.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\rsa.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha1.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha256.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha512.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_ciphersuites.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_cli.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_srv.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_tls.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\timing.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\x509.c" />
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\x509_crt.c" />
|
|
||||||
<ClCompile Include="..\..\common\base_env.cpp" />
|
<ClCompile Include="..\..\common\base_env.cpp" />
|
||||||
<ClCompile Include="..\..\common\base_record.cpp" />
|
<ClCompile Include="..\..\common\base_record.cpp" />
|
||||||
<ClCompile Include="..\..\common\ts_membuf.cpp" />
|
<ClCompile Include="..\..\common\ts_membuf.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@
|
||||||
<Filter Include="libuv\src\win">
|
<Filter Include="libuv\src\win">
|
||||||
<UniqueIdentifier>{89181d75-3db3-45a5-a35d-9083fb349de3}</UniqueIdentifier>
|
<UniqueIdentifier>{89181d75-3db3-45a5-a35d-9083fb349de3}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="mbedtls">
|
|
||||||
<UniqueIdentifier>{bedac06f-83d5-4cd3-832d-0bce55c3dc52}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\..\common\libex\include\ex\ex_const.h">
|
<ClInclude Include="..\..\..\..\common\libex\include\ex\ex_const.h">
|
||||||
|
|
@ -304,119 +301,5 @@
|
||||||
<ClCompile Include="..\..\..\..\external\libuv\src\win\process-stdio.c">
|
<ClCompile Include="..\..\..\..\external\libuv\src\win\process-stdio.c">
|
||||||
<Filter>libuv\src\win</Filter>
|
<Filter>libuv\src\win</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\rsa.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha1.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md5.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\bignum.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\md_wrap.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha256.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\sha512.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\asn1parse.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\oid.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\debug.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\x509.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pk.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pk_wrap.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\x509_crt.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\certs.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\entropy.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ctr_drbg.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\arc4.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pem.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\dhm.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\cipher.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\aes.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\des.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\base64.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\hmac_drbg.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\entropy_poll.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\cipher_wrap.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\blowfish.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkparse.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkcs5.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\pkcs12.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\error.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\timing.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_tls.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_ciphersuites.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_cli.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\..\external\mbedtls\library\ssl_srv.c">
|
|
||||||
<Filter>mbedtls</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -166,6 +166,8 @@ $app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
||||||
// window.open('/audit/replay/' + row_data.protocol_type + '/' + row_data.id);
|
// window.open('/audit/replay/' + row_data.protocol_type + '/' + row_data.id);
|
||||||
} else if (row_data.protocol_type === TP_PROTOCOL_TYPE_SSH) {
|
} else if (row_data.protocol_type === TP_PROTOCOL_TYPE_SSH) {
|
||||||
window.open('/audit/replay/' + row_data.protocol_type + '/' + row_data.id);
|
window.open('/audit/replay/' + row_data.protocol_type + '/' + row_data.id);
|
||||||
|
} else if (row_data.protocol_type === TP_PROTOCOL_TYPE_TELNET) {
|
||||||
|
window.open('/audit/replay/' + row_data.protocol_type + '/' + row_data.id);
|
||||||
}
|
}
|
||||||
} else if (action === 'cmd') {
|
} else if (action === 'cmd') {
|
||||||
//$app.dlg_accounts.show(row_id);
|
//$app.dlg_accounts.show(row_id);
|
||||||
|
|
@ -346,7 +348,9 @@ $app.on_table_host_render_created = function (render) {
|
||||||
if (fields.protocol_sub_type !== TP_PROTOCOL_TYPE_SSH_SFTP)
|
if (fields.protocol_sub_type !== TP_PROTOCOL_TYPE_SSH_SFTP)
|
||||||
ret.push('<a href="javascript:;" class="btn btn-sm btn-primary" data-action="replay" data-record-id="' + fields.id + '"><i class="fa fa-caret-square-o-right fa-fw"></i> 回放</a> ');
|
ret.push('<a href="javascript:;" class="btn btn-sm btn-primary" data-action="replay" data-record-id="' + fields.id + '"><i class="fa fa-caret-square-o-right fa-fw"></i> 回放</a> ');
|
||||||
}
|
}
|
||||||
if (fields.protocol_sub_type !== TP_PROTOCOL_TYPE_RDP_DESKTOP) {
|
if (fields.protocol_sub_type === TP_PROTOCOL_TYPE_SSH_SHELL
|
||||||
|
|| fields.protocol_sub_type === TP_PROTOCOL_TYPE_SSH_SFTP
|
||||||
|
) {
|
||||||
ret.push('<a href="javascript:;" class="btn btn-sm btn-info" data-action="cmd" data-record-id="' + fields.id + '"><i class="fa fa-list-alt fa-fw"></i> 日志</a> ');
|
ret.push('<a href="javascript:;" class="btn btn-sm btn-info" data-action="cmd" data-record-id="' + fields.id + '"><i class="fa fa-list-alt fa-fw"></i> 日志</a> ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,335 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
$app.on_init = function (cb_stack) {
|
||||||
|
var record_id = $app.options.record_id;
|
||||||
|
|
||||||
|
$app.record_hdr = null;
|
||||||
|
$app.record_data = [];
|
||||||
|
$app.record_data_offset = 0;
|
||||||
|
$app.played_pkg_count = 0;
|
||||||
|
$app.player_timer = null;
|
||||||
|
$app.is_playing = false;
|
||||||
|
$app.is_need_stop = false;
|
||||||
|
$app.need_skip = true;
|
||||||
|
$app.player_console_term = null;
|
||||||
|
$app.player_current_time = null;
|
||||||
|
$app.is_finished = false;
|
||||||
|
$app.record_tick = 50;
|
||||||
|
|
||||||
|
|
||||||
|
$app.speed_table = [
|
||||||
|
{speed: 1, name: '正常速度'},
|
||||||
|
{speed: 2, name: '快进 x2'},
|
||||||
|
{speed: 4, name: '快进 x4'},
|
||||||
|
{speed: 8, name: '快进 x8'},
|
||||||
|
{speed: 16, name: '快进 x16'}
|
||||||
|
];
|
||||||
|
$app.speed_offset = 0;
|
||||||
|
|
||||||
|
|
||||||
|
$app.dom = {
|
||||||
|
time: $('#play-time'),
|
||||||
|
btn_play: $('#btn-play'),
|
||||||
|
btn_speed: $('#btn-speed'),
|
||||||
|
btn_skip: $('#btn-skip'),
|
||||||
|
btn_restart: $('#btn-restart'),
|
||||||
|
btn_big_font: $('#btn-big-font'),
|
||||||
|
btn_small_font: $('#btn-small-font'),
|
||||||
|
progress: $('#progress'),
|
||||||
|
status: $('#play-status'),
|
||||||
|
xterm_box: $('#xterm-box'),
|
||||||
|
xterm_terminal: null,
|
||||||
|
xterm_viewport: null
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.dom.progress.width($('#toolbar').width()).val(0);
|
||||||
|
|
||||||
|
Terminal.cursorBlink = false;
|
||||||
|
|
||||||
|
$tp.ajax_post_json('/audit/get-record-header', {protocol: TP_PROTOCOL_TYPE_TELNET, id: record_id},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$app.record_hdr = ret.data;
|
||||||
|
if ($app.record_hdr.width === 0)
|
||||||
|
$app.record_hdr.width = 80;
|
||||||
|
if ($app.record_hdr.height === 0)
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$app.req_record_data(record_id, 0);
|
||||||
|
|
||||||
|
$app.player_current_time = 0;
|
||||||
|
//setTimeout(init, 500);
|
||||||
|
$app.init_and_play();
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('读取录像信息失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
console.error('load init info error ', ret.code);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络通讯失败');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$app.dom.btn_big_font.click(function () {
|
||||||
|
if (_.isNull($app.dom.xterm_terminal))
|
||||||
|
return;
|
||||||
|
var _size = parseInt($app.dom.xterm_terminal.css('font-size'));
|
||||||
|
if (_size >= 24)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$app.dom.xterm_terminal.css('font-size', _size + 1);
|
||||||
|
|
||||||
|
$app.player_console_term.charMeasure.measure();
|
||||||
|
$app.adjust_viewport();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_small_font.click(function () {
|
||||||
|
if (_.isNull($app.dom.xterm_terminal))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var _size = parseInt($app.dom.xterm_terminal.css('font-size'));
|
||||||
|
if (_size <= 12)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$app.dom.xterm_terminal.css('font-size', _size - 1);
|
||||||
|
|
||||||
|
$app.player_console_term.charMeasure.measure();
|
||||||
|
$app.adjust_viewport();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_play.click(function () {
|
||||||
|
if ($app.is_playing)
|
||||||
|
$app.pause();
|
||||||
|
else
|
||||||
|
$app.play();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_skip.click(function () {
|
||||||
|
var obj = $('#btn-skip i');
|
||||||
|
if ($app.need_skip) {
|
||||||
|
$app.need_skip = false;
|
||||||
|
obj.removeClass('fa-check-square-o').addClass('fa-square-o');
|
||||||
|
} else {
|
||||||
|
$app.need_skip = true;
|
||||||
|
obj.removeClass('fa-square-o').addClass('fa-check-square-o');
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('skip:', $app.need_skip);
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.btn_restart.click(function () {
|
||||||
|
$app.restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.speed_offset = 0;
|
||||||
|
$app.dom.btn_speed.text($app.speed_table[$app.speed_offset].name);
|
||||||
|
|
||||||
|
$app.dom.btn_speed.click(function () {
|
||||||
|
var length = $app.speed_table.length;
|
||||||
|
$app.speed_offset += 1;
|
||||||
|
if ($app.speed_offset === length) {
|
||||||
|
$app.speed_offset = 0;
|
||||||
|
}
|
||||||
|
$app.dom.btn_speed.text($app.speed_table[$app.speed_offset].name);
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.dom.progress.mousedown(function () {
|
||||||
|
$app.pause();
|
||||||
|
});
|
||||||
|
$app.dom.progress.mouseup(function () {
|
||||||
|
$app.player_current_time = parseInt($app.record_hdr.time_used * $app.dom.progress.val() / 100);
|
||||||
|
setTimeout(function () {
|
||||||
|
$app.init_and_play();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
$app.dom.progress.mousemove(function () {
|
||||||
|
$app.player_current_time = parseInt($app.record_hdr.time_used * $app.dom.progress.val() / 100);
|
||||||
|
$app.dom.time.text(parseInt(($app.player_current_time) / 1000) + '/' + parseInt($app.record_hdr.time_used / 1000) + '秒');
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.adjust_viewport = function () {
|
||||||
|
if (!_.isNull($app.dom.xterm_viewport)) {
|
||||||
|
$app.dom.xterm_viewport.width(parseInt(window.getComputedStyle($app.dom.xterm_rows[0]).width));
|
||||||
|
$app.dom.xterm_viewport.height(parseInt(window.getComputedStyle($app.dom.xterm_rows[0]).height) - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.req_record_data = function (record_id, offset) {
|
||||||
|
$tp.ajax_post_json('/audit/get-record-data', {protocol: TP_PROTOCOL_TYPE_TELNET, id: record_id, offset: offset},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
// 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) {
|
||||||
|
$app.req_record_data(record_id, $app.record_data_offset);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$app.dom.status.text("读取录像数据失败:" + tp_error_msg(ret.code));
|
||||||
|
$tp.notify_error('读取录像数据失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
console.log('req_record_info error ', ret.code);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
console.log('req_record_info error');
|
||||||
|
},
|
||||||
|
30 * 1000
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.init_and_play = function() {
|
||||||
|
if (_.isNull($app.player_console_term)) {
|
||||||
|
$app.player_console_term = new Terminal({
|
||||||
|
cols: $app.record_hdr.width,
|
||||||
|
rows: $app.record_hdr.height
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.player_console_term.on('refresh', function () {
|
||||||
|
$app.adjust_viewport();
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.player_console_term.open(document.getElementById('xterm-box'), true);
|
||||||
|
|
||||||
|
$app.dom.xterm_terminal = $('#xterm-box .terminal');
|
||||||
|
$app.dom.xterm_rows = $('#xterm-box .terminal .xterm-rows');
|
||||||
|
$app.dom.xterm_viewport = $('#xterm-box .terminal .xterm-viewport');
|
||||||
|
} else {
|
||||||
|
$app.player_console_term.reset($app.record_hdr.width, $app.record_hdr.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.record_hdr.pkg_count === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$app.dom.progress.val(0);
|
||||||
|
// $app.dom.status.text("正在播放");
|
||||||
|
$app.dom.btn_play.children().removeClass().addClass('fa fa-pause').text(' 暂停');
|
||||||
|
|
||||||
|
$app.is_need_stop = false;
|
||||||
|
$app.is_playing = true;
|
||||||
|
$app.is_finished = false;
|
||||||
|
$app.played_pkg_count = 0;
|
||||||
|
//setTimeout(do_play, $app.record_tick);
|
||||||
|
$app.do_play();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.do_play = function() {
|
||||||
|
if ($app.is_need_stop) {
|
||||||
|
$app.is_playing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.record_data.length <= $app.played_pkg_count) {
|
||||||
|
$app.dom.status.text("正在缓存数据...");
|
||||||
|
$app.player_timer = setTimeout($app.do_play, $app.record_tick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.dom.status.text("正在播放");
|
||||||
|
$app.player_current_time += $app.record_tick * $app.speed_table[$app.speed_offset].speed;
|
||||||
|
|
||||||
|
var _record_tick = $app.record_tick;
|
||||||
|
|
||||||
|
for (var i = $app.played_pkg_count; i < $app.record_data.length; i++) {
|
||||||
|
if ($app.is_need_stop)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var play_data = $app.record_data[i];
|
||||||
|
|
||||||
|
if (play_data.t < $app.player_current_time) {
|
||||||
|
if (play_data.a === 1) {
|
||||||
|
$app.player_console_term.resize(play_data.w, play_data.h);
|
||||||
|
} else if (play_data.a === 2) {
|
||||||
|
$app.player_console_term.write(play_data.d);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$app.player_console_term.write(tp_base64_decode(play_data.d));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($app.played_pkg_count + 1) === $app.record_hdr.pkg_count) {
|
||||||
|
$app.dom.progress.val(100);
|
||||||
|
$app.dom.status.text('播放完成');
|
||||||
|
$app.dom.time.text(parseInt($app.record_hdr.time_used / 1000) + '秒');
|
||||||
|
$app.is_finished = true;
|
||||||
|
$app.is_playing = false;
|
||||||
|
$app.dom.btn_play.children().removeClass().addClass('fa fa-play').text(' 播放');
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$app.played_pkg_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.is_need_stop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ($app.need_skip) {
|
||||||
|
if (play_data.t - $app.player_current_time > 800) {
|
||||||
|
$app.player_current_time = play_data.t; // - $app.record_tick * $app.speed_table[$app.speed_offset].speed;
|
||||||
|
_record_tick = 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sync progress bar.
|
||||||
|
var _progress = parseInt($app.player_current_time * 100 / $app.record_hdr.time_used);
|
||||||
|
$app.dom.progress.val(_progress);
|
||||||
|
var temp = parseInt($app.player_current_time / 1000);
|
||||||
|
$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) {
|
||||||
|
$app.dom.progress.val(100);
|
||||||
|
$app.dom.status.text('播放完成');
|
||||||
|
$app.dom.time.text(parseInt($app.record_hdr.time_used / 1000) + '秒');
|
||||||
|
$app.is_finished = true;
|
||||||
|
$app.is_playing = false;
|
||||||
|
$app.dom.btn_play.children().removeClass().addClass('fa fa-play').text(' 播放');
|
||||||
|
} else {
|
||||||
|
if (!$app.is_need_stop)
|
||||||
|
$app.player_timer = setTimeout($app.do_play, _record_tick);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.play = function() {
|
||||||
|
if ($app.is_playing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.is_finished) {
|
||||||
|
$app.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.dom.btn_play.children().removeClass().addClass('fa fa-pause').text(' 暂停');
|
||||||
|
|
||||||
|
$app.is_need_stop = false;
|
||||||
|
$app.is_playing = true;
|
||||||
|
$app.player_timer = setTimeout($app.do_play, $app.record_tick);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.pause = function() {
|
||||||
|
if (!_.isNull($app.player_timer))
|
||||||
|
clearTimeout($app.player_timer);
|
||||||
|
$app.dom.btn_play.children().removeClass().addClass('fa fa-play').text(' 播放');
|
||||||
|
$app.is_need_stop = true;
|
||||||
|
$app.is_playing = false;
|
||||||
|
$app.dom.status.text("已暂停");
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.restart = function() {
|
||||||
|
if (!_.isNull($app.player_timer))
|
||||||
|
clearTimeout($app.player_timer);
|
||||||
|
$app.player_current_time = 0;
|
||||||
|
$app.init_and_play();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
<%!
|
||||||
|
page_title_ = '录像回放'
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%inherit file="../page_single_base.mako"/>
|
||||||
|
|
||||||
|
<%block name="extend_js_file">
|
||||||
|
<script type="text/javascript" src="${ static_url('plugins/xterm/xterm.js') }"></script>
|
||||||
|
<script type="text/javascript" src="${ static_url('js/audit/replay-telnet.js') }"></script>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="extend_css_file">
|
||||||
|
<link href="${ static_url('plugins/xterm/xterm.css') }" rel="stylesheet" type="text/css"/>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="embed_css">
|
||||||
|
<style type="text/css">
|
||||||
|
.container {
|
||||||
|
width:100%;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
#xterm-box {
|
||||||
|
margin: 10px 0;
|
||||||
|
## background-color: #1e1e1e;
|
||||||
|
## margin-top: 10px;
|
||||||
|
## margin-bottom: 48px;
|
||||||
|
## width: 300px;
|
||||||
|
## border: 1px solid #9c9c9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal {
|
||||||
|
font-family: Consolas, Monaco, courier-new, courier, monospace;
|
||||||
|
color: #b7b7b7;
|
||||||
|
font-size: 13px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal {
|
||||||
|
## background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal .xterm-viewport {
|
||||||
|
## background-color: transparent;
|
||||||
|
## display:none;
|
||||||
|
## overflow: auto;
|
||||||
|
padding-right:17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal .xterm-rows {
|
||||||
|
## margin:5px;
|
||||||
|
padding:5px;
|
||||||
|
border-right: 1px dashed #363636;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="page_header">
|
||||||
|
<div class="container-fluid top-navbar">
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><i class="fa fa-server"></i> ${self.attr.page_title_}</li>
|
||||||
|
<li class="sub-title"><span id="recorder-info"></span></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div id="toolbar" style="display: inline-block;">
|
||||||
|
<button id="btn-play" type="button" class="btn btn-primary btn-sm" style="width:80px;"><i class="fa fa-pause fa-fw"> 暂停</i></button>
|
||||||
|
<button id="btn-restart" type="button" class="btn btn-success btn-sm"><i class="fa fa-refresh fa-fw"></i> 重新播放</button>
|
||||||
|
|
||||||
|
<button id="btn-speed" type="button" class="btn btn-info btn-sm" style="width:80px;">正常速度</button>
|
||||||
|
|
||||||
|
<button id="btn-big-font" type="button" class="btn btn-default btn-sm"><i class="fa fa-font fa-fw"></i>+</button>
|
||||||
|
<button id="btn-small-font" type="button" class="btn btn-default btn-sm"><i class="fa fa-font fa-fw"></i>-</button>
|
||||||
|
|
||||||
|
<div style="display:inline-block;position:relative;top:4px;margin-left:10px;margin-right:15px;">
|
||||||
|
<span id="btn-skip" style="cursor:pointer;"><i class="fa fa-check-square-o fa-fw"></i> 跳过无操作时间</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span id="play-status" class="badge badge-normal" style="margin-left:5px;">正在获取数据</span>
|
||||||
|
<span id="play-time" class="badge badge-success" style="margin-left:5px;">总时长:未知</span>
|
||||||
|
</div>
|
||||||
|
<input id="progress" type="range" value="0" min=0 max=100 style="margin-top: 10px;"/>
|
||||||
|
<div id="xterm-box"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<%block name="extend_content">
|
||||||
|
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<%block name="embed_js">
|
||||||
|
<script type="text/javascript">
|
||||||
|
$app.add_options(${page_param});
|
||||||
|
</script>
|
||||||
|
</%block>
|
||||||
|
|
@ -499,6 +499,9 @@ class ReplayHandler(TPBaseHandler):
|
||||||
elif protocol == TP_PROTOCOL_TYPE_SSH:
|
elif protocol == TP_PROTOCOL_TYPE_SSH:
|
||||||
param = {'record_id': record_id}
|
param = {'record_id': record_id}
|
||||||
self.render('audit/replay-ssh.mako', page_param=json.dumps(param))
|
self.render('audit/replay-ssh.mako', page_param=json.dumps(param))
|
||||||
|
elif protocol == TP_PROTOCOL_TYPE_TELNET:
|
||||||
|
param = {'record_id': record_id}
|
||||||
|
self.render('audit/replay-telnet.mako', page_param=json.dumps(param))
|
||||||
|
|
||||||
|
|
||||||
# # class PlayRdpHandler(TPBaseAdminAuthHandler):
|
# # class PlayRdpHandler(TPBaseAdminAuthHandler):
|
||||||
|
|
@ -641,6 +644,8 @@ class DoGetRecordDataHandler(TPBaseJsonHandler):
|
||||||
data_list, data_size, err = record.read_rdp_record_data(record_id, offset)
|
data_list, data_size, err = record.read_rdp_record_data(record_id, offset)
|
||||||
elif protocol_type == TP_PROTOCOL_TYPE_SSH:
|
elif protocol_type == TP_PROTOCOL_TYPE_SSH:
|
||||||
data_list, data_size, err = record.read_ssh_record_data(record_id, offset)
|
data_list, data_size, err = record.read_ssh_record_data(record_id, offset)
|
||||||
|
elif protocol_type == TP_PROTOCOL_TYPE_TELNET:
|
||||||
|
data_list, data_size, err = record.read_telnet_record_data(record_id, offset)
|
||||||
else:
|
else:
|
||||||
self.write_json(TPE_NOT_EXISTS)
|
self.write_json(TPE_NOT_EXISTS)
|
||||||
self.write_json(err, data={'data_list': data_list, 'data_size': data_size})
|
self.write_json(err, data={'data_list': data_list, 'data_size': data_size})
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,8 @@ def read_record_head(protocol_type, record_id):
|
||||||
path_name = 'rdp'
|
path_name = 'rdp'
|
||||||
elif protocol_type == TP_PROTOCOL_TYPE_SSH:
|
elif protocol_type == TP_PROTOCOL_TYPE_SSH:
|
||||||
path_name = 'ssh'
|
path_name = 'ssh'
|
||||||
|
elif protocol_type == TP_PROTOCOL_TYPE_TELNET:
|
||||||
|
path_name = 'telnet'
|
||||||
|
|
||||||
record_path = os.path.join(tp_cfg().core.replay_path, path_name, '{:09d}'.format(int(record_id)))
|
record_path = os.path.join(tp_cfg().core.replay_path, path_name, '{:09d}'.format(int(record_id)))
|
||||||
header_file_path = os.path.join(record_path, 'tp-{}.tpr'.format(path_name))
|
header_file_path = os.path.join(record_path, 'tp-{}.tpr'.format(path_name))
|
||||||
|
|
@ -366,6 +368,82 @@ def read_ssh_record_data(record_id, offset):
|
||||||
return data_list, data_size, TPE_OK
|
return data_list, data_size, TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def read_telnet_record_data(record_id, offset):
|
||||||
|
if not tp_cfg().core.detected:
|
||||||
|
return None, TPE_NO_CORE_SERVER
|
||||||
|
|
||||||
|
record_path = os.path.join(tp_cfg().core.replay_path, 'telnet', '{:09d}'.format(int(record_id)))
|
||||||
|
file_data = os.path.join(record_path, 'tp-telnet.dat')
|
||||||
|
|
||||||
|
if not os.path.exists(file_data):
|
||||||
|
return None, 0, TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
data_list = list()
|
||||||
|
data_size = 0
|
||||||
|
file = None
|
||||||
|
try:
|
||||||
|
file_size = os.path.getsize(file_data)
|
||||||
|
if offset >= file_size:
|
||||||
|
return None, 0, TPE_FAILED
|
||||||
|
|
||||||
|
file = open(file_data, 'rb')
|
||||||
|
if offset > 0:
|
||||||
|
file.seek(offset, io.SEEK_SET)
|
||||||
|
|
||||||
|
# read 1000 packages one time from offset.
|
||||||
|
for i in range(1000):
|
||||||
|
"""
|
||||||
|
// 一个数据包的头
|
||||||
|
typedef struct TS_RECORD_PKG
|
||||||
|
{
|
||||||
|
ex_u8 type; // 包的数据类型
|
||||||
|
ex_u32 size; // 这个包的总大小(不含包头)
|
||||||
|
ex_u32 time_ms; // 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天)
|
||||||
|
ex_u8 _reserve[3]; // 保留
|
||||||
|
}TS_RECORD_PKG;
|
||||||
|
"""
|
||||||
|
_data = file.read(12)
|
||||||
|
data_size += 12
|
||||||
|
_action, _size, _time, = struct.unpack_from('=BII', _data)
|
||||||
|
if offset + data_size + _size > file_size:
|
||||||
|
return None, 0, TPE_FAILED
|
||||||
|
|
||||||
|
_data = file.read(_size)
|
||||||
|
data_size += _size
|
||||||
|
|
||||||
|
temp = dict()
|
||||||
|
temp['a'] = _action
|
||||||
|
temp['t'] = _time
|
||||||
|
if _action == 1:
|
||||||
|
# this is window size changed.
|
||||||
|
w, h = struct.unpack_from('HH', _data)
|
||||||
|
temp['w'] = w
|
||||||
|
temp['h'] = h
|
||||||
|
elif _action == 2:
|
||||||
|
try:
|
||||||
|
_d = _data.decode()
|
||||||
|
temp['d'] = _d
|
||||||
|
except:
|
||||||
|
_data = base64.b64encode(_data)
|
||||||
|
temp['a'] = 3
|
||||||
|
temp['d'] = _data.decode()
|
||||||
|
else:
|
||||||
|
return None, 0, TPE_FAILED
|
||||||
|
|
||||||
|
data_list.append(temp)
|
||||||
|
if offset + data_size == file_size:
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
log.e('failed to read record file: {}\n'.format(file_data))
|
||||||
|
return None, 0, TPE_FAILED
|
||||||
|
finally:
|
||||||
|
if file is not None:
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
return data_list, data_size, TPE_OK
|
||||||
|
|
||||||
|
|
||||||
def delete_log(log_list):
|
def delete_log(log_list):
|
||||||
try:
|
try:
|
||||||
where = list()
|
where = list()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue