From b161f13f6dd7c9ca57ca048070c087fbf511b9b6 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Wed, 6 Dec 2017 18:08:46 +0800 Subject: [PATCH] =?UTF-8?q?windows=E7=89=88=E5=8A=A9=E6=89=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=89=E6=8B=A9RDP=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E4=BA=86=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=8F=AA=E6=94=AF=E6=8C=81?= =?UTF-8?q?mstsc=E5=92=8Cfreerdp=E4=B8=A4=E7=A7=8D=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E8=87=AA=E5=AE=9A=E4=B9=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tp_assist_win/cfg/tp-assist.default.json | 155 +++++++------ client/tp_assist_win/site/index.html | 45 +++- client/tp_assist_win/site/js/config.js | 69 ++++++ client/tp_assist_win/ts_cfg.cpp | 54 +++++ client/tp_assist_win/ts_cfg.h | 4 + client/tp_assist_win/ts_http_rpc.cpp | 212 ++++++++++++++---- 6 files changed, 426 insertions(+), 113 deletions(-) diff --git a/client/tp_assist_win/cfg/tp-assist.default.json b/client/tp_assist_win/cfg/tp-assist.default.json index b7703c2..0a6ce75 100644 --- a/client/tp_assist_win/cfg/tp-assist.default.json +++ b/client/tp_assist_win/cfg/tp-assist.default.json @@ -1,71 +1,88 @@ { - "ssh": { - "selected": "putty", - "available": [ - { - "name":"putty", - "display": "PuTTY(内置)", - "app": "{assist_tools_path}\\putty\\putty.exe", - "cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}" - }, - { - "name": "crt", - "display": "SecureCRT", - "app": "", - "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}" - }, - { - "name": "xshell", - "display": "Xshell", - "app": "", - "cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}" - }, - { - "name": "other", - "display": "自定义", - "app": "", - "cmdline": "" - } - ] - }, - "scp": { - "selected": "winscp", - "available": [ - { - "name":"winscp", - "display": "WinSCP(内置)", - "app": "{assist_tools_path}\\winscp\\winscp.exe", - "cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}" - }, - { - "name": "other", - "display": "自定义", - "app": "", - "cmdline": "" - } - ] - }, - "telnet": { - "selected": "putty", - "available": [ - { - "name":"putty", - "display": "PuTTY(内置)", - "app": "{assist_tools_path}\\putty\\putty.exe", - "cmdline": "telnet://{user_name}@{host_ip}:{host_port}" - }, - { - "name": "crt", - "display": "SecureCRT", - "app": "", - "cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}" - }, - { - "name": "other", - "display": "自定义", - "app": "", - "cmdline": "" - } - ] - } + "ssh": { + "selected": "putty", + "available": [ + { + "name":"putty", + "display": "PuTTY(内置)", + "app": "{assist_tools_path}\\putty\\putty.exe", + "cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}" + }, + { + "name": "crt", + "display": "SecureCRT", + "app": "", + "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}" + }, + { + "name": "xshell", + "display": "Xshell", + "app": "", + "cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}" + }, + { + "name": "other", + "display": "自定义", + "app": "", + "cmdline": "" + } + ] + }, + "scp": { + "selected": "winscp", + "available": [ + { + "name":"winscp", + "display": "WinSCP(内置)", + "app": "{assist_tools_path}\\winscp\\winscp.exe", + "cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}" + }, + { + "name": "other", + "display": "自定义", + "app": "", + "cmdline": "" + } + ] + }, + "telnet": { + "selected": "putty", + "available": [ + { + "name":"putty", + "display": "PuTTY(内置)", + "app": "{assist_tools_path}\\putty\\putty.exe", + "cmdline": "telnet://{user_name}@{host_ip}:{host_port}" + }, + { + "name": "crt", + "display": "SecureCRT", + "app": "", + "cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}" + }, + { + "name": "other", + "display": "自定义", + "app": "", + "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" + } } diff --git a/client/tp_assist_win/site/index.html b/client/tp_assist_win/site/index.html index 55af950..0ffd9f2 100644 --- a/client/tp_assist_win/site/index.html +++ b/client/tp_assist_win/site/index.html @@ -41,7 +41,7 @@

此处配置保存到本地计算机上,如果更换计算机,需要重新配置!

- 注意:命令参数设置中,如需传递主机信息和登录信息,可以用以下变量替换(注意大小写!): + 注意:命令行参数设置中,可以用以下变量替换(注意大小写!):
+ +
+

本地 RDP 客户端配置

+ +
+ RDP专用命令行参数: + +
+ + +
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+
+ +
diff --git a/client/tp_assist_win/site/js/config.js b/client/tp_assist_win/site/js/config.js index 29a7cac..a6cacf5 100644 --- a/client/tp_assist_win/site/js/config.js +++ b/client/tp_assist_win/site/js/config.js @@ -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(''); + } + + 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(); }); diff --git a/client/tp_assist_win/ts_cfg.cpp b/client/tp_assist_win/ts_cfg.cpp index 9031381..acbee67 100644 --- a/client/tp_assist_win/ts_cfg.cpp +++ b/client/tp_assist_win/ts_cfg.cpp @@ -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; } diff --git a/client/tp_assist_win/ts_cfg.h b/client/tp_assist_win/ts_cfg.h index 5e2d23f..4e0d6cd 100644 --- a/client/tp_assist_win/ts_cfg.h +++ b/client/tp_assist_win/ts_cfg.h @@ -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); diff --git a/client/tp_assist_win/ts_http_rpc.cpp b/client/tp_assist_win/ts_http_rpc.cpp index e94d928..ea0aca1 100644 --- a/client/tp_assist_win/ts_http_rpc.cpp +++ b/client/tp_assist_win/ts_http_rpc.cpp @@ -44,14 +44,12 @@ End Sub ֹˣubuntuԣ֪Ƿܹ֧еLinuxSecureCRTԴ˱ʾԡ */ -#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 -// #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) {