实现:运维授权策略中,“连接控制->RDP选项”设置的选项可以起作用了。

pull/105/head
Apex Liu 2018-04-11 01:30:55 +08:00
parent 1657622385
commit 24baf11273
12 changed files with 1513 additions and 1448 deletions

View File

@ -88,7 +88,7 @@ audiomode:i:0\n\
redirectprinters:i:0\n\
redirectcomports:i:0\n\
redirectsmartcards:i:0\n\
redirectclipboard:i:1\n\
redirectclipboard:i:%d\n\
redirectposdevices:i:0\n\
autoreconnection enabled:i:0\n\
authentication level:i:2\n\
@ -106,7 +106,7 @@ gatewaybrokeringtype:i:0\n\
use redirection server name:i:0\n\
rdgiskdcproxy:i:0\n\
kdcproxyname:s:\n\
drivestoredirect:s:*\n\
drivestoredirect:s:%s\n\
username:s:%s\n\
password 51:b:%s\n\
";
@ -577,6 +577,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
if (!jsRoot["teleport_ip"].isString()
|| !jsRoot["teleport_port"].isNumeric() || !jsRoot["remote_host_ip"].isString()
|| !jsRoot["session_id"].isString() || !jsRoot["protocol_type"].isNumeric() || !jsRoot["protocol_sub_type"].isNumeric()
|| !jsRoot["protocol_flag"].isNumeric()
)
{
_create_json_ret(buf, TPE_PARAM);
@ -585,6 +586,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
int pro_type = jsRoot["protocol_type"].asUInt();
int pro_sub = jsRoot["protocol_sub_type"].asInt();
ex_u32 protocol_flag = jsRoot["protocol_flag"].asUInt();
ex_astr teleport_ip = jsRoot["teleport_ip"].asCString();
int teleport_port = jsRoot["teleport_port"].asUInt();
@ -613,6 +615,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
// RDP
//==============================================
bool flag_clipboard = (protocol_flag & TP_FLAG_RDP_CLIPBOARD);
bool flag_disk = (protocol_flag & TP_FLAG_RDP_DISK);
bool flag_console = (protocol_flag & TP_FLAG_RDP_CONSOLE);
int rdp_w = 800;
int rdp_h = 640;
bool rdp_console = false;
@ -647,6 +653,9 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
}
}
if (!flag_console)
rdp_console = false;
int split_pos = sid.length() - 2;
ex_astr real_sid = sid.substr(0, split_pos);
@ -701,9 +710,9 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
cy = 0;
}
int console_mode = 0;
if (rdp_console)
console_mode = 1;
// int console_mode = 0;
// if (rdp_console)
// console_mode = 1;
std::string psw51b;
if (!calc_psw51b(szPwd, psw51b))
@ -716,10 +725,13 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
real_sid = "01" + real_sid;
char sz_rdp_file_content[4096] = { 0 };
sprintf_s(sz_rdp_file_content, rdp_content.c_str(),
console_mode, display, width, higth
sprintf_s(sz_rdp_file_content, rdp_content.c_str()
, (flag_console && rdp_console) ? 1 : 0
, display, width, higth
, cx, cy, cx + width + 100, cy + higth + 100
, flag_clipboard ? 1 : 0
, teleport_ip.c_str(), teleport_port
, flag_disk ? "*" : ""
, real_sid.c_str()
, psw51b.c_str()
);
@ -770,16 +782,16 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
ex_astr2wstr(sz_size, w_screen);
}
wchar_t* w_console = NULL;
if (rdp_console)
{
w_console = L"/admin";
}
else
{
w_console = L"";
}
// wchar_t* w_console = NULL;
//
// if (flag_console && rdp_console)
// {
// w_console = L"/admin";
// }
// else
// {
// w_console = L"";
// }
ex_wstr w_password;
ex_astr2wstr(szPwd, w_password);
@ -793,10 +805,23 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
// ±äÁ¿Ìæ»»
ex_replace_all(w_exe_path, _T("{size}"), w_screen);
ex_replace_all(w_exe_path, _T("{console}"), w_console);
if (flag_console && rdp_console)
ex_replace_all(w_exe_path, _T("{console}"), L"/admin");
else
ex_replace_all(w_exe_path, _T("{console}"), L"");
//ex_replace_all(w_exe_path, _T("{clipboard}"), L"+clipboard");
if(flag_clipboard)
ex_replace_all(w_exe_path, _T("{clipboard}"), L"/clipboard");
else
ex_replace_all(w_exe_path, _T("{clipboard}"), L"-clipboard");
if(flag_disk)
ex_replace_all(w_exe_path, _T("{drives}"), L"/drives");
else
ex_replace_all(w_exe_path, _T("{drives}"), L"-drives");
}
else {
_create_json_ret(buf, TPE_FAILED);

View File

@ -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.)
//=======================================================
// 错误值
//=======================================================

View File

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

View File

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

View File

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

View File

@ -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秒后自动销毁

View File

@ -83,8 +83,10 @@ 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())
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())
@ -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;
}

View File

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

View File

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

View File

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

View File

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