添加urlprotocol启动方法

添加urlprotocol启动方法
pull/124/head
horizonlin 2018-12-11 14:09:18 +08:00 committed by GitHub
parent fc72e2c292
commit 7fa5c8936b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 122 additions and 36 deletions

View File

@ -16,22 +16,22 @@
/*
1.
SecureCRT /N "tab name"
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使 /T
SecureCRT.exe /T /N "TP#ssh://192.168.1.3" /SSH2 /L root /PASSWORD 1234 120.26.109.25
3.
telnet
telnet
putty.exe telnet://administrator@127.0.0.1:52389
SecureCRT
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
------------------
startup.vbs
------------------
#$language = "VBScript"
#$interface = "1.0"
Sub main
@ -40,11 +40,11 @@ Sub main
crt.Screen.Send "SESSION-ID" & VbCr
crt.Screen.Synchronous = False
End Sub
------------------
------------------
4. puttyIP
4. puttyIP
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@192.168.1.2: \w\a\]$PS1"
ubuntuLinuxSecureCRT
ubuntuLinuxSecureCRT
*/
//#define RDP_CLIENT_SYSTEM_BUILTIN
@ -203,6 +203,40 @@ bool calc_psw51b(const char* password, std::string& ret)
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<std::string>& 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;
@ -317,7 +351,7 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat
if (uri == "/")
{
ex_wstr page = L"<html lang=\"zh_CN\"><head><meta charset=\"utf-8\"/><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>Teleport助手</title>\n<style type=\"text/css\">\n.box{padding:20px;margin:40px;border:1px solid #78b17c;background-color:#e4ffe5;}\n</style>\n</head><body><div class=\"box\">Teleport助手工作正常</div></body></html>";
ex_wstr page = L"<html lang=\"zh_CN\"><head><meta charset=\"utf-8\"/><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>Teleport助手</title>\n<style type=\"text/css\">\n.box{padding:20px;margin:40px;border:1px solid #78b17c;background-color:#e4ffe5;}\n</style>\n</head><body><div class=\"box\">Teleport助手工作正常</div></body></html>";
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]);
@ -424,7 +458,7 @@ int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_as
ex_astrs strs;
size_t pos_start = 1; // 跳过第一个字节,一定是 '/'
size_t pos_start = 1; // 跳过第一个字节,一定是 '/'
size_t i = 0;
for (i = pos_start; i < req->uri.len; ++i)
@ -437,7 +471,7 @@ int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_as
tmp_uri.assign(req->uri.p + pos_start, i - pos_start);
strs.push_back(tmp_uri);
}
pos_start = i + 1; // 跳过当前找到的分隔符
pos_start = i + 1; // 跳过当前找到的分隔符
}
}
if (pos_start < req->uri.len)
@ -485,7 +519,7 @@ int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_as
if (func_args.length() > 0)
{
// 将参数进行 url-decode 解码
// 将参数进行 url-decode 解码
int len = func_args.length() * 2;
ex_chars sztmp;
sztmp.resize(len);
@ -536,7 +570,7 @@ void TsHttpRpc::_process_js_request(const ex_astr& func_cmd, const ex_astr& func
void TsHttpRpc::_create_json_ret(ex_astr& buf, int errcode)
{
// 返回: {"code":123}
// 返回: {"code":123}
Json::FastWriter jr_writer;
Json::Value jr_root;
@ -551,13 +585,65 @@ void TsHttpRpc::_create_json_ret(ex_astr& buf, Json::Value& jr_root)
buf = jr_writer.write(jr_root);
}
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<std::string> strv;
SplitString(func_args, strv, ",");
func_args = "";
for (std::vector<std::string>::size_type i = 0; i < strv.size(); i++) {
std::vector<std::string> 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}
// 入参:{"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"}}
// SSH返回 {"code":0, "data":{"sid":"0123abcde"}}
// RDP返回 {"code":0, "data":{"sid":"0123abcde0A"}}
Json::Reader jreader;
Json::Value jsRoot;
@ -573,7 +659,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
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()
@ -688,7 +774,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
int iHeight = GetSystemMetrics(SM_CYSCREEN);
if (rdp_w == 0 || rdp_h == 0) {
//全屏
//全屏
width = iWidth;
higth = iHeight;
display = 2;
@ -763,7 +849,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
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") {
@ -773,7 +859,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
ex_wstr w_screen;
if (rdp_w == 0 || rdp_h == 0) {
//全屏
//全屏
w_screen = _T("/f");
}
else {
@ -800,10 +886,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
w_sid = L"02" + w_sid;
w_exe_path += L" /gdi:sw"; // 使用软件渲染gdi:hw使用硬件加速但是会出现很多黑块录像回放时又是正常的
w_exe_path += L" -grab-keyboard"; // [new style] 防止启动FreeRDP后失去本地键盘响应必须得先最小化一下FreeRDP窗口不过貌似不起作用
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)
@ -899,7 +985,7 @@ void TsHttpRpc::_rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf)
return;
}
// 判断参数是否正确
// 判断参数是否正确
if (!jsRoot["rid"].isInt()
|| !jsRoot["web"].isString()
|| !jsRoot["sid"].isString()
@ -924,9 +1010,9 @@ void TsHttpRpc::_rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf)
char cmd_args[1024] = { 0 };
ex_strformat(cmd_args, 1023, "%d \"%s\" \"%09d-%s-%s-%s-%s\"", rid, a_sid.c_str(), rid, a_user.c_str(), a_acc.c_str(), a_host.c_str(), a_start.c_str());
// TODO: 理论上不应该由助手来提前做域名转为IP这样的操作而是应该讲域名发送给播放器由播放器自己去处理
// 但是在改造FreeRDP制作的播放器时为了从服务器上下载文件使用了Mongoose库如果传入的是域名会出现问题貌似是异步查询DNS的问题
// 所以暂时先由助手进行域名IP转换。
// TODO: 理论上不应该由助手来提前做域名转为IP这样的操作而是应该讲域名发送给播放器由播放器自己去处理
// 但是在改造FreeRDP制作的播放器时为了从服务器上下载文件使用了Mongoose库如果传入的是域名会出现问题貌似是异步查询DNS的问题
// 所以暂时先由助手进行域名IP转换。
{
unsigned int port_i = 0;
struct mg_str scheme, query, fragment, user_info, host, path;
@ -942,7 +1028,7 @@ void TsHttpRpc::_rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf)
ex_astr _scheme;
_scheme.assign(scheme.p, scheme.len);
// 将host从域名转换为IP
// 将host从域名转换为IP
ex_astr str_tp_host;
str_tp_host.assign(host.p, host.len);
struct hostent *tp_host = gethostbyname(str_tp_host.c_str());
@ -1052,7 +1138,7 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) {
_create_json_ret(buf, TPE_JSON_FORMAT);
return;
}
// 判断参数是否正确
// 判断参数是否正确
if (!jsRoot["action"].isNumeric())
{
_create_json_ret(buf, TPE_PARAM);
@ -1077,9 +1163,9 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) {
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrTitle = _T("选择文件");
ofn.lpstrTitle = _T("选择文件");
ofn.hwndOwner = hParent;
ofn.lpstrFilter = _T("可执行程序 (*.exe)\0*.exe\0");
ofn.lpstrFilter = _T("可执行程序 (*.exe)\0*.exe\0");
ofn.lpstrFile = wszReturnPath;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = wsDefaultPath.c_str();
@ -1102,12 +1188,12 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) {
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = NULL;
bi.pidlRoot = NULL;
bi.pszDisplayName = wszReturnPath; //此参数如为NULL则不能显示对话框
bi.lpszTitle = _T("选择目录");
bi.pszDisplayName = wszReturnPath; //此参数如为NULL则不能显示对话框
bi.lpszTitle = _T("选择目录");
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.iImage = 0; //初始化入口参数bi结束
LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框
bi.iImage = 0; //初始化入口参数bi结束
LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框
if (pIDList)
{
ret = true;