From c701a90670f5679cf5b402f6aca616462025bc41 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Sat, 14 May 2022 19:11:13 +0800 Subject: [PATCH] =?UTF-8?q?win=E7=89=88=E5=8A=A9=E6=89=8B=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E4=BD=BF=E7=94=A8url-protocol=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=90=AF=E5=8A=A8=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?http=E6=9C=8D=E5=8A=A1=E4=BA=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/builder/core/env.py | 28 +- client/cfg/cacert.cer | 21 - client/cfg/localhost.key | 28 - client/cfg/localhost.pem | 22 - client/cfg/tp-assist.windows.json | 38 +- client/tp_assist_macos/src/csrc/ts_cfg.cpp | 338 +---- client/tp_assist_win/dlg_main.cpp | 6 - client/tp_assist_win/resource.h | Bin 3306 -> 3212 bytes client/tp_assist_win/stdafx.h | 2 +- client/tp_assist_win/tp_assist.cpp | 361 ++--- client/tp_assist_win/tp_assist.rc | Bin 8792 -> 8606 bytes client/tp_assist_win/tp_assist.vs2017.vcxproj | 22 +- .../tp_assist.vs2017.vcxproj.filters | 352 +++-- client/tp_assist_win/ts_cfg.cpp | 303 ++--- client/tp_assist_win/ts_cfg.h | 23 +- client/tp_assist_win/ts_const.h | 4 +- client/tp_assist_win/ts_env.cpp | 12 - client/tp_assist_win/ts_env.h | 9 +- client/tp_assist_win/ts_http_rpc.cpp | 1191 ----------------- client/tp_assist_win/ts_http_rpc.h | 94 -- client/tp_assist_win/ts_network.cpp | 346 ----- client/tp_assist_win/ts_network.h | 43 - client/tp_assist_win/ts_utils.cpp | 39 + client/tp_assist_win/ts_utils.h | 8 + client/tp_assist_win/ts_ws_client.cpp | 923 +++++++++++++ client/tp_assist_win/ts_ws_client.h | 82 ++ common/libex/src/ex_path.cpp | 4 +- config.json.in | 1 + dist/client/windows/assist/setup.nsh | Bin 29210 -> 29258 bytes make.sh | 12 +- server/tp_core/core/main.cpp | 8 +- server/tp_core/core/tp_core.vs2017.vcxproj | 6 +- .../tp_core/protocol/ssh/tpssh.vs2017.vcxproj | 6 +- .../www/teleport/static/js/assist/config.js | 2 +- 34 files changed, 1603 insertions(+), 2731 deletions(-) delete mode 100644 client/cfg/cacert.cer delete mode 100644 client/cfg/localhost.key delete mode 100644 client/cfg/localhost.pem delete mode 100644 client/tp_assist_win/ts_http_rpc.cpp delete mode 100644 client/tp_assist_win/ts_http_rpc.h delete mode 100644 client/tp_assist_win/ts_network.cpp delete mode 100644 client/tp_assist_win/ts_network.h create mode 100644 client/tp_assist_win/ts_utils.cpp create mode 100644 client/tp_assist_win/ts_utils.h create mode 100644 client/tp_assist_win/ts_ws_client.cpp create mode 100644 client/tp_assist_win/ts_ws_client.h diff --git a/build/builder/core/env.py b/build/builder/core/env.py index 1bcc88a..4439875 100644 --- a/build/builder/core/env.py +++ b/build/builder/core/env.py @@ -124,15 +124,13 @@ class Env(object): if warn_miss_tool: cc.w(' - can not locate `perl`, so I can not build openssl.') - self.visual_studio_path = self._get_visual_studio_path() - if self.visual_studio_path is None or not os.path.exists(self.visual_studio_path): - if warn_miss_tool: - cc.w(' - can not locate Visual Studio installation, so I can build nothing.') + # self.visual_studio_path = self._get_visual_studio_path() + # if self.visual_studio_path is None or not os.path.exists(self.visual_studio_path): + # if warn_miss_tool: + # cc.w(' - can not locate Visual Studio installation, so I can build nothing.') if 'msbuild' in _tmp: self.msbuild = _tmp['msbuild'] - else: - self.msbuild = self._get_msbuild() if self.msbuild is None or not os.path.exists(self.msbuild): if warn_miss_tool: @@ -250,15 +248,15 @@ class Env(object): # return p[0] if p is not None else None - def _get_visual_studio_path(self): - p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7', r'15.0') - return p[0] if p is not None else None - - def _get_msbuild(self): - vs2017 = self._get_visual_studio_path() - if vs2017 is None: - return None - return os.path.join(vs2017, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') + # def _get_visual_studio_path(self): + # p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7', r'15.0') + # return p[0] if p is not None else None + # + # def _get_msbuild(self): + # vs2017 = self._get_visual_studio_path() + # if vs2017 is None: + # return None + # return os.path.join(vs2017, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') def _get_perl(self): p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\perl', 'BinDir') diff --git a/client/cfg/cacert.cer b/client/cfg/cacert.cer deleted file mode 100644 index 7be85a8..0000000 --- a/client/cfg/cacert.cer +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDhDCCAmygAwIBAgIBADANBgkqhkiG9w0BAQsFADAzMQswCQYDVQQGEwJDTjEN -MAsGA1UEChMEdHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBMCAXDTIxMDcwMzA1 -NTA0N1oYDzIxMjEwNjA5MDU1MDQ3WjAzMQswCQYDVQQGEwJDTjENMAsGA1UEChME -dHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEArk1q4RZGBRJwJPYjEVUskFiFadz6trJC5430DFxwLVCEvMHh -KlgTb/a1jC53DmGsbJHlNs9yd7ja08AUITsbcUnST976LFpOe+ck6E2x1rhlWrXP -rN1B+xzfFy1AMNubr97MHoCfrdErWxKzaRUX55GRXbWMsugcfsvr7t8JQh3xbo91 -0Xcq0QvC7t5PoDQ6VX6Uc0Utx7lbW4OoA7wU4d2JjUcvBlQHQsu/qZLojzXyEl2Q -AwfILypiapl01iBM2XPpaPpXC58//Etx/ul3oHsLsPEUzxbiCptx8xjE9IWaKqf6 -GlnjhpZzw8W24h2CvWyy9EYw3QdUI4EBQhVZtwIDAQABo4GgMIGdMB0GA1UdDgQW -BBR7wuXeCTbB+3mfLFcwm3anZ2C4UDBbBgNVHSMEVDBSgBR7wuXeCTbB+3mfLFcw -m3anZ2C4UKE3pDUwMzELMAkGA1UEBhMCQ04xDTALBgNVBAoTBHRwNGExFTATBgNV -BAMTDFRQNEEgUm9vdCBDQYIBADAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAfd12+QaYrtM/KfZnSqDLwvGksuOZ1OOX -8xApJo35GPpFLlFTdkwQ9Z3unWXIfJGFYGAiRpy83ghraOaxqGDngqJdr1hT0RTQ -KqVlBZufbB010Dhl/6TcetZTeXLa3Xjw9d9jc79Prmc/485pa6lh2QSodHJwfz7J -zzUe5g09hzLdqrurIGdsMzFRMRwo2KpXMhx4jEqk4IMTD9rQnzCxBWS8rPbsnDTm -f0/kW3R70JbUFN5Dnd669g6t1L923+ICysR6q+Ep7cGhY1b9iMCn4Ia8r4VwgYuH -PAvw0ajzvj7RRW0M9Szo2jaWXHz6XeKmK3t8TW2x4gOn+irOenItEg== ------END CERTIFICATE----- diff --git a/client/cfg/localhost.key b/client/cfg/localhost.key deleted file mode 100644 index 5c93a5a..0000000 --- a/client/cfg/localhost.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDf3tDR3kM5solf -OA9AKlM+DzFgG9G0RzR8b91KdIwWzIk+WyyqOHEkyXX3QmykKWqE74ZTB1/iWpWk -5Z73LonGgdc9alfkP/esAUPbF1030Z7AO9Kswt9ZRFv4qEMCFkPdz5bJ5EFble2z -OVmkLcJJpvDvuB82Sja4gfVaG+Lt++om9CxSL93bvn9cWs8EMC9ClbgPqu3N5Gnb -mulQDFwsnJDTkMhn8QvkXWkoQrI43vSqdQpGzqGCKcdpDhYbLzd/Vmf9bZTIvYZb -n1TYT8o+zGcpwQyT0HDhT9LlwRgh0jbYy63wSil0pLnA1DruZyZIgp8sQXKh6IU6 -h9g4tC2jAgMBAAECggEAL1hMCVZcGUOs0bplX0iUOje0VYMMone8neR6hFiJl/jB -vbJCi+1L4F/K1vPxTfaEVIDjg4O3v4MwyqLVL6lj8dtbzd1DoT31/yZ1V0xlpnxq -enUsZOUBnztZyAitwy86Qxq35RKkz92xW4nxb0tOH41yvv/NegnP8M1rOhdTssiC -nX8KQgdZLuVI3Q5PeJpycKTthXIsxqQufZJZAyYrXZsR6gkGaNlOV/7eNFrh6PPS -pStHHQYWPyjyUZREHzo371ZKawXaC5pJZY7b4s76mCPOxpL8VjFuXKAdW61po6XV -Ff4wAd/eutyaur6ZgriY8oRX+10FnyYiwRo3QUv+4QKBgQD9PNGvN6BqKxhWM3Su -HGpcp/fyNMidoKdP1maFEtisMUIhNm+i1CSsn1dn006bv/6igSmVNI4FdyCU8dP/ -tbWUWl0r3fTRnlduJxkvZmoVXqW78BXx4ejnKDZfTNtUNWT/4h1nKTYQh42O/WXC -Wzl/LB154dDMMUIp+KEnOFQhdwKBgQDiT/yqcoYVYCV2nk/q2BML8/NvhHK1+Hgv -oqGKe2zmNxQcCH/H70TjWJRojxQJZe4311MP2Qu5RvgHfmtotb3Fi2gGYv6dwS9n -VdcFILjoiQAMe8KLfZBGAmsN3bQ9g2BrbD1sFjVCUsOT1c2zI4ESQXW5Dz4F5Fpe -9zBYR1DANQKBgF15mLDDqLvnwmj3P2eRZ5ViDvzhjPfaOEgZDOisBzywRge6b0S8 -Z/ksK/hQIGEPYq+bW70OlCniSi2Qgj+OVEM5g9DQcjD58K3hUsOTWy8eK7EOsxsA -15aT2lYdKYyQ1QI69b2BkcpSLueME4bFY5jUsOCvgQIOYKzbcKjoeu2LAoGAFl3L -XdkVsVUgPrnkshQKxdqlS3cukxdsYWDUUEhkedglr6OTZWIbT9C4UiEZ3NfrFC++ -sMlFpFkEOFFhMicMC1L8w+zStyqZkb/lEUernqezjohIsNqHALRKekNYBeBPDi7T -XzROrTBazeiKfNLcdb5scQ61lYV8/Pe3GnJp46UCgYEAmI8xIBGBNWcXY1V4ismY -FM/8anrOFSPrgmyp9NcUu7mXxIWTPg+3vIykwV+uqkWh0BgSnGitQ9BKIHgJU3sz -K8ft7edhwgKq3x8y0Gs8+1JOm2TvKhavZoKcSOi6/2xeGunMbEpL/zsOcEMOmp+V -a/PsyIEsETicUZJmFZxAiGs= ------END PRIVATE KEY----- diff --git a/client/cfg/localhost.pem b/client/cfg/localhost.pem deleted file mode 100644 index 412d551..0000000 --- a/client/cfg/localhost.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIGAhNQQY0BMA0GCSqGSIb3DQEBCwUAMDMxCzAJBgNVBAYT -AkNOMQ0wCwYDVQQKEwR0cDRhMRUwEwYDVQQDEwxUUDRBIFJvb3QgQ0EwHhcNMjEw -NzAzMDU1MDU0WhcNMjIwNzAzMDU1MDU0WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3Qw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDf3tDR3kM5solfOA9AKlM+ -DzFgG9G0RzR8b91KdIwWzIk+WyyqOHEkyXX3QmykKWqE74ZTB1/iWpWk5Z73LonG -gdc9alfkP/esAUPbF1030Z7AO9Kswt9ZRFv4qEMCFkPdz5bJ5EFble2zOVmkLcJJ -pvDvuB82Sja4gfVaG+Lt++om9CxSL93bvn9cWs8EMC9ClbgPqu3N5GnbmulQDFws -nJDTkMhn8QvkXWkoQrI43vSqdQpGzqGCKcdpDhYbLzd/Vmf9bZTIvYZbn1TYT8o+ -zGcpwQyT0HDhT9LlwRgh0jbYy63wSil0pLnA1DruZyZIgp8sQXKh6IU6h9g4tC2j -AgMBAAGjgcswgcgwHQYDVR0OBBYEFBKWKx7CKoM7m5kaK5uN5woCrFFCMFsGA1Ud -IwRUMFKAFHvC5d4JNsH7eZ8sVzCbdqdnYLhQoTekNTAzMQswCQYDVQQGEwJDTjEN -MAsGA1UEChMEdHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBggEAMAwGA1UdEwEB -/wQCMAAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBoGA1UdEQQT -MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAeM48uhEnkmdw -viwmdErYx/aYjl4Cs1woFAalkrhX42Ogld3B/LhIuBePiuKrPmrCOtM03qUXFKq4 -Fg0A4eZnUiPHxTUzToa4yipY2xlxTh5oxy/MmXRyKfCO10mq7gTqtU7iUYy3fPvE -eDfL5ZIaCT+G8a/UI/EQjfhu00C37zRIvfhYkqCho+NoM087oADVQ9CGStWy4aHs -hh2fkKBZEYgOFSm6jPotEiqGJr2KHZ7pLi9f8zGsW2Srdpc7IC1aYD2QzHMqptzt -YEAFsMw2OvK+7zJGkJkNnejlcr9gc6j2JWkYYTuCI2D+rh0nFDkmMnDchzyYJyOQ -6U4OOh97yg== ------END CERTIFICATE----- diff --git a/client/cfg/tp-assist.windows.json b/client/cfg/tp-assist.windows.json index ff007f9..125009e 100755 --- a/client/cfg/tp-assist.windows.json +++ b/client/cfg/tp-assist.windows.json @@ -1,45 +1,52 @@ { + "file_version": 3, "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}" + "cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}", + "desc": [] }, { "name": "crt", "display": "SecureCRT", "app": "", - "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}" + "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}", + "desc": [] }, { "name": "xshell", "display": "Xshell", "app": "", - "cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}" + "cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}", + "desc": [] }, { "name": "other", "display": "自定义", "app": "", - "cmdline": "" + "cmdline": "", + "desc": [] } ] }, - "scp": { + "sftp": { "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}" + "cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}", + "desc": [] }, { "name": "other", "display": "自定义", "app": "", - "cmdline": "" + "cmdline": "", + "desc": [] } ] }, @@ -49,19 +56,22 @@ "name": "putty", "display": "PuTTY(内置)", "app": "{assist_tools_path}\\putty\\putty.exe", - "cmdline": "telnet://{user_name}@{host_ip}:{host_port}" + "cmdline": "telnet://{user_name}@{host_ip}:{host_port}", + "desc": [] }, { "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}" - }, + "cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}", + "desc": [] + }, { "name": "other", "display": "自定义", "app": "", - "cmdline": "" + "cmdline": "", + "desc": [] } ] }, @@ -70,13 +80,15 @@ "app": "mstsc.exe", "cmdline": "\"{tmp_rdp_file}\"", "display": "微软RDP客户端(系统自带)", - "name": "mstsc" + "name": "mstsc", + "desc": [] }, { "app": "{assist_tools_path}\\tprdp\\wfreerdp.exe", "cmdline": "/v:{host_ip}:{host_port} /u:{user_name} /t:\"TP#{real_ip}\"", "display": "FreeRDP(内置)", - "name": "freerdp" + "name": "freerdp", + "desc": [] } ], "selected": "mstsc" diff --git a/client/tp_assist_macos/src/csrc/ts_cfg.cpp b/client/tp_assist_macos/src/csrc/ts_cfg.cpp index 005c9e9..77213e8 100644 --- a/client/tp_assist_macos/src/csrc/ts_cfg.cpp +++ b/client/tp_assist_macos/src/csrc/ts_cfg.cpp @@ -117,23 +117,12 @@ bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CO break; } - -// if (cfg.application.empty() || cfg.cmdline.empty()) { -// EXLOGE("invalid config, error 6.\n"); -// return false; -// } return true; } bool TsCfg::_load(const ex_astr& str_json) { -// Json::Reader jreader; -// -// if (!jreader.parse(str_json.c_str(), m_root)) { -// EXLOGE("can not parse new config data, not in json format?\n"); -// return false; -// } Json::CharReaderBuilder jcrb; std::unique_ptr const jreader(jcrb.newCharReader()); const char *str_json_begin = str_json.c_str(); @@ -145,7 +134,7 @@ bool TsCfg::_load(const ex_astr& str_json) { } //=================================== - // check ssh config + // check config //=================================== if(!_parse_app(m_root, "ssh", ssh)) return false; @@ -156,330 +145,5 @@ bool TsCfg::_load(const ex_astr& str_json) { if(!_parse_app(m_root, "rdp", rdp)) return false; -#if 0 - if (!m_root["ssh"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if (!m_root["ssh"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - sel_name = m_root["ssh"]["selected"].asCString(); - - if (!m_root["ssh"]["available"].isArray() || m_root["ssh"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - for (i = 0; i < m_root["ssh"]["available"].size(); ++i) { - - if ( - !m_root["ssh"]["available"][i]["name"].isString() - || !m_root["ssh"]["available"][i]["app"].isString() - || !m_root["ssh"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["ssh"]["available"][i]["display"].isNull()) { - m_root["ssh"]["available"][i]["display"] = m_root["ssh"]["available"][i]["name"]; - } - - if (m_root["ssh"]["available"][i]["name"].asCString() != sel_name) - continue; - - ssh_app = m_root["ssh"]["available"][i]["app"].asCString(); - ssh_cmdline = m_root["ssh"]["available"][i]["cmdline"].asCString(); - - break; - } - - if (ssh_app.length() == 0 || ssh_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } - - - //=================================== - // check sftp config - //=================================== - - if (!m_root["scp"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if (!m_root["scp"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - sel_name = m_root["scp"]["selected"].asCString(); - - if (!m_root["scp"]["available"].isArray() || m_root["scp"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - for (i = 0; i < m_root["sftp"]["available"].size(); ++i) { - - if ( - !m_root["sftp"]["available"][i]["name"].isString() - || !m_root["sftp"]["available"][i]["app"].isString() - || !m_root["sftp"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["scp"]["available"][i]["display"].isNull()) { - m_root["scp"]["available"][i]["display"] = m_root["scp"]["available"][i]["name"]; - } - - if (m_root["scp"]["available"][i]["name"].asCString() != sel_name) - continue; - -// tmp = m_root["scp"]["available"][i]["app"].asCString(); -// ex_astr2wstr(tmp, scp_app, EX_CODEPAGE_UTF8); - scp_app = m_root["scp"]["available"][i]["app"].asCString(); -// tmp = m_root["scp"]["available"][i]["cmdline"].asCString(); -// ex_astr2wstr(tmp, scp_cmdline, EX_CODEPAGE_UTF8); - scp_cmdline = m_root["scp"]["available"][i]["cmdline"].asCString(); - - break; - } - - if (scp_app.length() == 0 || scp_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } - - //=================================== - // check telnet config - //=================================== - - if (!m_root["telnet"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if (!m_root["telnet"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - sel_name = m_root["telnet"]["selected"].asCString(); - - if (!m_root["telnet"]["available"].isArray() || m_root["telnet"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - for (i = 0; i < m_root["telnet"]["available"].size(); ++i) { - - if ( - !m_root["telnet"]["available"][i]["name"].isString() - || !m_root["telnet"]["available"][i]["app"].isString() - || !m_root["telnet"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["telnet"]["available"][i]["display"].isNull()) { - m_root["telnet"]["available"][i]["display"] = m_root["telnet"]["available"][i]["name"]; - } - - if (m_root["telnet"]["available"][i]["name"].asCString() != sel_name) - continue; - -// tmp = m_root["telnet"]["available"][i]["app"].asCString(); -// ex_astr2wstr(tmp, telnet_app, EX_CODEPAGE_UTF8); -// tmp = m_root["telnet"]["available"][i]["cmdline"].asCString(); -// ex_astr2wstr(tmp, telnet_cmdline, EX_CODEPAGE_UTF8); - telnet_app = m_root["telnet"]["available"][i]["app"].asCString(); - telnet_cmdline = m_root["telnet"]["available"][i]["cmdline"].asCString(); - - break; - } - - if (telnet_app.length() == 0 || telnet_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - 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); - rdp_app = m_root["rdp"]["available"][i]["app"].asCString(); - rdp_cmdline = m_root["rdp"]["available"][i]["cmdline"].asCString(); - rdp_name = m_root["rdp"]["available"][i]["name"].asCString(); - - break; - } - - if (rdp_app.length() == 0 || rdp_cmdline.length() == 0 || rdp_name.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } -#endif - -#if 0 - // ------------ term --------------------- - - if (!m_root["term"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if( !m_root["term"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - term_name = m_root["term"]["selected"].asCString(); - - if(!m_root["term"]["available"].isArray() || m_root["term"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - int i = 0; - for (i = 0; i < m_root["term"]["available"].size(); ++i) { - - if( - !m_root["term"]["available"][i]["name"].isString() - || !m_root["term"]["available"][i]["app"].isString() - || !m_root["term"]["available"][i]["profile"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if(m_root["term"]["available"][i]["name"].asCString() != term_name) - continue; - - if(m_root["term"]["available"][i]["disp"].isString()) { - term_display = m_root["term"]["available"][i]["display"].asCString(); - } else if(m_root["term"]["available"][i]["disp"].isNull()) { - m_root["term"]["available"][i]["disp"] = term_name; - term_display = term_name; - } else { - EXLOGE("invalid config, error 5.\n"); - return false; - } - - term_app = m_root["term"]["available"][i]["app"].asCString(); - term_profile = m_root["term"]["available"][i]["profile"].asCString(); - - break; - } - - if(term_name.length() == 0 || term_app.length() == 0 || term_profile.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } - - // ------------ RDP --------------------- - - 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; - } - - rdp_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]["profile"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if(m_root["rdp"]["available"][i]["name"].asCString() != rdp_name) - continue; - - if(m_root["rdp"]["available"][i]["disp"].isString()) { - rdp_display = m_root["term"]["available"][i]["display"].asCString(); - } else if(m_root["rdp"]["available"][i]["disp"].isNull()) { - m_root["rdp"]["available"][i]["disp"] = rdp_name; - rdp_display = rdp_name; - } else { - EXLOGE("invalid config, error 5.\n"); - return false; - } - - rdp_app = m_root["rdp"]["available"][i]["app"].asCString(); - //rdp_profile = m_root["rdp"]["available"][i]["profile"].asCString(); - - break; - } - - if(rdp_name.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } -#endif - return true; } diff --git a/client/tp_assist_win/dlg_main.cpp b/client/tp_assist_win/dlg_main.cpp index fbb8bd7..d98d8b4 100644 --- a/client/tp_assist_win/dlg_main.cpp +++ b/client/tp_assist_win/dlg_main.cpp @@ -94,12 +94,6 @@ INT_PTR CALLBACK eomDlgMainProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARA return TRUE; }break; - case IDM_OPEN_CONFIG: - { - ShellExecute(nullptr, _T("open"), _T("http://127.0.0.1:50022/config"), nullptr, nullptr, SW_SHOW); - return TRUE; - }break; - default: break; } diff --git a/client/tp_assist_win/resource.h b/client/tp_assist_win/resource.h index 10cca6692a1384864e2110255bfb259ab8136513..cdbfde786fdd097a06f78cc9fa7c6181d861f557 100644 GIT binary patch delta 12 TcmaDQ*(14O2HWOuY+qObC6Wc7 delta 44 zcmeB?d?mSI2HRu>R+hphW8s**i9>Gl9JUXv01++> Aq5uE@ diff --git a/client/tp_assist_win/stdafx.h b/client/tp_assist_win/stdafx.h index 5d3df69..ba4b031 100644 --- a/client/tp_assist_win/stdafx.h +++ b/client/tp_assist_win/stdafx.h @@ -4,7 +4,7 @@ #include -#include "ts_network.h" +// #include "ts_network.h" //#include "ts_log.h" //#include "ts_ini.h" #include "ts_env.h" diff --git a/client/tp_assist_win/tp_assist.cpp b/client/tp_assist_win/tp_assist.cpp index 922d16c..2e79c41 100644 --- a/client/tp_assist_win/tp_assist.cpp +++ b/client/tp_assist_win/tp_assist.cpp @@ -3,10 +3,11 @@ #include #include "resource.h" #include "dlg_main.h" -#include "ts_http_rpc.h" +//#include "ts_http_rpc.h" +#include "ts_ws_client.h" #ifdef _DEBUG -# include +// # include #endif #pragma comment(lib, "shlwapi.lib") @@ -22,224 +23,252 @@ static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void failed(const char* msg); void failed(const wchar_t* msg); -static HANDLE g_SingleInstanceMutexHandle=NULL; +static HANDLE g_SingleInstanceMutexHandle = NULL; -HINSTANCE g_hInstance=NULL; -ULONG g_ulSingleInstanceMsgId=0; -static TCHAR szKernalName[MAX_PATH]={ 0 }; +HINSTANCE g_hInstance = NULL; +ULONG g_ulSingleInstanceMsgId = 0; +static TCHAR szKernalName[MAX_PATH] = { 0 }; -HWND g_hwndBase=NULL; -int g_argc=0; -wchar_t** g_argv=NULL; +HWND g_hwndBase = NULL; +int g_argc = 0; +wchar_t** g_argv = NULL; -#define EOM_ASSIST_GUID _T("A6EFE1250C5F4416BFA819FE92CBD4B4") -#define EOM_ASSIST_INSTANCE _T("TS_ASSIST_SINGLE_INSTANCE") -#define EOM_ASSIST_WIN_CLASS _T("TS_ASSIST_WINDOW_CLASS") -#define MAKEDWORD(low, high) ((DWORD)(((WORD)(((DWORD_PTR)(low)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(high)) & 0xffff))) << 16)) +ex_astr g_url_protocol; -DWORD WINAPI HttpServerThreadProc(LPVOID lpParam) { - http_rpc_main_loop(false); - return 0; -} +#define TP_ASSIST_GUID _T("A6EFE1250C5F4416BFA819FE92CBD4B4") +#define TP_ASSIST_INSTANCE _T("TS_ASSIST_SINGLE_INSTANCE") +#define TP_ASSIST_WIN_CLASS _T("TS_ASSIST_WINDOW_CLASS") +#define MAKEDWORD(low, high) ((DWORD)(((WORD)(((DWORD_PTR)(low)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(high)) & 0xffff))) << 16)) -DWORD WINAPI HttpsServerThreadProc(LPVOID lpParam) { - http_rpc_main_loop(true); - return 0; -} +//DWORD WINAPI HttpServerThreadProc(LPVOID lpParam) { +// http_rpc_main_loop(false); +// return 0; +//} +// +//DWORD WINAPI HttpsServerThreadProc(LPVOID lpParam) { +// http_rpc_main_loop(true); +// return 0; +//} int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) { - EXLOG_USE_LOGGER(&g_ex_logger); + EXLOG_USE_LOGGER(&g_ex_logger); - WORD wVersionRequested; - WSADATA wsaData; - int err; + WORD wVersionRequested; + WSADATA wsaData; + int err; - wVersionRequested=MAKEWORD(1, 1); + wVersionRequested = MAKEWORD(1, 1); - err=WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - return 0; - } + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + return 0; + } - if (LOBYTE(wsaData.wVersion) != 1 || - HIBYTE(wsaData.wVersion) != 1) { - WSACleanup(); - return 0; - } + if (LOBYTE(wsaData.wVersion) != 1 || + HIBYTE(wsaData.wVersion) != 1) { + WSACleanup(); + return 0; + } - g_env.init(); + g_env.init(); #ifdef EX_DEBUG - EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG); + EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG); #else - EXLOG_LEVEL(EX_LOG_LEVEL_INFO); + EXLOG_LEVEL(EX_LOG_LEVEL_INFO); #endif - EXLOG_FILE(L"tp_assist.log", g_env.m_log_path.c_str(), EX_LOG_FILE_MAX_SIZE, EX_LOG_FILE_MAX_COUNT); + EXLOG_FILE(L"tp_assist.log", g_env.m_log_path.c_str(), EX_LOG_FILE_MAX_SIZE, EX_LOG_FILE_MAX_COUNT); - // g_cfgSSH.init(); - // g_cfgScp.init(); - // g_cfgTelnet.init(); - g_cfg.init(); + if (!g_cfg.init()) { + MessageBox(NULL, _T("޷ļ"), _T(""), MB_OK | MB_ICONERROR); + return FALSE; + } - g_hInstance=hInstance; - _stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), EOM_ASSIST_GUID, EOM_ASSIST_INSTANCE); - g_ulSingleInstanceMsgId=RegisterWindowMessage(szKernalName); - if (0 == g_ulSingleInstanceMsgId) - return FALSE; + g_hInstance = hInstance; + _stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), TP_ASSIST_GUID, TP_ASSIST_INSTANCE); + g_ulSingleInstanceMsgId = RegisterWindowMessage(szKernalName); + if (0 == g_ulSingleInstanceMsgId) + return FALSE; - LPWSTR szCmdLine=(LPWSTR)::GetCommandLineW(); //ȡв - g_argv=CommandLineToArgvW(szCmdLine, &g_argc); //вַ - std::wstring arg; - for (int i=0; i < g_argc; ++i) { - arg = g_argv[i]; - if (0 == lstrcmp(g_argv[i], _T("--stop"))) { - PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_INSTANCE_EXIT, 0); - LocalFree(g_argv); - g_argv=NULL; - return -1; - }else if (arg.find(L"teleport_ip",0) !=std::wstring::npos && arg.find(L"teleport_port") != std::wstring::npos && arg.find(L"remote_host_ip") != std::wstring::npos && arg.find(L"session_id") != std::wstring::npos) { - //wchar_t **תΪstd::string - size_t len = wcslen(g_argv[i]) + 1; - size_t converted = 0; - char *CStr; - CStr = (char*)malloc(len * sizeof(char)); - wcstombs_s(&converted, CStr, len, g_argv[i], _TRUNCATE); - std::string func_args = CStr; - - //TsHttpRpc_rpc_func_run_clientͻ - TsHttpRpc ts_http_rpc; - ex_astr buf; - ts_http_rpc._rpc_func_url_protocol(func_args, buf); - - free(CStr); + LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //ȡв + g_argv = CommandLineToArgvW(szCmdLine, &g_argc); //вַ + + for (int i = 0; i < g_argc; ++i) { + ex_wstr arg = g_argv[i]; + if (0 == lstrcmp(g_argv[i], _T("--stop"))) { + PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_INSTANCE_EXIT, 0); LocalFree(g_argv); g_argv = NULL; - return 0; + return -1; } - } + else if (arg.find(L"teleport://", 0) == 0) { + // url-protocol + // teleport://register?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"} - // make sure run single instance. - _stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), EOM_ASSIST_GUID, EOM_ASSIST_INSTANCE); - g_SingleInstanceMutexHandle=CreateMutex(NULL, FALSE, szKernalName); - if (GetLastError() == ERROR_ALREADY_EXISTS) { - PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_SHOW_EXIST_DLGUI, 0); - CloseHandle(g_SingleInstanceMutexHandle); - LocalFree(g_argv); - g_argv=NULL; - return 0; - } + EXLOGV(L"url-protocol: %s\n", arg.c_str()); + ex_wstr2astr(arg, g_url_protocol); + + break; + } + } + + // make sure run single instance. + _stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), TP_ASSIST_GUID, TP_ASSIST_INSTANCE); + g_SingleInstanceMutexHandle = CreateMutex(NULL, FALSE, szKernalName); + if (GetLastError() == ERROR_ALREADY_EXISTS) { + // if we got url-protocol, send it by WM_COPYDATA, else just bring running instance to front. + if (g_url_protocol.empty()) + { + PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_SHOW_EXIST_DLGUI, 0); + } + else + { + HWND hwnd = FindWindow(TP_ASSIST_WIN_CLASS, NULL); + if (hwnd == NULL) { + MessageBoxW(NULL, _T("Ѿˣ޷λ"), _T(""), MB_OK | MB_ICONERROR); + } + else + { + COPYDATASTRUCT data; + data.dwData = NULL; + data.cbData = g_url_protocol.length() + 1; // include zero end. + data.lpData = (void*)g_url_protocol.c_str(); + SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&data); + } + } + + CloseHandle(g_SingleInstanceMutexHandle); + LocalFree(g_argv); + g_argv = NULL; + return 0; + } - // create dialog-box window. - MyRegisterClass(); + // create dialog-box window. + MyRegisterClass(); - // Perform application initialization: - if (!InitInstance()) { - CloseHandle(g_SingleInstanceMutexHandle); - LocalFree(g_argv); - g_argv=NULL; - return FALSE; - } + // Perform application initialization: + if (!InitInstance()) { + CloseHandle(g_SingleInstanceMutexHandle); + LocalFree(g_argv); + g_argv = NULL; + return FALSE; + } - HANDLE hThreadHttpServer=NULL; - DWORD dwThreadId=0; - hThreadHttpServer=CreateThread(NULL, 0, HttpServerThreadProc, NULL, 0, &dwThreadId); + //HANDLE hThreadHttpServer=NULL; + //DWORD dwThreadId=0; + //hThreadHttpServer=CreateThread(NULL, 0, HttpServerThreadProc, NULL, 0, &dwThreadId); - HANDLE hThreadHttpsServer=NULL; - dwThreadId=0; - hThreadHttpsServer=CreateThread(NULL, 0, HttpsServerThreadProc, NULL, 0, &dwThreadId); + //HANDLE hThreadHttpsServer=NULL; + //dwThreadId=0; + //hThreadHttpsServer=CreateThread(NULL, 0, HttpsServerThreadProc, NULL, 0, &dwThreadId); - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } - http_rpc_stop(false); - WaitForSingleObject(hThreadHttpServer, INFINITE); + //http_rpc_stop(false); + //WaitForSingleObject(hThreadHttpServer, INFINITE); - http_rpc_stop(true); - WaitForSingleObject(hThreadHttpsServer, INFINITE); + //http_rpc_stop(true); + //WaitForSingleObject(hThreadHttpsServer, INFINITE); - CloseHandle(g_SingleInstanceMutexHandle); + CloseHandle(g_SingleInstanceMutexHandle); - LocalFree(g_argv); - g_argv=NULL; - return 0; + LocalFree(g_argv); + g_argv = NULL; + return 0; } void failed(const char* msg) { - OutputDebugStringA(msg); + OutputDebugStringA(msg); } void failed(const wchar_t* msg) { - OutputDebugStringW(msg); + OutputDebugStringW(msg); } ATOM MyRegisterClass() { - WNDCLASSEX wcex; + WNDCLASSEX wcex; - wcex.cbSize=sizeof(WNDCLASSEX); + wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style=CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc=WndProc; - wcex.cbClsExtra=0; - wcex.cbWndExtra=0; - wcex.hInstance=g_hInstance; - wcex.hIcon=LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NORMAL_BIG)); - wcex.hCursor=LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1); - wcex.lpszMenuName=MAKEINTRESOURCE(IDR_ASSIST); - wcex.lpszClassName=EOM_ASSIST_WIN_CLASS; - wcex.hIconSm=LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_NORMAL_SMALL)); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = g_hInstance; + wcex.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NORMAL_BIG)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wcex.lpszMenuName = MAKEINTRESOURCE(IDR_ASSIST); + wcex.lpszClassName = TP_ASSIST_WIN_CLASS; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_NORMAL_SMALL)); - return RegisterClassEx(&wcex); + return RegisterClassEx(&wcex); } BOOL InitInstance(void) { - g_hwndBase=CreateWindow(EOM_ASSIST_WIN_CLASS, _T(""), WS_OVERLAPPEDWINDOW, 8, 0, 8, 0, NULL, NULL, g_hInstance, NULL); - if (!g_hwndBase) - return FALSE; + g_hwndBase = CreateWindow(TP_ASSIST_WIN_CLASS, _T(""), WS_OVERLAPPEDWINDOW, 8, 0, 8, 0, NULL, NULL, g_hInstance, NULL); + if (!g_hwndBase) + return FALSE; - ShowWindow(g_hwndBase, SW_HIDE); + ShowWindow(g_hwndBase, SW_HIDE); - return TRUE; + return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (g_ulSingleInstanceMsgId == message) { - if (WMU_INSTANCE_EXIT == wParam) { - PostMessage(g_hDlgMain, WM_COMMAND, MAKEDWORD(IDCANCEL, 0), NULL); - return 0; - } else if (WMU_SHOW_EXIST_DLGUI == wParam) { - ShowWindow(g_hDlgMain, SW_SHOW); - SetWindowPos(g_hDlgMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - SetActiveWindow(g_hDlgMain); - BringWindowToTop(g_hDlgMain); - SetWindowPos(g_hDlgMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - return 0; - } - } + if (g_ulSingleInstanceMsgId == message) { + if (WMU_INSTANCE_EXIT == wParam) { + PostMessage(g_hDlgMain, WM_COMMAND, MAKEDWORD(IDCANCEL, 0), NULL); + return 0; + } + else if (WMU_SHOW_EXIST_DLGUI == wParam) { + ShowWindow(g_hDlgMain, SW_SHOW); + SetWindowPos(g_hDlgMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetActiveWindow(g_hDlgMain); + BringWindowToTop(g_hDlgMain); + SetWindowPos(g_hDlgMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + return 0; + } + } - switch (message) { - case WM_CREATE: - PostMessage(hWnd, WM_COMMAND, MAKEDWORD(IDM_MAIN, 0), NULL); - return DefWindowProc(hWnd, message, wParam, lParam); - break; - case WM_COMMAND: + switch (message) { + case WM_CREATE: + PostMessage(hWnd, WM_COMMAND, MAKEDWORD(IDM_MAIN, 0), NULL); - if (IDM_MAIN == LOWORD(wParam)) { - CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DLG_MAIN), hWnd, eomDlgMainProc); - ShowWindow(g_hDlgMain, SW_HIDE); - } - break; - case WM_DESTROY: - SendMessage(g_hDlgMain, WMU_DLG_MAIN_EXIT, NULL, NULL); - PostQuitMessage(0); - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; + if (!g_url_protocol.empty()) + { + TsWsClient::url_scheme_handler(g_url_protocol); + } + + return DefWindowProc(hWnd, message, wParam, lParam); + break; + case WM_COMMAND: + if (IDM_MAIN == LOWORD(wParam)) { + CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DLG_MAIN), hWnd, eomDlgMainProc); + ShowWindow(g_hDlgMain, SW_HIDE); + } + break; + case WM_DESTROY: + TsWsClient::stop_all_client(); + SendMessage(g_hDlgMain, WMU_DLG_MAIN_EXIT, NULL, NULL); + PostQuitMessage(0); + break; + case WM_COPYDATA: + { + COPYDATASTRUCT* data = (COPYDATASTRUCT*)lParam; + ex_astr url_protocol((char*)data->lpData); + // MessageBoxA(hWnd, url_protocol.c_str(), "url-protocol", MB_OK); + TsWsClient::url_scheme_handler(url_protocol); + break; + } + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; } diff --git a/client/tp_assist_win/tp_assist.rc b/client/tp_assist_win/tp_assist.rc index 8f6c38901e8496556373fd152b05cd6ee99733e5..76388273875ba434bbd94ed654695e6194f82cf1 100644 GIT binary patch delta 59 zcmccNGS7Jfo7m<9Vj)b7ypx3`4JY?VN^Fjj+{HAxNLFXElgt)Iqs`xCj2VGkvB@EF PLX*#kb8U{3`^5|ZSr-%Z delta 93 zcmbQ|e8Xh}n;5h2#JtI}Vycrjh{#O#664}_X7Fe5V{l{eWN@E6QA~YugP7H3Hn9+< s$uSZJoBJd#FtNrk7%(VJPL#gOXt3E{#+VT%AR;_@maNd`S+XoF0M#NHE&u=k diff --git a/client/tp_assist_win/tp_assist.vs2017.vcxproj b/client/tp_assist_win/tp_assist.vs2017.vcxproj index c5ef904..d75cf4f 100644 --- a/client/tp_assist_win/tp_assist.vs2017.vcxproj +++ b/client/tp_assist_win/tp_assist.vs2017.vcxproj @@ -15,19 +15,19 @@ Win32Proj tp_assist tp_assist - 8.1 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode false @@ -106,7 +106,6 @@ - @@ -114,9 +113,9 @@ - - + + @@ -160,7 +159,6 @@ NotUsing - Create Create @@ -168,8 +166,14 @@ - - + + NotUsing + NotUsing + + + Use + Use + diff --git a/client/tp_assist_win/tp_assist.vs2017.vcxproj.filters b/client/tp_assist_win/tp_assist.vs2017.vcxproj.filters index c020865..8a2d763 100644 --- a/client/tp_assist_win/tp_assist.vs2017.vcxproj.filters +++ b/client/tp_assist_win/tp_assist.vs2017.vcxproj.filters @@ -1,180 +1,174 @@ - - - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - jsoncpp - - - jsoncpp - - - jsoncpp - - - mongoose - - - libex\src - - - libex\src - - - libex\src - - - libex\src - - - libex\src - - - libex\src - - - - - resource - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - main app - - - mongoose - - - main app - - - libex\header - - - libex\header - - - libex\header - - - libex\header - - - libex\header - - - libex\header - - - libex\header - - - main app - - - main app - - - libex\header - - - libex\header - - - libex\header - - - teleport - - - - - resource - - - resource - - - resource - - - - - {52b425b1-8aa9-4e08-acbd-c88387350530} - - - {adabe93d-3938-4b11-9352-5b67a1efd7e3} - - - {35a345a0-6147-4c87-97c9-3b0b2a57e348} - - - {0942cec3-67df-4d19-bbc1-e962145e496f} - - - {a88e05d3-51f4-463f-84cc-c3bc86f07aac} - - - {e3e7a811-5905-4ad5-86a7-9721af5d015a} - - - {d7d49fa4-5192-42c5-bc70-5584d9d646c6} - - - {1291a5cf-cb08-4ad6-8a86-8a0486297c63} - - - - - resource - - - - - jsoncpp - - + + + + + main app + + + main app + + + main app + + + main app + + + main app + + + jsoncpp + + + jsoncpp + + + jsoncpp + + + mongoose + + + libex\src + + + libex\src + + + libex\src + + + libex\src + + + libex\src + + + libex\src + + + main app + + + main app + + + + + resource + + + main app + + + main app + + + main app + + + main app + + + main app + + + main app + + + mongoose + + + libex\header + + + libex\header + + + libex\header + + + libex\header + + + libex\header + + + libex\header + + + libex\header + + + main app + + + main app + + + libex\header + + + libex\header + + + libex\header + + + teleport + + + main app + + + main app + + + + + resource + + + resource + + + resource + + + + + {52b425b1-8aa9-4e08-acbd-c88387350530} + + + {adabe93d-3938-4b11-9352-5b67a1efd7e3} + + + {35a345a0-6147-4c87-97c9-3b0b2a57e348} + + + {0942cec3-67df-4d19-bbc1-e962145e496f} + + + {a88e05d3-51f4-463f-84cc-c3bc86f07aac} + + + {e3e7a811-5905-4ad5-86a7-9721af5d015a} + + + {d7d49fa4-5192-42c5-bc70-5584d9d646c6} + + + {1291a5cf-cb08-4ad6-8a86-8a0486297c63} + + + + + resource + + + + + jsoncpp + + \ No newline at end of file diff --git a/client/tp_assist_win/ts_cfg.cpp b/client/tp_assist_win/ts_cfg.cpp index f9214f6..e4274b7 100644 --- a/client/tp_assist_win/ts_cfg.cpp +++ b/client/tp_assist_win/ts_cfg.cpp @@ -21,6 +21,20 @@ bool TsCfg::init(void) { if (!_load(file_content)) return false; + if (!m_root.isObject()) { + EXLOGE("invalid config file, not in json format?\n"); + return false; + } + + if (m_root["file_version"].isNull()) { + EXLOGE("invalid config file, maybe need create new one?\n"); + return false; + } + + if (!m_root["file_version"].isInt()) { + + } + return true; } @@ -29,8 +43,9 @@ bool TsCfg::save(const ex_astr& new_value) if (!_load(new_value)) return false; - //Json::StyledWriter jwriter; Json::StreamWriterBuilder jwb; + jwb["indentation"] = " "; + jwb["emitUTF8"] = true; std::unique_ptr jwriter(jwb.newStreamWriter()); ex_aoss os; jwriter->write(m_root, &os); @@ -44,8 +59,78 @@ bool TsCfg::save(const ex_astr& new_value) return true; } +bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg) { + const Json::Value& jApp = m_root[str_app.c_str()]; + if (!jApp.isObject()) + return false; + + if (!jApp["selected"].isString()) { + EXLOGE("invalid config, error 2.\n"); + return false; + } + ex_astr _selected = jApp["selected"].asCString();; + + if (!jApp["available"].isArray() || jApp["available"].size() == 0) { + EXLOGE("invalid config, error 3.\n"); + return false; + } + const Json::Value& jAppList = jApp["available"]; + + ex_astr tmp_val; + for (size_t i = 0; i < jAppList.size(); ++i) { + if ( + !jAppList[i]["name"].isString() + || !jAppList[i]["app"].isString() + || !jAppList[i]["cmdline"].isString() + || !jAppList[i]["desc"].isArray() + ) { + EXLOGE("invalid config, error 4.\n"); + return false; + } + + if (jAppList[i]["name"].asString().empty()) { + EXLOGE("invalid config, need name.\n"); + return false; + } + + if (jAppList[i]["display"].isNull() || jAppList[i]["display"].asString().empty()) { + tmp_val = jAppList[i]["name"].asString(); + } + else + tmp_val = jAppList[i]["display"].asString(); + ex_astr2wstr(tmp_val, cfg.display); + + if (jAppList[i]["name"].asString() != _selected) + continue; + + tmp_val = jAppList[i]["name"].asString(); + ex_astr2wstr(tmp_val, cfg.name); + + // cfg.display = jAppList[i]["display"].asCString(); + tmp_val = jAppList[i]["app"].asCString(); + ex_astr2wstr(tmp_val, cfg.application); + tmp_val = jAppList[i]["cmdline"].asCString(); + ex_astr2wstr(tmp_val, cfg.cmdline); + + if (jAppList[i]["desc"].size() > 0) { + const Json::Value& jAppDescList = jAppList[i]["desc"]; + + for (size_t j = 0; j < jAppDescList.size(); ++j) { + if (!jAppDescList[j].isString()) + return false; + ex_wstr w_tmp; + ex_astr2wstr(jAppDescList[j].asString(), w_tmp); + cfg.description.push_back(w_tmp); + } + } + + break; + } + + return true; +} + bool TsCfg::_load(const ex_astr& str_json) { - //Json::Reader jreader; Json::CharReaderBuilder jcrb; std::unique_ptr const jreader(jcrb.newCharReader()); const char *str_json_begin = str_json.c_str(); @@ -56,219 +141,17 @@ bool TsCfg::_load(const ex_astr& str_json) { return false; } - ex_astr sel_name; - size_t i = 0; - ex_astr tmp; - //=================================== - // check ssh config + // check config //=================================== - - if (!m_root["ssh"].isObject()) { - EXLOGE("invalid config, error 1.\n"); + if (!_parse_app(m_root, "ssh", ssh)) return false; - } - - if (!m_root["ssh"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); + if (!_parse_app(m_root, "sftp", sftp)) return false; - } - - sel_name = m_root["ssh"]["selected"].asCString(); - - if (!m_root["ssh"]["available"].isArray() || m_root["ssh"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); + if(!_parse_app(m_root, "telnet", telnet)) + return false; + if (!_parse_app(m_root, "rdp", rdp)) return false; - } - - for (i = 0; i < m_root["ssh"]["available"].size(); ++i) { - - if ( - !m_root["ssh"]["available"][i]["name"].isString() - || !m_root["ssh"]["available"][i]["app"].isString() - || !m_root["ssh"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["ssh"]["available"][i]["display"].isNull()) { - m_root["ssh"]["available"][i]["display"] = m_root["ssh"]["available"][i]["name"]; - } - - if (m_root["ssh"]["available"][i]["name"].asCString() != sel_name) - continue; - - tmp = m_root["ssh"]["available"][i]["app"].asCString(); - ex_astr2wstr(tmp, ssh_app, EX_CODEPAGE_UTF8); - tmp = m_root["ssh"]["available"][i]["cmdline"].asCString(); - ex_astr2wstr(tmp, ssh_cmdline, EX_CODEPAGE_UTF8); - - break; - } - - if (ssh_app.length() == 0 || ssh_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } - - //=================================== - // check sftp config - //=================================== - - if (!m_root["scp"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if (!m_root["scp"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - sel_name = m_root["scp"]["selected"].asCString(); - - if (!m_root["scp"]["available"].isArray() || m_root["scp"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - for (i = 0; i < m_root["scp"]["available"].size(); ++i) { - - if ( - !m_root["scp"]["available"][i]["name"].isString() - || !m_root["scp"]["available"][i]["app"].isString() - || !m_root["scp"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["scp"]["available"][i]["display"].isNull()) { - m_root["scp"]["available"][i]["display"] = m_root["scp"]["available"][i]["name"]; - } - - if (m_root["scp"]["available"][i]["name"].asCString() != sel_name) - continue; - - tmp = m_root["scp"]["available"][i]["app"].asCString(); - ex_astr2wstr(tmp, scp_app, EX_CODEPAGE_UTF8); - tmp = m_root["scp"]["available"][i]["cmdline"].asCString(); - ex_astr2wstr(tmp, scp_cmdline, EX_CODEPAGE_UTF8); - - break; - } - - if (scp_app.length() == 0 || scp_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - return false; - } - - //=================================== - // check telnet config - //=================================== - - if (!m_root["telnet"].isObject()) { - EXLOGE("invalid config, error 1.\n"); - return false; - } - - if (!m_root["telnet"]["selected"].isString()) { - EXLOGE("invalid config, error 2.\n"); - return false; - } - - sel_name = m_root["telnet"]["selected"].asCString(); - - if (!m_root["telnet"]["available"].isArray() || m_root["telnet"]["available"].size() == 0) { - EXLOGE("invalid config, error 3.\n"); - return false; - } - - for (i = 0; i < m_root["telnet"]["available"].size(); ++i) { - - if ( - !m_root["telnet"]["available"][i]["name"].isString() - || !m_root["telnet"]["available"][i]["app"].isString() - || !m_root["telnet"]["available"][i]["cmdline"].isString() - ) { - EXLOGE("invalid config, error 4.\n"); - return false; - } - - if (m_root["telnet"]["available"][i]["display"].isNull()) { - m_root["telnet"]["available"][i]["display"] = m_root["telnet"]["available"][i]["name"]; - } - - if (m_root["telnet"]["available"][i]["name"].asCString() != sel_name) - continue; - - tmp = m_root["telnet"]["available"][i]["app"].asCString(); - ex_astr2wstr(tmp, telnet_app, EX_CODEPAGE_UTF8); - tmp = m_root["telnet"]["available"][i]["cmdline"].asCString(); - ex_astr2wstr(tmp, telnet_cmdline, EX_CODEPAGE_UTF8); - - break; - } - - if (telnet_app.length() == 0 || telnet_cmdline.length() == 0) { - EXLOGE("invalid config, error 6.\n"); - 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 4e0d6cd..6a33a56 100644 --- a/client/tp_assist_win/ts_cfg.h +++ b/client/tp_assist_win/ts_cfg.h @@ -6,6 +6,14 @@ #include +typedef struct APP_CONFIG { + ex_wstr name; + ex_wstr display; + ex_wstr application; + ex_wstr cmdline; + ex_wstrs description; +}APP_CONFIG; + class TsCfg { public: @@ -17,19 +25,14 @@ public: Json::Value& get_root() { return m_root; } - ex_wstr ssh_app; - ex_wstr ssh_cmdline; - ex_wstr scp_app; - ex_wstr scp_cmdline; - ex_wstr telnet_app; - ex_wstr telnet_cmdline; - - ex_wstr rdp_name; - ex_wstr rdp_app; - ex_wstr rdp_cmdline; + APP_CONFIG ssh; + APP_CONFIG sftp; + APP_CONFIG telnet; + APP_CONFIG rdp; protected: bool _load(const ex_astr& str_json); + bool _parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg); protected: Json::Value m_root; diff --git a/client/tp_assist_win/ts_const.h b/client/tp_assist_win/ts_const.h index a5197d3..a89efb7 100644 --- a/client/tp_assist_win/ts_const.h +++ b/client/tp_assist_win/ts_const.h @@ -4,7 +4,7 @@ #define TS_WEB_URL L"https://tp4a.com/" #define TS_TRAY_MSG L"Teleport" -#define TS_HTTP_RPC_PORT 50022 -#define TS_HTTPS_RPC_PORT 50023 +//#define TS_HTTP_RPC_PORT 50022 +//#define TS_HTTPS_RPC_PORT 50023 #endif // __TS_CONST_H__ diff --git a/client/tp_assist_win/ts_env.cpp b/client/tp_assist_win/ts_env.cpp index 767ef7b..e267ec1 100644 --- a/client/tp_assist_win/ts_env.cpp +++ b/client/tp_assist_win/ts_env.cpp @@ -37,22 +37,10 @@ bool TsEnv::init(void) ex_wstr cfg_default; #ifdef _DEBUG - m_site_path = m_exec_path; - ex_path_join(m_site_path, true, L"..", L"..", L"..", L"..", L"client", L"tp_assist_win", L"site", NULL); - -// m_tools_path = m_exec_path; -// ex_path_join(m_tools_path, true, L"..", L"..", L"..", L"..", L"client", L"tools", NULL); - cfg_default = m_exec_path; ex_path_join(cfg_default, true, L"..", L"..", L"..", L"..", L"client", L"tp_assist_win", L"cfg", L"tp-assist.default.json", NULL); #else - m_site_path = m_exec_path; - ex_path_join(m_site_path, false, L"site", NULL); - -// m_tools_path = m_exec_path; -// ex_path_join(m_tools_path, false, L"tools", NULL); - cfg_default = m_exec_path; ex_path_join(cfg_default, false, L"tp-assist.default.json", NULL); #endif diff --git a/client/tp_assist_win/ts_env.h b/client/tp_assist_win/ts_env.h index d96c01b..87e0a8e 100644 --- a/client/tp_assist_win/ts_env.h +++ b/client/tp_assist_win/ts_env.h @@ -14,15 +14,8 @@ public: public: ex_wstr m_exec_file; ex_wstr m_exec_path; - - ex_wstr m_cfg_file; -// ex_wstr m_res_path; - -// ex_wstr m_ssh_client_conf_file; -// ex_wstr m_scp_client_conf_file; -// ex_wstr m_telnet_client_conf_file; + ex_wstr m_cfg_file; ex_wstr m_log_path; - ex_wstr m_site_path; ex_wstr m_tools_path; }; diff --git a/client/tp_assist_win/ts_http_rpc.cpp b/client/tp_assist_win/ts_http_rpc.cpp deleted file mode 100644 index 0916e89..0000000 --- a/client/tp_assist_win/ts_http_rpc.cpp +++ /dev/null @@ -1,1191 +0,0 @@ -#include "stdafx.h" - -#pragma warning(disable:4091) - -#include -#include -#include - -#pragma comment(lib, "Crypt32.lib") - -#include - -#include "ts_http_rpc.h" -#include "dlg_main.h" -#include "ts_ver.h" -#include "ts_env.h" - -/* -1. -SecureCRT支持设置标签页的标题,命令行参数 /N "tab name"就可以 -Example: -To launch a new Telnet session, displaying the name "Houston, TX" on the tab, use the following: -/T /N "Houston, TX" /TELNET 192.168.0.6 - -2. -多次启动的SecureCRT放到一个窗口的不同标签页中,使用参数: /T - SecureCRT.exe /T /N "TP#ssh://192.168.1.3" /SSH2 /L root /PASSWORD 1234 120.26.109.25 - -3. -telnet客户端的启动: - putty.exe telnet://administrator@127.0.0.1:52389 -如果是SecureCRT,则需要 - SecureCRT.exe /T /N "TP#telnet://192.168.1.3" /SCRIPT X:\path\to\startup.vbs /TELNET 127.0.0.1 52389 -其中,startup.vbs的内容为: ----------文件开始--------- -#$language = "VBScript" -#$interface = "1.0" -Sub main - crt.Screen.Synchronous = True - crt.Screen.WaitForString "ogin: " - crt.Screen.Send "SESSION-ID" & VbCr - crt.Screen.Synchronous = False -End Sub ----------文件结束--------- - -4. 为了让putty的窗口标签显示正常的IP,可以尝试在连接成功后,主动向服务端发送下列命令: - PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@192.168.1.2: \w\a\]$PS1" -手工测试了,ubuntu服务器可以,不知道是否能够支持所有的Linux。SecureCRT对此表示忽略。 -*/ - -//#define RDP_CLIENT_SYSTEM_BUILTIN -// #define RDP_CLIENT_SYSTEM_ACTIVE_CONTROL -//#define RDP_CLIENT_FREERDP - - -//#ifdef RDP_CLIENT_SYSTEM_BUILTIN - -//connect to console:i:%d -//compression:i:1 -//bitmapcachepersistenable:i:1 - -std::string rdp_content = "\ -administrative session:i:%d\n\ -screen mode id:i:%d\n\ -use multimon:i:0\n\ -desktopwidth:i:%d\n\ -desktopheight:i:%d\n\ -session bpp:i:16\n\ -winposstr:s:0,1,%d,%d,%d,%d\n\ -bitmapcachepersistenable:i:1\n\ -bitmapcachesize:i:32000\n\ -compression:i:1\n\ -keyboardhook:i:2\n\ -audiocapturemode:i:0\n\ -videoplaybackmode:i:1\n\ -connection type:i:7\n\ -networkautodetect:i:1\n\ -bandwidthautodetect:i:1\n\ -disableclipboardredirection:i:0\n\ -displayconnectionbar:i:1\n\ -enableworkspacereconnect:i:0\n\ -disable wallpaper:i:1\n\ -allow font smoothing:i:0\n\ -allow desktop composition:i:0\n\ -disable full window drag:i:1\n\ -disable menu anims:i:1\n\ -disable themes:i:1\n\ -disable cursor setting:i:1\n\ -full address:s:%s:%d\n\ -audiomode:i:0\n\ -redirectprinters:i:0\n\ -redirectcomports:i:0\n\ -redirectsmartcards:i:0\n\ -redirectclipboard:i:%d\n\ -redirectposdevices:i:0\n\ -autoreconnection enabled:i:0\n\ -authentication level:i:2\n\ -prompt for credentials:i:0\n\ -negotiate security layer:i:1\n\ -remoteapplicationmode:i:0\n\ -alternate shell:s:\n\ -shell working directory:s:\n\ -gatewayhostname:s:\n\ -gatewayusagemethod:i:4\n\ -gatewaycredentialssource:i:4\n\ -gatewayprofileusagemethod:i:0\n\ -promptcredentialonce:i:0\n\ -gatewaybrokeringtype:i:0\n\ -use redirection server name:i:0\n\ -rdgiskdcproxy:i:0\n\ -kdcproxyname:s:\n\ -drivestoredirect:s:%s\n\ -username:s:%s\n\ -password 51:b:%s\n\ -"; - -// https://www.donkz.nl/overview-rdp-file-settings/ -// -// authentication level:i:2\n -// -// -// negotiate security layer:i:1\n -// 0 = negotiation is not enabled and the session is started by using Secure Sockets Layer (SSL). -// 1 = negotiation is enabled and the session is started by using x.224 encryption. - - - -//redirectdirectx:i:0\n\ -//prompt for credentials on client:i:0\n\ - -//#endif - - -TsHttpRpc g_http_interface; -TsHttpRpc g_https_interface; - -void http_rpc_main_loop(bool is_https) { - if (is_https) { - if (!g_https_interface.init_https()) { - EXLOGE("[ERROR] can not start HTTPS-RPC listener, maybe port %d is already in use.\n", TS_HTTPS_RPC_PORT); - return; - } - - EXLOGW("======================================================\n"); - EXLOGW("[rpc] TeleportAssist-HTTPS-RPC ready on 127.0.0.1:%d\n", TS_HTTPS_RPC_PORT); - - g_https_interface.run(); - - EXLOGW("[rpc] HTTPS-Server main loop end.\n"); - } else { - if (!g_http_interface.init_http()) { - EXLOGE("[ERROR] can not start HTTP-RPC listener, maybe port %d is already in use.\n", TS_HTTP_RPC_PORT); - return; - } - - EXLOGW("======================================================\n"); - EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on 127.0.0.1:%d\n", TS_HTTP_RPC_PORT); - - g_http_interface.run(); - - EXLOGW("[rpc] HTTP-Server main loop end.\n"); - } -} - -void http_rpc_stop(bool is_https) { - if (is_https) - g_https_interface.stop(); - else - g_http_interface.stop(); -} - -#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W') - -int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded) { - int i, j, a, b; - - for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) { - if (src[i] == '%') { - if (i < src_len - 2 && isxdigit(*(const unsigned char *)(src + i + 1)) && - isxdigit(*(const unsigned char *)(src + i + 2))) { - a = tolower(*(const unsigned char *)(src + i + 1)); - b = tolower(*(const unsigned char *)(src + i + 2)); - dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b)); - i += 2; - } else { - return -1; - } - } else if (is_form_url_encoded && src[i] == '+') { - dst[j] = ' '; - } else { - dst[j] = src[i]; - } - } - - dst[j] = '\0'; /* Null-terminate the destination */ - - return i >= src_len ? j : -1; -} - -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", nullptr, nullptr, nullptr, 0, &DataOut)) - return false; - - char szRet[5] = { 0 }; - for (DWORD i = 0; i < DataOut.cbData; ++i) { - sprintf_s(szRet, 5, "%02X", DataOut.pbData[i]); - ret += szRet; - } - - LocalFree(DataOut.pbData); - return true; -} - -bool isDegital(std::string str) { - for (int i = 0; i < str.size(); i++) { - if (str.at(i) == '-' && str.size() > 1) // 有可能出现负数 - continue; - if (str.at(i) > '9' || str.at(i) < '0') - return false; - } - return true; -} - -std::string strtolower(std::string str) { - for (int i = 0; i < str.size(); i++) - { - str[i] = tolower(str[i]); - } - return str; -} - -void SplitString(const std::string& s, std::vector& v, const std::string& c) -{ - std::string::size_type pos1, pos2; - pos2 = s.find(c); - pos1 = 0; - while (std::string::npos != pos2) - { - v.push_back(s.substr(pos1, pos2 - pos1)); - - pos1 = pos2 + c.size(); - pos2 = s.find(c, pos1); - } - if (pos1 != s.length()) - v.push_back(s.substr(pos1)); -} - -TsHttpRpc::TsHttpRpc() { - m_stop = false; - mg_mgr_init(&m_mg_mgr, nullptr); -} - -TsHttpRpc::~TsHttpRpc() { - mg_mgr_free(&m_mg_mgr); -} - -bool TsHttpRpc::init_http() { - struct mg_connection* nc = nullptr; - - char addr[128] = { 0 }; - ex_strformat(addr, 128, "tcp://127.0.0.1:%d", TS_HTTP_RPC_PORT); - - nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler); - if (!nc) { - EXLOGE("[rpc] TsHttpRpc::init 127.0.0.1:%d\n", TS_HTTP_RPC_PORT); - return false; - } - nc->user_data = this; - - mg_set_protocol_http_websocket(nc); - - return _on_init(); -} - -bool TsHttpRpc::init_https() { - ex_wstr file_ssl_cert = g_env.m_exec_path; - ex_path_join(file_ssl_cert, true, L"cfg", L"localhost.pem", NULL); - ex_wstr file_ssl_key = g_env.m_exec_path; - ex_path_join(file_ssl_key, true, L"cfg", L"localhost.key", NULL); - ex_astr _ssl_cert; - ex_wstr2astr(file_ssl_cert, _ssl_cert); - ex_astr _ssl_key; - ex_wstr2astr(file_ssl_key, _ssl_key); - - const char *err = NULL; - struct mg_bind_opts bind_opts; - memset(&bind_opts, 0, sizeof(bind_opts)); - bind_opts.ssl_cert = _ssl_cert.c_str(); - bind_opts.ssl_key = _ssl_key.c_str(); - bind_opts.error_string = &err; - - - char addr[128] = { 0 }; - ex_strformat(addr, 128, "tcp://127.0.0.1:%d", TS_HTTPS_RPC_PORT); - - struct mg_connection* nc = nullptr; - nc = mg_bind_opt(&m_mg_mgr, addr, _mg_event_handler, bind_opts); - if (!nc) { - EXLOGE("[rpc] TsHttpRpc::init 127.0.0.1:%d\n", TS_HTTPS_RPC_PORT); - return false; - } - nc->user_data = this; - - mg_set_protocol_http_websocket(nc); - - return _on_init(); -} - -bool TsHttpRpc::_on_init() { - char file_name[MAX_PATH] = { 0 }; - if (!GetModuleFileNameA(nullptr, file_name, MAX_PATH)) - return false; - - int len = strlen(file_name); - - if (file_name[len] == '\\') - file_name[len] = '\0'; - - char* match = strrchr(file_name, '\\'); - if (match) - *match = '\0'; - - m_content_type_map[".js"] = "application/javascript"; - m_content_type_map[".png"] = "image/png"; - m_content_type_map[".jpeg"] = "image/jpeg"; - m_content_type_map[".jpg"] = "image/jpeg"; - m_content_type_map[".gif"] = "image/gif"; - m_content_type_map[".ico"] = "image/x-icon"; - m_content_type_map[".json"] = "image/json"; - m_content_type_map[".html"] = "text/html"; - m_content_type_map[".css"] = "text/css"; - m_content_type_map[".tif"] = "image/tiff"; - m_content_type_map[".tiff"] = "image/tiff"; - m_content_type_map[".svg"] = "text/html"; - - return true; -} - -void TsHttpRpc::run(void) { - while (!m_stop) { - mg_mgr_poll(&m_mg_mgr, 500); - } -} - -void TsHttpRpc::stop(void) { - m_stop = true; -} - -void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_data) { - struct http_message *hm = (struct http_message*)ev_data; - - TsHttpRpc* _this = (TsHttpRpc*)nc->user_data; - if (!_this) { - EXLOGE("[ERROR] invalid http request.\n"); - return; - } - - switch (ev) { - case MG_EV_HTTP_REQUEST: - { - ex_astr uri; - ex_chars _uri; - _uri.resize(hm->uri.len + 1); - memset(&_uri[0], 0, hm->uri.len + 1); - memcpy(&_uri[0], hm->uri.p, hm->uri.len); - uri = &_uri[0]; - -#ifdef EX_DEBUG - char* dbg_method = nullptr; - if (hm->method.len == 3 && 0 == memcmp(hm->method.p, "GET", hm->method.len)) - dbg_method = "GET"; - else if (hm->method.len == 4 && 0 == memcmp(hm->method.p, "POST", hm->method.len)) - dbg_method = "POST"; - else - dbg_method = "UNSUPPORTED-HTTP-METHOD"; - - EXLOGV("[rpc] got %s request: %s\n", dbg_method, uri.c_str()); -#endif - ex_astr ret_buf; - bool b_is_html = false; - -// if (uri == "/") { -// ex_wstr page = L"Teleport助手\n\n
Teleport助手工作正常!
"; -// ex_wstr2astr(page, ret_buf, EX_CODEPAGE_UTF8); -// -// mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n%s", ret_buf.size() - 1, &ret_buf[0]); -// nc->flags |= MG_F_SEND_AND_CLOSE; -// return; -// } - - if (uri == "/") { - uri = "/status.html"; - b_is_html = true; - } - else if (uri == "/config") { - uri = "/index.html"; - b_is_html = true; - } - - ex_astr temp; - int offset = uri.find("/", 1); - if (offset > 0) { - temp = uri.substr(1, offset - 1); - - if (temp == "api") { - ex_astr method; - ex_astr json_param; - int rv = _this->_parse_request(hm, method, json_param); - if (0 != rv) { - EXLOGE("[ERROR] http-rpc got invalid request.\n"); - _this->_create_json_ret(ret_buf, rv); - } else { - _this->_process_js_request(method, json_param, ret_buf); - } - - mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: application/json\r\n\r\n%s", ret_buf.length(), &ret_buf[0]); - nc->flags |= MG_F_SEND_AND_CLOSE; - return; - } - } - - - ex_astr file_suffix; - offset = uri.rfind("."); - if (offset > 0) { - file_suffix = uri.substr(offset, uri.length()); - } - - ex_wstr2astr(g_env.m_site_path, temp); - ex_astr index_path = temp + uri; - - - FILE* file = ex_fopen(index_path.c_str(), "rb"); - if (file) { - unsigned long file_size = 0; - char* buf = nullptr; - size_t ret = 0; - - fseek(file, 0, SEEK_END); - file_size = ftell(file); - buf = new char[file_size]; - memset(buf, 0, file_size); - fseek(file, 0, SEEK_SET); - ret = fread(buf, 1, file_size, file); - fclose(file); - - ex_astr content_type = _this->get_content_type(file_suffix); - - mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: %s\r\n\r\n", file_size, content_type.c_str()); - mg_send(nc, buf, (int)file_size); - delete[]buf; - nc->flags |= MG_F_SEND_AND_CLOSE; - return; - } else if (b_is_html) { - ex_wstr page = L"404 Not Found

404 Not Found


Teleport Assistor configuration page not found.

"; - ex_wstr2astr(page, ret_buf, EX_CODEPAGE_UTF8); - - mg_printf(nc, "HTTP/1.0 404 File Not Found\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: text/html\r\n\r\n%s", ret_buf.size() - 1, &ret_buf[0]); - nc->flags |= MG_F_SEND_AND_CLOSE; - return; - } - - } - break; - default: - break; - } -} - -int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args) { - if (!req) - return TPE_FAILED; - - bool is_get = true; - if (req->method.len == 3 && 0 == memcmp(req->method.p, "GET", req->method.len)) - is_get = true; - else if (req->method.len == 4 && 0 == memcmp(req->method.p, "POST", req->method.len)) - is_get = false; - else - return TPE_HTTP_METHOD; - - ex_astrs strs; - - size_t pos_start = 1; // 跳过第一个字节,一定是 '/' - - size_t i = 0; - for (i = pos_start; i < req->uri.len; ++i) { - if (req->uri.p[i] == '/') { - if (i - pos_start > 0) { - ex_astr tmp_uri; - tmp_uri.assign(req->uri.p + pos_start, i - pos_start); - strs.push_back(tmp_uri); - } - pos_start = i + 1; // 跳过当前找到的分隔符 - } - } - if (pos_start < req->uri.len) { - ex_astr tmp_uri; - tmp_uri.assign(req->uri.p + pos_start, req->uri.len - pos_start); - strs.push_back(tmp_uri); - } - - if (strs.empty() || strs[0] != "api") - return TPE_PARAM; - - if (is_get) { - if (2 == strs.size()) { - func_cmd = strs[1]; - } else if (3 == strs.size()) { - func_cmd = strs[1]; - func_args = strs[2]; - } else { - return TPE_PARAM; - } - } else { - if (2 == strs.size()) { - func_cmd = strs[1]; - } else { - return TPE_PARAM; - } - - if (req->body.len > 0) { - func_args.assign(req->body.p, req->body.len); - } - } - - if (func_args.length() > 0) { - // 将参数进行 url-decode 解码 - int len = func_args.length() * 2; - ex_chars sztmp; - sztmp.resize(len); - memset(&sztmp[0], 0, len); - if (-1 == ts_url_decode(func_args.c_str(), func_args.length(), &sztmp[0], len, 0)) - return TPE_HTTP_URL_ENCODE; - - func_args = &sztmp[0]; - } - - EXLOGV("[rpc] method=%s, json_param=%s\n", func_cmd.c_str(), func_args.c_str()); - - return TPE_OK; -} - -void TsHttpRpc::_process_js_request(const ex_astr& func_cmd, const ex_astr& func_args, ex_astr& buf) { - if (func_cmd == "get_version") { - _rpc_func_get_version(func_args, buf); - } else if (func_cmd == "run") { - _rpc_func_run_client(func_args, buf); - } else if (func_cmd == "rdp_play") { - _rpc_func_rdp_play(func_args, buf); - } else if (func_cmd == "get_config") { - _rpc_func_get_config(func_args, buf); - } else if (func_cmd == "set_config") { - _rpc_func_set_config(func_args, buf); - } else if (func_cmd == "file_action") { - _rpc_func_file_action(func_args, buf); - } else { - EXLOGE("[rpc] got unknown command: %s\n", func_cmd.c_str()); - _create_json_ret(buf, TPE_UNKNOWN_CMD); - } -} - -void TsHttpRpc::_create_json_ret(ex_astr& buf, int errcode) { - // 返回: {"code":123} - - Json::Value jr_root; - jr_root["code"] = errcode; - - // buf = jr_writer.write(jr_root); - Json::StreamWriterBuilder jwb; - std::unique_ptr jwriter(jwb.newStreamWriter()); - ex_aoss os; - jwriter->write(jr_root, &os); - buf = os.str(); -} - -void TsHttpRpc::_create_json_ret(ex_astr& buf, Json::Value& jr_root) { -// Json::FastWriter jr_writer; -// buf = jr_writer.write(jr_root); - Json::StreamWriterBuilder jwb; - std::unique_ptr jwriter(jwb.newStreamWriter()); - ex_aoss os; - jwriter->write(jr_root, &os); - buf = os.str(); -} - -void TsHttpRpc::_rpc_func_url_protocol(const ex_astr& args, ex_astr& buf) -{ - //处理urlprotocol调用访式 - // 将参数进行 url-decode 解码 - std::string func_args = args; - if (func_args.length() > 0) - { - int len = func_args.length() * 2; - ex_chars sztmp; - sztmp.resize(len); - memset(&sztmp[0], 0, len); - if (-1 == ts_url_decode(func_args.c_str(), func_args.length(), &sztmp[0], len, 0)) - return ; - - func_args = &sztmp[0]; - } - EXLOGD(("%s\n"), func_args.c_str()); - //处理传参过来的teleport://{}/,只保留参数部份 - std::string urlproto_appname = TP_URLPROTO_APP_NAME; - urlproto_appname += "://{"; - func_args.erase(0, urlproto_appname.length());//去除第一个URLPROTO_APP_NAME以及://字符 - int pos = func_args.length() - 1; - if (func_args.substr(pos, 1) == "/") - func_args.erase(pos - 1, 2);//去除最后一个}/字符 - else - func_args.erase(pos, 1); - - //由于命令行、ie浏览器参数传递时会把原来json结构中的"号去掉,需要重新格式化参数为json格式 - if (func_args.find("\"", 0) == std::string::npos) { - std::vector strv; - SplitString(func_args, strv, ","); - func_args = ""; - for (std::vector::size_type i = 0; i < strv.size(); i++) { - std::vector strv1; - SplitString(strv[i], strv1, ":"); - strv1[0] = "\"" + strv1[0] + "\""; - if (!isDegital(strv1[1]) && strtolower(strv1[1]) != "true" && strtolower(strv1[1]) != "false") - strv1[1] = "\"" + strv1[1] + "\""; - - strv[i] = strv1[0] + ":" + strv1[1]; - if (i == 0) - func_args = strv[i]; - else - func_args += "," + strv[i]; - } - } - func_args = "{" + func_args + "}"; - EXLOGD(("%s\n"), func_args.c_str()); - //调用TsHttpRpc类里的_rpc_func_run_client启动客户端 - _rpc_func_run_client(func_args, buf); -} - -void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) { - // 入参:{"ip":"192.168.5.11","port":22,"uname":"root","uauth":"abcdefg","authmode":1,"protocol":2} - // authmode: 1=password, 2=private-key - // protocol: 1=rdp, 2=ssh - // SSH返回: {"code":0, "data":{"sid":"0123abcde"}} - // RDP返回: {"code":0, "data":{"sid":"0123abcde0A"}} - - //Json::Reader jreader; - Json::Value jsRoot; - - Json::CharReaderBuilder jcrb; - std::unique_ptr const jreader(jcrb.newCharReader()); - const char *str_json_begin = func_args.c_str(); - ex_astr err; - - //if (!jreader.parse(func_args.c_str(), jsRoot)) { - if (!jreader->parse(str_json_begin, str_json_begin + func_args.length(), &jsRoot, &err)) { - _create_json_ret(buf, TPE_JSON_FORMAT); - return; - } - if (!jsRoot.isObject()) { - _create_json_ret(buf, TPE_PARAM); - return; - } - - // 判断参数是否正确 - 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); - return; - } - - 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(); - - ex_astr remote_host_name = jsRoot["remote_host_name"].asCString(); - - ex_astr real_host_ip = jsRoot["remote_host_ip"].asCString(); - ex_astr sid = jsRoot["session_id"].asCString(); - - ex_wstr w_exe_path; - WCHAR w_szCommandLine[MAX_PATH] = { 0 }; - - - ex_wstr w_sid; - ex_astr2wstr(sid, w_sid); - ex_wstr w_teleport_ip; - ex_astr2wstr(teleport_ip, w_teleport_ip); - ex_wstr w_real_host_ip; - ex_astr2wstr(real_host_ip, w_real_host_ip); - ex_wstr w_remote_host_name; - ex_astr2wstr(remote_host_name, w_remote_host_name); - 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 - //============================================== - - bool flag_clipboard = ((protocol_flag & TP_FLAG_RDP_CLIPBOARD) == TP_FLAG_RDP_CLIPBOARD); - bool flag_disk = ((protocol_flag & TP_FLAG_RDP_DISK) == TP_FLAG_RDP_DISK); - bool flag_console = ((protocol_flag & TP_FLAG_RDP_CONSOLE) == TP_FLAG_RDP_CONSOLE); - - int rdp_w = 800; - int rdp_h = 640; - bool rdp_console = false; - - if (!jsRoot["rdp_width"].isNull()) { - if (jsRoot["rdp_width"].isNumeric()) { - rdp_w = jsRoot["rdp_width"].asUInt(); - } else { - _create_json_ret(buf, TPE_PARAM); - return; - } - } - - if (!jsRoot["rdp_height"].isNull()) { - if (jsRoot["rdp_height"].isNumeric()) { - rdp_h = jsRoot["rdp_height"].asUInt(); - } else { - _create_json_ret(buf, TPE_PARAM); - return; - } - } - - if (!jsRoot["rdp_console"].isNull()) { - if (jsRoot["rdp_console"].isBool()) { - rdp_console = jsRoot["rdp_console"].asBool(); - } else { - _create_json_ret(buf, TPE_PARAM); - return; - } - } - - if (!flag_console) - rdp_console = false; - - - int split_pos = sid.length() - 2; - ex_astr real_sid = sid.substr(0, split_pos); - ex_astr str_pwd_len = sid.substr(split_pos, sid.length()); - int n_pwd_len = strtol(str_pwd_len.c_str(), nullptr, 16); - n_pwd_len -= real_sid.length(); - n_pwd_len -= 2; - char szPwd[256] = { 0 }; - for (int i = 0; i < n_pwd_len; i++) { - szPwd[i] = '*'; - } - - ex_astr2wstr(real_sid, w_sid); - - w_exe_path = _T("\""); - w_exe_path += g_cfg.rdp_app + _T("\" "); - - ex_wstr rdp_name = g_cfg.rdp_name; - if (rdp_name == L"mstsc") { - w_exe_path += g_cfg.rdp_cmdline; - - int width = 0; - int higth = 0; - int cx = 0; - int cy = 0; - - int display = 1; - int iWidth = GetSystemMetrics(SM_CXSCREEN); - int iHeight = GetSystemMetrics(SM_CYSCREEN); - - if (rdp_w == 0 || rdp_h == 0) { - //全屏 - width = iWidth; - higth = iHeight; - display = 2; - } else { - width = rdp_w; - higth = rdp_h; - display = 1; - } - - cx = (iWidth - width) / 2; - cy = (iHeight - higth) / 2; - if (cx < 0) { - cx = 0; - } - if (cy < 0) { - cy = 0; - } - - // int console_mode = 0; - // if (rdp_console) - // console_mode = 1; - - std::string psw51b; - if (!calc_psw51b(szPwd, psw51b)) { - EXLOGE("calc password failed.\n"); - _create_json_ret(buf, TPE_FAILED); - return; - } - - real_sid = "01" + real_sid; - - char sz_rdp_file_content[4096] = { 0 }; - sprintf_s(sz_rdp_file_content, 4096, rdp_content.c_str() - , (flag_console && rdp_console) ? 1 : 0 - , display, width, higth - , cx, cy, cx + width + 100, cy + higth + 100 - , teleport_ip.c_str(), teleport_port - , flag_clipboard ? 1 : 0 - , flag_disk ? "*" : "" - , real_sid.c_str() - , psw51b.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) { - EXLOGE("fopen failed (%d).\n", GetLastError()); - _create_json_ret(buf, TPE_FAILED); - return; - } - - ex_astr temp_host_ip = real_host_ip; - ex_replace_all(temp_host_ip, ".", "-"); - - sprintf_s(sz_file_name, MAX_PATH, ("%s%s.rdp"), temp_path, temp_host_ip.c_str()); - - FILE* f = NULL; - if (fopen_s(&f, sz_file_name, "wt") != 0) { - EXLOGE("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") { - w_exe_path += L"{size} {console} {clipboard} {drives} "; - w_exe_path += g_cfg.rdp_cmdline; - - ex_wstr w_screen; - - if (rdp_w == 0 || rdp_h == 0) { - //全屏 - w_screen = _T("/f"); - } else { - char sz_size[64] = { 0 }; - ex_strformat(sz_size, 63, "/size:%dx%d", rdp_w, rdp_h); - ex_astr2wstr(sz_size, w_screen); - } - - // 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); - w_exe_path += L" /p:"; - w_exe_path += w_password; - - w_sid = L"02" + w_sid; - - w_exe_path += L" /gdi:sw"; // 使用软件渲染,gdi:hw使用硬件加速,但是会出现很多黑块(录像回放时又是正常的!) - w_exe_path += L" -grab-keyboard"; // [new style] 防止启动FreeRDP后,失去本地键盘响应,必须得先最小化一下FreeRDP窗口(不过貌似不起作用) - - // 变量替换 - ex_replace_all(w_exe_path, _T("{size}"), w_screen); - - 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); - return; - } - } else if (pro_type == TP_PROTOCOL_TYPE_SSH) { - //============================================== - // SSH - //============================================== - - if (pro_sub == TP_PROTOCOL_TYPE_SSH_SHELL) { - w_exe_path = _T("\""); - w_exe_path += g_cfg.ssh_app + _T("\" "); - w_exe_path += g_cfg.ssh_cmdline; - } else { - w_exe_path = _T("\""); - w_exe_path += g_cfg.scp_app + _T("\" "); - w_exe_path += g_cfg.scp_cmdline; - } - } else if (pro_type == TP_PROTOCOL_TYPE_TELNET) { - //============================================== - // TELNET - //============================================== - w_exe_path = _T("\""); - w_exe_path += g_cfg.telnet_app + _T("\" "); - w_exe_path += g_cfg.telnet_cmdline; - } - - ex_replace_all(w_exe_path, _T("{host_ip}"), w_teleport_ip.c_str()); - ex_replace_all(w_exe_path, _T("{host_port}"), w_port); - ex_replace_all(w_exe_path, _T("{user_name}"), w_sid.c_str()); - ex_replace_all(w_exe_path, _T("{host_name}"), w_remote_host_name.c_str()); - ex_replace_all(w_exe_path, _T("{real_ip}"), w_real_host_ip.c_str()); - ex_replace_all(w_exe_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str()); - - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - - Json::Value root_ret; - ex_astr utf8_path; - ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8); - root_ret["path"] = utf8_path; - - if (!CreateProcess(NULL, (wchar_t *)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str()); - root_ret["code"] = TPE_START_CLIENT; - _create_json_ret(buf, root_ret); - return; - } - - root_ret["code"] = TPE_OK; - _create_json_ret(buf, root_ret); -} - -void TsHttpRpc::_rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf) { - //Json::Reader jreader; - Json::Value jsRoot; - - Json::CharReaderBuilder jcrb; - std::unique_ptr const jreader(jcrb.newCharReader()); - const char *str_json_begin = func_args.c_str(); - ex_astr err; - - //if (!jreader.parse(func_args.c_str(), jsRoot)) { - if (!jreader->parse(str_json_begin, str_json_begin + func_args.length(), &jsRoot, &err)) { - _create_json_ret(buf, TPE_JSON_FORMAT); - return; - } - - // 判断参数是否正确 - if (!jsRoot["rid"].isInt() - || !jsRoot["web"].isString() - || !jsRoot["sid"].isString() - ) { - _create_json_ret(buf, TPE_PARAM); - return; - } - - int rid = jsRoot["rid"].asInt(); - ex_astr a_url_base = jsRoot["web"].asCString(); - ex_astr a_sid = jsRoot["sid"].asCString(); - - char cmd_args[1024] = { 0 }; - ex_strformat(cmd_args, 1023, "%s/%d", a_sid.c_str(), rid); - - ex_wstr w_url_base; - ex_astr2wstr(a_url_base, w_url_base); - ex_wstr w_cmd_args; - ex_astr2wstr(cmd_args, w_cmd_args); - - ex_wstr w_exe_path; - w_exe_path = _T("\""); - w_exe_path += g_env.m_exec_path + _T("\\tp-player.exe\""); - w_exe_path += _T(" \""); - w_exe_path += w_url_base; - w_exe_path += _T("/"); - w_exe_path += w_cmd_args; - - Json::Value root_ret; - ex_astr utf8_path; - ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8); - root_ret["cmdline"] = utf8_path; - - EXLOGD(w_exe_path.c_str()); - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (!CreateProcess(NULL, (wchar_t *)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str()); - root_ret["code"] = TPE_START_CLIENT; - _create_json_ret(buf, root_ret); - return; - } - - root_ret["code"] = TPE_OK; - _create_json_ret(buf, root_ret); - return; -} - -void TsHttpRpc::_rpc_func_get_config(const ex_astr& func_args, ex_astr& buf) { - Json::Value jr_root; - jr_root["code"] = 0; - jr_root["data"] = g_cfg.get_root(); - _create_json_ret(buf, jr_root); -} - -void TsHttpRpc::_rpc_func_set_config(const ex_astr& func_args, ex_astr& buf) { - //Json::Reader jreader; - Json::Value jsRoot; - Json::CharReaderBuilder jcrb; - std::unique_ptr const jreader(jcrb.newCharReader()); - const char *str_json_begin = func_args.c_str(); - ex_astr err; - - //if (!jreader.parse(func_args.c_str(), jsRoot)) { - if (!jreader->parse(str_json_begin, str_json_begin + func_args.length(), &jsRoot, &err)) { - _create_json_ret(buf, TPE_JSON_FORMAT); - return; - } - - if (!g_cfg.save(func_args)) - _create_json_ret(buf, TPE_FAILED); - else - _create_json_ret(buf, TPE_OK); -} - -void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) { - - //Json::Reader jreader; - Json::Value jsRoot; - - Json::CharReaderBuilder jcrb; - std::unique_ptr const jreader(jcrb.newCharReader()); - const char *str_json_begin = func_args.c_str(); - ex_astr err; - - //if (!jreader.parse(func_args.c_str(), jsRoot)) { - if (!jreader->parse(str_json_begin, str_json_begin + func_args.length(), &jsRoot, &err)) { - _create_json_ret(buf, TPE_JSON_FORMAT); - return; - } - // 判断参数是否正确 - if (!jsRoot["action"].isNumeric()) { - _create_json_ret(buf, TPE_PARAM); - return; - } - int action = jsRoot["action"].asUInt(); - - HWND hParent = GetForegroundWindow(); - if (NULL == hParent) - hParent = g_hDlgMain; - - BOOL ret = FALSE; - wchar_t wszReturnPath[MAX_PATH] = _T(""); - - if (action == 1 || action == 2) { - OPENFILENAME ofn; - ex_wstr wsDefaultName; - ex_wstr wsDefaultPath; - StringCchCopy(wszReturnPath, MAX_PATH, wsDefaultName.c_str()); - - ZeroMemory(&ofn, sizeof(ofn)); - - ofn.lStructSize = sizeof(ofn); - ofn.lpstrTitle = _T("选择文件"); - ofn.hwndOwner = hParent; - ofn.lpstrFilter = _T("可执行程序 (*.exe)\0*.exe\0"); - ofn.lpstrFile = wszReturnPath; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrInitialDir = wsDefaultPath.c_str(); - ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST; - - if (action == 1) { - ofn.Flags |= OFN_FILEMUSTEXIST; - ret = GetOpenFileName(&ofn); - } else { - ofn.Flags |= OFN_OVERWRITEPROMPT; - ret = GetSaveFileName(&ofn); - } - } else if (action == 3) { - BROWSEINFO bi; - ZeroMemory(&bi, sizeof(BROWSEINFO)); - bi.hwndOwner = NULL; - bi.pidlRoot = NULL; - bi.pszDisplayName = wszReturnPath; //此参数如为NULL则不能显示对话框 - bi.lpszTitle = _T("选择目录"); - bi.ulFlags = BIF_RETURNONLYFSDIRS; - bi.lpfn = NULL; - bi.iImage = 0; //初始化入口参数bi结束 - LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框 - if (pIDList) { - ret = true; - SHGetPathFromIDList(pIDList, wszReturnPath); - } else { - ret = false; - } - } else if (action == 4) { - ex_wstr wsDefaultName; - ex_wstr wsDefaultPath; - - if (wsDefaultPath.length() == 0) { - _create_json_ret(buf, TPE_PARAM); - return; - } - - ex_wstr::size_type pos = 0; - - while (ex_wstr::npos != (pos = wsDefaultPath.find(L"/", pos))) { - wsDefaultPath.replace(pos, 1, L"\\"); - pos += 1; - } - - ex_wstr wArg = L"/select, \""; - wArg += wsDefaultPath; - wArg += L"\""; - if ((int)ShellExecute(hParent, _T("open"), _T("explorer"), wArg.c_str(), NULL, SW_SHOW) > 32) - ret = true; - else - ret = false; - } - - if (ret) { - if (action == 1 || action == 2 || action == 3) { - ex_astr utf8_path; - ex_wstr2astr(wszReturnPath, utf8_path, EX_CODEPAGE_UTF8); - Json::Value root; - root["code"] = TPE_OK; - root["path"] = utf8_path; - _create_json_ret(buf, root); - - return; - } else { - _create_json_ret(buf, TPE_OK); - return; - } - } else { - _create_json_ret(buf, TPE_FAILED); - return; - } -} - -void TsHttpRpc::_rpc_func_get_version(const ex_astr& func_args, ex_astr& buf) { - Json::Value root_ret; - ex_wstr w_version = TP_ASSIST_VER; - ex_astr version; - ex_wstr2astr(w_version, version, EX_CODEPAGE_UTF8); - root_ret["version"] = version; - root_ret["code"] = TPE_OK; - _create_json_ret(buf, root_ret); - return; -} diff --git a/client/tp_assist_win/ts_http_rpc.h b/client/tp_assist_win/ts_http_rpc.h deleted file mode 100644 index 25dbb50..0000000 --- a/client/tp_assist_win/ts_http_rpc.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef __TS_HTTP_RPC_H__ -#define __TS_HTTP_RPC_H__ - -#include "../../external/mongoose/mongoose.h" - -#include "ts_const.h" - -#include -#include -#include - -#include -#include - - -/* -//================================================================= -ӿʹ˵ - -󣬼 127.0.0.1:50022httpʽҪ£ - -GET ʽ -http://127.0.0.1:50022/method/json_param -json_paramʹurl_encodeбjsonʽַ - -POST ʽ -http://127.0.0.1:50022/method -postjson_param - -УURIΪ֣ -method ִе񷽷 -json_param 񷽷ĸӲûиӲⲿֿʡԡ - -ظʽִн󣬷һjsonʽַߣʽ£ - -{"code":0,"data":varb} - -УcodeDZеģֵһ룬0ʾɹʧܣûdata򡣲ɹʱdata -ķݣʽݾִе񷽷ͬͬ - -*/ - -void http_rpc_main_loop(bool is_https); -void http_rpc_stop(bool is_https); - -typedef std::map content_type_map; - -// for https server, see -// http://www.xiaovdiy.cn/?post=284 - -class TsHttpRpc { -public: - TsHttpRpc(); - ~TsHttpRpc(); - - bool init_http(); - bool init_https(); - void run(void); - void stop(void); - void _rpc_func_url_protocol(const ex_astr& func_args, ex_astr& buf); - - ex_astr get_content_type(ex_astr file_suffix) { - content_type_map::iterator it=m_content_type_map.find(file_suffix); - if (it != m_content_type_map.end()) { - return it->second; - } else { - return "application/octet-stream"; - } - }; - -private: - bool _on_init(); - int _parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args); - void _process_js_request(const ex_astr& func_cmd, const ex_astr& func_args, ex_astr& buf); - void _create_json_ret(ex_astr& buf, int errcode); - void _create_json_ret(ex_astr& buf, Json::Value& jr_root); - - void _rpc_func_run_client(const ex_astr& func_args, ex_astr& buf); - // void _rpc_func_check(const ex_astr& func_args, ex_astr& buf); - void _rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf); - void _rpc_func_get_config(const ex_astr& func_args, ex_astr& buf); - void _rpc_func_set_config(const ex_astr& func_args, ex_astr& buf); - void _rpc_func_file_action(const ex_astr& func_args, ex_astr& buf); - void _rpc_func_get_version(const ex_astr& func_args, ex_astr& buf); - - static void _mg_event_handler(struct mg_connection *nc, int ev, void *ev_data); - -private: - content_type_map m_content_type_map; - struct mg_mgr m_mg_mgr; - bool m_stop; -}; - -#endif // __TS_HTTP_RPC_H__ diff --git a/client/tp_assist_win/ts_network.cpp b/client/tp_assist_win/ts_network.cpp deleted file mode 100644 index 236afa2..0000000 --- a/client/tp_assist_win/ts_network.cpp +++ /dev/null @@ -1,346 +0,0 @@ -#include "stdafx.h" -#include "msocketx.h" -#include "ts_network.h" - -#include -using namespace std; - -unsigned short CalcChecksum(char *pBuffer, int nLen) -{ - //Checksum for ICMP is calculated in the same way as for - //IP header - - //This code was taken from: http://www.netfor2.com/ipsum.htm - - unsigned short nWord; - unsigned int nSum = 0; - int i; - - //Make 16 bit words out of every two adjacent 8 bit words in the packet - //and add them up - for (i = 0; i < nLen; i = i + 2) - { - nWord = ((pBuffer[i] << 8) & 0xFF00) + (pBuffer[i + 1] & 0xFF); - nSum = nSum + (unsigned int)nWord; - } - - //Take only 16 bits out of the 32 bit sum and add up the carries - while (nSum >> 16) - { - nSum = (nSum & 0xFFFF) + (nSum >> 16); - } - - //One's complement the result - nSum = ~nSum; - - return ((unsigned short)nSum); -} - -bool ValidateChecksum(char *pBuffer, int nLen) -{ - unsigned short nWord; - unsigned int nSum = 0; - int i; - - //Make 16 bit words out of every two adjacent 8 bit words in the packet - //and add them up - for (i = 0; i < nLen; i = i + 2) - { - nWord = ((pBuffer[i] << 8) & 0xFF00) + (pBuffer[i + 1] & 0xFF); - nSum = nSum + (unsigned int)nWord; - } - - //Take only 16 bits out of the 32 bit sum and add up the carries - while (nSum >> 16) - { - nSum = (nSum & 0xFFFF) + (nSum >> 16); - } - - //To validate the checksum on the received message we don't complement the sum - //of one's complement - //One's complement the result - //nSum = ~nSum; - - //The sum of one's complement should be 0xFFFF - return ((unsigned short)nSum == 0xFFFF); -} - -int ICMPSendTo(ICMPheaderRet* pICMPheaderRet, char* pszRemoteIP, int nMessageSize, int nCount) -{ - int nTimeOut = 500; //Request time out for echo request (in milliseconds) - ICMPheader sendHdr; - //char *pSendBuffer = NULL; - SOCKET sock; - sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //Create a raw socket which will use ICMP - if (sock == INVALID_SOCKET) - { - return -1; - } - SOCKADDR_IN dest; //Dest address to send the ICMP request - memset(&dest, 0, sizeof(0)); - dest.sin_addr.S_un.S_addr = inet_addr(pszRemoteIP); - dest.sin_family = AF_INET; - //dest.sin_port = rand (); //Pick a random port - - - int nResult = 0; - int nTry = 0; - int nSequence = 0; - fd_set fdRead; - //SYSTEMTIME timeSend, timeRecv; - unsigned long timeTick = 0; - int nTotalRoundTripTime = 0, nMaxRoundTripTime = 0, nMinRoundTripTime = -1, nRoundTripTime = 0; - int nPacketsSent = 0, nPacketsReceived = 0; - - timeval timeInterval = { 0, 0 }; - timeInterval.tv_usec = nTimeOut * 1000; - - sendHdr.nId = htons(rand()); //Set the transaction Id - - - while (nPacketsSent < nCount) - { - //Create the message buffer, which is big enough to store the header and the message data - ///pSendBuffer = new char [sizeof (ICMPheader) + nMessageSize]; - char Sendbuf[1024] = { 0 }; - int len = (sizeof(ICMPheader) + nMessageSize); - sendHdr.byCode = 0; //Zero for ICMP echo and reply messages - sendHdr.nSequence = htons(nSequence++); - sendHdr.byType = 8; //Eight for ICMP echo message - sendHdr.nChecksum = 0; //Checksum is calculated later on - - memcpy_s(Sendbuf, sizeof(ICMPheader), &sendHdr, sizeof(ICMPheader)); //Copy the message header in the buffer - memset(Sendbuf + sizeof(ICMPheader), 'x', nMessageSize); //Fill the message with some arbitary value - - //Calculate checksum over ICMP header and message data - sendHdr.nChecksum = htons(CalcChecksum(Sendbuf, sizeof(ICMPheader) + nMessageSize)); - - //Copy the message header back into the buffer - memcpy_s(Sendbuf, sizeof(ICMPheader), &sendHdr, sizeof(ICMPheader)); - - //::GetSystemTime (&timeSend); - timeTick = GetTickCount(); - nResult = sendto(sock, Sendbuf, sizeof(ICMPheader) + nMessageSize, 0, (SOCKADDR *)&dest, sizeof(SOCKADDR_IN)); - - //Save the time at which the ICMP echo message was sent - - - ++nPacketsSent; - - if (nResult == SOCKET_ERROR) - { - cerr << endl << "An error occured in sendto operation: " << "WSAGetLastError () = " << WSAGetLastError() << endl; - //UnInitialize (); - closesocket(sock); - return -1; - } - next: - FD_ZERO(&fdRead); - FD_SET(sock, &fdRead); - - if ((nResult = select(0, &fdRead, NULL, NULL, &timeInterval)) - == SOCKET_ERROR) - { - cerr << endl << "An error occured in select operation: " << "WSAGetLastError () = " << - WSAGetLastError() << endl; - closesocket(sock); - //delete []pSendBuffer; - return -2; - } - //printf("FD_ISSET Enter --- 0\n"); - if (nResult > 0 && FD_ISSET(sock, &fdRead)) - { - //printf("FD_ISSET Enter --- 1\n"); - //Allocate a large buffer to store the response - char buf[1500] = { 0 }; - struct sockaddr_in addr; - int addr_len = sizeof(struct sockaddr_in); - memset(&addr, 0, sizeof(sockaddr_in)); - if ((nResult = recvfrom(sock, buf, 1500, 0, (struct sockaddr *)&addr, &addr_len)) - == SOCKET_ERROR) - { - cerr << endl << "An error occured in recvfrom operation: " << "WSAGetLastError () = " << - WSAGetLastError() << endl; - //UnInitialize (); - //delete []pSendBuffer; - closesocket(sock); - return -3; - } - - //printf("FD_ISSET Enter --- 2 IP%s\n",inet_ntoa(addr.sin_addr)); - string strIP = inet_ntoa(addr.sin_addr); - if (strIP.compare(pszRemoteIP) == 0) - { - //Get the time at which response is received - //::GetSystemTime (&timeRecv); - //We got a response so we construct the ICMP header and message out of it - ICMPheader recvHdr; - char *pICMPbuffer = NULL; - - //The response includes the IP header as well, so we move 20 bytes ahead to read the ICMP header - pICMPbuffer = buf + sizeof(IPheader); - - //ICMP message length is calculated by subtracting the IP header size from the - //total bytes received - int nICMPMsgLen = nResult - sizeof(IPheader); - - //Construct the ICMP header - memcpy_s(&recvHdr, sizeof(recvHdr), pICMPbuffer, sizeof(recvHdr)); - - //Construct the IP header from the response - IPheader ipHdr; - memcpy_s(&ipHdr, sizeof(ipHdr), buf, sizeof(ipHdr)); - - recvHdr.nId = recvHdr.nId; - recvHdr.nSequence = recvHdr.nSequence; - recvHdr.nChecksum = ntohs(recvHdr.nChecksum); - - if (recvHdr.byType == 0 && - recvHdr.nId == sendHdr.nId && - recvHdr.nSequence == sendHdr.nSequence && - ValidateChecksum(pICMPbuffer, nICMPMsgLen) && - memcmp(Sendbuf + sizeof(ICMPheader), buf + sizeof(ICMPheader) + sizeof(IPheader), - nResult - sizeof(ICMPheader) - sizeof(IPheader)) == 0) - { - printf("FD_ISSET Enter --- 3\n"); - int nRoundTripTime = 0; - - nRoundTripTime = (GetTickCount() - timeTick); - - nTotalRoundTripTime = nTotalRoundTripTime + nRoundTripTime; - - if (nMinRoundTripTime == -1) - { - nMinRoundTripTime = nRoundTripTime; - nMaxRoundTripTime = nRoundTripTime; - } - else if (nRoundTripTime < nMinRoundTripTime) - { - nMinRoundTripTime = nRoundTripTime; - } - else if (nRoundTripTime > nMaxRoundTripTime) - { - nMaxRoundTripTime = nRoundTripTime; - } - - ++nPacketsReceived; - } - else - { - cout << "The echo reply is not correct! Type : " << recvHdr.byType << endl; - } - } - else - { - goto next; - } - - //Check if the response is an echo reply, transaction ID and sequence number are same - //as for the request, and that the checksum is correct - //if (recvHdr.byType == 0 && - // recvHdr.nId == sendHdr.nId && - // recvHdr.nSequence == sendHdr.nSequence && - // ValidateChecksum (pICMPbuffer, nICMPMsgLen) && - // memcmp (pSendBuffer + sizeof(ICMPheader), pRecvBuffer + sizeof (ICMPheader) + sizeof(IPheader), - // nResult - sizeof (ICMPheader) - sizeof(IPheader)) == 0) - //{ - // printf("FD_ISSET Enter --- 3\n"); - - // int nRoundTripTime = 0; - - // nRoundTripTime = (GetTickCount() - timeTick); - - // nTotalRoundTripTime = nTotalRoundTripTime + nRoundTripTime; - - // if (nMinRoundTripTime == -1) - // { - // nMinRoundTripTime = nRoundTripTime; - // nMaxRoundTripTime = nRoundTripTime; - // } - // else if (nRoundTripTime < nMinRoundTripTime) - // { - // nMinRoundTripTime = nRoundTripTime; - // } - // else if (nRoundTripTime > nMaxRoundTripTime) - // { - // nMaxRoundTripTime = nRoundTripTime; - // } - - // ++nPacketsReceived; - //} - //else - //{ - // cout << "The echo reply is not correct!" << endl; - //} - - //delete []pRecvBuffer; - } - else - { - cout << "Request timed out. Tick : " << GetTickCount() << endl; - } - } - cout << endl << "Ping statistics for " << pszRemoteIP << ":" << endl << '\t' << "Packets: Sent = " << nPacketsSent << ", Received = " << - nPacketsReceived << ", Lost = " << (nPacketsSent - nPacketsReceived) << " (" << - ((nPacketsSent - nPacketsReceived) / (float)nPacketsSent) * 100 << "% loss)" << endl << '\t'; - - pICMPheaderRet->nPacketsSent = nPacketsSent; - pICMPheaderRet->nPacketsReceived = nPacketsReceived; - if (nPacketsReceived > 0) - { - // cout << "\rApproximate round trip times in milli-seconds:" << endl << '\t' << "Minimum = " << nMinRoundTripTime << - // "ms, Maximum = " << nMaxRoundTripTime << "ms, Average = " << nTotalRoundTripTime / (float)nPacketsReceived << "ms" << endl; - - pICMPheaderRet->nMinRoundTripTime = nMinRoundTripTime; - pICMPheaderRet->nMaxRoundTripTime = nMaxRoundTripTime; - pICMPheaderRet->nAverageRoundTripTime = (int)(nTotalRoundTripTime / (float)nPacketsReceived); - } - else - { - - pICMPheaderRet->nMinRoundTripTime = -1; - pICMPheaderRet->nMaxRoundTripTime = -1; - pICMPheaderRet->nAverageRoundTripTime = -1; - //getchar(); - } - closesocket(sock); - //cout << '\r' << endl; - return 0; - -} - -bool TestTCPPort(const ex_astr& strServerIP, int port) -{ - int icount = 0; - - unsigned int uibegconn = GetTickCount(); - unsigned int uicostconn = 0; - - msocketx sock; - sock.create(SOCK_STREAM, IPPROTO_TCP); - sock.setsocktime(1000); - int iconn = sock.connect(strServerIP.c_str(), port, false); - - - bool bFailed = true; - - while (++icount <= 2) - { - int nRet = sock.wait(1000, CAN_CONNECTX); - if (nRet < 0) - { - continue; - } - - if ((nRet & CAN_CONNECTX) == CAN_CONNECTX) - { - return true; - } - else - { - continue; - } - } - - return false; -} diff --git a/client/tp_assist_win/ts_network.h b/client/tp_assist_win/ts_network.h deleted file mode 100644 index cbbfee0..0000000 --- a/client/tp_assist_win/ts_network.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include - -struct ICMPheaderRet -{ - unsigned int ulSrcServerIP; //IPַ - unsigned int ulDesServerIP; //IPַ - int nPacketsSent; //͵İ - int nPacketsReceived; //յİ - int nMinRoundTripTime; //ʱ - int nMaxRoundTripTime; //ʱ - int nAverageRoundTripTime; //ƽʱ - int nSesssionID; //sessionId -}; -typedef std::mapICMPheaderRetMap; - -struct ICMPheader -{ - unsigned char byType; - unsigned char byCode; - unsigned short nChecksum; - unsigned short nId; - unsigned short nSequence; - unsigned int Tick; -}; - -struct IPheader -{ - unsigned char byVerLen; - unsigned char byTos; - unsigned short nTotalLength; - unsigned short nId; - unsigned short nOffset; - unsigned char byTtl; - unsigned char byProtocol; - unsigned short nChecksum; - unsigned int nSrcAddr; - unsigned int nDestAddr; -}; -bool TestTCPPort(const ex_astr& strServerIP, int port); - -int ICMPSendTo(ICMPheaderRet* pICMPheaderRet, char* pszRemoteIP, int nMessageSize, int nCount); diff --git a/client/tp_assist_win/ts_utils.cpp b/client/tp_assist_win/ts_utils.cpp new file mode 100644 index 0000000..9659d56 --- /dev/null +++ b/client/tp_assist_win/ts_utils.cpp @@ -0,0 +1,39 @@ +// #include +#include "ts_utils.h" + +#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W') + +int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded) +{ + int i, j, a, b; + + for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) + { + if (src[i] == '%') + { + if (i < src_len - 2 && isxdigit(*(const unsigned char *)(src + i + 1)) && + isxdigit(*(const unsigned char *)(src + i + 2))) { + a = tolower(*(const unsigned char *)(src + i + 1)); + b = tolower(*(const unsigned char *)(src + i + 2)); + dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b)); + i += 2; + } + else + { + return -1; + } + } + else if (is_form_url_encoded && src[i] == '+') + { + dst[j] = ' '; + } + else + { + dst[j] = src[i]; + } + } + + dst[j] = '\0'; /* Null-terminate the destination */ + + return i >= src_len ? j : -1; +} diff --git a/client/tp_assist_win/ts_utils.h b/client/tp_assist_win/ts_utils.h new file mode 100644 index 0000000..d3f83d7 --- /dev/null +++ b/client/tp_assist_win/ts_utils.h @@ -0,0 +1,8 @@ +#ifndef __TS_UTILS_H__ +#define __TS_UTILS_H__ + +#include + +int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded); + +#endif // __TS_UTILS_H__ diff --git a/client/tp_assist_win/ts_ws_client.cpp b/client/tp_assist_win/ts_ws_client.cpp new file mode 100644 index 0000000..73ff77f --- /dev/null +++ b/client/tp_assist_win/ts_ws_client.cpp @@ -0,0 +1,923 @@ +#include "stdafx.h" + +#pragma warning(disable:4091) + +#include +#include +#include + +#pragma comment(lib, "Crypt32.lib") + +#include + +//#ifndef MAX_PATH +//# define MAX_PATH 1024 +//#endif + +// #include "../AppDelegate-C-Interface.h" + +#include "ts_ws_client.h" +#include "ts_ver.h" +#include "ts_env.h" +#include "ts_cfg.h" +#include "ts_utils.h" + +//#ifdef RDP_CLIENT_SYSTEM_BUILTIN + +//connect to console:i:%d +//compression:i:1 +//bitmapcachepersistenable:i:1 + +std::string rdp_content = "\ +administrative session:i:%d\n\ +screen mode id:i:%d\n\ +use multimon:i:0\n\ +desktopwidth:i:%d\n\ +desktopheight:i:%d\n\ +session bpp:i:16\n\ +winposstr:s:0,1,%d,%d,%d,%d\n\ +bitmapcachepersistenable:i:1\n\ +bitmapcachesize:i:32000\n\ +compression:i:1\n\ +keyboardhook:i:2\n\ +audiocapturemode:i:0\n\ +videoplaybackmode:i:1\n\ +connection type:i:7\n\ +networkautodetect:i:1\n\ +bandwidthautodetect:i:1\n\ +disableclipboardredirection:i:0\n\ +displayconnectionbar:i:1\n\ +enableworkspacereconnect:i:0\n\ +disable wallpaper:i:1\n\ +allow font smoothing:i:0\n\ +allow desktop composition:i:0\n\ +disable full window drag:i:1\n\ +disable menu anims:i:1\n\ +disable themes:i:1\n\ +disable cursor setting:i:1\n\ +full address:s:%s:%d\n\ +audiomode:i:0\n\ +redirectprinters:i:0\n\ +redirectcomports:i:0\n\ +redirectsmartcards:i:0\n\ +redirectclipboard:i:%d\n\ +redirectposdevices:i:0\n\ +autoreconnection enabled:i:0\n\ +authentication level:i:2\n\ +prompt for credentials:i:0\n\ +negotiate security layer:i:1\n\ +remoteapplicationmode:i:0\n\ +alternate shell:s:\n\ +shell working directory:s:\n\ +gatewayhostname:s:\n\ +gatewayusagemethod:i:4\n\ +gatewaycredentialssource:i:4\n\ +gatewayprofileusagemethod:i:0\n\ +promptcredentialonce:i:0\n\ +gatewaybrokeringtype:i:0\n\ +use redirection server name:i:0\n\ +rdgiskdcproxy:i:0\n\ +kdcproxyname:s:\n\ +drivestoredirect:s:%s\n\ +username:s:%s\n\ +password 51:b:%s\n\ +"; + +// https://www.donkz.nl/overview-rdp-file-settings/ +// +// authentication level:i:2\n +// +// +// negotiate security layer:i:1\n +// 0 = negotiation is not enabled and the session is started by using Secure Sockets Layer (SSL). +// 1 = negotiation is enabled and the session is started by using x.224 encryption. + + + +//redirectdirectx:i:0\n\ +//prompt for credentials on client:i:0\n\ + +//#endif + +TsWsClient g_ws_client; +TsWsClient g_wss_client; + +void* g_app = NULL; + +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", nullptr, nullptr, nullptr, 0, &DataOut)) + return false; + + char szRet[5] = { 0 }; + for (DWORD i = 0; i < DataOut.cbData; ++i) { + sprintf_s(szRet, 5, "%02X", DataOut.pbData[i]); + ret += szRet; + } + + LocalFree(DataOut.pbData); + return true; +} + +// static +void TsWsClient::init_app(void* app) +{ + g_app = app; +} + +void TsWsClient::stop_all_client() +{ + g_ws_client.stop(); + g_wss_client.stop(); +} + +// ============================================================================ +// static +void TsWsClient::url_scheme_handler(const std::string& url) +{ + // from command line: + // teleport://register?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"} + // from system-url-protocol handler. why Windows add extra '/' for me??? + // teleport://register/?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"} + + std::string protocol; + std::string method; + std::string param; + + std::string::size_type pos_protocol = url.find("://"); + if (pos_protocol == std::string::npos) + { + EXLOGE("[ws] invalid url: %s\n", url.c_str()); + return; + } + + std::string::size_type pos_method = url.find('?'); + if (pos_method == std::string::npos) + { + EXLOGE("[ws] invalid url: %s\n", url.c_str()); + return; + } + + protocol.assign(url, 0, pos_protocol); + if (protocol != "teleport") + { + EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str()); + return; + } + + // now we support 'register' method only. + method.assign(url, pos_protocol + 3, pos_method - pos_protocol - 3); + if (method[method.length() - 1] == '/') + method.erase(method.length() - 1, 1); + if (method != "register") + { + EXLOGE("[ws] unknown method: %s\n", method.c_str()); + return; + } + + param.assign(url, pos_method + 7); // ?param= + if (param.empty()) + { + EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str()); + return; + } + + + // decode param with url-decode. + size_t len = param.length() * 2; + ex_chars sztmp; + sztmp.resize(len); + memset(&sztmp[0], 0, len); + if (-1 == ts_url_decode(param.c_str(), (int)param.length(), &sztmp[0], (int)len, 0)) + { + EXLOGE("[ws] url-decode param failed: %s\n", param.c_str()); + return; + } + param = &sztmp[0]; + + EXLOGV("[rpc] method=%s, json_param=%s\n", method.c_str(), param.c_str()); + + Json::CharReaderBuilder jcrb; + std::unique_ptr const jreader(jcrb.newCharReader()); + const char* str_json_begin = param.c_str(); + + Json::Value js_root; + ex_astr err; + if (!jreader->parse(str_json_begin, str_json_begin + param.length(), &js_root, &err)) + { + EXLOGE("[ws] param not in json format: %s\n", param.c_str()); + return; + } + if (!js_root.isObject()) + { + EXLOGE("[ws] invalid param, need json object: %s\n", param.c_str()); + return; + } + + // now we support 'register' method only. + _process_register(param, js_root); +} + +// static +void TsWsClient::_process_register(const std::string& param, Json::Value& js_root) +{ + // {"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"} + + // check param + if (!js_root["ws_url"].isString() || !js_root["assist_id"].isNumeric() || !js_root["session_id"].isString()) + { + EXLOGE("[ws] invalid param: %s\n", param.c_str()); + return; + } + + std::string ws_url = js_root["ws_url"].asCString(); + uint32_t assist_id = js_root["assist_id"].asUInt(); + std::string session_id = js_root["session_id"].asCString(); + + std::string protocol; + protocol.assign(ws_url, 0, 3); + if (protocol == "ws:") + { + g_ws_client._register(ws_url, assist_id, session_id); + } + else if (protocol == "wss") + { + g_wss_client._register(ws_url, assist_id, session_id); + } + else + { + EXLOGE("[ws] invalid ws_url: %s\n", ws_url.c_str()); + return; + } +} + + +// ============================================================================ + +TsWsClient::TsWsClient() : + ExThreadBase("ws-client-thread"), + m_nc(NULL), + m_assist_id(0) +{ + mg_mgr_init(&m_mg_mgr, NULL); +} + +TsWsClient::~TsWsClient() +{ + mg_mgr_free(&m_mg_mgr); +} + +void TsWsClient::_thread_loop(void) +{ + while (!m_need_stop) + { + mg_mgr_poll(&m_mg_mgr, 500); + } + + EXLOGV("[ws] main loop end.\n"); +} + +void TsWsClient::_register(const std::string& ws_url, uint32_t assist_id, const std::string& session_id) +{ + if (m_assist_id == 0) + m_assist_id = assist_id; + + ex_wstr w_ver(TP_ASSIST_VER); + ex_astr a_ver; + ex_wstr2astr(w_ver, a_ver); + + // + char msg[256] = { 0 }; + ex_strformat( + msg, 256, "{\"type\":0,\"method\":\"register\",\"param\":{\"client\":\"assist\",\"sid\":\"%s\",\"request_assist_id\":%u,\"assist_id\":%u,\"assist_ver\":\"%s\"}}", + session_id.c_str(), assist_id, m_assist_id, a_ver.c_str()); + + if (!m_is_running) + { + // not start yet. + std::string url = ws_url; + url += msg; + + m_nc = mg_connect_ws(&m_mg_mgr, _mg_event_handler, url.c_str(), NULL, NULL); + if (!m_nc) + { + EXLOGE("[ws] TsWsClient::init failed: %s\n", url.c_str()); + return; + } + m_nc->user_data = this; + + start(); + return; + } + + + EXLOGV("[ws] send: %s\n", msg); + mg_send_websocket_frame(m_nc, WEBSOCKET_OP_TEXT, msg, strlen(msg)); +} + +// static +void TsWsClient::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_data) +{ + auto* _this = (TsWsClient*)nc->user_data; + if (NULL == _this) + { + EXLOGE("[ERROR] invalid request.\n"); + return; + } + + switch (ev) + { + case MG_EV_CONNECT: + { + int status = *((int*)ev_data); + if (status != 0) + { + EXLOGE("[ERROR] -- connect to ws server failed: %d\n", status); + } + + break; + } + + case MG_EV_WEBSOCKET_HANDSHAKE_DONE: + { + auto* hm = (struct http_message*)ev_data; + if (hm->resp_code == 101) + { + EXLOGV("-- ws server connected\n"); + } + else + { + EXLOGE("[ERROR] -- connect to ws server failed, HTTP code: %d\n", hm->resp_code); + } + break; + } + + + case MG_EV_WEBSOCKET_FRAME: + { + // on_message(). + auto* wm = (struct websocket_message*)ev_data; + // EXLOGV("%d: %s\n", wm->size, wm->data); + std::string message; + message.assign((const char*)wm->data, wm->size); + std::string buf; + _this->_on_message(message, buf); + + if (!buf.empty()) + { + mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, buf.c_str(), buf.length()); + } + + break; + } + + + case MG_EV_CLOSE: + { + EXLOGV("-- ws server disconnected\n"); + _this->m_need_stop = true; + break; + } + } +} + +void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code) +{ + Json::Value js_data(Json::objectValue); + _create_response(buf, msg_ret, err_code, L"", js_data); +} + +void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message) +{ + Json::Value js_data(Json::objectValue); + _create_response(buf, msg_ret, err_code, message, js_data); +} + +void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message, Json::Value& data) +{ + ex_astr _message; + // ex_wstr2astr(message, _message, EX_CODEPAGE_UTF8); + ex_wstr2astr(message, _message); + + Json::Value js_ret; + js_ret["type"] = MESSAGE_TYPE_RESPONSE; + js_ret["command_id"] = msg_ret.command_id; + js_ret["method"] = msg_ret.method; + js_ret["code"] = err_code; + js_ret["message"] = _message; + js_ret["data"] = data; + + Json::StreamWriterBuilder jwb; + // jwb["emitUTF8"] = true; + jwb["indentation"] = ""; // 压缩格式,没有换行和不必要的空白字符 + std::unique_ptr js_writer(jwb.newStreamWriter()); + ex_aoss os; + js_writer->write(js_ret, &os); + buf = os.str(); +} + +void TsWsClient::_on_message(const std::string& message, std::string& buf) +{ + // { + // "type":0, + // "method":"run", + // "param":{ + // "teleport_ip":"127.0.0.1","teleport_port":52189,"remote_host_ip":"39.97.125.170", + // "remote_host_name":"tp4a.com","session_id":"9DE744","protocol_type":2, + // "protocol_sub_type":200,"protocol_flag":4294967295 + // } + // } + + AssistMessage msg_req; + + Json::CharReaderBuilder jrb; + std::unique_ptr const js_reader(jrb.newCharReader()); + const char* str_json_begin = message.c_str(); + + Json::Value js_root; + ex_astr err; + if (!js_reader->parse(str_json_begin, str_json_begin + message.length(), &js_root, &err)) + { + _create_response(buf, msg_req, TPE_JSON_FORMAT); + return; + } + if (!js_root.isObject()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + if (js_root["type"].isNull() || !js_root["type"].isInt()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + int cmd_type = js_root["type"].asInt(); + if (!(cmd_type == MESSAGE_TYPE_REQUEST || cmd_type == MESSAGE_TYPE_RESPONSE)) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + // 收到的信息已经是“返回值”了,说明已经是一条命令的结束了,不用继续处理 + // todo: 可能需要记录日志,或者展示结果。 + //if (cmd_type == MESSAGE_TYPE_RESPONSE) + //{ + // char msg[129] = { 0 }; + // _snprintf_s(msg, 128, "%d %d", cmd_type, MESSAGE_TYPE_RESPONSE); + // MessageBoxA(NULL, msg, "INFO", MB_OK); + // return; + //} + + if (js_root["method"].isNull() || !js_root["method"].isString() || js_root["command_id"].isNull() || !js_root["command_id"].isInt()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + msg_req.command_id = js_root["command_id"].asInt(); + msg_req.method = js_root["method"].asString(); + + if (msg_req.command_id == 0 || msg_req.method.empty()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + if (msg_req.method == "run") + { + _rpc_func_run_client(buf, msg_req, js_root); + } + else if (msg_req.method == "get_config") + { + _rpc_func_get_config(buf, msg_req, js_root); + } + else if (msg_req.method == "set_config") + { + _rpc_func_set_config(buf, msg_req, js_root); + } + else if (msg_req.method == "select_file") + { + _rpc_func_select_file(buf, msg_req, js_root); + } + else + { + EXLOGE("[ws] got unknown command: %s\n", msg_req.method.c_str()); + _create_response(buf, msg_req, TPE_UNKNOWN_CMD); + } +} + +void TsWsClient::_rpc_func_get_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root) +{ + Json::Value& ret = g_cfg.get_root(); + ret["os_type"] = "windows"; + + _create_response(buf, msg_req, TPE_OK, L"", ret); +} + +void TsWsClient::_rpc_func_set_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root) +{ + if (js_root["param"].isNull() || !js_root["param"].isObject()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + Json::Value& js_param = js_root["param"]; + + Json::StreamWriterBuilder jwb; + std::unique_ptr js_writer(jwb.newStreamWriter()); + ex_aoss os; + js_writer->write(js_param, &os); + + if (!g_cfg.save(os.str())) + _create_response(buf, msg_req, TPE_FAILED); + else + _create_response(buf, msg_req, TPE_OK); +} + +void TsWsClient::_rpc_func_select_file(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root) +{ + // _create_response(buf, msg_req, TPE_FAILED, L"尚不支持在macOS平台选择应用,请手动填写应用程序路径!"); + // _create_response(buf, msg_req, TPE_FAILED, L"尚不支持选择应用,请手动填写应用程序路径!"); + + if (js_root["param"].isNull() || !js_root["param"].isObject() || js_root["param"]["app_type"].isNull()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + // Json::Value& js_param = js_root["param"]; + + HWND hParent = GetForegroundWindow(); + if (NULL == hParent) + hParent = NULL; + + + BOOL ret = FALSE; + wchar_t wszReturnPath[MAX_PATH] = _T(""); + + OPENFILENAME ofn; + ex_wstr wsDefaultName; + ex_wstr wsDefaultPath; + StringCchCopy(wszReturnPath, MAX_PATH, wsDefaultName.c_str()); + + ZeroMemory(&ofn, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.lpstrTitle = NULL;// L"Select application execute file"; + ofn.hwndOwner = hParent; + ofn.lpstrFilter = L"Execute file (*.exe)\0*.exe\0"; + ofn.lpstrFile = wszReturnPath; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrInitialDir = wsDefaultPath.c_str(); + ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST; + ofn.Flags |= OFN_FILEMUSTEXIST; + + ret = GetOpenFileNameW(&ofn); + + if (!ret) + { + _create_response(buf, msg_req, TPE_FAILED, L"用户取消了选择操作!"); + return; + } + + ex_astr utf8_path; + ex_wstr2astr(wszReturnPath, utf8_path, EX_CODEPAGE_UTF8); + + Json::Value js_ret; + js_ret["app_type"] = js_root["param"]["app_type"]; + js_ret["app_path"] = utf8_path; + + _create_response(buf, msg_req, TPE_OK, L"", js_ret); +} + +void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root) { + // { + // "method":"run", + // "param":{ + // "teleport_ip":"127.0.0.1","teleport_port":52189,"remote_host_ip":"39.97.125.170", + // "remote_host_name":"tp4a.com","session_id":"9DE744","protocol_type":2, + // "protocol_sub_type":200,"protocol_flag":4294967295 + // } + // } + + // 判断参数是否正确 + if (js_root["param"].isNull() || !js_root["param"].isObject()) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + Json::Value& js_param = js_root["param"]; + + if (!js_param["teleport_ip"].isString() + || !js_param["teleport_port"].isNumeric() || !js_param["remote_host_ip"].isString() + || !js_param["session_id"].isString() || !js_param["protocol_type"].isNumeric() || !js_param["protocol_sub_type"].isNumeric() + || !js_param["protocol_flag"].isNumeric() + ) + { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + int pro_type = js_param["protocol_type"].asUInt(); + int pro_sub = js_param["protocol_sub_type"].asInt(); + ex_u32 protocol_flag = js_param["protocol_flag"].asUInt(); + + ex_astr teleport_ip = js_param["teleport_ip"].asCString(); + int teleport_port = js_param["teleport_port"].asUInt(); + + ex_astr real_host_ip = js_param["remote_host_ip"].asCString(); + ex_astr remote_host_name = js_param["remote_host_name"].asCString(); + ex_astr sid = js_param["session_id"].asCString(); + + ex_wstr w_exe_path; + WCHAR w_szCommandLine[MAX_PATH] = { 0 }; + + + ex_wstr w_sid; + ex_astr2wstr(sid, w_sid); + ex_wstr w_teleport_ip; + ex_astr2wstr(teleport_ip, w_teleport_ip); + ex_wstr w_real_host_ip; + ex_astr2wstr(real_host_ip, w_real_host_ip); + ex_wstr w_remote_host_name; + ex_astr2wstr(remote_host_name, w_remote_host_name); + 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 + //============================================== + + bool flag_clipboard = ((protocol_flag & TP_FLAG_RDP_CLIPBOARD) == TP_FLAG_RDP_CLIPBOARD); + bool flag_disk = ((protocol_flag & TP_FLAG_RDP_DISK) == TP_FLAG_RDP_DISK); + bool flag_console = ((protocol_flag & TP_FLAG_RDP_CONSOLE) == TP_FLAG_RDP_CONSOLE); + + int rdp_w = 800; + int rdp_h = 640; + bool rdp_console = false; + + if (!js_param["rdp_width"].isNull()) { + if (js_param["rdp_width"].isNumeric()) { + rdp_w = js_param["rdp_width"].asUInt(); + } + else { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + } + + if (!js_param["rdp_height"].isNull()) { + if (js_param["rdp_height"].isNumeric()) { + rdp_h = js_param["rdp_height"].asUInt(); + } + else { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + } + + if (!js_param["rdp_console"].isNull()) { + if (js_param["rdp_console"].isBool()) { + rdp_console = js_param["rdp_console"].asBool(); + } + else { + _create_response(buf, msg_req, TPE_PARAM); + return; + } + } + + if (!flag_console) + rdp_console = false; + + + int split_pos = sid.length() - 2; + ex_astr real_sid = sid.substr(0, split_pos); + ex_astr str_pwd_len = sid.substr(split_pos, sid.length()); + int n_pwd_len = strtol(str_pwd_len.c_str(), nullptr, 16); + n_pwd_len -= real_sid.length(); + n_pwd_len -= 2; + char szPwd[256] = { 0 }; + for (int i = 0; i < n_pwd_len; i++) { + szPwd[i] = '*'; + } + + ex_astr2wstr(real_sid, w_sid); + + w_exe_path = _T("\""); + w_exe_path += g_cfg.rdp.application + _T("\" "); + + ex_wstr rdp_name = g_cfg.rdp.name; + if (rdp_name == L"mstsc") { + w_exe_path += g_cfg.rdp.cmdline; + + int width = 0; + int higth = 0; + int cx = 0; + int cy = 0; + + int display = 1; + int iWidth = GetSystemMetrics(SM_CXSCREEN); + int iHeight = GetSystemMetrics(SM_CYSCREEN); + + if (rdp_w == 0 || rdp_h == 0) { + //全屏 + width = iWidth; + higth = iHeight; + display = 2; + } + else { + width = rdp_w; + higth = rdp_h; + display = 1; + } + + cx = (iWidth - width) / 2; + cy = (iHeight - higth) / 2; + if (cx < 0) { + cx = 0; + } + if (cy < 0) { + cy = 0; + } + + // int console_mode = 0; + // if (rdp_console) + // console_mode = 1; + + std::string psw51b; + if (!calc_psw51b(szPwd, psw51b)) { + EXLOGE("calc password failed.\n"); + _create_response(buf, msg_req, TPE_PARAM); + return; + } + + real_sid = "01" + real_sid; + + char sz_rdp_file_content[4096] = { 0 }; + sprintf_s(sz_rdp_file_content, 4096, rdp_content.c_str() + , (flag_console && rdp_console) ? 1 : 0 + , display, width, higth + , cx, cy, cx + width + 100, cy + higth + 100 + , teleport_ip.c_str(), teleport_port + , flag_clipboard ? 1 : 0 + , flag_disk ? "*" : "" + , real_sid.c_str() + , psw51b.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) { + EXLOGE("fopen failed (%d).\n", GetLastError()); + _create_response(buf, msg_req, TPE_FAILED); + return; + } + + ex_astr temp_host_ip = real_host_ip; + ex_replace_all(temp_host_ip, ".", "-"); + + sprintf_s(sz_file_name, MAX_PATH, ("%s%s.rdp"), temp_path, temp_host_ip.c_str()); + + FILE* f = NULL; + if (fopen_s(&f, sz_file_name, "wt") != 0) { + EXLOGE("fopen failed (%d).\n", GetLastError()); + _create_response(buf, msg_req, 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") { + w_exe_path += L"{size} {console} {clipboard} {drives} "; + w_exe_path += g_cfg.rdp.cmdline; + + ex_wstr w_screen; + + if (rdp_w == 0 || rdp_h == 0) { + //全屏 + w_screen = _T("/f"); + } + else { + char sz_size[64] = { 0 }; + ex_strformat(sz_size, 63, "/size:%dx%d", rdp_w, rdp_h); + ex_astr2wstr(sz_size, w_screen); + } + + // 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); + w_exe_path += L" /p:"; + w_exe_path += w_password; + + w_sid = L"02" + w_sid; + + w_exe_path += L" /gdi:sw"; // 使用软件渲染,gdi:hw使用硬件加速,但是会出现很多黑块(录像回放时又是正常的!) + w_exe_path += L" -grab-keyboard"; // [new style] 防止启动FreeRDP后,失去本地键盘响应,必须得先最小化一下FreeRDP窗口(不过貌似不起作用) + + // 变量替换 + ex_replace_all(w_exe_path, _T("{size}"), w_screen); + + 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_response(buf, msg_req, TPE_FAILED); + return; + } + } + else if (pro_type == TP_PROTOCOL_TYPE_SSH) { + //============================================== + // SSH + //============================================== + + if (pro_sub == TP_PROTOCOL_TYPE_SSH_SHELL) { + w_exe_path = _T("\""); + w_exe_path += g_cfg.ssh.application + _T("\" "); + w_exe_path += g_cfg.ssh.cmdline; + } + else { + w_exe_path = _T("\""); + w_exe_path += g_cfg.sftp.application + _T("\" "); + w_exe_path += g_cfg.sftp.cmdline; + } + } + else if (pro_type == TP_PROTOCOL_TYPE_TELNET) { + //============================================== + // TELNET + //============================================== + w_exe_path = _T("\""); + w_exe_path += g_cfg.telnet.application + _T("\" "); + w_exe_path += g_cfg.telnet.cmdline; + } + + ex_replace_all(w_exe_path, _T("{host_ip}"), w_teleport_ip.c_str()); + ex_replace_all(w_exe_path, _T("{host_port}"), w_port); + ex_replace_all(w_exe_path, _T("{user_name}"), w_sid.c_str()); + ex_replace_all(w_exe_path, _T("{host_name}"), w_remote_host_name.c_str()); + ex_replace_all(w_exe_path, _T("{real_ip}"), w_real_host_ip.c_str()); + ex_replace_all(w_exe_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str()); + + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + Json::Value js_data; + ex_astr utf8_path; + ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8); + js_data["path"] = utf8_path; + + if (!CreateProcess(NULL, (wchar_t*)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str()); + _create_response(buf, msg_req, TPE_START_CLIENT); + return; + } + + _create_response(buf, msg_req, TPE_OK, L"", js_data); +} diff --git a/client/tp_assist_win/ts_ws_client.h b/client/tp_assist_win/ts_ws_client.h new file mode 100644 index 0000000..2f5f95a --- /dev/null +++ b/client/tp_assist_win/ts_ws_client.h @@ -0,0 +1,82 @@ +#ifndef __TS_WS_CLIENT_H__ +#define __TS_WS_CLIENT_H__ + +#include "ts_const.h" + +#include +#include +#include + +#include +#include +#include + +#include "../../external/mongoose/mongoose.h" + +#define MESSAGE_TYPE_REQUEST 0 +#define MESSAGE_TYPE_RESPONSE 1 + +typedef struct AssistMessage +{ + int command_id; + std::string method; + + AssistMessage() : + command_id(0), + method("UNKNOWN") {} +} AssistMessage; + +class TsWsClient : public ExThreadBase +{ +public: + TsWsClient(); + + ~TsWsClient(); + + static void init_app(void* app); + static void stop_all_client(); + + static void url_scheme_handler(const std::string& url); + +protected: + void _thread_loop(void); + + // bool _on_init(); + +private: + void _register(const std::string& ws_url, uint32_t assist_id, const std::string& session_id); + + void _on_message(const std::string& message, std::string& buf); + + void _rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root); + + void _rpc_func_get_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root); + + void _rpc_func_set_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root); + + void _rpc_func_select_file(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root); + + void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code); + + void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message); + + void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message, Json::Value& data); + + // void _rpc_func_check(const ex_astr& func_args, ex_astr& buf); + // void _rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf); + // void _rpc_func_file_action(const ex_astr& func_args, ex_astr& buf); + // void _rpc_func_get_version(const ex_astr& func_args, ex_astr& buf); + + + + static void _mg_event_handler(struct mg_connection* nc, int ev, void* ev_data); + + static void _process_register(const std::string& param, Json::Value& js_root); + +private: + struct mg_mgr m_mg_mgr; + struct mg_connection* m_nc; + uint32_t m_assist_id; +}; + +#endif // __TS_WS_CLIENT_H__ diff --git a/common/libex/src/ex_path.cpp b/common/libex/src/ex_path.cpp index a3ca7b9..c7c632c 100644 --- a/common/libex/src/ex_path.cpp +++ b/common/libex/src/ex_path.cpp @@ -177,8 +177,8 @@ EX_BOOL ex_is_file_exists(const wchar_t* in_file) EX_BOOL ex_is_file_exists(const char* in_file) { #ifdef EX_OS_WIN32 - ex_wstr _in_path; - ex_astr2wstr(in_path, _in_path); + ex_wstr _in_file; + ex_astr2wstr(in_file, _in_file); if (!PathFileExists(_in_file.c_str())) return EX_FALSE; if (PathIsDirectory(_in_file.c_str())) diff --git a/config.json.in b/config.json.in index 2028aa1..fb1b5ac 100644 --- a/config.json.in +++ b/config.json.in @@ -17,6 +17,7 @@ "#.toolchain.example.windows": { "qt_path": "C:\\Qt\\Qt5.15.2\\5.15.2\\msvc2017", "cmake": "C:\\Program Files(x86)\\CMake\\bin\\cmake.exe", + "msbuild": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe", "wget": "", "7z": "", "nsis": "" diff --git a/dist/client/windows/assist/setup.nsh b/dist/client/windows/assist/setup.nsh index e0ca4e1f83a1305f6dc01f51af22c5fff6060ed1..74ed15a79df896d2ae32a5fa94a060a72a9a4e57 100644 GIT binary patch delta 62 zcmbRBgz?l9#tllY`Z^2>3?2;L49*Ne47OmFD?=nhJdp3h;K&dRgswmw50v!>!jR31 Hu0M4E%1sTW delta 14 WcmX^0gmKmr#tllYn}b|`=l}pV2L`kN diff --git a/make.sh b/make.sh index 808637b..bbe6a90 100755 --- a/make.sh +++ b/make.sh @@ -7,7 +7,8 @@ PATH_ROOT=$(cd "$(dirname "$0")"; pwd) # environment if you want to build teleport components for such # platforms. # ================================================================= -PY_EXEC_WINDOWS="C:\\apps\\py37-x86\\python.exe" +# PY_EXEC_WINDOWS="C:\\apps\\py37-x86\\python.exe" +PY_EXEC_WINDOWS="C:\\apps\\py39-x64\\python.exe" PY_EXEC_MACOS="/usr/local/bin/python3" set -e @@ -54,10 +55,10 @@ function build_win on_error "Sorry, need x86 version of Python 3.7 or above." fi # and must be x86 version. - $("${pyexec}" -c "import platform;import sys;ret=0 if platform.architecture()[0]=='32bit' else 1;sys.exit(ret)") - if [ $? -ne 0 ]; then - on_error "Sorry, need x86 version of Python 3.7 or above." - fi + # ret=$("${pyexec}" -c "import platform;import sys;ret=0 if platform.architecture()[0]=='32bit' else 1;print(ret)") + # if [ $ret -ne 0 ]; then + # on_error "Sorry, need x86 version of Python 3.7 or above." + # fi ${pyexec} -B "${PATH_ROOT}/build/build.py" $@ } @@ -151,6 +152,7 @@ elif [ ${SYS_NAME} = "Darw" ] ; then build_macos $@ elif [ ${SYS_NAME} == "MSYS" ] ; then export CFG_FILE=config.windows.json + echo $CFG_FILE build_win $@ else on_error_begin "Unsupported platform." diff --git a/server/tp_core/core/main.cpp b/server/tp_core/core/main.cpp index 9cb8870..77b532e 100644 --- a/server/tp_core/core/main.cpp +++ b/server/tp_core/core/main.cpp @@ -190,7 +190,7 @@ int app_main_(int argc, wchar_t** argv) #ifdef EX_OS_WIN32 #ifdef EX_DEBUG -#include +//#include #endif static SERVICE_STATUS g_ServiceStatus = { 0 }; @@ -210,7 +210,7 @@ int main() int _argc = 0; wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串; - ret = _app_main(_argc, _argv); + ret = app_main_(_argc, _argv); LocalFree(_argv); _argv = nullptr; @@ -218,7 +218,7 @@ int main() return ret; } -static bool _run_daemon(void) +static bool run_daemon_(void) { SERVICE_TABLE_ENTRY DispatchTable[2]; DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME; @@ -238,7 +238,7 @@ static bool _run_daemon(void) static DWORD WINAPI service_thread_func(LPVOID lpParam) { - int ret = _main_loop(); + int ret = main_loop_(); // 更新服务状态(如果服务还在运行,将其设置为停止状态) g_ServiceStatus.dwWin32ExitCode = 0; diff --git a/server/tp_core/core/tp_core.vs2017.vcxproj b/server/tp_core/core/tp_core.vs2017.vcxproj index ee0e4d1..1a8ac46 100644 --- a/server/tp_core/core/tp_core.vs2017.vcxproj +++ b/server/tp_core/core/tp_core.vs2017.vcxproj @@ -15,13 +15,13 @@ Win32Proj tp_core tp_core - 8.1 + 10.0
Application true - v141 + v142 Unicode @@ -29,7 +29,7 @@ false true Unicode - v141 + v142 diff --git a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj index cd5eb27..0638af9 100644 --- a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj +++ b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj @@ -14,20 +14,20 @@ {FDA16D20-09B7-45AF-ADF1-DAF3EF2C0531} Win32Proj tpssh - 8.1 + 10.0 tpssh DynamicLibrary true - v141 + v142 Unicode DynamicLibrary false - v141 + v142 true Unicode diff --git a/server/www/teleport/static/js/assist/config.js b/server/www/teleport/static/js/assist/config.js index 585088b..7faf40b 100644 --- a/server/www/teleport/static/js/assist/config.js +++ b/server/www/teleport/static/js/assist/config.js @@ -90,7 +90,7 @@ $app.init_dom_event = function (cb_stack) { $app._on_type_change($app.cfg.rdp, $app.dom.rdp_type, $app.dom.rdp_app, $app.dom.rdp_cmdline, $app.dom.rdp_desc); }); $app.dom.ssh_select_app.click(function () { - $assist.select_local_file('ssg'); + $assist.select_local_file('ssh'); }); $app.dom.sftp_select_app.click(function () { $assist.select_local_file('sftp');