mirror of https://github.com/tp4a/teleport
1. 去掉在rdp的sid前填写的两个字节;2. 格式化部分代码。
parent
e82eecfd04
commit
e9de6513eb
|
@ -692,8 +692,8 @@ class BuilderMacOS(BuilderBase):
|
|||
cc.w('already exists, skip.')
|
||||
|
||||
def _build_openssl(self, file_name):
|
||||
cc.w('skip build openssl again.')
|
||||
return
|
||||
# cc.w('skip build openssl again.')
|
||||
# return
|
||||
|
||||
if not self._download_openssl(file_name):
|
||||
return
|
||||
|
@ -943,6 +943,7 @@ def main():
|
|||
builder.build_jsoncpp()
|
||||
builder.build_mongoose()
|
||||
builder.build_zlib()
|
||||
builder.build_mbedtls()
|
||||
builder.build_openssl()
|
||||
elif command == 'ext-server':
|
||||
builder.prepare_python()
|
||||
|
|
|
@ -3,44 +3,47 @@
|
|||
|
||||
TsCfg g_cfg;
|
||||
|
||||
TsCfg::TsCfg()
|
||||
{}
|
||||
TsCfg::TsCfg() {}
|
||||
|
||||
TsCfg::~TsCfg()
|
||||
{}
|
||||
TsCfg::~TsCfg() {}
|
||||
|
||||
bool TsCfg::init(void) {
|
||||
ex_astr file_content;
|
||||
if(!ex_read_text_file(g_env.m_cfg_file, file_content)) {
|
||||
EXLOGE("can not load config file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!_load(file_content))
|
||||
return false;
|
||||
bool TsCfg::init(void)
|
||||
{
|
||||
ex_astr file_content;
|
||||
if (!ex_read_text_file(g_env.m_cfg_file, file_content))
|
||||
{
|
||||
EXLOGE("can not load config file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!m_root.isObject()) {
|
||||
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()) {
|
||||
|
||||
if (m_root["file_version"].isNull())
|
||||
{
|
||||
EXLOGE("invalid config file, maybe need create new one?\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!m_root["file_version"].isInt()) {
|
||||
|
||||
|
||||
if (!m_root["file_version"].isInt())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TsCfg::save(const ex_astr& new_value)
|
||||
{
|
||||
if(!_load(new_value))
|
||||
return false;
|
||||
|
||||
if (!_load(new_value))
|
||||
return false;
|
||||
|
||||
Json::StreamWriterBuilder jwb;
|
||||
jwb["indentation"] = " ";
|
||||
jwb["emitUTF8"] = true;
|
||||
|
@ -49,67 +52,78 @@ bool TsCfg::save(const ex_astr& new_value)
|
|||
jwriter->write(m_root, &os);
|
||||
ex_astr val = os.str();
|
||||
|
||||
if(!ex_write_text_file(g_env.m_cfg_file, val)) {
|
||||
EXLOGE("can not save config file.\n");
|
||||
return false;
|
||||
}
|
||||
if (!ex_write_text_file(g_env.m_cfg_file, val))
|
||||
{
|
||||
EXLOGE("can not save config file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg) {
|
||||
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())
|
||||
if (!jApp.isObject())
|
||||
return false;
|
||||
|
||||
if (!jApp["selected"].isString()) {
|
||||
|
||||
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) {
|
||||
if (!jApp["available"].isArray() || jApp["available"].size() == 0)
|
||||
{
|
||||
EXLOGE("invalid config, error 3.\n");
|
||||
return false;
|
||||
}
|
||||
const Json::Value& jAppList = jApp["available"];
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < jAppList.size(); ++i) {
|
||||
for (i = 0; i < jAppList.size(); ++i)
|
||||
{
|
||||
if (
|
||||
!jAppList[i]["name"].isString()
|
||||
|| !jAppList[i]["app"].isString()
|
||||
|| !jAppList[i]["cmdline"].isString()
|
||||
|| !jAppList[i]["desc"].isArray()
|
||||
) {
|
||||
!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()) {
|
||||
|
||||
if (jAppList[i]["name"].asString().empty())
|
||||
{
|
||||
EXLOGE("invalid config, need name.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jAppList[i]["display"].isNull() || jAppList[i]["display"].asString().empty()) {
|
||||
if (jAppList[i]["display"].isNull() || jAppList[i]["display"].asString().empty())
|
||||
{
|
||||
cfg.display = jAppList[i]["name"].asCString();
|
||||
} else
|
||||
}
|
||||
else
|
||||
cfg.display = jAppList[i]["display"].asCString();
|
||||
|
||||
if (jAppList[i]["name"].asCString() != _selected)
|
||||
continue;
|
||||
|
||||
|
||||
cfg.name = jAppList[i]["name"].asCString();
|
||||
cfg.display = jAppList[i]["display"].asCString();
|
||||
cfg.application = jAppList[i]["app"].asCString();
|
||||
cfg.cmdline = jAppList[i]["cmdline"].asCString();
|
||||
|
||||
if(jAppList[i]["desc"].size() > 0) {
|
||||
if (jAppList[i]["desc"].size() > 0)
|
||||
{
|
||||
const Json::Value& jAppDescList = jAppList[i]["desc"];
|
||||
|
||||
|
||||
int j = 0;
|
||||
for(j = 0; j < jAppDescList.size(); ++j) {
|
||||
if(!jAppDescList[j].isString())
|
||||
for (j = 0; j < jAppDescList.size(); ++j)
|
||||
{
|
||||
if (!jAppDescList[j].isString())
|
||||
return false;
|
||||
cfg.description.push_back(jAppDescList[j].asCString());
|
||||
}
|
||||
|
@ -122,28 +136,30 @@ bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CO
|
|||
}
|
||||
|
||||
|
||||
bool TsCfg::_load(const ex_astr& str_json) {
|
||||
bool TsCfg::_load(const ex_astr& str_json)
|
||||
{
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
const char *str_json_begin = str_json.c_str();
|
||||
const char* str_json_begin = str_json.c_str();
|
||||
|
||||
ex_astr err;
|
||||
if (!jreader->parse(str_json_begin, str_json_begin + str_json.length(), &m_root, &err)) {
|
||||
if (!jreader->parse(str_json_begin, str_json_begin + str_json.length(), &m_root, &err))
|
||||
{
|
||||
EXLOGE("can not parse new config data, not in json format? %s\n", err.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//===================================
|
||||
// check config
|
||||
//===================================
|
||||
if(!_parse_app(m_root, "ssh", ssh))
|
||||
//===================================
|
||||
// check config
|
||||
//===================================
|
||||
if (!_parse_app(m_root, "ssh", ssh))
|
||||
return false;
|
||||
if(!_parse_app(m_root, "sftp", sftp))
|
||||
if (!_parse_app(m_root, "sftp", sftp))
|
||||
return false;
|
||||
if(!_parse_app(m_root, "telnet", telnet))
|
||||
if (!_parse_app(m_root, "telnet", telnet))
|
||||
return false;
|
||||
if(!_parse_app(m_root, "rdp", rdp))
|
||||
if (!_parse_app(m_root, "rdp", rdp))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,36 +6,40 @@
|
|||
|
||||
#include <json/json.h>
|
||||
|
||||
typedef struct APP_CONFIG {
|
||||
typedef struct APP_CONFIG
|
||||
{
|
||||
ex_astr name;
|
||||
ex_astr display;
|
||||
ex_astr application;
|
||||
ex_astr cmdline;
|
||||
ex_astrs description;
|
||||
}APP_CONFIG;
|
||||
} APP_CONFIG;
|
||||
|
||||
class TsCfg
|
||||
{
|
||||
public:
|
||||
TsCfg();
|
||||
virtual ~TsCfg();
|
||||
TsCfg();
|
||||
|
||||
virtual ~TsCfg();
|
||||
|
||||
bool init(void);
|
||||
|
||||
bool init(void);
|
||||
bool save(const ex_astr& new_value);
|
||||
|
||||
Json::Value& get_root() {return m_root;}
|
||||
|
||||
Json::Value& get_root() { return m_root; }
|
||||
|
||||
APP_CONFIG ssh;
|
||||
APP_CONFIG sftp;
|
||||
APP_CONFIG telnet;
|
||||
APP_CONFIG rdp;
|
||||
|
||||
protected:
|
||||
bool _load(const ex_astr& str_json);
|
||||
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;
|
||||
Json::Value m_root;
|
||||
};
|
||||
|
||||
extern TsCfg g_cfg;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "ts_env.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
# include <direct.h>
|
||||
//# include <ShlObj.h>
|
||||
|
@ -12,34 +13,33 @@ TsEnv g_env;
|
|||
//
|
||||
//=======================================================
|
||||
|
||||
TsEnv::TsEnv()
|
||||
{}
|
||||
TsEnv::TsEnv() {}
|
||||
|
||||
TsEnv::~TsEnv()
|
||||
{}
|
||||
TsEnv::~TsEnv() {}
|
||||
|
||||
bool TsEnv::init(const char* bundle_path, const char* cfg_file, const char* res_path, const char* log_path)
|
||||
{
|
||||
ex_astr2wstr(bundle_path, m_bundle_path);
|
||||
ex_astr2wstr(cfg_file, m_cfg_file);
|
||||
ex_astr2wstr(res_path, m_res_path);
|
||||
ex_astr2wstr(res_path, m_res_path);
|
||||
ex_astr2wstr(log_path, m_log_path);
|
||||
|
||||
#ifdef EX_DEBUG
|
||||
m_site_path = L"/Users/apex/work/tp4a/teleport/client/tp_assist_macos/site";
|
||||
//m_bundle_path = L"/Users/apex/work/tp4a/teleport/out/client/x64/release";
|
||||
#else
|
||||
m_site_path = m_res_path;
|
||||
ex_path_join(m_site_path, false, L"site", NULL);
|
||||
m_site_path = m_res_path;
|
||||
ex_path_join(m_site_path, false, L"site", NULL);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len) {
|
||||
(void) ctx;
|
||||
while (len--) *buf++ = (arc4random() % 255);
|
||||
return 0;
|
||||
int mg_ssl_if_mbed_random(void* ctx, unsigned char* buf, size_t len)
|
||||
{
|
||||
(void)ctx;
|
||||
while (len--) { *buf++ = (arc4random() % 255); }
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,25 +6,26 @@
|
|||
class TsEnv
|
||||
{
|
||||
public:
|
||||
TsEnv();
|
||||
~TsEnv();
|
||||
TsEnv();
|
||||
|
||||
bool init(const char* bundle_path, const char* cfg_file, const char* res_path, const char* log_path);
|
||||
~TsEnv();
|
||||
|
||||
bool init(const char* bundle_path, const char* cfg_file, const char* res_path, const char* log_path);
|
||||
|
||||
public:
|
||||
ex_wstr m_bundle_path;
|
||||
ex_wstr m_cfg_file;
|
||||
ex_wstr m_res_path;
|
||||
|
||||
// ex_wstr m_exec_file;
|
||||
// ex_wstr m_exec_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_log_path;
|
||||
ex_wstr m_site_path;
|
||||
// ex_wstr m_tools_path;
|
||||
ex_wstr m_cfg_file;
|
||||
ex_wstr m_res_path;
|
||||
|
||||
// ex_wstr m_exec_file;
|
||||
// ex_wstr m_exec_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_log_path;
|
||||
ex_wstr m_site_path;
|
||||
// ex_wstr m_tools_path;
|
||||
};
|
||||
|
||||
extern TsEnv g_env;
|
||||
|
|
|
@ -17,23 +17,26 @@ TsHttpRpc g_http_interface;
|
|||
|
||||
TsHttpRpc::TsHttpRpc() : ExThreadBase("http-rpc-thread")
|
||||
{
|
||||
mg_mgr_init(&m_mg_mgr, NULL);
|
||||
mg_mgr_init(&m_mg_mgr, NULL);
|
||||
}
|
||||
|
||||
TsHttpRpc::~TsHttpRpc()
|
||||
{
|
||||
mg_mgr_free(&m_mg_mgr);
|
||||
mg_mgr_free(&m_mg_mgr);
|
||||
}
|
||||
|
||||
bool TsHttpRpc::init() {
|
||||
bool TsHttpRpc::init()
|
||||
{
|
||||
struct mg_connection* nc = NULL;
|
||||
|
||||
for(int port = TS_HTTP_RPC_PORT_MIN; port < TS_HTTP_RPC_PORT_MAX; ++port) {
|
||||
char addr[128] = { 0 };
|
||||
for (int port = TS_HTTP_RPC_PORT_MIN; port < TS_HTTP_RPC_PORT_MAX; ++port)
|
||||
{
|
||||
char addr[128] = {0};
|
||||
ex_strformat(addr, 128, "tcp://127.0.0.1:%d", port);
|
||||
|
||||
nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler);
|
||||
if (!nc) {
|
||||
if (!nc)
|
||||
{
|
||||
EXLOGW("[WRN] can not start HTTP-RPC listener, maybe port %d is already in use.\n", port);
|
||||
continue;
|
||||
}
|
||||
|
@ -41,8 +44,9 @@ bool TsHttpRpc::init() {
|
|||
m_port = port;
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_port == 0) {
|
||||
|
||||
if (m_port == 0)
|
||||
{
|
||||
EXLOGE("[rpc] can not listen on port %d~%d\n", TS_HTTP_RPC_PORT_MIN, TS_HTTP_RPC_PORT_MAX);
|
||||
return false;
|
||||
}
|
||||
|
@ -54,7 +58,8 @@ bool TsHttpRpc::init() {
|
|||
return _on_init();
|
||||
}
|
||||
|
||||
bool TsHttpRpc::_on_init() {
|
||||
bool TsHttpRpc::_on_init()
|
||||
{
|
||||
m_content_type_map[".js"] = "application/javascript";
|
||||
m_content_type_map[".png"] = "image/png";
|
||||
m_content_type_map[".jpeg"] = "image/jpeg";
|
||||
|
@ -73,258 +78,262 @@ bool TsHttpRpc::_on_init() {
|
|||
|
||||
void TsHttpRpc::_thread_loop(void)
|
||||
{
|
||||
while (!m_need_stop)
|
||||
{
|
||||
mg_mgr_poll(&m_mg_mgr, 500);
|
||||
}
|
||||
while (!m_need_stop)
|
||||
{
|
||||
mg_mgr_poll(&m_mg_mgr, 500);
|
||||
}
|
||||
|
||||
EXLOGV("[core] rpc main loop end.\n");
|
||||
EXLOGV("[core] rpc main loop end.\n");
|
||||
}
|
||||
|
||||
void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_data)
|
||||
void TsHttpRpc::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_data)
|
||||
{
|
||||
struct http_message *hm = (struct http_message*)ev_data;
|
||||
struct http_message* hm = (struct http_message*)ev_data;
|
||||
|
||||
TsHttpRpc* _this = (TsHttpRpc*)nc->user_data;
|
||||
if (NULL == _this)
|
||||
{
|
||||
EXLOGE("[ERROR] invalid http request.\n");
|
||||
return;
|
||||
}
|
||||
TsHttpRpc* _this = (TsHttpRpc*)nc->user_data;
|
||||
if (NULL == _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];
|
||||
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
|
||||
const char* dbg_method = NULL;
|
||||
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";
|
||||
const char* dbg_method = NULL;
|
||||
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());
|
||||
EXLOGV("[rpc] got %s request: %s\n", dbg_method, uri.c_str());
|
||||
#endif
|
||||
ex_astr ret_buf;
|
||||
ex_astr ret_buf;
|
||||
bool b_is_html = false;
|
||||
|
||||
if (uri == "/") {
|
||||
if (uri == "/")
|
||||
{
|
||||
uri = "/status.html";
|
||||
b_is_html = true;
|
||||
}
|
||||
else if (uri == "/config") {
|
||||
else if (uri == "/config")
|
||||
{
|
||||
uri = "/index.html";
|
||||
b_is_html = true;
|
||||
}
|
||||
|
||||
ex_astr temp;
|
||||
size_t offset = uri.find("/", 1);
|
||||
if (offset > 0)
|
||||
{
|
||||
temp = uri.substr(1, offset-1);
|
||||
ex_astr temp;
|
||||
size_t 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);
|
||||
}
|
||||
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.c_str());
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
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.c_str());
|
||||
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_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;
|
||||
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 = 0;
|
||||
size_t ret = 0;
|
||||
FILE* file = ex_fopen(index_path.c_str(), "rb");
|
||||
if (file)
|
||||
{
|
||||
unsigned long file_size = 0;
|
||||
char* buf = 0;
|
||||
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);
|
||||
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);
|
||||
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"<html lang=\"zh_CN\"><html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr><center><p>Teleport Assistor configuration page not found.</p></center></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: %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"<html lang=\"zh_CN\"><html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr><center><p>Teleport Assistor configuration page not found.</p></center></body></html>";
|
||||
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.length(), ret_buf.c_str());
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
return;
|
||||
}
|
||||
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.length(), ret_buf.c_str());
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args)
|
||||
{
|
||||
if (NULL == req)
|
||||
return TPE_FAILED;
|
||||
if (NULL == 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;
|
||||
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;
|
||||
ex_astrs strs;
|
||||
|
||||
size_t pos_start = 1; // skip first charactor, it must be '/'
|
||||
size_t pos_start = 1; // skip first charactor, it must be '/'
|
||||
|
||||
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; // skip current split chactor.
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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; // skip current split chactor.
|
||||
}
|
||||
}
|
||||
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 (0 == strs.size() || strs[0] != "api")
|
||||
return TPE_PARAM;
|
||||
if (0 == strs.size() || 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 (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 (req->body.len > 0)
|
||||
{
|
||||
func_args.assign(req->body.p, req->body.len);
|
||||
}
|
||||
}
|
||||
|
||||
if (func_args.length() > 0)
|
||||
{
|
||||
// decode param with url-decode.
|
||||
size_t len = func_args.length() * 2;
|
||||
ex_chars sztmp;
|
||||
sztmp.resize(len);
|
||||
memset(&sztmp[0], 0, len);
|
||||
if (-1 == ex_url_decode(func_args.c_str(), (int)func_args.length(), &sztmp[0], (int)len, 0))
|
||||
return TPE_HTTP_URL_ENCODE;
|
||||
if (func_args.length() > 0)
|
||||
{
|
||||
// decode param with url-decode.
|
||||
size_t len = func_args.length() * 2;
|
||||
ex_chars sztmp;
|
||||
sztmp.resize(len);
|
||||
memset(&sztmp[0], 0, len);
|
||||
if (-1 == ex_url_decode(func_args.c_str(), (int)func_args.length(), &sztmp[0], (int)len, 0))
|
||||
return TPE_HTTP_URL_ENCODE;
|
||||
|
||||
func_args = &sztmp[0];
|
||||
}
|
||||
func_args = &sztmp[0];
|
||||
}
|
||||
|
||||
EXLOGV("[rpc] method=%s, json_param=%s\n", func_cmd.c_str(), func_args.c_str());
|
||||
EXLOGV("[rpc] method=%s, json_param=%s\n", func_cmd.c_str(), func_args.c_str());
|
||||
|
||||
return TPE_OK;
|
||||
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 == "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);
|
||||
}
|
||||
if (func_cmd == "get_version")
|
||||
{
|
||||
_rpc_func_get_version(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)
|
||||
{
|
||||
// return {"code":123}
|
||||
// return {"code":123}
|
||||
|
||||
Json::Value jr_root;
|
||||
jr_root["code"] = errcode;
|
||||
Json::Value jr_root;
|
||||
jr_root["code"] = errcode;
|
||||
Json::StreamWriterBuilder jwb;
|
||||
std::unique_ptr<Json::StreamWriter> jwriter(jwb.newStreamWriter());
|
||||
ex_aoss os;
|
||||
|
@ -341,31 +350,35 @@ void TsHttpRpc::_create_json_ret(ex_astr& buf, Json::Value& jr_root)
|
|||
buf = os.str();
|
||||
}
|
||||
|
||||
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_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) {
|
||||
void TsHttpRpc::_rpc_func_set_config(const ex_astr& func_args, ex_astr& buf)
|
||||
{
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
const char *str_json_begin = func_args.c_str();
|
||||
const char* str_json_begin = func_args.c_str();
|
||||
Json::Value jsRoot;
|
||||
ex_astr err;
|
||||
if (!jreader->parse(str_json_begin, str_json_begin + func_args.length(), &jsRoot, &err)) {
|
||||
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);
|
||||
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) {
|
||||
void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf)
|
||||
{
|
||||
_create_json_ret(buf, TPE_FAILED);
|
||||
#if 0
|
||||
Json::Reader jreader;
|
||||
|
@ -406,13 +419,14 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) {
|
|||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
//=================================================================
|
||||
|
||||
# HTTP-RPC-INTERFACE:
|
||||
|
||||
|
||||
listen on http://localhost:50022.
|
||||
|
||||
|
||||
----------------
|
||||
GET method:
|
||||
http://127.0.0.1:50022/method/json_param
|
||||
|
||||
|
||||
here `json_param` is string in json format and encoded by url_encode().
|
||||
|
||||
----------------
|
||||
|
@ -30,22 +30,22 @@
|
|||
http://127.0.0.1:50022/method
|
||||
|
||||
here the data field of POST should be json_param.
|
||||
|
||||
|
||||
|
||||
|
||||
## URI detail:
|
||||
|
||||
|
||||
- method the method to request to execute.
|
||||
- json_param param of the method and it is optional.
|
||||
|
||||
## RESULT
|
||||
|
||||
A string in json format should returned with following format:
|
||||
|
||||
|
||||
{"code":0,"data":varb}
|
||||
|
||||
`code` field always exists and 0 means success.
|
||||
`data` field is optional.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -54,47 +54,54 @@ typedef std::map<ex_astr, ex_astr> content_type_map;
|
|||
class TsHttpRpc : public ExThreadBase
|
||||
{
|
||||
public:
|
||||
TsHttpRpc();
|
||||
~TsHttpRpc();
|
||||
TsHttpRpc();
|
||||
|
||||
~TsHttpRpc();
|
||||
|
||||
bool init();
|
||||
|
||||
int get_port() {return m_port;}
|
||||
int get_port() { return m_port; }
|
||||
|
||||
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";
|
||||
}
|
||||
};
|
||||
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";
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
void _thread_loop(void);
|
||||
void _thread_loop(void);
|
||||
|
||||
bool _on_init();
|
||||
|
||||
private:
|
||||
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_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;
|
||||
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_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;
|
||||
int m_port;
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,7 @@ public:
|
|||
~TsWsClient();
|
||||
|
||||
void init();
|
||||
|
||||
void stop_all_client();
|
||||
|
||||
void url_scheme_handler(const std::string& url);
|
||||
|
@ -57,7 +58,7 @@ private:
|
|||
void _rpc_func_select_file(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
|
||||
|
||||
void _rpc_func_replay_rdp(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
|
||||
|
||||
|
||||
void _send_result(int err_code, Json::Value& jr_root);
|
||||
|
||||
void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code);
|
||||
|
@ -69,8 +70,9 @@ private:
|
|||
static void _mg_event_handler(struct mg_connection* nc, int ev, void* ev_data);
|
||||
|
||||
void _process_register(const std::string& param, Json::Value& js_root);
|
||||
|
||||
|
||||
void _process_run(const std::string& param, Json::Value& js_root);
|
||||
|
||||
void _process_replay_rdp(const std::string& param, Json::Value& js_root);
|
||||
|
||||
private:
|
||||
|
|
|
@ -161,9 +161,9 @@ bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info)
|
|||
if (info->protocol_type == TP_PROTOCOL_TYPE_RDP)
|
||||
{
|
||||
info->ref_count = 1; // 因为RDP连接之前可能会有很长时间用于确认是否连接、是否信任证书,所以很容易超时,我们认为将引用计数+1,防止因超时被清除。
|
||||
char szTmp[8] = {0};
|
||||
snprintf(szTmp, 8, "%02X", (unsigned char)(info->acc_username.length() + info->acc_secret.length()));
|
||||
sid += szTmp;
|
||||
// char szTmp[8] = {0};
|
||||
// snprintf(szTmp, 8, "%02X", (unsigned char)(info->acc_username.length() + info->acc_secret.length()));
|
||||
// sid += szTmp;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -518,11 +518,9 @@ $app.connect_remote = function (uni_id, acc_id, host_id, protocol_type, protocol
|
|||
is_interactive: false,
|
||||
};
|
||||
if (protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
args.extends({
|
||||
rdp_width: $app.dlg_rdp_options.rdp_w,
|
||||
rdp_height: $app.dlg_rdp_options.rdp_h,
|
||||
rdp_console: $app.dlg_rdp_options.rdp_console
|
||||
});
|
||||
args.rdp_width = $app.dlg_rdp_options.rdp_w;
|
||||
args.rdp_height = $app.dlg_rdp_options.rdp_h;
|
||||
args.rdp_console = $app.dlg_rdp_options.rdp_console;
|
||||
}
|
||||
|
||||
if (uni_id === 'none')
|
||||
|
|
Loading…
Reference in New Issue