格式化代码;使用auto和nullptr。

dev
Apex Liu 2020-11-03 01:29:48 +08:00
parent c2cf5b1842
commit d8c6bd0c84
19 changed files with 590 additions and 585 deletions

View File

@ -43,6 +43,7 @@
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_proxy.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_recorder.h" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_web/src/main.cpp" charset="GBK" />

View File

@ -108,10 +108,12 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t* data, uint32_t
}
break;
case 0x0d:return_count++;
case 0x0d:
return_count++;
last_return_pos = offset;
break;
default:break;
default:
break;
}
if (!valid_input)
@ -220,12 +222,14 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
case '6':
case '7':
case '8':
case '9':esc_arg = esc_arg * 10 + (ch - '0');
case '9':
esc_arg = esc_arg * 10 + (ch - '0');
break;
case 0x3f:
case ';':
case '>':m_cmd.reset();
case '>':
m_cmd.reset();
return;
case 0x4b: { // 'K'
@ -279,7 +283,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
break;
}
default:esc_mode = false;
default:
esc_mode = false;
break;
}
@ -332,7 +337,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
break;
}
default:m_cmd.replace(ch);
default:
m_cmd.replace(ch);
if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n");
@ -489,7 +495,8 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t* data, u
str2_len = (int) ((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str());
break;
default:return;
default:
return;
}
int total_len = 5 + str1_len + 4;

View File

@ -5,10 +5,9 @@
#include <ex.h>
typedef std::map<SshSession *, unsigned char> ts_ssh_sessions;
typedef std::map<SshSession*, unsigned char> ts_ssh_sessions;
class SshProxy : public ExThreadBase
{
class SshProxy : public ExThreadBase {
public:
SshProxy() noexcept;
@ -20,7 +19,7 @@ public:
void set_cfg(ex_u32 noop_timeout);
void kill_sessions(const ex_astrs &sessions);
void kill_sessions(const ex_astrs& sessions);
protected:
void _thread_loop() override;
@ -29,14 +28,14 @@ protected:
private:
ssh_bind m_bind;
int m_timer_counter_check_noop;
int m_timer_counter_keep_alive;
int m_timer_counter_check_noop;
int m_timer_counter_keep_alive;
ExThreadLock m_lock;
bool m_listener_running;
bool m_listener_running;
ex_astr m_host_ip;
int m_host_port;
int m_host_port;
ts_ssh_sessions m_sessions;

View File

@ -67,7 +67,6 @@ void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
_save_to_data_file();
TS_RECORD_PKG pkg = {0};
//memset(&pkg, 0, sizeof(TS_RECORD_PKG));
pkg.type = type;
pkg.size = (ex_u32) size;
@ -79,9 +78,6 @@ void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
m_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG));
m_cache.append(data, size);
//m_head.info.packages++;
//m_header_changed = true;
}
void TppSshRec::record_win_size_startup(int width, int height) {
@ -100,20 +96,6 @@ void TppSshRec::record_win_size_change(int width, int height) {
// 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。
void TppSshRec::record_command(int flag, const ex_astr& cmd) {
char szTime[100] = {0};
#ifdef EX_OS_WIN32
// SYSTEMTIME st;
// GetLocalTime(&st);
// sprintf_s(szTime, 100, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, flag);
#else
// time_t timep;
// struct tm *p;
// time(&timep);
// p = localtime(&timep);
// if (p == nullptr)
// return;
// sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag);
#endif
ex_strformat(szTime, 99, "%d,%d,", (ex_u32) (ex_get_tick_count() - m_start_time), flag);
size_t lenTime = strlen(szTime);

View File

@ -3,46 +3,51 @@
#include "../../common/base_record.h"
#define TS_RECORD_TYPE_SSH_TERM_SIZE 0x01 // 终端大小(行数与列数)
#define TS_RECORD_TYPE_SSH_DATA 0x02 // 用于展示的数据内容
#define TS_RECORD_TYPE_SSH_TERM_SIZE 0x01 // 终端大小(行数与列数)
#define TS_RECORD_TYPE_SSH_DATA 0x02 // 用于展示的数据内容
#pragma pack(push,1)
#pragma pack(push, 1)
// 记录窗口大小改变的数据包
typedef struct TS_RECORD_WIN_SIZE
{
ex_u16 width;
ex_u16 height;
}TS_RECORD_WIN_SIZE;
typedef struct TS_RECORD_WIN_SIZE {
ex_u16 width;
ex_u16 height;
} TS_RECORD_WIN_SIZE;
#pragma pack(pop)
class TppSshRec : public TppRecBase
{
class TppSshRec : public TppRecBase {
public:
TppSshRec();
virtual ~TppSshRec();
TppSshRec();
void record(ex_u8 type, const ex_u8* data, size_t size);
void record_win_size_startup(int width, int height);
void record_win_size_change(int width, int height);
void record_command(int flag, const ex_astr& cmd);
virtual ~TppSshRec();
void record(ex_u8 type, const ex_u8* data, size_t size);
void record_win_size_startup(int width, int height);
void record_win_size_change(int width, int height);
void record_command(int flag, const ex_astr& cmd);
void save_record();
protected:
bool _on_begin(const TPP_CONNECT_INFO* info);
bool _on_end();
bool _on_begin(const TPP_CONNECT_INFO* info) override;
bool _save_to_info_file();
bool _save_to_data_file();
bool _save_to_cmd_file();
bool _on_end() override;
bool _save_to_info_file();
bool _save_to_data_file();
bool _save_to_cmd_file();
protected:
TS_RECORD_HEADER m_head;
bool m_header_changed;
TS_RECORD_HEADER m_head;
bool m_header_changed;
MemBuffer m_cmd_cache;
MemBuffer m_cmd_cache;
bool m_save_full_header;

View File

@ -82,8 +82,7 @@ void SshSession::_on_stopped() {
void SshSession::_set_last_error(int err_code) {
#ifndef TEST_SSH_SESSION_000000
int db_id = 0;
if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0)
{
if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0) {
EXLOGE("[%s] can not write session error to database.\n", m_dbg_name.c_str());
return;
}
@ -323,7 +322,7 @@ bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv)
uint32_t dbg_id = m_pair_id++;
auto _pair = new SshChannelPair(this, dbg_id, ch_tp2cli, ch_tp2srv);
if(!_pair->record_begin(m_conn_info)) {
if (!_pair->record_begin(m_conn_info)) {
delete _pair;
return false;
}
@ -784,7 +783,7 @@ int SshSession::_on_client_pty_request(ssh_session /*session*/, ssh_channel chan
}
cp->win_width = x;
cp->rec.record_win_size_change(x, y);
cp->rec.record_win_size_startup(x, y);
int rc = ssh_channel_request_pty_size(cp->rsc_tp2srv, term, x, y);
while (rc == SSH_AGAIN) {

View File

@ -33,8 +33,7 @@ class SshProxy;
class SshSession;
class SshSession :
public ExThreadBase {
class SshSession : public ExThreadBase {
public:
SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char* client_ip, uint16_t client_port);

View File

@ -96,8 +96,11 @@ TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) {
return TPE_PARAM;
switch (cmd) {
case TPP_CMD_SET_RUNTIME_CFG:return tpp_cmd_set_runtime_config(param);
case TPP_CMD_KILL_SESSIONS:return tpp_cmd_kill_sessions(param);
default:return TPE_UNKNOWN_CMD;
case TPP_CMD_SET_RUNTIME_CFG:
return tpp_cmd_set_runtime_config(param);
case TPP_CMD_KILL_SESSIONS:
return tpp_cmd_kill_sessions(param);
default:
return TPE_UNKNOWN_CMD;
}
}

View File

@ -12,11 +12,12 @@ ex_astr _uv_str_error(int retcode) {
return err;
}
TelnetConn::TelnetConn(TelnetSession *sess, bool is_server_side) : m_session(sess), m_is_server(is_server_side) {
TelnetConn::TelnetConn(TelnetSession* sess, bool is_server_side) : m_session(sess), m_is_server(is_server_side) {
if (is_server_side) {
m_name = "cli<->tp";
m_state = TELNET_CONN_STATE_CONNECTED;
} else {
}
else {
m_name = "tp<->srv";
m_state = TELNET_CONN_STATE_FREE;
}
@ -29,11 +30,10 @@ TelnetConn::TelnetConn(TelnetSession *sess, bool is_server_side) : m_session(ses
m_stop_handle.data = this;
}
TelnetConn::~TelnetConn() {
}
TelnetConn::~TelnetConn() = default;
bool TelnetConn::start_recv() {
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) {
EXLOGE("[telnet] [%s] can not start to read.\n", m_name);
m_session->close(TP_SESS_STAT_ERR_IO);
@ -59,46 +59,46 @@ void TelnetConn::_do_close() {
EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
m_state = TELNET_CONN_STATE_CLOSING;
uv_close(handle(), NULL);
uv_close(handle(), nullptr);
return;
}
uv_read_stop((uv_stream_t *) &m_handle);
uv_read_stop((uv_stream_t*) &m_handle);
uv_close(handle(), _uv_on_closed);
}
//static
void TelnetConn::_on_stop_cb(uv_async_t *handle) {
TelnetConn *_this = (TelnetConn *) handle->data;
uv_close((uv_handle_t *) &_this->m_stop_handle, _this->_on_stop_handler_closed);
void TelnetConn::_on_stop_cb(uv_async_t* handle) {
auto _this = (TelnetConn*) handle->data;
uv_close((uv_handle_t*) &_this->m_stop_handle, _this->_on_stop_handler_closed);
}
//static
void TelnetConn::_on_stop_handler_closed(uv_handle_t *handle) {
TelnetConn *_this = (TelnetConn *) handle->data;
void TelnetConn::_on_stop_handler_closed(uv_handle_t* handle) {
auto _this = (TelnetConn*) handle->data;
_this->_do_close();
}
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
TelnetConn *_this = (TelnetConn *) handle->data;
void TelnetConn::_uv_on_closed(uv_handle_t* handle) {
auto _this = (TelnetConn*) handle->data;
_this->m_state = TELNET_CONN_STATE_FREE;
_this->m_session->on_conn_close();
}
void TelnetConn::_on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
// TelnetConn *_this = (TelnetConn *) handle->data;
buf->base = (char *) calloc(1, suggested_size);
void TelnetConn::_on_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
buf->base = (char*) calloc(1, suggested_size);
buf->len = suggested_size;
}
void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
TelnetConn *_this = (TelnetConn *) handle->data;
void TelnetConn::_on_recv(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
auto _this = (TelnetConn*) handle->data;
if (nread == 0) {
free(buf->base);
return;
} else if (nread < 0) {
}
else if (nread < 0) {
free(buf->base);
if (nread == UV_EOF)
@ -118,49 +118,50 @@ void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *bu
_this->m_session->close(TP_SESS_STAT_END);
return;
} else {
}
else {
// #ifdef LOG_DATA
// if(!_this->m_session->is_relay())
// EXLOG_BIN((ex_u8*)buf->base, nread, "[telnet] [%s] RECV %d.", _this->m_name, nread);
// #endif
}
_this->m_buf_data.append((ex_u8 *) buf->base, nread);
_this->m_buf_data.append((ex_u8*) buf->base, nread);
free(buf->base);
_this->m_session->do_next(_this);
}
bool TelnetConn::send(MemBuffer &mbuf) {
bool TelnetConn::send(MemBuffer& mbuf) {
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);
}
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
// if (!m_session->is_relay())
// EXLOG_BIN(data, size, "[telnet] [%s] SEND %dB.", m_name, size);
// #endif
uv_write_t *w = (uv_write_t *) calloc(1, sizeof(uv_write_t));
auto w = (uv_write_t*) calloc(1, sizeof(uv_write_t));
ex_u8 *_data = (ex_u8 *) calloc(1, size);
if (NULL == _data) {
auto _data = (ex_u8*) calloc(1, size);
if (nullptr == _data) {
free(w);
EXLOGE("[telnet] alloc buffer %dB failed.\n", size);
return false;
}
memcpy(_data, data, size);
uv_buf_t *_buf = (uv_buf_t *) calloc(1, sizeof(uv_buf_t));
_buf->base = (char *) _data;
auto _buf = (uv_buf_t*) calloc(1, sizeof(uv_buf_t));
_buf->base = (char*) _data;
_buf->len = size;
w->data = _buf;
if (0 == uv_write(w, (uv_stream_t *) &m_handle, _buf, 1, _on_send_done))
if (0 == uv_write(w, (uv_stream_t*) &m_handle, _buf, 1, _on_send_done))
return true;
else {
EXLOGE("[telnet] [%s] raw_send() failed.\n", m_name);
@ -168,8 +169,8 @@ bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
}
}
void TelnetConn::_on_send_done(uv_write_t *req, int status) {
uv_buf_t *_buf = (uv_buf_t *) req->data;
void TelnetConn::_on_send_done(uv_write_t* req, int status) {
auto _buf = (uv_buf_t*) req->data;
free(_buf->base);
free(_buf);
free(req);
@ -180,26 +181,31 @@ void TelnetConn::_on_send_done(uv_write_t *req, int status) {
}
}
void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
void TelnetConn::connect(const char* server_ip, ex_u16 server_port) {
m_server_ip = server_ip;
m_server_port = server_port;
if (m_state == TELNET_CONN_STATE_CONNECTED) {
// 当前已经连接上了服务器了,断开重连
EXLOGV("[telnet] [%s] [%s] try to disconnect from real TELNET server %s:%d and reconnect.\n", m_name,
m_session->client_addr(), server_ip, server_port);
EXLOGV(
"[telnet] [%s] [%s] try to disconnect from real TELNET server %s:%d and reconnect.\n", m_name,
m_session->client_addr(), server_ip, server_port
);
m_state = TELNET_CONN_STATE_CLOSING;
uv_close((uv_handle_t *) &m_handle, _uv_on_reconnect);
uv_close((uv_handle_t*) &m_handle, _uv_on_reconnect);
return;
} else {
EXLOGV("[telnet] [%s] [%s] try to connect to real TELNET server %s:%d\n", m_name, m_session->client_addr(),
server_ip, server_port);
}
else {
EXLOGV(
"[telnet] [%s] [%s] try to connect to real TELNET server %s:%d\n", m_name, m_session->client_addr(),
server_ip, server_port
);
}
struct sockaddr_in addr;
uv_ip4_addr(server_ip, server_port, &addr);
uv_connect_t *conn_req = (uv_connect_t *) calloc(1, sizeof(uv_connect_t));
auto conn_req = (uv_connect_t*) calloc(1, sizeof(uv_connect_t));
conn_req->data = this;
// 设置一个超时回调,如果超时发生时连接尚未完成,就报错
@ -216,26 +222,26 @@ void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
m_state = TELNET_CONN_STATE_CONNECTING;
int err = 0;
if ((err = uv_tcp_connect(conn_req, &m_handle, (const struct sockaddr *) &addr, _uv_on_connected)) != 0) {
if ((err = uv_tcp_connect(conn_req, &m_handle, (const struct sockaddr*) &addr, _uv_on_connected)) != 0) {
free(conn_req);
EXLOGE("[telnet] [%s] can not connect to server: %s\n", m_name, uv_strerror(err));
m_timer_running = false;
uv_timer_stop(&m_timer_connect_timeout);
uv_close((uv_handle_t *) &m_timer_connect_timeout, NULL);
uv_close((uv_handle_t*) &m_timer_connect_timeout, nullptr);
m_state = TELNET_CONN_STATE_FREE;
m_session->close(TP_SESS_STAT_ERR_CONNECT);
}
}
void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer) {
TelnetConn *_this = (TelnetConn *) timer->data;
void TelnetConn::_uv_on_connect_timeout(uv_timer_t* timer) {
auto _this = (TelnetConn*) timer->data;
if (_this->m_timer_running) {
_this->m_timer_running = false;
uv_timer_stop(&_this->m_timer_connect_timeout);
uv_close((uv_handle_t *) &_this->m_timer_connect_timeout, NULL);
uv_close((uv_handle_t*) &_this->m_timer_connect_timeout, nullptr);
}
// 如果在连接成功之前就超时了,则关闭连接
@ -244,8 +250,8 @@ void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer) {
uv_close(_this->handle(), _uv_on_closed);
}
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
TelnetConn *_this = (TelnetConn *) handle->data;
void TelnetConn::_uv_on_reconnect(uv_handle_t* handle) {
auto _this = (TelnetConn*) handle->data;
_this->m_state = TELNET_CONN_STATE_FREE;
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
@ -254,14 +260,14 @@ void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
_this->connect(_this->m_server_ip.c_str(), _this->m_server_port);
}
void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
TelnetConn *_this = (TelnetConn *) req->data;
void TelnetConn::_uv_on_connected(uv_connect_t* req, int status) {
auto _this = (TelnetConn*) req->data;
free(req);
if (_this->m_timer_running) {
_this->m_timer_running = false;
uv_timer_stop(&_this->m_timer_connect_timeout);
uv_close((uv_handle_t *) &_this->m_timer_connect_timeout, NULL);
uv_close((uv_handle_t*) &_this->m_timer_connect_timeout, nullptr);
}
if (status != 0) {

View File

@ -18,33 +18,33 @@ class TelnetSession;
class TelnetConn {
public:
TelnetConn(TelnetSession *sess, bool is_server_side);
TelnetConn(TelnetSession* sess, bool is_server_side);
~TelnetConn();
TelnetSession *session() { return m_session; }
TelnetSession* session() { return m_session; }
// just for debug-info
const char *name() const { return m_name; }
const char* name() const { return m_name; }
bool is_server_side() const { return m_is_server; }
ex_u8 state() const { return m_state; }
uv_handle_t *handle() { return (uv_handle_t *) &m_handle; }
uv_handle_t* handle() { return (uv_handle_t*) &m_handle; }
uv_tcp_t *tcp_handle() { return &m_handle; }
uv_tcp_t* tcp_handle() { return &m_handle; }
uv_stream_t *stream_handle() { return (uv_stream_t *) &m_handle; }
uv_stream_t* stream_handle() { return (uv_stream_t*) &m_handle; }
MemBuffer &data() { return m_buf_data; }
MemBuffer& data() { return m_buf_data; }
bool send(MemBuffer &mbuf);
bool send(MemBuffer& mbuf);
bool send(const ex_u8 *data, size_t size);
bool send(const ex_u8* data, size_t size);
// 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 TELNET_CONN_STATE_XXXX.
void close();
@ -52,35 +52,35 @@ public:
bool start_recv();
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);
static void _on_send_done(uv_write_t *req, int status);
static void _on_send_done(uv_write_t* req, int status);
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_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 _on_stop_cb(uv_async_t *handle);
static void _on_stop_cb(uv_async_t* handle);
static void _on_stop_handler_closed(uv_handle_t *handle);
static void _on_stop_handler_closed(uv_handle_t* handle);
void _do_close();
bool _raw_send(const ex_u8 *data, size_t size);
bool _raw_send(const ex_u8* data, size_t size);
private:
TelnetSession *m_session;
TelnetSession* m_session;
bool m_is_server;
// for debug-info.
const char *m_name;
const char* m_name;
uv_tcp_t m_handle;
uv_timer_t m_timer_connect_timeout;

View File

@ -46,8 +46,8 @@ void TelnetProxy::timer() {
m_timer_counter = 0;
ExThreadSmartLock locker(m_lock);
ex_u32 t_now = (ex_u32) time(NULL);
ts_telnet_sessions::iterator it = m_sessions.begin();
auto t_now = (ex_u32) time(nullptr);
auto it = m_sessions.begin();
for (; it != m_sessions.end(); ++it) {
it->first->save_record();
if (0 != m_noop_timeout_sec)
@ -59,9 +59,9 @@ void TelnetProxy::set_cfg(ex_u32 noop_timeout) {
m_noop_timeout_sec = noop_timeout;
}
void TelnetProxy::kill_sessions(const ex_astrs &sessions) {
void TelnetProxy::kill_sessions(const ex_astrs& sessions) {
ExThreadSmartLock locker(m_lock);
ts_telnet_sessions::iterator it = m_sessions.begin();
auto it = m_sessions.begin();
for (; it != m_sessions.end(); ++it) {
for (size_t i = 0; i < sessions.size(); ++i) {
if (it->first->sid() == sessions[i]) {
@ -72,20 +72,20 @@ void TelnetProxy::kill_sessions(const ex_astrs &sessions) {
}
}
void TelnetProxy::_thread_loop(void) {
void TelnetProxy::_thread_loop() {
struct sockaddr_in addr;
if (0 != uv_ip4_addr(m_host_ip.c_str(), m_host_port, &addr)) {
EXLOGE("[telnet] invalid ip/port for TELNET listener.\n");
return;
}
if (0 != uv_tcp_bind(&m_listener_handle, (const struct sockaddr *) &addr, 0)) {
if (0 != uv_tcp_bind(&m_listener_handle, (const struct sockaddr*) &addr, 0)) {
EXLOGE("[telnet] can not bind %s:%d.\n", m_host_ip.c_str(), m_host_port);
return;
}
// 开始监听,有客户端连接到来时,会回调 _on_client_connect()
if (0 != uv_listen((uv_stream_t *) &m_listener_handle, 8, _on_client_connect)) {
if (0 != uv_listen((uv_stream_t*) &m_listener_handle, 8, _on_client_connect)) {
EXLOGE("[telnet] can not listen on %s:%d.\n", m_host_ip.c_str(), m_host_port);
return;
}
@ -114,7 +114,7 @@ void TelnetProxy::_thread_loop(void) {
}
// static
void TelnetProxy::_on_stop(void) {
void TelnetProxy::_on_stop() {
ExThreadBase::_on_stop();
if (m_is_running) {
@ -123,19 +123,18 @@ void TelnetProxy::_on_stop(void) {
}
// static
void TelnetProxy::_on_listener_closed(uv_handle_t *handle) {
TelnetProxy *_this = (TelnetProxy *) handle->data;
void TelnetProxy::_on_listener_closed(uv_handle_t* handle) {
auto _this = (TelnetProxy*) handle->data;
EXLOGV("[telnet] listener close.\n");
uv_close((uv_handle_t *) &_this->m_stop_handle, _on_stop_handle_closed);
// _this->_close_all_sessions();
uv_close((uv_handle_t*) &_this->m_stop_handle, _on_stop_handle_closed);
}
void TelnetProxy::clean_session() {
uv_async_send(&m_clean_session_handle);
}
void TelnetProxy::_close_all_sessions(void) {
void TelnetProxy::_close_all_sessions() {
ExThreadSmartLock locker(m_lock);
if (m_sessions.empty()) {
@ -143,26 +142,27 @@ void TelnetProxy::_close_all_sessions(void) {
return;
}
ts_telnet_sessions::iterator it = m_sessions.begin();
auto it = m_sessions.begin();
for (; it != m_sessions.end(); ++it) {
it->first->close(TP_SESS_STAT_ERR_RESET);
}
}
// static
void TelnetProxy::_on_clean_session_cb(uv_async_t *handle) {
TelnetProxy *_this = (TelnetProxy *) handle->data;
void TelnetProxy::_on_clean_session_cb(uv_async_t* handle) {
auto _this = (TelnetProxy*) handle->data;
// check closed session
ExThreadSmartLock locker(_this->m_lock);
ts_telnet_sessions::iterator it = _this->m_sessions.begin();
auto it = _this->m_sessions.begin();
for (; it != _this->m_sessions.end();) {
if (it->first->is_closed()) {
delete it->first;
_this->m_sessions.erase(it++);
EXLOGD("[telnet] - removed one session.\n");
} else {
}
else {
it++;
}
}
@ -177,29 +177,29 @@ void TelnetProxy::_on_clean_session_cb(uv_async_t *handle) {
//}
//static
void TelnetProxy::_on_stop_handle_closed(uv_handle_t *handle) {
TelnetProxy *_this = (TelnetProxy *) handle->data;
void TelnetProxy::_on_stop_handle_closed(uv_handle_t* handle) {
auto _this = (TelnetProxy*) handle->data;
_this->_close_all_sessions();
}
//static
void TelnetProxy::_on_stop_cb(uv_async_t *handle) {
TelnetProxy *_this = (TelnetProxy *) handle->data;
uv_close((uv_handle_t *) &_this->m_listener_handle, _on_listener_closed);
void TelnetProxy::_on_stop_cb(uv_async_t* handle) {
auto _this = (TelnetProxy*) handle->data;
uv_close((uv_handle_t*) &_this->m_listener_handle, _on_listener_closed);
}
// static
void TelnetProxy::_on_client_connect(uv_stream_t *server, int status) {
void TelnetProxy::_on_client_connect(uv_stream_t* server, int status) {
if (0 != status)
return;
TelnetProxy *_this = (TelnetProxy *) server->data;
auto _this = (TelnetProxy*) server->data;
_this->_on_accept(server);
}
bool TelnetProxy::_on_accept(uv_stream_t *server) {
TelnetSession *sess = new TelnetSession(this);
bool TelnetProxy::_on_accept(uv_stream_t* server) {
auto sess = new TelnetSession(this);
if (0 != uv_accept(server, sess->client()->stream_handle())) {
EXLOGE("[telnet] socket accept failed.\n");
@ -216,7 +216,7 @@ bool TelnetProxy::_on_accept(uv_stream_t *server) {
struct sockaddr sock_client;
int namelen = sizeof(sock_client);
if (0 == uv_tcp_getpeername(sess->client()->tcp_handle(), &sock_client, &namelen)) {
sockaddr_in *addrin = (sockaddr_in *) &sock_client;
auto addrin = (sockaddr_in*) &sock_client;
char ip[17] = {0};
if (0 == uv_ip4_name(addrin, ip, sizeof(ip))) {
char client_addr[64] = {0};
@ -238,5 +238,5 @@ bool TelnetProxy::_on_accept(uv_stream_t *server) {
}
void TelnetProxy::_close_clean_session_handle() {
uv_close((uv_handle_t *) &m_clean_session_handle, NULL);
uv_close((uv_handle_t*) &m_clean_session_handle, nullptr);
}

View File

@ -27,9 +27,9 @@ public:
void clean_session();
protected:
void _thread_loop();
void _thread_loop() override;
void _on_stop();
void _on_stop() override;
void _close_all_sessions();

View File

@ -1,197 +1,173 @@
#include "telnet_recorder.h"
static ex_u8 TPP_RECORD_MAGIC[4] = { 'T', 'P', 'P', 'R' };
static ex_u8 TPP_RECORD_MAGIC[4] = {'T', 'P', 'P', 'R'};
TppTelnetRec::TppTelnetRec()
{
m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
TppTelnetRec::TppTelnetRec() {
m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
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 = 0x04;
m_header_changed = false;
m_save_full_header = false;
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 = 0x04;
m_header_changed = false;
m_save_full_header = false;
m_file_info = NULL;
m_file_data = NULL;
m_file_cmd = NULL;
m_file_info = nullptr;
m_file_data = nullptr;
m_file_cmd = nullptr;
}
TppTelnetRec::~TppTelnetRec()
{
end();
TppTelnetRec::~TppTelnetRec() {
end();
}
bool TppTelnetRec::_on_begin(const TPP_CONNECT_INFO* info)
{
if (NULL == info)
return false;
m_head.basic.timestamp = (ex_u64)time(NULL);
m_head.basic.protocol_type = (ex_u16)info->protocol_type;
m_head.basic.protocol_sub_type = (ex_u16)info->protocol_sub_type;
m_head.basic.conn_port = (ex_u16)info->conn_port;
bool TppTelnetRec::_on_begin(const TPP_CONNECT_INFO* info) {
if (nullptr == info)
return false;
m_head.basic.timestamp = (ex_u64) time(nullptr);
m_head.basic.protocol_type = (ex_u16) info->protocol_type;
m_head.basic.protocol_sub_type = (ex_u16) info->protocol_sub_type;
m_head.basic.conn_port = (ex_u16) info->conn_port;
memcpy(m_head.basic.acc_username, info->acc_username, strlen(info->acc_username) >= 63 ? 63 : strlen(info->acc_username));
memcpy(m_head.basic.user_username, info->user_username, strlen(info->user_username) >= 63 ? 63 : strlen(info->user_username));
memcpy(m_head.basic.host_ip, info->host_ip, strlen(info->host_ip) >= 39 ? 39 : strlen(info->host_ip));
memcpy(m_head.basic.conn_ip, info->conn_ip, strlen(info->conn_ip) >= 39 ? 39 : strlen(info->conn_ip));
memcpy(m_head.basic.client_ip, info->client_ip, strlen(info->client_ip) >= 39 ? 39 : strlen(info->client_ip));
memcpy(m_head.basic.acc_username, info->acc_username, strlen(info->acc_username) >= 63 ? 63 : strlen(info->acc_username));
memcpy(m_head.basic.user_username, info->user_username, strlen(info->user_username) >= 63 ? 63 : strlen(info->user_username));
memcpy(m_head.basic.host_ip, info->host_ip, strlen(info->host_ip) >= 39 ? 39 : strlen(info->host_ip));
memcpy(m_head.basic.conn_ip, info->conn_ip, strlen(info->conn_ip) >= 39 ? 39 : strlen(info->conn_ip));
memcpy(m_head.basic.client_ip, info->client_ip, strlen(info->client_ip) >= 39 ? 39 : strlen(info->client_ip));
return true;
return true;
}
bool TppTelnetRec::_on_end()
{
// 如果还有剩下未写入的数据,写入文件中。
save_record();
bool TppTelnetRec::_on_end() {
// 如果还有剩下未写入的数据,写入文件中。
save_record();
if (m_file_info != NULL)
fclose(m_file_info);
if (m_file_data != NULL)
fclose(m_file_data);
if (m_file_cmd != NULL)
fclose(m_file_cmd);
if (m_file_info != nullptr)
fclose(m_file_info);
if (m_file_data != nullptr)
fclose(m_file_data);
if (m_file_cmd != nullptr)
fclose(m_file_cmd);
return true;
return true;
}
void TppTelnetRec::save_record() {
_save_to_data_file();
_save_to_cmd_file();
_save_to_data_file();
_save_to_cmd_file();
}
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size)
{
if (data == NULL || 0 == size)
return;
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size) {
if (data == nullptr || 0 == size)
return;
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
_save_to_data_file();
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
_save_to_data_file();
TS_RECORD_PKG pkg = { 0 };
pkg.type = type;
pkg.size = (ex_u32)size;
TS_RECORD_PKG pkg = {0};
pkg.type = type;
pkg.size = (ex_u32) 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;
}
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_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG));
m_cache.append(data, size);
}
// void TppTelnetRec::record_win_size(int width, int height)
// {
// m_head.basic.width = (ex_u16)width;
// m_head.basic.height = (ex_u16)height;
// m_save_full_header = true;
// m_header_changed = true;
// }
void TppTelnetRec::record_win_size_startup(int width, int height)
{
m_head.basic.width = (ex_u16)width;
m_head.basic.height = (ex_u16)height;
m_save_full_header = true;
void TppTelnetRec::record_win_size_startup(int width, int height) {
m_head.basic.width = (ex_u16) width;
m_head.basic.height = (ex_u16) height;
m_save_full_header = true;
}
void TppTelnetRec::record_win_size_change(int width, int height)
{
TS_RECORD_WIN_SIZE pkg = { 0 };
pkg.width = (ex_u16)width;
pkg.height = (ex_u16)height;
record(TS_RECORD_TYPE_TELNET_TERM_SIZE, (ex_u8*)&pkg, sizeof(TS_RECORD_WIN_SIZE));
void TppTelnetRec::record_win_size_change(int width, int height) {
TS_RECORD_WIN_SIZE pkg = {0};
pkg.width = (ex_u16) width;
pkg.height = (ex_u16) height;
record(TS_RECORD_TYPE_TELNET_TERM_SIZE, (ex_u8*) &pkg, sizeof(TS_RECORD_WIN_SIZE));
}
bool TppTelnetRec::_save_to_info_file() {
if (!m_header_changed)
return true;
if (!m_header_changed)
return true;
if (m_file_info == NULL) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
fname += L".tpr";
if (m_file_info == nullptr) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
fname += L".tpr";
m_file_info = ex_fopen(fname, L"wb");
if (NULL == m_file_info)
{
EXLOGE("[ssh] can not open record info-file for write.\n");
return false;
}
m_file_info = ex_fopen(fname, L"wb");
if (nullptr == m_file_info) {
EXLOGE("[ssh] can not open record info-file for write.\n");
return false;
}
// first time to save header, write whole header.
m_save_full_header = true;
}
// first time to save header, write whole header.
m_save_full_header = true;
}
fseek(m_file_info, 0L, SEEK_SET);
if (m_save_full_header) {
fwrite(&m_head, ts_record_header_size, 1, m_file_info);
fflush(m_file_info);
m_save_full_header = false;
}
else {
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
fflush(m_file_info);
}
fseek(m_file_info, 0L, SEEK_SET);
if (m_save_full_header) {
fwrite(&m_head, ts_record_header_size, 1, m_file_info);
fflush(m_file_info);
m_save_full_header = false;
}
else {
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
fflush(m_file_info);
}
return true;
return true;
}
bool TppTelnetRec::_save_to_data_file()
{
if (m_cache.size() == 0)
return true;
bool TppTelnetRec::_save_to_data_file() {
if (m_cache.size() == 0)
return true;
if (m_file_data == NULL) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
fname += L".dat";
if (m_file_data == nullptr) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
fname += L".dat";
m_file_data = ex_fopen(fname, L"wb");
if (NULL == m_file_data)
{
EXLOGE("[ssh] can not open record data-file for write.\n");
return false;
}
m_file_data = ex_fopen(fname, L"wb");
if (nullptr == m_file_data) {
EXLOGE("[ssh] can not open record data-file for write.\n");
return false;
}
m_header_changed = true;
}
m_header_changed = true;
}
fwrite(m_cache.data(), m_cache.size(), 1, m_file_data);
fflush(m_file_data);
m_cache.empty();
fwrite(m_cache.data(), m_cache.size(), 1, m_file_data);
fflush(m_file_data);
m_cache.empty();
return _save_to_info_file();
return _save_to_info_file();
}
bool TppTelnetRec::_save_to_cmd_file()
{
if (m_cmd_cache.size() == 0)
return true;
bool TppTelnetRec::_save_to_cmd_file() {
if (m_cmd_cache.size() == 0)
return true;
if (NULL == m_file_cmd) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
fname += L"-cmd.txt";
m_file_cmd = ex_fopen(fname, L"wb");
if (NULL == m_file_cmd)
{
EXLOGE("[ssh] can not open record cmd-file for write.\n");
return false;
}
if (nullptr == m_file_cmd) {
ex_wstr fname = m_base_path;
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
fname += L"-cmd.txt";
m_file_cmd = ex_fopen(fname, L"wb");
if (nullptr == m_file_cmd) {
EXLOGE("[ssh] can not open record cmd-file for write.\n");
return false;
}
m_header_changed = true;
}
m_header_changed = true;
}
fwrite(m_cmd_cache.data(), m_cmd_cache.size(), 1, m_file_cmd);
fflush(m_file_cmd);
m_cmd_cache.empty();
fwrite(m_cmd_cache.data(), m_cmd_cache.size(), 1, m_file_cmd);
fflush(m_file_cmd);
m_cmd_cache.empty();
return _save_to_info_file();
return _save_to_info_file();
}

View File

@ -3,52 +3,56 @@
#include "../../common/base_record.h"
#define TS_RECORD_TYPE_TELNET_TERM_SIZE 0x01 // 终端大小(行数与列数)
#define TS_RECORD_TYPE_TELNET_DATA 0x02 // 用于展示的数据内容
#define TS_RECORD_TYPE_TELNET_TERM_SIZE 0x01 // 终端大小(行数与列数)
#define TS_RECORD_TYPE_TELNET_DATA 0x02 // 用于展示的数据内容
#pragma pack(push,1)
#pragma pack(push, 1)
// 记录窗口大小改变的数据包
typedef struct TS_RECORD_WIN_SIZE
{
ex_u16 width;
ex_u16 height;
}TS_RECORD_WIN_SIZE;
// 记录窗口大小改变的数据包
typedef struct TS_RECORD_WIN_SIZE {
ex_u16 width;
ex_u16 height;
} TS_RECORD_WIN_SIZE;
#pragma pack(pop)
class TppTelnetRec : public TppRecBase
{
class TppTelnetRec : public TppRecBase {
public:
TppTelnetRec();
virtual ~TppTelnetRec();
TppTelnetRec();
virtual ~TppTelnetRec();
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_startup(int width, int height);
void record_win_size_change(int width, int height);
void record_win_size_startup(int width, int height);
void save_record();
void record_win_size_change(int width, int height);
void save_record();
protected:
bool _on_begin(const TPP_CONNECT_INFO* info);
bool _on_end();
bool _on_begin(const TPP_CONNECT_INFO* info) override;
bool _save_to_info_file();
bool _save_to_data_file();
bool _save_to_cmd_file();
bool _on_end() override;
bool _save_to_info_file();
bool _save_to_data_file();
bool _save_to_cmd_file();
protected:
TS_RECORD_HEADER m_head;
bool m_header_changed;
TS_RECORD_HEADER m_head;
bool m_header_changed;
MemBuffer m_cmd_cache;
MemBuffer m_cmd_cache;
bool m_save_full_header;
bool m_save_full_header;
FILE* m_file_info;
FILE* m_file_data;
FILE* m_file_cmd;
FILE* m_file_info;
FILE* m_file_data;
FILE* m_file_cmd;
};
#endif // __TELNET_RECORDER_H__

View File

@ -3,25 +3,25 @@
#include "tpp_env.h"
#include <teleport_const.h>
#define TELNET_IAC 0xFF
#define TELNET_DONT 0xFE
#define TELNET_DO 0xFD
#define TELNET_WONT 0xFC
#define TELNET_WILL 0xFB
#define TELNET_SB 0xFA
#define TELNET_SE 0xF0
#define TELNET_IAC 0xFF
#define TELNET_DONT 0xFE
#define TELNET_DO 0xFD
#define TELNET_WONT 0xFC
#define TELNET_WILL 0xFB
#define TELNET_SB 0xFA
#define TELNET_SE 0xF0
TelnetSession::TelnetSession(TelnetProxy *proxy) :
TelnetSession::TelnetSession(TelnetProxy* proxy) :
m_proxy(proxy),
m_conn_info(NULL) {
m_conn_info(nullptr) {
m_state = TP_SESS_STAT_RUNNING;
m_startup_win_size_recorded = false;
m_db_id = 0;
m_is_relay = false;
m_is_closed = false;
m_first_client_pkg = true;
m_last_access_timestamp = (ex_u32) time(NULL);
m_last_access_timestamp = (ex_u32) time(nullptr);
m_win_width = 0;
m_win_height = 0;
@ -43,7 +43,7 @@ TelnetSession::~TelnetSession() {
delete m_conn_client;
delete m_conn_server;
if (NULL != m_conn_info) {
if (nullptr != m_conn_info) {
g_telnet_env.free_connect_info(m_conn_info);
}
@ -102,7 +102,7 @@ bool TelnetSession::_on_session_end() {
return true;
}
uv_loop_t *TelnetSession::get_loop(void) {
uv_loop_t* TelnetSession::get_loop() {
return m_proxy->get_loop();
}
@ -110,47 +110,47 @@ void TelnetSession::close(int err_code) {
_do_close(err_code);
}
void TelnetSession::do_next(TelnetConn *conn, sess_state status) {
void TelnetSession::do_next(TelnetConn* conn, sess_state status) {
if (m_status < s_close)
m_status = status;
do_next(conn);
}
void TelnetSession::do_next(TelnetConn *conn) {
void TelnetSession::do_next(TelnetConn* conn) {
sess_state new_status;
ASSERT(m_status != s_dead);
switch (m_status) {
case s_noop:
return;
case s_noop:
return;
case s_client_connect:
new_status = _do_client_connect(conn);
break;
case s_client_connect:
new_status = _do_client_connect(conn);
break;
case s_negotiation_with_client:
new_status = _do_negotiation_with_client(conn);
break;
case s_server_connected:
new_status = _do_server_connected();
break;
case s_relay:
new_status = _do_relay(conn);
break;
case s_negotiation_with_client:
new_status = _do_negotiation_with_client(conn);
break;
case s_server_connected:
new_status = _do_server_connected();
break;
case s_relay:
new_status = _do_relay(conn);
break;
case s_close:
new_status = _do_close(m_state);
break;
case s_closing:
new_status = _do_check_closing();
break;
case s_all_conn_closed:
new_status = s_dead;
break;
default:
//UNREACHABLE();
return;
case s_close:
new_status = _do_close(m_state);
break;
case s_closing:
new_status = _do_check_closing();
break;
case s_all_conn_closed:
new_status = s_dead;
break;
default:
//UNREACHABLE();
return;
}
m_status = new_status;
@ -179,14 +179,16 @@ sess_state TelnetSession::_do_close(int state) {
m_state = TP_SESS_STAT_ERR_INTERNAL;
else
m_state = state;
} else {
}
else {
if (!m_is_relay)
_session_error(state);
m_state = state;
}
EXLOGV("[telnet] close session.\n");
EXLOGD("[telnet] _do_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
m_conn_server->state());
EXLOGD(
"[telnet] _do_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
m_conn_server->state());
m_conn_client->close();
m_conn_server->close();
@ -202,21 +204,22 @@ sess_state TelnetSession::_do_check_closing() {
}
void TelnetSession::on_conn_close() {
EXLOGD("[telnet] on_conn_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
m_conn_server->state());
EXLOGD(
"[telnet] on_conn_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
m_conn_server->state());
if (m_conn_client->state() == TELNET_CONN_STATE_FREE && m_conn_server->state() == TELNET_CONN_STATE_FREE) {
m_status = s_all_conn_closed;
do_next(m_conn_client);
}
}
sess_state TelnetSession::_do_client_connect(TelnetConn *conn) {
sess_state TelnetSession::_do_client_connect(TelnetConn* conn) {
// putty会率先发第一个包SecureCRT会通过脚本发第一个包
return _do_negotiation_with_client(conn);
}
sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
if (NULL == conn)
sess_state TelnetSession::_do_negotiation_with_client(TelnetConn* conn) {
if (nullptr == conn)
return s_negotiation_with_client;
if (0 == conn->data().size())
@ -225,7 +228,7 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
if (m_first_client_pkg) {
m_first_client_pkg = false;
MemBuffer &mbuf = conn->data();
MemBuffer& mbuf = conn->data();
if (mbuf.size() > 14 && 0 == memcmp(mbuf.data(), "session:", 8)) {
m_is_putty_mode = false;
@ -238,11 +241,12 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
break;
}
mbuf.append((ex_u8 *) "\x00", 1);
m_sid = (char *) mbuf.data();
mbuf.append((ex_u8*) "\x00", 1);
m_sid = (char*) mbuf.data();
return _do_connect_server();
} else {
}
else {
m_is_putty_mode = true;
}
}
@ -287,36 +291,44 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
if (s.get_u8() == TELNET_SE) {
have_SE = true;
break;
} else
}
else
return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
}
} else {
}
else {
ms_sub.put_u8(ch_sub);
}
}
if (!have_SE)
return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
} else if (ch_cmd == TELNET_DONT) {
}
else if (ch_cmd == TELNET_DONT) {
ms_resp.put_u8(TELNET_IAC);
ms_resp.put_u8(TELNET_WONT);
ms_resp.put_u8(s.get_u8());
} else if (ch_cmd == TELNET_DO) {
}
else if (ch_cmd == TELNET_DO) {
ms_resp.put_u8(TELNET_IAC);
ms_resp.put_u8(TELNET_WILL);
ms_resp.put_u8(s.get_u8());
} else if (ch_cmd == TELNET_WONT) {
}
else if (ch_cmd == TELNET_WONT) {
ms_resp.put_u8(TELNET_IAC);
ms_resp.put_u8(TELNET_DONT);
ms_resp.put_u8(s.get_u8());
} else if (ch_cmd == TELNET_WILL) {
}
else if (ch_cmd == TELNET_WILL) {
ms_resp.put_u8(TELNET_IAC);
ms_resp.put_u8(TELNET_DO);
ms_resp.put_u8(s.get_u8());
} else {
}
else {
s.skip(1);
}
} else {
}
else {
ms_msg.put_u8(ch);
}
}
@ -350,7 +362,7 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
0x03, 0x53, 0x46, 0x55, 0x54, 0x4c, 0x4e, 0x54, 0x56, 0x45, 0x52, 0x03, 0x53, 0x46, 0x55, 0x54,
0x4c, 0x4e, 0x54, 0x4d, 0x4f, 0x44, 0x45, 0xff, 0xf0
};
m_conn_client->send((ex_u8 *) _d, sizeof(_d));
m_conn_client->send((ex_u8*) _d, sizeof(_d));
return s_negotiation_with_client;
}
@ -366,8 +378,8 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
break;
}
mbuf_sub.append((ex_u8 *) "\x00", 1);
m_sid = (char *) mbuf_sub.data();
mbuf_sub.append((ex_u8*) "\x00", 1);
m_sid = (char*) mbuf_sub.data();
}
}
@ -384,10 +396,11 @@ sess_state TelnetSession::_do_connect_server() {
m_conn_info = g_telnet_env.get_connect_info(m_sid.c_str());
if (NULL == m_conn_info) {
if (nullptr == m_conn_info) {
EXLOGE("[telnet] no such session: %s\n", m_sid.c_str());
return _do_close(TP_SESS_STAT_ERR_SESSION);
} else {
}
else {
m_conn_ip = m_conn_info->conn_ip;
m_conn_port = m_conn_info->conn_port;
m_acc_name = m_conn_info->acc_username;
@ -454,7 +467,7 @@ sess_state TelnetSession::_do_server_connected() {
char buf[512] = {0};
const char *auth_mode = NULL;
const char* auth_mode = nullptr;
if (m_conn_info->auth_type == TP_AUTH_TYPE_PASSWORD)
auth_mode = "password";
else if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE)
@ -464,29 +477,30 @@ sess_state TelnetSession::_do_server_connected() {
ex_astr line(w, '=');
snprintf(buf, sizeof(buf),
"\r\n"\
snprintf(
buf, sizeof(buf),
"\r\n"\
"%s\r\n"\
"Teleport TELNET Bastion Server...\r\n"\
" - teleport to %s:%d\r\n"\
" - authroized by %s\r\n"\
"%s\r\n"\
"\r\n\r\n",
line.c_str(),
m_conn_ip.c_str(),
m_conn_port, auth_mode,
line.c_str()
line.c_str(),
m_conn_ip.c_str(),
m_conn_port, auth_mode,
line.c_str()
);
m_conn_client->send((ex_u8 *) buf, strlen(buf));
m_conn_client->send((ex_u8*) buf, strlen(buf));
if (m_is_putty_mode) {
if (m_conn_info->auth_type != TP_AUTH_TYPE_NONE) {
ex_astr login_info = "login: ";
login_info += m_conn_info->acc_username;
login_info += "\r\n";
m_conn_client->send((ex_u8 *) login_info.c_str(), login_info.length());
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, (ex_u8 *) login_info.c_str(), login_info.length());
m_conn_client->send((ex_u8*) login_info.c_str(), login_info.length());
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, (ex_u8*) login_info.c_str(), login_info.length());
}
ex_u8 _d[] = "\xff\xfb\x1f\xff\xfb\x20\xff\xfb\x18\xff\xfb\x27\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03";
@ -496,10 +510,10 @@ sess_state TelnetSession::_do_server_connected() {
return s_relay;
}
sess_state TelnetSession::_do_relay(TelnetConn *conn) {
m_last_access_timestamp = (ex_u32) time(NULL);
sess_state TelnetSession::_do_relay(TelnetConn* conn) {
m_last_access_timestamp = (ex_u32) time(nullptr);
TelnetSession *_this = conn->session();
TelnetSession* _this = conn->session();
bool is_processed = false;
if (conn->is_server_side()) {
@ -528,7 +542,8 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
m_conn_server->send(m_conn_client->data().data(), m_conn_client->data().size());
m_conn_client->data().empty();
} else {
}
else {
// EXLOG_BIN(m_conn_server->data().data(), m_conn_server->data().size(), "--> server:");
// 收到了服务端返回的数据
@ -536,15 +551,17 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
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->_parse_find_and_send(m_conn_server, m_conn_client, _this->m_username_prompt.c_str(),
_this->m_acc_name.c_str())) {
if (_this->_parse_find_and_send(
m_conn_server, m_conn_client, _this->m_username_prompt.c_str(),
_this->m_acc_name.c_str())) {
// _this->m_username_sent = true;
is_processed = true;
}
}
if (!_this->m_password_sent && _this->m_password_prompt.length() > 0) {
if (_this->_parse_find_and_send(m_conn_server, m_conn_client, _this->m_password_prompt.c_str(),
_this->m_acc_secret.c_str())) {
if (_this->_parse_find_and_send(
m_conn_server, m_conn_client, _this->m_password_prompt.c_str(),
_this->m_acc_secret.c_str())) {
_this->m_username_sent = true;
_this->m_password_sent = true;
_this->m_username_sent = true;
@ -564,8 +581,10 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
return s_relay;
}
bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn_remote, const char *find,
const char *send) {
bool TelnetSession::_parse_find_and_send(
TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find,
const char* send
) {
// EXLOGV("find prompt and send: [%s] => [%s]\n", find, send);
// EXLOG_BIN(conn_recv->data().data(), conn_recv->data().size(), "find prompt in data:");
@ -583,8 +602,8 @@ bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn
MemBuffer mbuf_msg;
mbuf_msg.reserve(128);
mbuf_msg.append((ex_u8 *) send, send_len);
mbuf_msg.append((ex_u8 *) "\x0d\x0a", 2);
mbuf_msg.append((ex_u8*) send, send_len);
mbuf_msg.append((ex_u8*) "\x0d\x0a", 2);
// EXLOG_BIN(mbuf_msg.data(), mbuf_msg.size(), "find prompt and send:");
conn_recv->send(mbuf_msg.data(), mbuf_msg.size());
return true;
@ -668,7 +687,7 @@ bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn
return false;
}
bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *conn_remote) {
bool TelnetSession::_putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote) {
bool replaced = false;
MemBuffer mbuf_msg;
@ -701,7 +720,8 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
if (s.get_u8() == TELNET_SE) {
have_SE = true;
break;
} else
}
else
return false;
}
}
@ -724,20 +744,22 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
ms_msg.put_u8(TELNET_IAC);
ms_msg.put_u8(TELNET_SB);
ms_msg.put_bin((ex_u8 *) "\x27\x00\x00\x55\x53\x45\x52\x01", 8);
ms_msg.put_bin((ex_u8*) "\x27\x00\x00\x55\x53\x45\x52\x01", 8);
ms_msg.put_bin((ex_u8 *) m_acc_name.c_str(), m_acc_name.length());
ms_msg.put_bin((ex_u8*) m_acc_name.c_str(), m_acc_name.length());
ms_msg.put_u8(TELNET_IAC);
ms_msg.put_u8(TELNET_SE);
replaced = true;
} else {
}
else {
ms_msg.put_u8(ch);
ms_msg.put_u8(ch_cmd);
ms_msg.put_u8(s.get_u8());
}
} else {
}
else {
ms_msg.put_u8(ch);
}
}
@ -750,7 +772,7 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
return false;
}
bool TelnetSession::_parse_win_size(TelnetConn *conn) {
bool TelnetSession::_parse_win_size(TelnetConn* conn) {
if (conn->data().size() < 9)
return false;
if (conn->data().data()[0] != TELNET_IAC)
@ -777,7 +799,8 @@ bool TelnetSession::_parse_win_size(TelnetConn *conn) {
if (s.get_u8() == TELNET_SE) {
have_SE = true;
break;
} else
}
else
return false;
}
}

View File

@ -7,115 +7,134 @@
#include "telnet_conn.h"
enum sess_state {
s_noop, // 什么都不做,等特定状态满足
s_noop, // 什么都不做,等特定状态满足
s_client_connect, // 客户端连接
s_negotiation_with_client, // 与客户端进行握手直到得到客户端发来的登录用户名其实是SessionID
s_client_connect, // 客户端连接
s_negotiation_with_client, // 与客户端进行握手直到得到客户端发来的登录用户名其实是SessionID
s_server_connected, // 成功连接上服务器了
s_server_connected, // 成功连接上服务器了
s_relay, // 正常转发数据
s_relay, // 正常转发数据
s_close, // 关闭会话
s_closing, // 正在关闭双方连接
s_all_conn_closed, // 两端均已关闭
s_close, // 关闭会话
s_closing, // 正在关闭双方连接
s_all_conn_closed, // 两端均已关闭
s_dead // 可以销毁此会话了
s_dead // 可以销毁此会话了
};
class TelnetProxy;
class TelnetSession
{
class TelnetSession {
public:
TelnetSession(TelnetProxy* proxy);
virtual ~TelnetSession();
TelnetSession(TelnetProxy* proxy);
TelnetProxy* get_proxy() { return m_proxy; }
virtual ~TelnetSession();
TelnetConn* client() { return m_conn_client; }
TelnetConn* server() { return m_conn_server; }
uv_loop_t* get_loop();
TelnetProxy* get_proxy() { return m_proxy; }
void set_state(int state) { m_state = state; }
void close(int err_code);
void on_conn_close();
TelnetConn* client() { return m_conn_client; }
void do_next(TelnetConn* conn);
void do_next(TelnetConn* conn, sess_state status);
TelnetConn* server() { return m_conn_server; }
// save record cache into file. be called per 5 seconds.
void save_record();
void record(ex_u8 type, const ex_u8* data, size_t size) {
m_rec.record(type, data, size);
}
//
void check_noop_timeout(ex_u32 t_now, ex_u32 timeout);
const ex_astr& sid() { return m_sid; }
uv_loop_t* get_loop();
void client_addr(const char* addr) { m_client_addr = addr; }
const char* client_addr() const { return m_client_addr.c_str(); }
void set_state(int state) { m_state = state; }
bool is_relay() { return m_is_relay; }
bool is_closed() { return m_is_closed; }
void close(int err_code);
void on_conn_close();
void do_next(TelnetConn* conn);
void do_next(TelnetConn* conn, sess_state status);
// save record cache into file. be called per 5 seconds.
void save_record();
void record(ex_u8 type, const ex_u8* data, size_t size) {
m_rec.record(type, data, size);
}
//
void check_noop_timeout(ex_u32 t_now, ex_u32 timeout);
const ex_astr& sid() { return m_sid; }
void client_addr(const char* addr) { m_client_addr = addr; }
const char* client_addr() const { return m_client_addr.c_str(); }
bool is_relay() const { return m_is_relay; }
bool is_closed() const { return m_is_closed; }
protected:
// 继承自 TppSessionBase
bool _on_session_begin();
bool _on_session_end();
void _session_error(int err_code);
// 继承自 TppSessionBase
bool _on_session_begin();
bool _on_session_end();
void _session_error(int err_code);
private:
sess_state _do_client_connect(TelnetConn* conn);
sess_state _do_negotiation_with_client(TelnetConn* conn);
sess_state _do_connect_server();
sess_state _do_server_connected();
sess_state _do_relay(TelnetConn* conn);
sess_state _do_close(int err_code);
sess_state _do_check_closing();
sess_state _do_client_connect(TelnetConn* conn);
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
bool _putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
bool _parse_win_size(TelnetConn* conn);
sess_state _do_negotiation_with_client(TelnetConn* conn);
sess_state _do_connect_server();
sess_state _do_server_connected();
sess_state _do_relay(TelnetConn* conn);
sess_state _do_close(int err_code);
sess_state _do_check_closing();
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
bool _putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
bool _parse_win_size(TelnetConn* conn);
private:
int m_state;
int m_state;
TPP_CONNECT_INFO* m_conn_info;
bool m_startup_win_size_recorded;
int m_db_id;
TPP_CONNECT_INFO* m_conn_info;
bool m_startup_win_size_recorded;
int m_db_id;
bool m_first_client_pkg;
bool m_is_relay; // 是否进入relay模式了只有进入relay模式才会有录像存在
bool m_is_closed;
ex_u32 m_last_access_timestamp;
bool m_first_client_pkg;
bool m_is_relay; // 是否进入relay模式了只有进入relay模式才会有录像存在
bool m_is_closed;
ex_u32 m_last_access_timestamp;
TppTelnetRec m_rec;
int m_win_width;
int m_win_height;
TppTelnetRec m_rec;
int m_win_width;
int m_win_height;
TelnetProxy* m_proxy;
TelnetConn* m_conn_client; // 与真正客户端通讯的连接(自身作为服务端)
TelnetConn* m_conn_server; // 与真正服务端通讯的连接(自身作为客户端)
TelnetProxy* m_proxy;
TelnetConn* m_conn_client; // 与真正客户端通讯的连接(自身作为服务端)
TelnetConn* m_conn_server; // 与真正服务端通讯的连接(自身作为客户端)
ExThreadLock m_lock;
ExThreadLock m_lock;
ex_astr m_sid;
ex_astr m_conn_ip;
ex_u16 m_conn_port;
ex_astr m_acc_name;
ex_astr m_acc_secret;
ex_astr m_username_prompt;
ex_astr m_password_prompt;
ex_astr m_sid;
ex_astr m_conn_ip;
ex_u16 m_conn_port;
ex_astr m_acc_name;
ex_astr m_acc_secret;
ex_astr m_username_prompt;
ex_astr m_password_prompt;
sess_state m_status;
ex_astr m_client_addr;
sess_state m_status;
ex_astr m_client_addr;
bool m_is_putty_mode;
//bool m_is_putty_eat_username;
bool m_is_putty_mode;
bool m_username_sent;
bool m_password_sent;
bool m_username_sent;
bool m_password_sent;
};
#endif // __TELNET_SESSION_H__

View File

@ -2,32 +2,30 @@
TppTelnetEnv g_telnet_env;
TppTelnetEnv::TppTelnetEnv()
{}
TppTelnetEnv::TppTelnetEnv() = default;
TppTelnetEnv::~TppTelnetEnv()
{}
TppTelnetEnv::~TppTelnetEnv() = default;
bool TppTelnetEnv::_on_init(TPP_INIT_ARGS* args) {
ex_path_join(replay_path, false, L"telnet", NULL);
ex_path_join(replay_path, false, L"telnet", nullptr);
ExIniSection* ps = args->cfg->GetSection(L"protocol-telnet");
if (NULL == ps) {
EXLOGE("[telnet] invalid config(2).\n");
return false;
}
ExIniSection* ps = args->cfg->GetSection(L"protocol-telnet");
if (nullptr == ps) {
EXLOGE("[telnet] invalid config(2).\n");
return false;
}
ex_wstr tmp;
if (!ps->GetStr(L"bind-ip", tmp)) {
bind_ip = TS_TELNET_PROXY_HOST;
}
else {
ex_wstr2astr(tmp, bind_ip);
}
ex_wstr tmp;
if (!ps->GetStr(L"bind-ip", tmp)) {
bind_ip = TS_TELNET_PROXY_HOST;
}
else {
ex_wstr2astr(tmp, bind_ip);
}
if (!ps->GetInt(L"bind-port", bind_port)) {
bind_port = TS_TELNET_PROXY_PORT;
}
if (!ps->GetInt(L"bind-port", bind_port)) {
bind_port = TS_TELNET_PROXY_PORT;
}
return true;
return true;
}

View File

@ -7,14 +7,14 @@ class TppTelnetEnv : public TppEnvBase
{
public:
TppTelnetEnv();
~TppTelnetEnv();
virtual ~TppTelnetEnv();
public:
ex_astr bind_ip;
int bind_port;
private:
bool _on_init(TPP_INIT_ARGS* args);
bool _on_init(TPP_INIT_ARGS* args) override;
};
extern TppTelnetEnv g_telnet_env;

View File

@ -33,17 +33,7 @@ TPP_API void tpp_timer(void) {
g_telnet_proxy.timer();
}
// TPP_API void tpp_set_cfg(TPP_SET_CFG_ARGS* cfg_args) {
// g_telnet_proxy.set_cfg(cfg_args);
// }
static ex_rv _set_runtime_config(const char* param) {
// Json::Value jp;
// Json::Reader jreader;
//
// if (!jreader.parse(param, jp))
static ex_rv tpp_cmd_set_runtime_config(const char* param) {
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
@ -67,11 +57,7 @@ static ex_rv _set_runtime_config(const char* param) {
return TPE_PARAM;
}
static ex_rv _kill_sessions(const char* param) {
// Json::Value jp;
// Json::Reader jreader;
//
// if (!jreader.parse(param, jp))
static ex_rv tpp_cmd_kill_sessions(const char* param) {
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
@ -102,16 +88,14 @@ static ex_rv _kill_sessions(const char* param) {
TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) {
switch (cmd) {
case TPP_CMD_SET_RUNTIME_CFG:
if (param == NULL || strlen(param) == 0)
if (param == nullptr || strlen(param) == 0)
return TPE_PARAM;
return tpp_cmd_set_runtime_config(param);
case TPP_CMD_KILL_SESSIONS:
if (param == NULL || strlen(param) == 0)
if (param == nullptr || strlen(param) == 0)
return TPE_PARAM;
return tpp_cmd_kill_sessions(param);
default:
return TPE_UNKNOWN_CMD;
}
return TPE_NOT_IMPLEMENT;
}