mirror of https://github.com/tp4a/teleport
实现:运维授权策略中,“连接控制->RDP选项”设置的选项可以起作用了。
parent
1657622385
commit
24baf11273
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,27 @@
|
|||
#define TP_SESS_STAT_ERR_START_IO 108 // 会话结束,因为网络中断
|
||||
|
||||
|
||||
//=======================================================
|
||||
// 授权标记
|
||||
//=======================================================
|
||||
#define TP_FLAG_ALL 0xFFFFFFFF
|
||||
// 会话记录相关
|
||||
#define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放)
|
||||
#define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控
|
||||
// RDP相关
|
||||
#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面
|
||||
#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板
|
||||
#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射
|
||||
#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP(尚未实现)
|
||||
#define TP_FLAG_RDP_CONSOLE 0x00001000 //允许连接到管理员会话(RDP的console选项)
|
||||
// SSH相关
|
||||
#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL
|
||||
#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP
|
||||
#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发(尚未实现)
|
||||
#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令(尚未实现)
|
||||
#define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.)
|
||||
|
||||
|
||||
//=======================================================
|
||||
// 错误值
|
||||
//=======================================================
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct TPP_CONNECT_INFO
|
|||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
}TPP_CONNECT_INFO;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid)
|
|||
info->protocol_type = sinfo.protocol_type;
|
||||
info->protocol_sub_type = sinfo.protocol_sub_type;
|
||||
info->protocol_flag = sinfo.protocol_flag;
|
||||
info->record_flag = sinfo.record_flag;
|
||||
info->auth_type= sinfo.auth_type;
|
||||
|
||||
return info;
|
||||
|
|
|
@ -87,6 +87,7 @@ bool TsSessionManager::get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& inf
|
|||
info.protocol_type = it->second->protocol_type;
|
||||
info.protocol_sub_type = it->second->protocol_sub_type;
|
||||
info.protocol_flag = it->second->protocol_flag;
|
||||
info.record_flag = it->second->record_flag;
|
||||
info.auth_type = it->second->auth_type;
|
||||
|
||||
it->second->ref_count++;
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef struct TS_CONNECT_INFO
|
|||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
|
||||
int ref_count;// 这个连接信息的引用计数,如果创建的连接信息从来未被使用,则超过30秒后自动销毁
|
||||
|
|
|
@ -83,9 +83,11 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
EXLOGE("connection info: need `protocol_sub_type`.\n");
|
||||
if(!_jret["auth_type"].isInt())
|
||||
EXLOGE("connection info: need `auth_type`.\n");
|
||||
if(!_jret["protocol_flag"].isInt())
|
||||
EXLOGE("connection info: need `protocol_flag`.\n");
|
||||
if(!_jret["_enc"].isInt())
|
||||
if (!_jret["protocol_flag"].isUInt())
|
||||
EXLOGE("connection info: need `protocol_flag`.\n");
|
||||
if (!_jret["record_flag"].isUInt())
|
||||
EXLOGE("connection info: need `record_flag`.\n");
|
||||
if (!_jret["_enc"].isInt())
|
||||
EXLOGE("connection info: need `_enc`.\n");
|
||||
if(!_jret["user_username"].isString())
|
||||
EXLOGE("connection info: need `user_username`.\n");
|
||||
|
@ -112,7 +114,8 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
|| !_jret["protocol_type"].isInt()
|
||||
|| !_jret["protocol_sub_type"].isInt()
|
||||
|| !_jret["auth_type"].isInt()
|
||||
|| !_jret["protocol_flag"].isInt()
|
||||
|| !_jret["protocol_flag"].isUInt()
|
||||
|| !_jret["record_flag"].isUInt()
|
||||
|| !_jret["_enc"].isInt()
|
||||
|
||||
|| !_jret["user_username"].isString()
|
||||
|
@ -145,6 +148,7 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
int protocol_sub_type = 0;
|
||||
int auth_type = 0;
|
||||
int protocol_flag = 0;
|
||||
int record_flag = 0;
|
||||
bool _enc;
|
||||
|
||||
user_id = _jret["user_id"].asInt();
|
||||
|
@ -161,7 +165,8 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
password_prompt = _jret["password_prompt"].asString();
|
||||
protocol_type = _jret["protocol_type"].asInt();
|
||||
protocol_sub_type = _jret["protocol_sub_type"].asInt();
|
||||
protocol_flag = _jret["protocol_flag"].asInt();
|
||||
protocol_flag = _jret["protocol_flag"].asUInt();
|
||||
record_flag = _jret["record_flag"].asUInt();
|
||||
auth_type = _jret["auth_type"].asInt();
|
||||
_enc = _jret["_enc"].asBool();
|
||||
|
||||
|
@ -204,6 +209,7 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
info.protocol_sub_type = protocol_sub_type;
|
||||
info.auth_type = auth_type;
|
||||
info.protocol_flag = protocol_flag;
|
||||
info.record_flag = record_flag;
|
||||
|
||||
return TPE_OK;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "telnet_conn.h"
|
||||
#include "telnet_session.h"
|
||||
#include "../../common/ts_memstream.h"
|
||||
#include "../../common/ts_const.h"
|
||||
#include <teleport_const.h>
|
||||
|
||||
#include "telnet_conn.h"
|
||||
#include "telnet_session.h"
|
||||
#include "../../common/ts_memstream.h"
|
||||
#include "../../common/ts_const.h"
|
||||
#include <teleport_const.h>
|
||||
|
||||
ex_astr _uv_str_error(int retcode)
|
||||
{
|
||||
ex_astr err;
|
||||
|
@ -11,262 +11,262 @@ ex_astr _uv_str_error(int retcode)
|
|||
err += ":";
|
||||
err += uv_strerror(retcode);
|
||||
return std::move(err);
|
||||
}
|
||||
|
||||
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 {
|
||||
m_name = "tp<->srv";
|
||||
m_state = TELNET_CONN_STATE_FREE;
|
||||
}
|
||||
|
||||
m_timer_running = false;
|
||||
|
||||
uv_tcp_init(sess->get_loop(), &m_handle);
|
||||
m_handle.data = this;
|
||||
}
|
||||
|
||||
TelnetConn::~TelnetConn() {
|
||||
}
|
||||
|
||||
bool TelnetConn::start_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);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TelnetConn::close() {
|
||||
if (m_state == TELNET_CONN_STATE_FREE || m_state == TELNET_CONN_STATE_CLOSING)
|
||||
return;
|
||||
|
||||
if (m_timer_running) {
|
||||
m_timer_running = false;
|
||||
uv_timer_stop(&m_timer_connect_timeout);
|
||||
|
||||
EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
|
||||
m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close(handle(), NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uv_read_stop((uv_stream_t*)&m_handle);
|
||||
uv_close(handle() , _uv_on_closed);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
|
||||
TelnetConn *_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);
|
||||
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;
|
||||
|
||||
if (nread == 0) {
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
else if (nread < 0) {
|
||||
free(buf->base);
|
||||
|
||||
if (nread == UV_EOF)
|
||||
EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
|
||||
else if(nread == UV_ECONNRESET)
|
||||
EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
|
||||
else
|
||||
EXLOGD("[telnet] [%s] [recv] %s.\n", _this->m_name, _uv_str_error(nread).c_str());
|
||||
|
||||
|
||||
// if (nread == -4077)
|
||||
// EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
|
||||
// else if (nread == -104)
|
||||
// EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
|
||||
// else
|
||||
// EXLOGD("[telnet] [%s] [recv] nread=%d.\n", _this->m_name, nread);
|
||||
|
||||
_this->m_session->close(TP_SESS_STAT_END);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
free(buf->base);
|
||||
|
||||
_this->m_session->do_next(_this);
|
||||
}
|
||||
|
||||
bool TelnetConn::send(MemBuffer &mbuf) {
|
||||
return _raw_send(mbuf.data(), mbuf.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) {
|
||||
// #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));
|
||||
|
||||
ex_u8 *_data = (ex_u8 *) calloc(1, size);
|
||||
if (NULL == _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;
|
||||
_buf->len = size;
|
||||
|
||||
w->data = _buf;
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void TelnetConn::_on_send_done(uv_write_t *req, int status) {
|
||||
uv_buf_t *_buf = (uv_buf_t *) req->data;
|
||||
free(_buf->base);
|
||||
free(_buf);
|
||||
free(req);
|
||||
|
||||
if (status == UV_ECANCELED) {
|
||||
EXLOGE("[telnet] _on_send_done() got UV_ECANCELED.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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. %s:%d\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);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
EXLOGV("[telnet] [%s] [%s] try to connect to real TELNET server at %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));
|
||||
conn_req->data = this;
|
||||
|
||||
// 设置一个超时回调,如果超时发生时连接尚未完成,就报错
|
||||
uv_timer_init(m_session->get_loop(), &m_timer_connect_timeout);
|
||||
m_timer_connect_timeout.data = this;
|
||||
|
||||
#ifdef EX_DEBUG
|
||||
uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 5000, 0);
|
||||
#else
|
||||
uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 10000, 0);
|
||||
#endif
|
||||
|
||||
m_timer_running = true;
|
||||
|
||||
//m_is_connecting = true;
|
||||
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) {
|
||||
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, _uv_on_timer_connect_timeout_closed);
|
||||
|
||||
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;
|
||||
|
||||
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, _this->_uv_on_timer_connect_timeout_closed);
|
||||
}
|
||||
|
||||
// 如果在连接成功之前就超时了,则关闭连接
|
||||
EXLOGE("[telnet] [%s] timeout when connect to real TELNET server, cancel connection.\n", _this->m_name);
|
||||
_this->m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close(_this->handle(), _uv_on_closed);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *)handle->data;
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
|
||||
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
|
||||
_this->m_handle.data = _this;
|
||||
|
||||
_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;
|
||||
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, _this->_uv_on_timer_connect_timeout_closed);
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
EXLOGE("[telnet] [%s] cannot connect to real TELNET server. %s\n", _this->m_name, uv_strerror(status));
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
_this->m_session->close(TP_SESS_STAT_ERR_CONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
EXLOGW("[telnet] [%s] real TELNET server connected.\n", _this->m_session->client_addr());
|
||||
_this->m_state = TELNET_CONN_STATE_CONNECTED;
|
||||
|
||||
if (!_this->start_recv()) {
|
||||
_this->m_session->close(TP_SESS_STAT_ERR_IO);
|
||||
return;
|
||||
}
|
||||
|
||||
_this->m_session->do_next(_this, s_server_connected);
|
||||
}
|
||||
|
||||
//static
|
||||
void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
m_name = "tp<->srv";
|
||||
m_state = TELNET_CONN_STATE_FREE;
|
||||
}
|
||||
|
||||
m_timer_running = false;
|
||||
|
||||
uv_tcp_init(sess->get_loop(), &m_handle);
|
||||
m_handle.data = this;
|
||||
}
|
||||
|
||||
TelnetConn::~TelnetConn() {
|
||||
}
|
||||
|
||||
bool TelnetConn::start_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);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TelnetConn::close() {
|
||||
if (m_state == TELNET_CONN_STATE_FREE || m_state == TELNET_CONN_STATE_CLOSING)
|
||||
return;
|
||||
|
||||
if (m_timer_running) {
|
||||
m_timer_running = false;
|
||||
uv_timer_stop(&m_timer_connect_timeout);
|
||||
|
||||
EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
|
||||
m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close(handle(), NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uv_read_stop((uv_stream_t*)&m_handle);
|
||||
uv_close(handle() , _uv_on_closed);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
|
||||
TelnetConn *_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);
|
||||
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;
|
||||
|
||||
if (nread == 0) {
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
else if (nread < 0) {
|
||||
free(buf->base);
|
||||
|
||||
if (nread == UV_EOF)
|
||||
EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
|
||||
else if(nread == UV_ECONNRESET)
|
||||
EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
|
||||
else
|
||||
EXLOGD("[telnet] [%s] [recv] %s.\n", _this->m_name, _uv_str_error(nread).c_str());
|
||||
|
||||
|
||||
// if (nread == -4077)
|
||||
// EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
|
||||
// else if (nread == -104)
|
||||
// EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
|
||||
// else
|
||||
// EXLOGD("[telnet] [%s] [recv] nread=%d.\n", _this->m_name, nread);
|
||||
|
||||
_this->m_session->close(TP_SESS_STAT_END);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
free(buf->base);
|
||||
|
||||
_this->m_session->do_next(_this);
|
||||
}
|
||||
|
||||
bool TelnetConn::send(MemBuffer &mbuf) {
|
||||
return _raw_send(mbuf.data(), mbuf.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) {
|
||||
// #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));
|
||||
|
||||
ex_u8 *_data = (ex_u8 *) calloc(1, size);
|
||||
if (NULL == _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;
|
||||
_buf->len = size;
|
||||
|
||||
w->data = _buf;
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void TelnetConn::_on_send_done(uv_write_t *req, int status) {
|
||||
uv_buf_t *_buf = (uv_buf_t *) req->data;
|
||||
free(_buf->base);
|
||||
free(_buf);
|
||||
free(req);
|
||||
|
||||
if (status == UV_ECANCELED) {
|
||||
EXLOGE("[telnet] _on_send_done() got UV_ECANCELED.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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. %s:%d\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);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
EXLOGV("[telnet] [%s] [%s] try to connect to real TELNET server at %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));
|
||||
conn_req->data = this;
|
||||
|
||||
// 设置一个超时回调,如果超时发生时连接尚未完成,就报错
|
||||
uv_timer_init(m_session->get_loop(), &m_timer_connect_timeout);
|
||||
m_timer_connect_timeout.data = this;
|
||||
|
||||
#ifdef EX_DEBUG
|
||||
uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 5000, 0);
|
||||
#else
|
||||
uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 10000, 0);
|
||||
#endif
|
||||
|
||||
m_timer_running = true;
|
||||
|
||||
//m_is_connecting = true;
|
||||
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) {
|
||||
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, _uv_on_timer_connect_timeout_closed);
|
||||
|
||||
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;
|
||||
|
||||
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, _this->_uv_on_timer_connect_timeout_closed);
|
||||
}
|
||||
|
||||
// 如果在连接成功之前就超时了,则关闭连接
|
||||
EXLOGE("[telnet] [%s] timeout when connect to real TELNET server, cancel connection.\n", _this->m_name);
|
||||
_this->m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close(_this->handle(), _uv_on_closed);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *)handle->data;
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
|
||||
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
|
||||
_this->m_handle.data = _this;
|
||||
|
||||
_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;
|
||||
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, _this->_uv_on_timer_connect_timeout_closed);
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
EXLOGE("[telnet] [%s] cannot connect to real TELNET server. %s\n", _this->m_name, uv_strerror(status));
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
_this->m_session->close(TP_SESS_STAT_ERR_CONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
EXLOGW("[telnet] [%s] real TELNET server connected.\n", _this->m_session->client_addr());
|
||||
_this->m_state = TELNET_CONN_STATE_CONNECTED;
|
||||
|
||||
if (!_this->start_recv()) {
|
||||
_this->m_session->close(TP_SESS_STAT_ERR_IO);
|
||||
return;
|
||||
}
|
||||
|
||||
_this->m_session->do_next(_this, s_server_connected);
|
||||
}
|
||||
|
||||
//static
|
||||
void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
|
||||
}
|
||||
|
|
|
@ -108,7 +108,8 @@ $assist.do_teleport = function (args, func_success, func_error) {
|
|||
// rdp_console: args.rdp_console,
|
||||
session_id: session_id,
|
||||
protocol_type: parseInt(args.protocol_type),
|
||||
protocol_sub_type: parseInt(args.protocol_sub_type)
|
||||
protocol_sub_type: parseInt(args.protocol_sub_type),
|
||||
protocol_flag: parseInt(ret.data.protocol_flag)
|
||||
};
|
||||
|
||||
if(args.protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
|
|
|
@ -131,14 +131,29 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
if err != TPE_OK:
|
||||
return self.write_json(err)
|
||||
|
||||
policy_id = ops_auth['p_id']
|
||||
acc_id = ops_auth['a_id']
|
||||
host_id = ops_auth['h_id']
|
||||
|
||||
err, policy_info = ops.get_by_id(policy_id)
|
||||
if err != TPE_OK:
|
||||
return self.write_json(err)
|
||||
|
||||
err, acc_info = account.get_account_info(acc_id)
|
||||
if err != TPE_OK:
|
||||
return self.write_json(err)
|
||||
# log.v(acc_info)
|
||||
|
||||
if acc_info['protocol_type'] == TP_PROTOCOL_TYPE_RDP:
|
||||
acc_info['protocol_flag'] = policy_info['flag_rdp']
|
||||
elif acc_info['protocol_type'] == TP_PROTOCOL_TYPE_SSH:
|
||||
acc_info['protocol_flag'] = policy_info['flag_ssh']
|
||||
elif acc_info['protocol_type'] == TP_PROTOCOL_TYPE_TELNET:
|
||||
acc_info['protocol_flag'] = policy_info['flag_telnet']
|
||||
else:
|
||||
acc_info['protocol_flag'] = 0
|
||||
acc_info['record_flag'] = policy_info['flag_record']
|
||||
|
||||
elif _mode == 2:
|
||||
# 直接连接(无需授权),必须具有运维授权管理的权限方可进行
|
||||
ret = self.check_privilege(TP_PRIVILEGE_OPS_AUZ)
|
||||
|
@ -152,6 +167,9 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
if err != TPE_OK:
|
||||
return self.write_json(err)
|
||||
|
||||
acc_info['protocol_flag'] = TP_FLAG_ALL
|
||||
acc_info['record_flag'] = TP_FLAG_ALL
|
||||
|
||||
elif _mode == 0:
|
||||
# 测试连接,必须具有主机信息创建、编辑的权限方可进行
|
||||
ret = self.check_privilege(TP_PRIVILEGE_ASSET_CREATE)
|
||||
|
@ -180,6 +198,8 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
acc_info['auth_type'] = auth_type
|
||||
acc_info['protocol_type'] = _protocol_type
|
||||
acc_info['protocol_port'] = protocol_port
|
||||
acc_info['protocol_flag'] = TP_FLAG_ALL
|
||||
acc_info['record_flag'] = TP_FLAG_ALL
|
||||
acc_info['username'] = username
|
||||
|
||||
acc_info['password'] = password
|
||||
|
@ -226,7 +246,8 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
conn_info['acc_username'] = acc_info['username']
|
||||
conn_info['username_prompt'] = acc_info['username_prompt']
|
||||
conn_info['password_prompt'] = acc_info['password_prompt']
|
||||
conn_info['protocol_flag'] = 1
|
||||
conn_info['protocol_flag'] = acc_info['protocol_flag']
|
||||
conn_info['record_flag'] = acc_info['record_flag']
|
||||
|
||||
conn_info['protocol_type'] = acc_info['protocol_type']
|
||||
conn_info['protocol_sub_type'] = _protocol_sub_type
|
||||
|
@ -261,6 +282,7 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
data = dict()
|
||||
data['session_id'] = ret_data['sid']
|
||||
data['host_ip'] = host_info['ip']
|
||||
data['protocol_flag'] = acc_info['protocol_flag']
|
||||
|
||||
if conn_info['protocol_type'] == TP_PROTOCOL_TYPE_RDP:
|
||||
data['teleport_port'] = tp_cfg().core.rdp.port
|
||||
|
|
|
@ -69,6 +69,7 @@ class RpcHandler(TPBaseJsonHandler):
|
|||
if x is None:
|
||||
return self.write_json(TPE_NOT_EXISTS)
|
||||
else:
|
||||
print(x)
|
||||
return self.write_json(TPE_OK, data=x)
|
||||
|
||||
def _session_begin(self, param):
|
||||
|
|
|
@ -24,21 +24,6 @@ def get_by_id(pid):
|
|||
return TPE_OK, s.recorder[0]
|
||||
|
||||
|
||||
# def get_by_username(username):
|
||||
# s = SQL(get_db())
|
||||
# s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'password', 'oath_secret', 'role_id', 'state', 'email', 'last_login'], alt_name='u')
|
||||
# s.left_join('role', ['name', 'privilege'], join_on='r.id=u.id', alt_name='r', out_map={'name': 'role'})
|
||||
# s.where('u.username="{}"'.format(username))
|
||||
# err = s.query()
|
||||
# if err != TPE_OK:
|
||||
# return err
|
||||
#
|
||||
# if len(s.recorder) == 0:
|
||||
# return TPE_NOT_EXISTS, {}
|
||||
#
|
||||
# return TPE_OK, s.recorder[0]
|
||||
#
|
||||
|
||||
def get_policies(sql_filter, sql_order, sql_limit):
|
||||
dbtp = get_db().table_prefix
|
||||
s = SQL(get_db())
|
||||
|
@ -484,7 +469,7 @@ def rank_reorder(handler, pid, new_rank, start_rank, end_rank, direct):
|
|||
def get_auth(auth_id):
|
||||
db = get_db()
|
||||
s = SQL(db)
|
||||
err = s.select_from('ops_map', ['id', 'h_id', 'u_id', 'a_id']).where('ops_map.uni_id="{}"'.format(auth_id)).query()
|
||||
err = s.select_from('ops_map', ['id', 'p_id', 'h_id', 'u_id', 'a_id']).where('ops_map.uni_id="{}"'.format(auth_id)).query()
|
||||
if err != TPE_OK:
|
||||
return None, err
|
||||
if len(s.recorder) == 0:
|
||||
|
|
Loading…
Reference in New Issue