准备改进核心服务关于session管理部分,以及ssh转发模块关于录像记录部分。

pull/105/head
Apex Liu 2017-11-19 22:51:48 +08:00
parent 6cd8d29470
commit 83b9ba01bc
10 changed files with 46 additions and 30 deletions

View File

@ -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会被移除

View File

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

View File

@ -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());
}
}

View File

@ -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-idpassword可以用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);

View File

@ -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>&nbsp');
} 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>&nbsp');
// 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>&nbsp');
}
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>&nbsp');
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>&nbsp');
}
}

View File

@ -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/>没有挫折,何来辉煌。',

View File

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

View File

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

View File

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

View File

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