windows版助手支持选择RDP客户端了,目前只支持mstsc和freerdp两种,不允许自定义。

pull/105/head
Apex Liu 2017-12-06 18:08:46 +08:00
parent f5b5b12eec
commit b161f13f6d
6 changed files with 426 additions and 113 deletions

View File

@ -67,5 +67,22 @@
"cmdline": ""
}
]
},
"rdp" : {
"available" : [
{
"app" : "mstsc.exe",
"cmdline" : "\"{tmp_rdp_file}\"",
"display" : "微软RDP客户端系统自带",
"name" : "mstsc"
},
{
"app" : "{assist_tools_path}\\tprdp\\tprdp-client.exe",
"cmdline" : "{size} {console} /v:{host_ip}:{host_port} /u:{user_name} /p:**** {clipboard} {drives} /gdi:sw /t:\"TP#{real_ip}\"",
"display" : "FreeRDP内置",
"name" : "freerdp"
}
],
"selected" : "mstsc"
}
}

View File

@ -41,7 +41,7 @@
<div class="arg-detail arg-detail-common">
<p><strong>此处配置保存到本地计算机上,如果更换计算机,需要重新配置!</strong></p>
<span><strong>注意:</strong>命令参数设置中,如需传递主机信息和登录信息,可以用以下变量替换(注意大小写!):</span>
<span><strong>注意:</strong>命令参数设置中,可以用以下变量替换(注意大小写!):</span>
<ul>
<li><span class="arg-varb">{host_ip}</span> 替换主机IP地址</li>
<li><span class="arg-varb">{host_port}</span> 替换主机端口号</li>
@ -144,6 +144,49 @@
</div>
<hr/>
<p class="cfg-title">本地 RDP 客户端配置</p>
<div class="arg-detail arg-detail-common">
RDP专用命令行参数
<ul>
<li><span class="arg-varb">{tmp_rdp_file}</span> 替换为助手工具生成的临时配置文件(.rdp的绝对路径用于支持按.rdp配置文件进行连接的RDP客户端</li>
<li><span class="arg-varb">{size}</span> [仅FreeRDP] 替换为屏幕尺寸</li>
<li><span class="arg-varb">{console}</span> [仅FreeRDP] 替换为是否以Console模式连接</li>
<li><span class="arg-varb">{clipboard}</span> [仅FreeRDP] 替换为是否允许剪贴板</li>
<li><span class="arg-varb">{drives}</span> [仅FreeRDP] 替换为是否允许映射本地磁盘</li>
</ul>
</div>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="ssh-type" class="col-sm-2 control-label"><strong>客户端:</strong></label>
<div class="col-sm-4">
<select id="rdp-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="ssh-app" class="col-sm-2 control-label"><strong>程序路径:</strong></label>
<div class="col-sm-9">
<div class="input-group">
<input id="rdp-app" type="text" class="form-control input-args" placeholder="客户端可执行程序文件路径" readonly="readonly">
<span class="input-group-btn"><button class="btn btn-sm btn-primary" type="button" id="rdp-select-app">选择...</button></span>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="rdp-cmdline" class="col-sm-2 control-label"><strong>命令参数:</strong></label>
<div class="col-sm-9">
<input id="rdp-cmdline" type="text" class="form-control input-args" placeholder="客户端启动所需命令行参数"/>
</div>
</div>
</div>
<hr/>
<div class="form-horizontal">
<div class="form-group form-group-sm">

View File

@ -22,6 +22,11 @@ var dom = {
telnet_cmdline: $('#telnet-cmdline'),
telnet_select_app: $('#telnet-select-app'),
rdp_type: $('#rdp-type'),
rdp_app: $('#rdp-app'),
rdp_cmdline: $('#rdp-cmdline'),
rdp_select_app: $('#rdp-select-app'),
btn_save: $('#btn-save')
};
@ -168,6 +173,39 @@ function update_dom() {
dom.telnet_cmdline.val(cmdline);
}
}
dom.rdp_type.html('');
if (!_.isUndefined(g_cfg.rdp)) {
if (_.isUndefined(g_cfg.rdp.selected)) {
g_cfg.rdp.selected = '';
}
if (!_.isUndefined(g_cfg.rdp.available) && g_cfg.rdp.available.length > 0) {
var selected = '';
var app = '';
var cmdline = '';
var html = [];
for (var i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (selected === '' || item.name === g_cfg.rdp.selected) {
selected = item.name;
app = item.app;
cmdline = item.cmdline;
}
html.push('<option value="' + item.name + '">' + item.display + '</option>');
}
dom.rdp_type.html(html.join(''));
dom.rdp_type.val(selected);
dom.rdp_app.val(app);
dom.rdp_cmdline.val(cmdline);
}
}
}
function on_save() {
@ -199,6 +237,14 @@ function on_save() {
break;
}
}
for (i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (item.name === g_cfg.rdp.selected) {
item.app = dom.rdp_app.val();
item.cmdline = dom.rdp_cmdline.val();
break;
}
}
var args_ = encodeURIComponent(JSON.stringify(g_cfg));
@ -343,6 +389,29 @@ $(document).ready(function () {
});
dom.rdp_type.change(function () {
g_cfg.rdp.selected = dom.rdp_type.val();
for (var i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (item.name === g_cfg.rdp.selected) {
dom.rdp_app.val(item.app);
dom.rdp_cmdline.val(item.cmdline);
return;
}
}
notify_error('所选的配置项不存在!');
});
dom.rdp_select_app.click(function () {
select_local_file(function (code, path) {
if (code == 0) {
dom.rdp_app.val(path);
} else {
console.log("can not select file.");
}
});
});
dom.btn_save.click(function () {
on_save();
});

View File

@ -208,5 +208,59 @@ bool TsCfg::_load(const ex_astr& str_json) {
return false;
}
//===================================
// check rdp config
//===================================
if (!m_root["rdp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["rdp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["rdp"]["selected"].asCString();
if (!m_root["rdp"]["available"].isArray() || m_root["rdp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["rdp"]["available"].size(); ++i) {
if (
!m_root["rdp"]["available"][i]["name"].isString()
|| !m_root["rdp"]["available"][i]["app"].isString()
|| !m_root["rdp"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["rdp"]["available"][i]["display"].isNull()) {
m_root["rdp"]["available"][i]["display"] = m_root["rdp"]["available"][i]["name"];
}
if (m_root["rdp"]["available"][i]["name"].asCString() != sel_name)
continue;
tmp = m_root["rdp"]["available"][i]["app"].asCString();
ex_astr2wstr(tmp, rdp_app, EX_CODEPAGE_UTF8);
tmp = m_root["rdp"]["available"][i]["cmdline"].asCString();
ex_astr2wstr(tmp, rdp_cmdline, EX_CODEPAGE_UTF8);
tmp = m_root["rdp"]["available"][i]["name"].asCString();
ex_astr2wstr(tmp, rdp_name, EX_CODEPAGE_UTF8);
break;
}
if (rdp_app.length() == 0 || rdp_cmdline.length() == 0 || rdp_name.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
return true;
}

View File

@ -24,6 +24,10 @@ public:
ex_wstr telnet_app;
ex_wstr telnet_cmdline;
ex_wstr rdp_name;
ex_wstr rdp_app;
ex_wstr rdp_cmdline;
protected:
bool _load(const ex_astr& str_json);

View File

@ -44,14 +44,12 @@ End Sub
ubuntuLinuxSecureCRT
*/
#define RDP_CLIENT_SYSTEM_BUILTIN
//#define RDP_CLIENT_SYSTEM_BUILTIN
// #define RDP_CLIENT_SYSTEM_ACTIVE_CONTROL
//#define RDP_CLIENT_FREERDP
#ifdef RDP_CLIENT_SYSTEM_BUILTIN
// #include <WinCrypt.h>
// #pragma comment(lib, "Crypt32.lib")
//#ifdef RDP_CLIENT_SYSTEM_BUILTIN
std::string rdp_content = "\
connect to console:i:%d\n\
@ -107,11 +105,8 @@ username:s:%s\n\
//redirectdirectx:i:0\n\
//prompt for credentials on client:i:0\n\
//password 51:b:%s\n\
//password 51:b:01000000D08C9DDF0115D1118C7A00C04FC297EB0100000052A9E191EA75A948B359790578C9371A0000000008000000700073007700000003660000A8000000100000000A1DCCD2E50775CA25EC3857164B34DC0000000004800000A000000010000000FCE1A645B9B61AA450946BB6F955058108020000D83591CA47562D6DDAA689F050AE145039EBE22E00D1D3AEAA98373C7B63C3E8E7149072DF989EA43EFCE20513AD3D27B11BE7F17066A688E1DCE828AF85460AAC327B38E90776DB962888E4393D19637578984B19A187AAD95F6D2726ADE7DD315FF56C15FF5B3031014EDDCC3C24D1B81779AFDB006EE575F5BEFB8D2D2138D9D9D642BBB251CC5ED7226968764856EC660A646BACE748A13D6002A9A537AA70710615650B9387EED66DE28BD57B304BBDD7B581B943DA628EB0289E30A8BA784B76F7885BECCAB4FEF7820E97EE3C6E036EEAF6EAA669288DF2FCACC9BEC045C907EBBDE87AFB8CC6B07A600BD63AC891B61D95C2265DD9FD5E635D61BFBF5EDC28311375066611C610FB533D64515B643C82F57D9B183B05C156D91BC0974D38E546022B139E82452E6F1EDF76E52F732C3904E5E433F8F3D488DB0698427DBB0791A9F207F8CB6654CB8410BAF4A59C4F9E821E589ABC1E6E6E1D432181B690408F6884FE1007895A4D26D4A5A2C7458EE747DA35D44AC9FB08AB5477EA3E7CCDB3E37EE20FAFD0D0CF9584E420598B7003B347943AC28048F45E0FD21AD08148FFADCE0E7877219259A7BE722FFAE845A429BA2CF0A71F2D19EA7495530FABDB5106E8D404A38A7E6394C38457640EA7398C5D55F0C4D342CC6A39C77E10A2A5145AEA40B14F5C7C3760334D83C9BE748383FADE231248537353817D51F7B44F61B406ABC61400000071C354139F458B02D978015F785B97F7F6B307380\n\
//password 51:b:01000000";
#endif
//#endif
TsHttpRpc g_http_interface;
@ -174,34 +169,6 @@ int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_f
return i >= src_len ? j : -1;
}
// #ifdef RDP_CLIENT_SYSTEM_BUILTIN
// bool calc_psw51b(const char* password, std::string& ret)
// {
// DATA_BLOB DataIn;
// DATA_BLOB DataOut;
//
// ex_wstr w_pswd;
// ex_astr2wstr(password, w_pswd, EX_CODEPAGE_ACP);
//
// DataIn.cbData = w_pswd.length() * sizeof(wchar_t);
// DataIn.pbData = (BYTE*)w_pswd.c_str();
//
//
// if (!CryptProtectData(&DataIn, L"psw", NULL, NULL, NULL, 0, &DataOut))
// return false;
//
// char szRet[5] = {0};
// for (int i = 0; i < DataOut.cbData; ++i)
// {
// sprintf_s(szRet, 5, "%02X", DataOut.pbData[i]);
// ret += szRet;
// }
//
// LocalFree(DataOut.pbData);
// return true;
// }
// #endif
//
TsHttpRpc::TsHttpRpc()
{
m_stop = false;
@ -621,13 +588,14 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
WCHAR w_port[32] = { 0 };
swprintf_s(w_port, _T("%d"), teleport_port);
ex_wstr tmp_rdp_file; // for .rdp file
if (pro_type == TP_PROTOCOL_TYPE_RDP)
{
//==============================================
// RDP
//==============================================
//#if 1
#if 0
#if defined(RDP_CLIENT_SYSTEM_ACTIVE_CONTROL)
int split_pos = session_id.length() - 2;
@ -722,7 +690,6 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
w_exe_path += w_szCommandLine;
//#endif
#elif defined(RDP_CLIENT_SYSTEM_BUILTIN)
int width = 800;
@ -800,7 +767,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
, cx, cy, cx + width + 20, cy + higth + 40
, teleport_ip.c_str(), teleport_port
, real_sid.c_str()
, "administrator"
// , "administrator"
// , psw51b.c_str()
);
@ -820,12 +787,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
ex_replace_all(temp_host_ip, ".", "-");
// for debug
sprintf_s(sz_file_name, ("e:\\tmp\\rdp\\%s.rdp"), temp_host_ip.c_str());
//sprintf_s(sz_file_name, ("e:\\tmp\\rdp\\%s.rdp"), temp_host_ip.c_str());
//sprintf_s(sz_file_name, ("%s%s.rdp"), temp_path, temp_host_ip.c_str());
sprintf_s(sz_file_name, ("%s%s.rdp"), temp_path, temp_host_ip.c_str());
//FILE* f = fopen(sz_file_name, ("wt"));
//if (f == NULL)
FILE* f = NULL;
if(fopen_s(&f, sz_file_name, "wt") != 0)
{
@ -843,6 +808,167 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
w_exe_path = w_szCommandLine;
//BOOL bRet = DeleteFile(w_sz_file_name.c_str());
#endif
#endif
w_exe_path = _T("\"");
w_exe_path += g_cfg.rdp_app + _T("\" ");
w_exe_path += g_cfg.rdp_cmdline;
ex_wstr rdp_name = g_cfg.rdp_name;
if (rdp_name == L"mstsc") {
int width = 800;
int higth = 600;
int cx = 0;
int cy = 0;
int display = 1;
int iWidth = GetSystemMetrics(SM_CXSCREEN);
int iHeight = GetSystemMetrics(SM_CYSCREEN);
switch (windows_size)
{
case 0:
//全屏
width = iWidth;
higth = iHeight;
display = 2;
break;
case 1:
{
width = 800;
higth = 600;
display = 1;
break;
}
case 2:
{
width = 1024;
higth = 768;
display = 1;
break;
}
case 3:
{
width = 1280;
higth = 1024;
display = 1;
break;
}
default:
width = 800;
higth = 600;
break;
}
cx = (iWidth - width) / 2;
cy = (iHeight - higth) / 2;
if (cx < 0)
{
cx = 0;
}
if (cy < 0)
{
cy = 0;
}
int split_pos = sid.length() - 2;
std::string real_sid = sid.substr(0, split_pos);
char sz_rdp_file_content[4096] = { 0 };
sprintf_s(sz_rdp_file_content, rdp_content.c_str(),
console, display, width, higth
, cx, cy, cx + width + 20, cy + higth + 40
, teleport_ip.c_str(), teleport_port
, real_sid.c_str()
);
char sz_file_name[MAX_PATH] = { 0 };
char temp_path[MAX_PATH] = { 0 };
DWORD ret = GetTempPathA(MAX_PATH, temp_path);
if (ret <= 0)
{
printf("fopen failed (%d).\n", GetLastError());
_create_json_ret(buf, TPE_FAILED);
return;
}
ex_wstr w_s_id;
ex_astr2wstr(real_sid, w_s_id);
ex_astr temp_host_ip = real_host_ip;// replace_all_distinct(real_host_ip, ("."), "-");
ex_replace_all(temp_host_ip, ".", "-");
sprintf_s(sz_file_name, ("%s%s.rdp"), temp_path, temp_host_ip.c_str());
FILE* f = NULL;
if (fopen_s(&f, sz_file_name, "wt") != 0)
{
printf("fopen failed (%d).\n", GetLastError());
_create_json_ret(buf, TPE_OPENFILE);
return;
}
// Write a string into the file.
fwrite(sz_rdp_file_content, strlen(sz_rdp_file_content), 1, f);
fclose(f);
ex_astr2wstr(sz_file_name, tmp_rdp_file);
// 变量替换
ex_replace_all(w_exe_path, _T("{tmp_rdp_file}"), tmp_rdp_file);
}
else if (g_cfg.rdp_name == L"freerdp") {
wchar_t* w_screen = NULL;
switch (windows_size)
{
case 0: //全屏
w_screen = _T("/f");
break;
case 2:
w_screen = _T("/size:1024x768");
break;
case 3:
w_screen = _T("/size:1280x1024");
break;
case 1:
default:
w_screen = _T("/size:800x600");
break;
}
wchar_t* w_console = NULL;
if (console != 0)
{
w_console = L"/admin";
}
else
{
w_console = L"";
}
int split_pos = sid.length() - 2;
std::string real_sid = sid.substr(0, split_pos);
std::string str_pwd_len = sid.substr(split_pos, sid.length());
int n_pwd_len = strtol(str_pwd_len.c_str(), NULL, 16);
n_pwd_len -= real_sid.length();
WCHAR w_szPwd[256] = { 0 };
for (int i = 0; i < n_pwd_len; i++)
{
w_szPwd[i] = '*';
}
ex_astr2wstr(real_sid, w_sid);
// 变量替换
ex_replace_all(w_exe_path, _T("{size}"), w_screen);
ex_replace_all(w_exe_path, _T("{console}"), w_console);
ex_replace_all(w_exe_path, _T("{clipboard}"), L"+clipboard");
ex_replace_all(w_exe_path, _T("{drives}"), L"/drives");
}
else {
_create_json_ret(buf, TPE_FAILED);
return;
}
}
else if (pro_type == TP_PROTOCOL_TYPE_SSH)
{