mirror of https://github.com/tp4a/teleport
准备改进核心服务关于session管理部分,以及ssh转发模块关于录像记录部分。
parent
6cd8d29470
commit
83b9ba01bc
|
@ -28,7 +28,7 @@ void TsSessionManager::_thread_loop(void)
|
|||
ex_sleep_ms(1000);
|
||||
if (m_stop_flag)
|
||||
return;
|
||||
_check_connect_info();
|
||||
_remove_expired_connect_info();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ void TsSessionManager::_set_stop_flag(void)
|
|||
}
|
||||
|
||||
|
||||
void TsSessionManager::_check_connect_info(void)
|
||||
void TsSessionManager::_remove_expired_connect_info(void)
|
||||
{
|
||||
// 超过30秒未进行连接的connect-info会被移除
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ protected:
|
|||
|
||||
private:
|
||||
void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len);
|
||||
void _check_connect_info(void);
|
||||
|
||||
// 定时检查,超过30秒未进行连接的connect-info会被移除
|
||||
void _remove_expired_connect_info(void);
|
||||
|
||||
private:
|
||||
ExThreadLock m_lock;
|
||||
|
|
|
@ -176,7 +176,7 @@ void SshProxy::_dump_sftp_sessions()
|
|||
ts_sftp_sessions::iterator it = m_sftp_sessions.begin();
|
||||
for (; it != m_sftp_sessions.end(); ++it)
|
||||
{
|
||||
EXLOGD("ssh-proxy session: sid: %s\n", it->first.c_str());
|
||||
EXLOGD("[ssh] ssh-proxy session: sid: %s\n", it->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ void SshSession::save_record() {
|
|||
|
||||
|
||||
int SshSession::_on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata) {
|
||||
// 这里拿到的user就是我们要的session-id,password可以用ticket来填充,作为额外判断用户是否被允许访问的依据。
|
||||
// 这里拿到的user就是我们要的session-id。
|
||||
SshSession *_this = (SshSession *)userdata;
|
||||
_this->m_sid = user;
|
||||
EXLOGV("[ssh] authenticating, session-id: %s\n", _this->m_sid.c_str());
|
||||
|
@ -436,6 +436,10 @@ ssh_channel SshSession::_on_new_channel_request(ssh_session session, void *userd
|
|||
// 客户端尝试打开一个通道(然后才能通过这个通道发控制命令或者收发数据)
|
||||
EXLOGV("[ssh] client open channel\n");
|
||||
|
||||
// TODO: 记录会话开始,应该在这里进行,这样可以为每一个通道记录不同的日志,避免类似SecureCRT多标签页使用“复制会话”这样的功能将多个标签页中的记录混杂在一起。
|
||||
// TODO: 每个通道应该记录单独的录像文件
|
||||
|
||||
|
||||
SshSession *_this = (SshSession *)userdata;
|
||||
|
||||
ssh_channel cli_channel = ssh_channel_new(session);
|
||||
|
|
|
@ -42,10 +42,19 @@ $app.create_controls = function (cb_stack) {
|
|||
{
|
||||
title: 'ID',
|
||||
key: 'id',
|
||||
sort: true,
|
||||
sort_asc: false,
|
||||
// sort: true,
|
||||
// sort_asc: false,
|
||||
fields: {id: 'id'}
|
||||
},
|
||||
{
|
||||
title: '会话ID',
|
||||
key: 'sid',
|
||||
// sort: true,
|
||||
// sort_asc: false,
|
||||
render: 'sid',
|
||||
width: 60,
|
||||
fields: {sid: 'sid'}
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
key: 'user',
|
||||
|
@ -237,6 +246,10 @@ $app.on_table_host_render_created = function (render) {
|
|||
return _ret.join('');
|
||||
};
|
||||
|
||||
render.sid = function(row_id, fields) {
|
||||
return '<span class="mono">'+fields.sid+'</span>';
|
||||
};
|
||||
|
||||
render.user = function (row_id, fields) {
|
||||
if (_.isNull(fields.user_surname) || fields.user_surname.length === 0 || fields.user_username === fields.user_surname) {
|
||||
return fields.user_username;
|
||||
|
@ -357,14 +370,14 @@ $app.on_table_host_render_created = function (render) {
|
|||
var ret = [];
|
||||
|
||||
if (fields.state >= TP_SESS_STAT_STARTED || fields.state === TP_SESS_STAT_ERR_RESET) {
|
||||
//if (fields.time_end === 0) {
|
||||
if (fields.state === TP_SESS_STAT_STARTED) {
|
||||
ret.push('<a href="javascript:;" class="btn btn-sm btn-warning" data-action="sync" data-record-id="' + fields.id + '"><i class="fa fa-clone fa-fw"></i> 同步</a> ');
|
||||
} else {
|
||||
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_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> ');
|
||||
}
|
||||
if (fields.protocol_sub_type !== TP_PROTOCOL_TYPE_RDP_DESKTOP) {
|
||||
ret.push('<a href="javascript:;" class="btn btn-sm btn-info" data-action="cmd" data-record-id="' + fields.id + '"><i class="fa fa-file-text-o 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> ');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ var BLUR_BG_IMG = [
|
|||
'login-bg-7.png'
|
||||
];
|
||||
var SLOGAN = [
|
||||
'我感谢那段时光,<br/>因为不曾把我打倒的,<br/>最终让我变得更加强大!',
|
||||
'感谢那段时光,<br/>因为不曾把我们打倒的,<br/>最终让我们变得更加强大!',
|
||||
'宁愿在做事中犯错,<br/>也不要为了不犯错而什么都不做。',
|
||||
'从出生到死,<br/>只有900个月,<br/>所以虚耗每一分钟,<br/>都是巨大的浪费!',
|
||||
'没有播种,何来收获;<br/>没有辛劳,何来成功;<br/>没有磨难,何来荣耀;<br/>没有挫折,何来辉煌。',
|
||||
|
|
|
@ -49,7 +49,7 @@ $app.create_controls = function (cb_stack) {
|
|||
//sort: true,
|
||||
//header_render: 'filter_search_host',
|
||||
render: 'user',
|
||||
fields: {user_name: 'user_name', user_surname: 'user_surname'}
|
||||
fields: {user_username: 'user_username', user_surname: 'user_surname'}
|
||||
},
|
||||
{
|
||||
title: '来源',
|
||||
|
@ -65,7 +65,7 @@ $app.create_controls = function (cb_stack) {
|
|||
//sort: true,
|
||||
//header_render: 'filter_search_host',
|
||||
render: 'remote',
|
||||
fields: {account_name: 'account_name', real_host_ip: 'real_host_ip', host_ip: 'host_ip', host_port: 'host_port'}
|
||||
fields: {acc_username: 'acc_username', host_ip: 'host_ip', conn_ip: 'conn_ip', conn_port: 'conn_port'}
|
||||
},
|
||||
{
|
||||
title: '远程协议',
|
||||
|
@ -128,20 +128,19 @@ $app.create_controls = function (cb_stack) {
|
|||
//-------------------------------
|
||||
// 用户列表相关过滤器
|
||||
//-------------------------------
|
||||
$app.table_session_filter_search_host = $tp.create_table_header_filter_search($app.table_session, {
|
||||
$tp.create_table_header_filter_search($app.table_session, {
|
||||
name: 'search_host',
|
||||
place_holder: '搜索:主机IP/名称/描述/资产编号/等等...'
|
||||
});
|
||||
// 从cookie中读取用户分页限制的选择
|
||||
var _per_page = Cookies.get($app.page_id('ops_session') + '_per_page');
|
||||
$app.table_session_paging = $tp.create_table_paging($app.table_session, 'table-session-paging',
|
||||
$tp.create_table_paging($app.table_session, 'table-session-paging',
|
||||
{
|
||||
per_page: _per_page,
|
||||
per_page: Cookies.get($app.page_id('ops_session') + '_per_page'),
|
||||
on_per_page_changed: function (per_page) {
|
||||
Cookies.set($app.page_id('ops_session') + '_per_page', per_page, {expires: 365});
|
||||
}
|
||||
});
|
||||
$app.table_session_pagination = $tp.create_table_pagination($app.table_session, 'table-session-pagination');
|
||||
$tp.create_table_pagination($app.table_session, 'table-session-pagination');
|
||||
|
||||
//-------------------------------
|
||||
// 页面控件事件绑定
|
||||
|
@ -253,22 +252,20 @@ $app.on_table_session_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.user = function (row_id, fields) {
|
||||
if (_.isNull(fields.user_surname) || fields.user_surname.length === 0 || fields.user_name === fields.user_surname) {
|
||||
return fields.user_name;
|
||||
if (_.isNull(fields.user_surname) || fields.user_surname.length === 0 || fields.user_username === fields.user_surname) {
|
||||
return fields.user_username;
|
||||
} else {
|
||||
return fields.user_name + ' (' + fields.user_surname + ')';
|
||||
return fields.user_username + ' (' + fields.user_surname + ')';
|
||||
}
|
||||
};
|
||||
|
||||
render.remote = function (row_id, fields) {
|
||||
if (fields.real_host_ip === fields.host_ip) {
|
||||
return fields.account_name + '@' + fields.real_host_ip;// + ':' + fields.host_port;
|
||||
} else {
|
||||
return fields.account_name + '@' + fields.real_host_ip;// + '(' + fields.host_ip + ':' + fields.host_port + ')';
|
||||
}
|
||||
if (fields.host_ip === fields.conn_ip)
|
||||
return fields.acc_username + '@' + fields.host_ip + ':' + fields.conn_port;
|
||||
else
|
||||
return '<div title="由' + fields.conn_ip + ':' + fields.conn_port + '路由">' + fields.acc_username + '@' + fields.host_ip + '</div>';
|
||||
};
|
||||
|
||||
// fields: {protocol_type: 'protocol_type', protocol_sub_type: 'protocol_sub_type'}
|
||||
render.protocol = function (row_id, fields) {
|
||||
switch (fields.protocol_sub_type) {
|
||||
case 100:
|
||||
|
|
|
@ -259,7 +259,7 @@ $tp.create_table = function (options) {
|
|||
if (_tbl.options.data_source && _tbl.options.data_source.exclude)
|
||||
args.exclude = _tbl.options.data_source.exclude;
|
||||
|
||||
console.log('when load, args:', args);
|
||||
// console.log('when load, args:', args);
|
||||
// console.log('when load, order:', _order);
|
||||
// console.log('when load, limit:', _limit);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div id="login-area-username" class="login-account">
|
||||
<div class="inputbox">
|
||||
<div class="input-group input-group-lg">
|
||||
<span class="input-group-addon"><i class="fa fa-user fa-fw"></i></span>
|
||||
<span class="input-group-addon"><i class="fa fa-user-circle-o fa-fw"></i></span>
|
||||
<input data-field="username" type="text" class="form-control" placeholder="用户名" data-toggle="popover" data-trigger="manual" data-placement="top">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@ import tornado.gen
|
|||
|
||||
def get_records(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
|
||||
s = SQL(get_db())
|
||||
s.select_from('record', ['id', 'user_id', 'host_id', 'acc_id', 'state', 'user_username', 'user_surname', 'host_ip', 'conn_ip', 'conn_port', 'client_ip', 'acc_username', 'protocol_type', 'protocol_sub_type', 'time_begin', 'time_end'], alt_name='r')
|
||||
s.select_from('record', ['id', 'sid', 'user_id', 'host_id', 'acc_id', 'state', 'user_username', 'user_surname', 'host_ip', 'conn_ip', 'conn_port', 'client_ip', 'acc_username', 'protocol_type', 'protocol_sub_type', 'time_begin', 'time_end'], alt_name='r')
|
||||
|
||||
str_where = ''
|
||||
_where = list()
|
||||
|
|
Loading…
Reference in New Issue