diff --git a/build/build.py b/build/build.py index 241bd29..8ed47a6 100644 --- a/build/build.py +++ b/build/build.py @@ -155,6 +155,7 @@ def do_opt(opt): # cmd = '"%s" -B "%s" %s' % (utils.cfg.py_exec, os.path.join(BUILDER_PATH, script), arg) cmd = '%s -B %s %s' % (env.py_exec, os.path.join(env.builder_path, script), arg) + print(cmd) os.system(cmd) diff --git a/build/builder/core/ver.py b/build/builder/core/ver.py index bc57f30..fbc8d0a 100644 --- a/build/builder/core/ver.py +++ b/build/builder/core/ver.py @@ -1,3 +1,3 @@ # -*- coding: utf8 -*- -VER_TP_SERVER = "3.2.1" -VER_TP_ASSIST = "3.2.0" +VER_TP_SERVER = "3.2.2" +VER_TP_ASSIST = "3.2.2" diff --git a/client/cfg/localhost.key b/client/cfg/localhost.key index 852ff91..33108af 100644 --- a/client/cfg/localhost.key +++ b/client/cfg/localhost.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDxI1ZDRvuNnkVB -JgTZmnwF97d7Ace+R0gSSkWi2l2oezakLSdUUkiysr1wx45u2Du36FNqMGg7LiCZ -SX1e2Zba96PI6vwNGnlprCfXTe2eV3W8kMPKA6c9X8BTktMZINNHO3K591jGx+uM -fyrl6/CFVPHNkl73Ium9u91JXIX9BOata4RTlphmHADc+hPXuC6oeN8qayZvV2rV -Jfx1wMlWCMiGJM36JJO5pywteBCKQkVJuJ7y29XF2wT690o+i6ugk+yI2/2OpiET -2E5SYdvyhlbcU+iBERsnY3X7IvFY8/m00YIjIc3reGSEwt9M5WTPRCjgonnpQGAx -9xWXwqkzAgMBAAECggEAT9b2YdInye0EWxy+cFoBBGzPeE/PlcW+LCghRFlutzEM -l3FH21hfL6OUq7m3BCZeJ3cp3zfl2upb6sT1WKlMlHV36jc7ew8v8fgJPPVVXp7w -oZ2A5estvVltsX4knOZMbgJV6xLldvOMnvkf9/6VpV/Jq9nxzXvmzmZcT0TuLCaF -uPk/g/yD5qQ8LkWXDVJeBiDrrOZYo5F+T8bveYKKIEZV0ZAlXwJqVOUFnhffIaDF -fZVDOv4K3+q0aRDLTY2hxptHZiKzpLXgU634nBN3fiy0Fj88upNIus22gjaz+Jfx -2pYv22iGNXAMFQwGaeuT7d4+qhgxze8C7YlLJsJWCQKBgQD8kkXbgYG+8NoKmovz -ki9nuK1R6On5pNjZ344SJm6t/s4FaxQhE/4oHvODwgolqKyT2Sq1K8/5NInRGA29 -xPqqkkhwWk3Zf9VTXgmuXsOikPhbCOuiehO+6/ZthmHYy1jBMqkAIWYaL9Ytn2qb -dKMHwzNdnppQNdQnwmXI2ZdRBQKBgQD0aVTSOmKfKdIxH9qFLdbi2CoyJMzjAjm9 -Ss5M0OhI9wZnCXyjPBx4hOs+M/BKx4lQ296u2Dh+gSK3L8K3x8lVqqx8gd614qaC -EWzXZpAbd1S835o2vVYEWXU0iI9s0jkj+VnILEWBMRPYManRUATB2phwRPulimdu -o+BWN0GG1wKBgCYBxO1hMasQB1+tHf5LM0MCcWJwEDV27wLqNzDYA7O/MjVyhZbs -sURMVAyxuGEuXrno5hpZO3SeyVZjrj2uVKIyXSA7FpfyOqHO9tn8fKgL9LOORhcv -E6WZUH3uyO6cuwBnpTLV082BAVPgN2SpSpcycppV8Za8Yu6QvExbIgAZAoGBALcq -ANETxDj3hHggIQlRkwqpaOXvQkSVtGOxne1fWdTkmz24lFlYgRWotwsErX29D6Ez -RSzPCXd0m2mhN1G3PaEfqOgeA6NXWeV73Y+HY1PSGAT7pXyEY+QajoVyGdo5qWzW -P3yOAQCSoQaSIWulhgspILhyWgxzLpRx53t1KXw9AoGBAOxsrIrx/S6onTz58ncZ -m99OWwJX4WmY5KKhc5dWrfgHrNfldSbhjRhjALy6hSPzkaVy01wXKeeIZl64rUbd -S/r58yALQ5wuIHAi53BLStxgqEdHQHLg16GqL3b/+Waaf+Fy9y5eoUQ976HPr33G -uDJ1AAnWjX3KvcyZeWLFTU2/ +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+xdLVfN5IErS1 +UplYesMvkFZVBWlH2AojfJ8pSnaqfE6XeVWc/hoCpiqTSkGdoX4NLgy8cjAcvI9Z +1E4Xdcuch161F4HH68V0CZsSK7LHHjXI9SLbjSyoUL0BvDIEGG9D2Zyqy8xTiVc6 +gBZBvR1pGRsh59KiRMNCPN67lT6PGTt+OxMJmh2laYBWh28Lbqx4R1nBl8/m1wZa +QFhTTz0WBrBm4/3j95bQXIUjP0kW8uFcaIg0oA3/1EM5DrVQqJfp7ePEWevToP3H +4Ny1/Wg/gWTpSiB/dgN8c3vXokWxabGJG/Oq5CWjtw9gWFyR0I/OmFh8cnWPf2vf +QFVYQnv1AgMBAAECggEAeGs2ojuns6bbGnmBAjC7dBKP7Cr2QbtE6xGHBfFS5lqA +4WxddjOPB40L4t1EfdOqVXdz4p/RbtI3SmSQxo48cBmi1nx4F1Hj2VMW52ld+AJB +wQ+7aQq73aLZK3c3uw4Rbaq3EbiCyVgwD2U6p1RQdD68ubIzauostmrlzVJvorMZ +1J0hz1gsJuH87WpkgRdp910hEYiM7eUBrOKG+K0trohVeStsjjJyV47LKxXDtf2F +yUQvpbbIgHh2mXe29+d42hio2VrB5y1/+dc7wMiPlwBPG5xpv4eW1aaIGNTsHYCO +1dy8KQirOsrGLIp0GzEej2XL/wTlHJfv3nSpYR2gIQKBgQD4I3lySzFqFUlrvZoX +F9gYKbbH81gQakoAyk68qy4ENve5g+cChHTI6cO4fW8zIeEtLs/kDdpGuV20NmaD +Pb8lcd7nONGhQ1l75aNAy978e2WuAYQ4xfMLR+8jKdTDG9ttIqhGFSNXetMGINLJ +GkCl5fWAJ4p6oKBsUy2FgESECwKBgQDE0RWNQofR0UmxMPeHtD6i3pX2j3bb0GdM +1yh8vqE1IqXJesVM//gIgSZ4n3hd93AXDQIvJ6xkdtNKbnGi5wJLf1OiYW3iSkfC +l+Lgup10CVHJpOrBLxUGYZWjY4LsEX3z3MBNW4DQ6SNmIJN7xJAAewzq0UMMGk6P +IIQ7rvT//wKBgQCqiDa+xc6ACYEb+oIbvNdWQ9TKNgMfxOx2/pJ+N2a4ns5BQNVS +dZWNPpq0AACcM3x9gN5+7MZGNL6hS4HIUHc9VLTMU9A98/tbmsZHkdT90BBhNcmY ++vG9nwJKOEVwkYSLzHW5NG3FgTPl0kkKzHABk7jVClexTxLxX3i5dx2fYQKBgCla +bRbTJcp2GO+8BCZlPsvlzMiTeDvTXAEPLBiZzTFm6EKfIxl8ptbSnAy4JQhJVyng +t9bElTo+pUJ8VjAOLbNDO4Vgxz/Gr7E5TJg/XZnl42Nk3VZd2CMRGenMnNOREU/N +0DHwye4bLi7lJVfaAw+2yw4DjfzbAiqcgGwx5JRtAoGBAPFqMyLgZGtCBLrrJVxD +kswm0gABU7l/UXS7OfLTWmfr0vDzoZEcVeBcabwmpRnsTaj1+EHcpl8kZogO4mcg +0RiT+lc2E8TfZL5c4HEr4wSLbz8FEeKwhFa6ScNUOj5vVSnsFzW1xkVEBIM8akMR +UI4+yvEjUIpuQt35cyE9K/nx -----END PRIVATE KEY----- diff --git a/client/cfg/localhost.pem b/client/cfg/localhost.pem index b91d7e1..5b52a2a 100644 --- a/client/cfg/localhost.pem +++ b/client/cfg/localhost.pem @@ -1,24 +1,25 @@ -----BEGIN CERTIFICATE----- -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 +GAyD -----END CERTIFICATE----- diff --git a/client/tp_assist_macos/site/index.html b/client/tp_assist_macos/site/index.html index 35292c5..e92c53f 100644 --- a/client/tp_assist_macos/site/index.html +++ b/client/tp_assist_macos/site/index.html @@ -32,7 +32,7 @@ diff --git a/client/tp_assist_macos/site/status.html b/client/tp_assist_macos/site/status.html new file mode 100644 index 0000000..05ac758 --- /dev/null +++ b/client/tp_assist_macos/site/status.html @@ -0,0 +1,94 @@ + + + + + + + + + + + TELEPORT助手 + + + + + + + + + + + +
+
+ Teleport 助手 + +
+
+
+ + + + +
+ +
+ +
+ Teleport助手工作正常! +
+ +
+

如果在使用 HTTPS 方式访问 teleport 的 web 服务时检测不到助手,请点击这里,查看页面是否能够正常显示。

+

因为助手在配合HTTPS访问时使用了自签名证书,而自签名证书的颁发机构的根证书默认不被浏览器信任,因此,还需要将其设置为浏览器信任的根证书才行,根据浏览器的不同,具体设置方法有两种:

+

Chrome/IE/Edge/Opera 等浏览器

+
    +
  1. 在桌面的助手快捷方式上点击右键,然后选择“打开文件所在的位置”;
  2. +
  3. 右键点击 cacert.cer,在弹出菜单中选择“安装证书”;
  4. +
  5. 在打开的“证书导入向导”对话框中选择“当前用户”,点击下一步;
  6. +
  7. 选择“将所有的证书都放入下列存储”,然后点击“浏览”按钮;
  8. +
  9. 在打开的“选择证书存储”对话框中选择“受信任的根证书颁发机构”,点击确定;
  10. +
  11. 点击“下一步”,然后点击“完成”;
  12. +
  13. 系统提示“导入成功”,大功告成。
  14. +
+ +

FireFox火狐浏览器

+
    +
  1. 打开火狐浏览器的选项页面;
  2. +
  3. 点击左侧的“隐私与安全”,然后滚动页面到底部,点击“查看证书”按钮;
  4. +
  5. 在打开的“证书管理器”对话框中选择“证书颁发机构”选项卡;
  6. +
  7. 点击对话框底部的“导入”按钮,然后选择 cacert.cer 文件并点击“打开”按钮;
  8. +
  9. 在“下载证书”对话框中,勾选“信任由此证书颁发机构来标识网站”,然后点击“确定”;
  10. +
  11. 点击“确定”来关闭证书管理器对话框,大功告成。
  12. +
+ +

注意:导入证书后,请再次点击这里,查看页面是否能够正常显示。

+ +
+
+ +
+ + + + \ No newline at end of file diff --git a/client/tp_assist_macos/src/TP-Assist-Info.plist b/client/tp_assist_macos/src/TP-Assist-Info.plist index 63fffbc..330899a 100644 --- a/client/tp_assist_macos/src/TP-Assist-Info.plist +++ b/client/tp_assist_macos/src/TP-Assist-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.2.0 + 3.2.2 CFBundleSignature ???? CFBundleVersion - 3.2.0 + 3.2.2 LSApplicationCategoryType public.app-category.productivity LSMinimumSystemVersion diff --git a/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp b/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp index f74a9a7..eb63c99 100644 --- a/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp +++ b/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp @@ -32,9 +32,9 @@ int http_rpc_start(void* app) { EXLOGE("[ERROR] can not start HTTP-RPC listener, maybe port %d is already in use.\n", TS_HTTP_RPC_PORT); return -1; } - - EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on localhost:%d\n", TS_HTTP_RPC_PORT); - + + EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on 127.0.0.1:%d\n", TS_HTTP_RPC_PORT); + if(!g_http_interface.start()) return -2; @@ -43,9 +43,9 @@ int http_rpc_start(void* app) { EXLOGE("[ERROR] can not start HTTPS-RPC listener, maybe port %d is already in use.\n", TS_HTTPS_RPC_PORT); return -1; } - - EXLOGW("[rpc] TeleportAssist-HTTPS-RPC ready on localhost:%d\n", TS_HTTPS_RPC_PORT); - + + EXLOGW("[rpc] TeleportAssist-HTTPS-RPC ready on 127.0.0.1:%d\n", TS_HTTPS_RPC_PORT); + if(!g_https_interface.start()) return -2; @@ -106,22 +106,21 @@ TsHttpRpc::~TsHttpRpc() mg_mgr_free(&m_mg_mgr); } -bool TsHttpRpc::init_http() -{ - - char addr[128] = { 0 }; - ex_strformat(addr, 128, "tcp://localhost:%d", TS_HTTP_RPC_PORT); - +bool TsHttpRpc::init_http() { struct mg_connection* nc = NULL; + + 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 == NULL) { - EXLOGE("[rpc] TsHttpRpc::init_http() localhost:%d\n", TS_HTTP_RPC_PORT); + 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(); } @@ -135,27 +134,27 @@ bool TsHttpRpc::init_https() 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://localhost:%d", TS_HTTPS_RPC_PORT); + ex_strformat(addr, 128, "tcp://127.0.0.1:%d", TS_HTTPS_RPC_PORT); struct mg_connection* nc = NULL; nc = mg_bind_opt(&m_mg_mgr, addr, _mg_event_handler, bind_opts); - if (nc == NULL) { - EXLOGE("[rpc] TsHttpRpc::init_https() localhost:%d\n", TS_HTTPS_RPC_PORT); + 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(); } @@ -182,7 +181,7 @@ void TsHttpRpc::_thread_loop(void) { mg_mgr_poll(&m_mg_mgr, 500); } - + EXLOGV("[core] rpc main loop end.\n"); } @@ -225,23 +224,25 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat EXLOGV("[rpc] got %s request: %s\n", dbg_method, uri.c_str()); #endif ex_astr ret_buf; - bool b_is_index = false; + bool b_is_html = false; - if (uri == "/") - { - ex_wstr page = L"Teleport Assistor\n\n
Teleport Assistor works fine.
"; - ex_wstr2astr(page, ret_buf, EX_CODEPAGE_UTF8); +// if (uri == "/") { +// ex_wstr page = L"Teleport\n\n
Teleport Assistor works fine.
"; +// 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; +// } - mg_printf(nc, "HTTP/1.0 200 OK\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; - } - - if (uri == "/config") - { - uri = "/index.html"; - b_is_index = true; - } + if (uri == "/") { + uri = "/status.html"; + b_is_html = true; + } + else if (uri == "/config") { + uri = "/index.html"; + b_is_html = true; + } ex_astr temp; size_t offset = uri.find("/", 1); @@ -262,24 +263,24 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat { _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.size() - 1, &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) @@ -295,25 +296,23 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat 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_index) - { + } 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: @@ -336,7 +335,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; // skip first charactor, it must be '/' size_t i = 0; for (i = pos_start; i < req->uri.len; ++i) @@ -349,7 +348,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; // skip current split chactor. } } if (pos_start < req->uri.len) @@ -397,7 +396,7 @@ int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_as if (func_args.length() > 0) { - // url-decode + // decode param with url-decode. size_t len = func_args.length() * 2; ex_chars sztmp; sztmp.resize(len); @@ -448,7 +447,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} + // return {"code":123} Json::FastWriter jr_writer; Json::Value jr_root; @@ -465,11 +464,11 @@ void TsHttpRpc::_create_json_ret(ex_astr& buf, Json::Value& jr_root) 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} + // param: {"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 return {"code":0, "data":{"sid":"0123abcde"}} + // RDP return {"code":0, "data":{"sid":"0123abcde0A"}} Json::Reader jreader; Json::Value jsRoot; @@ -485,7 +484,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) return; } - // жϲǷȷ + // check param 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() @@ -512,8 +511,8 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) ex_astr s_exec; ex_astr s_arg; ex_astrs s_argv; - - + + if (pro_type == TP_PROTOCOL_TYPE_RDP) { //============================================== @@ -524,10 +523,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) _create_json_ret(buf, TPE_NOT_EXISTS); return; } - - bool flag_clipboard = (protocol_flag & TP_FLAG_RDP_CLIPBOARD); - bool flag_disk = (protocol_flag & TP_FLAG_RDP_DISK); - bool flag_console = (protocol_flag & TP_FLAG_RDP_CONSOLE); + + 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; @@ -578,9 +577,9 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) { szPwd[i] = '*'; } - + //ex_astr2wstr(real_sid, w_sid); - + //w_exe_path = _T("\""); //w_exe_path += g_cfg.rdp_app + _T("\" "); //w_exe_path += g_cfg.rdp_cmdline; @@ -593,10 +592,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) { ex_astr username = "02" + real_sid; - + s_argv.push_back("-u"); s_argv.push_back(username.c_str()); - + if (rdp_w == 0 || rdp_h == 0) { s_argv.push_back("-f"); } @@ -606,7 +605,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) s_argv.push_back("-g"); s_argv.push_back(sz_size); } - + if (flag_console && rdp_console) s_argv.push_back("/admin"); @@ -619,7 +618,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) // s_argv.push_back("+drives"); // else // s_argv.push_back("-drives"); - + { char sz_temp[128] = {0}; ex_strformat(sz_temp, 127, "%s:%d", teleport_ip.c_str(), teleport_port); @@ -639,10 +638,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) if(g_cfg.ssh.name == "terminal" || g_cfg.ssh.name == "iterm2") { char szCmd[1024] = {0}; ex_strformat(szCmd, 1023, "ssh %s@%s -p %d", sid.c_str(), teleport_ip.c_str(), teleport_port); - + char szTitle[128] = {0}; ex_strformat(szTitle, 127, "TP#%s", real_host_ip.c_str()); - + int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.ssh.name.c_str(), g_cfg.ssh.cmdline.c_str(), szTitle); if(ret == 0) _create_json_ret(buf, TPE_OK); @@ -650,20 +649,20 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) _create_json_ret(buf, TPE_FAILED); return; } - + if(g_cfg.ssh.application.length() == 0) { _create_json_ret(buf, TPE_NOT_EXISTS); return; } - + s_exec = g_cfg.ssh.application; s_argv.push_back(s_exec.c_str()); - + s_arg = g_cfg.ssh.cmdline; } else { - + // sorry, SFTP not supported yet for macOS. // _create_json_ret(buf, TPE_NOT_IMPLEMENT); // return; @@ -672,10 +671,10 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) _create_json_ret(buf, TPE_NOT_EXISTS); return; } - + s_exec = g_cfg.sftp.application; s_argv.push_back(s_exec.c_str()); - + s_arg = g_cfg.sftp.cmdline; } @@ -716,7 +715,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) // s_arg = g_cfg.telnet.cmdline; } - + //---- split s_arg and push to s_argv --- ex_astr::size_type p1 = 0; ex_astr::size_type p2 = 0; @@ -739,7 +738,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) ex_astr _t; _t.assign(tmp, p1, p2 - p1); tmp.erase(0, p2 + 2); - + s_argv.push_back(_t); } else { p1 = 0; @@ -754,12 +753,12 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) ex_astr _t; _t.assign(tmp, p1, p2 - p1); tmp.erase(0, p2 + 1); - + s_argv.push_back(_t); } } - - + + Json::Value root_ret; ex_astr utf8_path = s_exec; @@ -774,18 +773,18 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) utf8_path += " "; utf8_path += (*it); } - + root_ret["path"] = utf8_path; // for macOS, Create Process should be fork()/exec()... pid_t processId; if ((processId = fork()) == 0) { - + int i = 0; char** _argv = (char**)calloc(s_argv.size()+1, sizeof(char*)); if (!_argv) return; - + for (i = 0; i < s_argv.size(); ++i) { _argv[i] = ex_strdup(s_argv[i].c_str()); @@ -800,13 +799,13 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) } } free(_argv); - + } else if (processId < 0) { root_ret["code"] = TPE_FAILED; } else { root_ret["code"] = TPE_OK; } - + // root_ret["code"] = TPE_OK; _create_json_ret(buf, root_ret); @@ -848,7 +847,7 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) { #if 0 Json::Reader jreader; Json::Value jsRoot; - + if (!jreader.parse(func_args.c_str(), jsRoot)) { _create_json_ret(buf, TPE_JSON_FORMAT); return; @@ -859,7 +858,7 @@ void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) { // return; // } // int action = jsRoot["action"].asUInt(); - + AppDelegate_select_app(g_app); _create_json_ret(buf, TPE_FAILED); diff --git a/client/tp_assist_macos/src/csrc/ts_ver.h b/client/tp_assist_macos/src/csrc/ts_ver.h index a296cc3..878d1ff 100644 --- a/client/tp_assist_macos/src/csrc/ts_ver.h +++ b/client/tp_assist_macos/src/csrc/ts_ver.h @@ -1,6 +1,6 @@ -#ifndef __TS_ASSIST_VER_H__ -#define __TS_ASSIST_VER_H__ - -#define TP_ASSIST_VER L"3.2.0" - -#endif // __TS_ASSIST_VER_H__ +#ifndef __TS_ASSIST_VER_H__ +#define __TS_ASSIST_VER_H__ + +#define TP_ASSIST_VER L"3.2.2" + +#endif // __TS_ASSIST_VER_H__ diff --git a/client/tp_assist_win/dlg_main.cpp b/client/tp_assist_win/dlg_main.cpp index c2171cc..fbb8bd7 100644 --- a/client/tp_assist_win/dlg_main.cpp +++ b/client/tp_assist_win/dlg_main.cpp @@ -96,7 +96,7 @@ INT_PTR CALLBACK eomDlgMainProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARA case IDM_OPEN_CONFIG: { - ShellExecute(nullptr, _T("open"), _T("http://localhost:50022/config"), nullptr, nullptr, SW_SHOW); + ShellExecute(nullptr, _T("open"), _T("http://127.0.0.1:50022/config"), nullptr, nullptr, SW_SHOW); return TRUE; }break; diff --git a/client/tp_assist_win/site/index.html b/client/tp_assist_win/site/index.html index 60e67a2..789e132 100644 --- a/client/tp_assist_win/site/index.html +++ b/client/tp_assist_win/site/index.html @@ -32,7 +32,7 @@ diff --git a/client/tp_assist_win/site/status.html b/client/tp_assist_win/site/status.html new file mode 100644 index 0000000..05ac758 --- /dev/null +++ b/client/tp_assist_win/site/status.html @@ -0,0 +1,94 @@ + + + + + + + + + + + TELEPORT助手 + + + + + + + + + + + +
+
+ Teleport 助手 + +
+
+
+ + + + +
+ +
+ +
+ Teleport助手工作正常! +
+ +
+

如果在使用 HTTPS 方式访问 teleport 的 web 服务时检测不到助手,请点击这里,查看页面是否能够正常显示。

+

因为助手在配合HTTPS访问时使用了自签名证书,而自签名证书的颁发机构的根证书默认不被浏览器信任,因此,还需要将其设置为浏览器信任的根证书才行,根据浏览器的不同,具体设置方法有两种:

+

Chrome/IE/Edge/Opera 等浏览器

+
    +
  1. 在桌面的助手快捷方式上点击右键,然后选择“打开文件所在的位置”;
  2. +
  3. 右键点击 cacert.cer,在弹出菜单中选择“安装证书”;
  4. +
  5. 在打开的“证书导入向导”对话框中选择“当前用户”,点击下一步;
  6. +
  7. 选择“将所有的证书都放入下列存储”,然后点击“浏览”按钮;
  8. +
  9. 在打开的“选择证书存储”对话框中选择“受信任的根证书颁发机构”,点击确定;
  10. +
  11. 点击“下一步”,然后点击“完成”;
  12. +
  13. 系统提示“导入成功”,大功告成。
  14. +
+ +

FireFox火狐浏览器

+
    +
  1. 打开火狐浏览器的选项页面;
  2. +
  3. 点击左侧的“隐私与安全”,然后滚动页面到底部,点击“查看证书”按钮;
  4. +
  5. 在打开的“证书管理器”对话框中选择“证书颁发机构”选项卡;
  6. +
  7. 点击对话框底部的“导入”按钮,然后选择 cacert.cer 文件并点击“打开”按钮;
  8. +
  9. 在“下载证书”对话框中,勾选“信任由此证书颁发机构来标识网站”,然后点击“确定”;
  10. +
  11. 点击“确定”来关闭证书管理器对话框,大功告成。
  12. +
+ +

注意:导入证书后,请再次点击这里,查看页面是否能够正常显示。

+ +
+
+ +
+ + + + \ No newline at end of file diff --git a/client/tp_assist_win/tp_assist.rc b/client/tp_assist_win/tp_assist.rc index fabec21..b897b92 100644 Binary files a/client/tp_assist_win/tp_assist.rc and b/client/tp_assist_win/tp_assist.rc differ diff --git a/client/tp_assist_win/tp_assist.vs2015.vcxproj b/client/tp_assist_win/tp_assist.vs2015.vcxproj index 71ba5fe..c371da7 100644 --- a/client/tp_assist_win/tp_assist.vs2015.vcxproj +++ b/client/tp_assist_win/tp_assist.vs2015.vcxproj @@ -62,6 +62,7 @@ WIN32;MG_ENABLE_SSL;_DEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) true ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 + MultiThreadedDebug Windows diff --git a/client/tp_assist_win/tp_assist.vs2017.vcxproj b/client/tp_assist_win/tp_assist.vs2017.vcxproj index 11918c8..0ebbf9c 100644 --- a/client/tp_assist_win/tp_assist.vs2017.vcxproj +++ b/client/tp_assist_win/tp_assist.vs2017.vcxproj @@ -62,6 +62,7 @@ WIN32;MG_ENABLE_SSL;_DEBUG;_WINDOWS;_WINSOCK_DEPRECATED_NO_WARNINGS;MG_ENABLE_THREADS;MG_DISABLE_HTTP_DIGEST_AUTH;MG_DISABLE_MQTT;MG_DISABLE_SSI;MG_DISABLE_FILESYSTEM;%(PreprocessorDefinitions) true ..\..\common\teleport;..\..\common\libex\include;..\..\external\jsoncpp\include;..\..\external\openssl\inc32 + MultiThreadedDebug Windows diff --git a/client/tp_assist_win/ts_http_rpc.cpp b/client/tp_assist_win/ts_http_rpc.cpp index 5c5bb7d..6b0e262 100644 --- a/client/tp_assist_win/ts_http_rpc.cpp +++ b/client/tp_assist_win/ts_http_rpc.cpp @@ -129,7 +129,7 @@ void http_rpc_main_loop(bool is_https) { } EXLOGW("======================================================\n"); - EXLOGW("[rpc] TeleportAssist-HTTPS-RPC ready on localhost:%d\n", TS_HTTPS_RPC_PORT); + EXLOGW("[rpc] TeleportAssist-HTTPS-RPC ready on 127.0.0.1:%d\n", TS_HTTPS_RPC_PORT); g_https_interface.run(); @@ -141,7 +141,7 @@ void http_rpc_main_loop(bool is_https) { } EXLOGW("======================================================\n"); - EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on localhost:%d\n", TS_HTTP_RPC_PORT); + EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on 127.0.0.1:%d\n", TS_HTTP_RPC_PORT); g_http_interface.run(); @@ -259,7 +259,7 @@ bool TsHttpRpc::init_http() { nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler); if (!nc) { - EXLOGE("[rpc] TsHttpRpc::init localhost:%d\n", TS_HTTP_RPC_PORT); + EXLOGE("[rpc] TsHttpRpc::init 127.0.0.1:%d\n", TS_HTTP_RPC_PORT); return false; } nc->user_data = this; @@ -289,12 +289,11 @@ bool TsHttpRpc::init_https() { char addr[128] = { 0 }; ex_strformat(addr, 128, "tcp://127.0.0.1:%d", TS_HTTPS_RPC_PORT); - //ex_strformat(addr, 128, "%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 localhost:%d\n", TS_HTTPS_RPC_PORT); + EXLOGE("[rpc] TsHttpRpc::init 127.0.0.1:%d\n", TS_HTTPS_RPC_PORT); return false; } nc->user_data = this; @@ -375,20 +374,24 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat EXLOGV("[rpc] got %s request: %s\n", dbg_method, uri.c_str()); #endif ex_astr ret_buf; - bool b_is_index = false; + 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 == "/") { - 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; + uri = "/status.html"; + b_is_html = true; } - - if (uri == "/config") { + else if (uri == "/config") { uri = "/index.html"; - b_is_index = true; + b_is_html = true; } ex_astr temp; @@ -445,7 +448,7 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat delete[]buf; nc->flags |= MG_F_SEND_AND_CLOSE; return; - } else if (b_is_index) { + } 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); diff --git a/client/tp_assist_win/ts_http_rpc.h b/client/tp_assist_win/ts_http_rpc.h index 7a9fd25..25dbb50 100644 --- a/client/tp_assist_win/ts_http_rpc.h +++ b/client/tp_assist_win/ts_http_rpc.h @@ -17,14 +17,14 @@ //================================================================= ӿʹ˵ -󣬼 localhost:50022httpʽҪ£ +󣬼 127.0.0.1:50022httpʽҪ£ GET ʽ -http://localhost:50022/method/json_param +http://127.0.0.1:50022/method/json_param json_paramʹurl_encodeбjsonʽַ POST ʽ -http://localhost:50022/method +http://127.0.0.1:50022/method postjson_param УURIΪ֣ diff --git a/client/tp_assist_win/ts_ver.h b/client/tp_assist_win/ts_ver.h index a296cc3..878d1ff 100644 --- a/client/tp_assist_win/ts_ver.h +++ b/client/tp_assist_win/ts_ver.h @@ -1,6 +1,6 @@ -#ifndef __TS_ASSIST_VER_H__ -#define __TS_ASSIST_VER_H__ - -#define TP_ASSIST_VER L"3.2.0" - -#endif // __TS_ASSIST_VER_H__ +#ifndef __TS_ASSIST_VER_H__ +#define __TS_ASSIST_VER_H__ + +#define TP_ASSIST_VER L"3.2.2" + +#endif // __TS_ASSIST_VER_H__ diff --git a/dist/client/windows/assist/installer.nsi b/dist/client/windows/assist/installer.nsi index 9304d0c..04ed915 100644 Binary files a/dist/client/windows/assist/installer.nsi and b/dist/client/windows/assist/installer.nsi differ diff --git a/dist/client/windows/assist/setup.nsh b/dist/client/windows/assist/setup.nsh index de7f510..e0ca4e1 100644 Binary files a/dist/client/windows/assist/setup.nsh and b/dist/client/windows/assist/setup.nsh differ diff --git a/dist/server/script/core/utils.py b/dist/server/script/core/utils.py index c09ea42..303648c 100644 --- a/dist/server/script/core/utils.py +++ b/dist/server/script/core/utils.py @@ -14,11 +14,12 @@ from .env import env def remove(*args): path = os.path.join(*args) - cc.v(' - remove [%s] ... ' % path, end='') + # cc.v(' - remove [%s] ... ' % path, end='') if not (os.path.exists(path) or os.path.islink(path)): - cc.v('not exists, skip.') + # cc.v('not exists, skip.') return + cc.v(' - remove [%s] ... ' % path, end='') for i in range(5): cc.v('.', end='') try: diff --git a/dist/server/script/main.py b/dist/server/script/main.py index f3e0c3e..b364c89 100644 --- a/dist/server/script/main.py +++ b/dist/server/script/main.py @@ -498,6 +498,18 @@ class InstallerLinux(InstallerBase): elif os.path.exists('/etc/init.d/teleport'): self._is_installed = True self._install_path = '/usr/local/teleport' + + with open('/etc/init.d/teleport', 'r') as f: + lines = f.readlines() + for l in lines: + if l.startswith('DAEMON_PATH='): + l = l.replace('\r', '') + l = l.replace('\n', '') + x = l.split('=') + self._install_path = x[1] + break + + # self._fix_path() if self._is_installed: diff --git a/server/www/packages/packages-linux/x64/psutil/_pslinux.py b/server/www/packages/packages-linux/x64/psutil/_pslinux.py index ecc4c70..b775d39 100644 --- a/server/www/packages/packages-linux/x64/psutil/_pslinux.py +++ b/server/www/packages/packages-linux/x64/psutil/_pslinux.py @@ -1060,6 +1060,8 @@ def disk_io_counters(perdisk=False): # ...unless (Linux 2.6) the line refers to a partition instead # of a disk, in which case the line has less fields (7): # "3 1 hda1 8 8 8 8" + # 4.18+ has 4 fields added: + # "3 0 hda 8 8 8 8 8 8 8 8 8 8 8 0 0 0 0" # See: # https://www.kernel.org/doc/Documentation/iostats.txt # https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats @@ -1074,7 +1076,7 @@ def disk_io_counters(perdisk=False): reads = int(fields[2]) (reads_merged, rbytes, rtime, writes, writes_merged, wbytes, wtime, _, busy_time, _) = map(int, fields[4:14]) - elif flen == 14: + elif flen == 14 or flen == 18: # Linux 2.6+, line referring to a disk name = fields[2] (reads, reads_merged, rbytes, rtime, writes, writes_merged, diff --git a/server/www/teleport/static/js/maintenance/upgrade.js b/server/www/teleport/static/js/maintenance/upgrade.js new file mode 100644 index 0000000..8d8e4bb --- /dev/null +++ b/server/www/teleport/static/js/maintenance/upgrade.js @@ -0,0 +1,317 @@ +"use strict"; + +$app.on_init = function (cb_stack, cb_args) { + $app.dom = { + btn_upgrade: $('#btn-upgrade'), + steps_detail: $('#steps-detail'), + // db_info: $('#db-info'), + // account: $('#sysadmin-account'), + // email: $('#sysadmin-email'), + // password: $('#password'), + // password2: $('#password-again'), + message: $('#message'), + step2: $('#step2') + }; + + $app._make_info = function (key, value) { + return '' + key + ':' + value + ''; + }; + + // var html = []; + // if ($app.options.db.type === DB_TYPE_SQLITE) { + // html.push($app._make_info('数据库类型', 'SQLite')); + // html.push($app._make_info('数据库文件', $app.options.db.sqlite_file)); + // } else if ($app.options.db.type === DB_TYPE_MYSQL) { + // html.push($app._make_info('数据库类型', 'MySQL')); + // html.push($app._make_info('MySQL主机', $app.options.db.mysql_host)); + // html.push($app._make_info('MySQL端口', $app.options.db.mysql_port)); + // html.push($app._make_info('数据库名称', $app.options.db.mysql_db)); + // html.push($app._make_info('用户名', $app.options.db.mysql_user)); + // + // var _t = []; + // _t.push('
'); + // _t.push(' 注意:请确保您在执行后续创建操作之前,已经在MySQL中使用 UTF8字符集 创建了库“'); + // _t.push($app.options.db.mysql_db); + // _t.push('”,并且用户“'); + // _t.push($app.options.db.mysql_user); + // _t.push('”拥有在此库创建表的权限!'); + // _t.push('
'); + // $app.dom.db_info.after(_t.join('')); + // } else { + // html.push($app._make_info('数据库类型', '未知的数据库类型,请检查您的配置文件!')); + // $app.dom.btn_upgrade.attr('disabled', 'disabled').hide(); + // } + // $app.dom.db_info.append(html.join('')); + + $app.hide_op_box = function () { + $app.dom.message.hide(); + }; + + $app.show_op_box = function (op_type, op_msg) { + $app.dom.message.html(op_msg); + $app.dom.message.removeClass().addClass('op_box op_' + op_type); + $app.dom.message.show(); + }; + + $app.dom.btn_upgrade.click(function () { + // var str_account = $app.dom.account.val(); + // var str_email = $app.dom.email.val(); + // var str_password = $app.dom.password.val(); + // var str_password2 = $app.dom.password2.val(); + // + // if (str_account.length === 0) { + // $app.show_op_box('error', '请填写系统管理员登录账号名称!'); + // $app.dom.account.focus(); + // return; + // } + // if (str_email.length === 0) { + // $app.show_op_box('error', '请填写系统管理员的电子邮件地址!'); + // $app.dom.email.focus(); + // return; + // } + // if (!tp_is_email(str_email)) { + // $app.show_op_box('error', '电子邮件地址格式错啦,你会收不到邮件的!'); + // $app.dom.email.focus(); + // return; + // } + // if (str_password.length === 0) { + // $app.show_op_box('error', '请设置系统管理员登录密码!'); + // $app.dom.password.focus(); + // return; + // } + // if (str_password2.length === 0) { + // $app.show_op_box('error', '请再次输入系统管理员登录密码!'); + // $app.dom.password.focus(); + // return; + // } + // if (str_password !== str_password2) { + // $app.show_op_box('error', '两次输入的密码不一致!'); + // $app.dom.password2.focus().select(); + // return; + // } + + $app.dom.btn_upgrade.attr('disabled', 'disabled').hide(); + $app.hide_op_box(); + $app.dom.steps_detail.show(); + + $tp.ajax_post_json('/maintenance/rpc', {cmd: 'upgrade_db'}, + function (ret) { + if (ret.code === TPE_OK) { + + var cb_stack = CALLBACK_STACK.create(); + cb_stack + .add_delay(500, $app.get_task_ret, {task_id: ret.data.task_id}) + .exec(); + } + + }, + function () { +// $app.show_message('error', '无法连接到服务器!'); + $app.show_op_box('error', '无法连接到服务器!'); + } + ); + + }); + + $app.get_task_ret = function (cb_stack, cb_args) { + var task_id = cb_args.task_id || 0; + if (task_id === 0) { + console.log('task-id', task_id); + return; + } + + $tp.ajax_post_json('/maintenance/rpc', {cmd: 'get_task_ret', 'tid': task_id}, + function (ret) { + if (ret.code === TPE_OK) { + + // show step progress. + var all_ok = true; + var steps = ret.data.steps; + $app.dom.steps_detail.empty(); + + var html = []; + var icon_class = ''; + var err_class = ''; + for (var i = 0; i < steps.length; ++i) { + if (steps[i].stat === 0) + icon_class = 'fa-check'; + else + icon_class = 'fa-cog fa-spin'; + + if (steps[i].code !== 0) { + icon_class = 'fa-exclamation-circle'; + err_class = ' class="error"'; + steps[i].msg += ' 失败!'; + all_ok = false; + } + else { + err_class = ''; + } + + html.push(' '); + html.push(steps[i].msg); + html.push('

') + } + $app.dom.steps_detail.html(html.join('')); + $('html').animate({scrollTop: $(document).height()}, 300); + + if (!ret.data.running) { + if (all_ok) { + + $tp.ajax_post_json('/auth/do-logout', {}, + function () { + }, + function () { + } + ); + + $app.dom.step2.show('fast', function () { + // 确保页面滚动到最低端,使得下一步提示能够被看到。 + $('html').animate({scrollTop: $(document).height()}, 300); + }); + } + return; + } + + cb_stack + .add_delay(500, $app.get_task_ret, {task_id: task_id}) + .exec(); + } + + }, + function () { + $app.show_op_box('error', '无法连接到服务器!'); + } + ); + + }; + + cb_stack.exec(); +}; + + + + + + + + + + + + + + + + + + + + + + + + + + ywl.on_init = function (cb_stack, cb_args) { + ywl.dom = { + btn_upgrade_db: $('#btn-upgrade-db'), + steps_detail: $('#steps-detail') + }; + + ywl.dom.btn_upgrade_db.click(function () { + + ywl.dom.btn_upgrade_db.attr('disabled', 'disabled').hide(); + ywl.dom.steps_detail.show(); + + console.log('upgrade-db-click'); + ywl.ajax_post_json('/maintenance/rpc', {cmd: 'upgrade_db'}, + function (ret) { + console.log('upgrade-db:', ret); + if (ret.code === 0) { + + var cb_stack = CALLBACK_STACK.create(); + cb_stack + .add(ywl.get_task_ret, {task_id: ret.data.task_id}) + .add(ywl.delay_exec, {delay_ms: 500}) + .exec(); + } + + }, + function () { + ywl.show_message('error', '无法连接到服务器!'); + } + ); + + }); + + ywl.get_task_ret = function (cb_stack, cb_args) { + var task_id = cb_args.task_id || 0; + if (task_id === 0) { + console.log('task-id', task_id); + return; + } + + ywl.ajax_post_json('/maintenance/rpc', {cmd: 'get_task_ret', 'tid': task_id}, + function (ret) { + console.log('get_task_ret:', ret); + if (ret.code === 0) { + + // show step progress. + var steps = ret.data.steps; + ywl.dom.steps_detail.empty(); + + var html = []; + var icon_class = ''; + var err_class = ''; + for(var i = 0; i < steps.length; ++i) { + if(steps[i].code !== 0) { + err_class = ' class="error"'; + icon_class = 'fa-times-circle'; + } + else { + err_class = ''; + icon_class = 'fa-check'; + } + + if(steps[i].stat === 0) + ;//icon_class = 'fa-check'; + else + icon_class = 'fa-cog fa-spin'; + + html.push(' '); + html.push(steps[i].msg); + html.push('

') + } + ywl.dom.steps_detail.html(html.join('')); + + + if (!ret.data.running) { + $('#step2').show('fast'); + return; + } + + cb_stack + .add(ywl.get_task_ret, {task_id: task_id}) + .add(ywl.delay_exec, {delay_ms: 500}) + .exec(); + } + + }, + function () { + ywl.show_message('error', '无法连接到服务器!'); + } + ); + + }; + + cb_stack.exec(); + }; diff --git a/server/www/teleport/view/maintenance/upgrade.mako b/server/www/teleport/view/maintenance/upgrade.mako index 41233ba..b0bce8f 100644 --- a/server/www/teleport/view/maintenance/upgrade.mako +++ b/server/www/teleport/view/maintenance/upgrade.mako @@ -1,180 +1,43 @@ <%! + import app.app_ver as app_ver page_title_ = '升级TELEPORT服务' %> -<%inherit file="../page_maintenance_base.mako"/> -<%block name="breadcrumb"> - +<%inherit file="../page_single_base.mako"/> + +<%block name="extend_js_file"> + -<%block name="embed_css"> - +<%block name="page_header"> +
+
+ +
+ ## Begin Main Body. -
+
+

欢迎升级到 TELEPORT v${app_ver.TP_SERVER_VER} 社区版!现在还剩下一点点操作需要执行!

-
-
+
+

第一步:升级数据库

+ -

升级TELEPORT服务

-
+
+
-

第一步:升级数据库

-
-
- -
-
-
- - - -
+
- - -<%block name="embed_js"> - - diff --git a/server/www/teleport/webroot/app/app_ver.py b/server/www/teleport/webroot/app/app_ver.py index 51f9e64..80c4f61 100644 --- a/server/www/teleport/webroot/app/app_ver.py +++ b/server/www/teleport/webroot/app/app_ver.py @@ -1,3 +1,3 @@ # -*- coding: utf8 -*- -TP_SERVER_VER = "3.2.1" +TP_SERVER_VER = "3.2.2" TP_ASSIST_REQUIRE_VER = "3.1.0" diff --git a/server/www/teleport/webroot/app/base/database/create.py b/server/www/teleport/webroot/app/base/database/create.py index 6de0e82..d24212f 100644 --- a/server/www/teleport/webroot/app/base/database/create.py +++ b/server/www/teleport/webroot/app/base/database/create.py @@ -82,6 +82,7 @@ class DatabaseInit: def _create_core_server(self): """ 核心服务(为分布式准备) + v7 新增 特别注意:分布式部署时,核心服务的RPC通讯端口仅允许来自web服务的IP访问 """ @@ -152,7 +153,7 @@ class DatabaseInit: f.append('`surname` varchar(64) DEFAULT ""') # type 1=本地账号,2=LDAP(待扩展) f.append('`type` int(11) DEFAULT 1') - # ldap_dn: 用户的ldap全路径名称,仅用于LDAP导入的用户 + # ldap_dn: 用户的ldap全路径名称,仅用于LDAP导入的用户(v7版新增) f.append('`ldap_dn` varchar(128) DEFAULT ""') # avatar: 用户头像图片地址 f.append('`avatar` varchar(64) DEFAULT ""') @@ -186,6 +187,11 @@ class DatabaseInit: # last_ip: 最近一次成功登录IP f.append('`last_ip` varchar(40) DEFAULT ""') + # valid_from: 有效期起始时间,为0则不限(v7版新增) + f.append('`valid_from` int(11) DEFAULT 0') + # valid_to: 有效期终止时间,为0则不限(v7版新增) + f.append('`valid_to` int(11) DEFAULT 0') + # creator_id: 创建者的用户id,0=系统默认创建 f.append('`creator_id` int(11) DEFAULT 0') # create_time: 创建时间 @@ -321,11 +327,11 @@ class DatabaseInit: # 下面三个主机相关字段用于显示(注意更新host表时同步更新此字段) - # host_ip: 主机IP地址 + # host_ip: 主机IP地址(v7版新增) f.append('`host_ip` varchar(40) NOT NULL') - # router_ip: 路由IP + # router_ip: 路由IP(v7版新增) f.append('`router_ip` varchar(40) DEFAULT ""') - # router_port: 路由端口 + # router_port: 路由端口(v7版新增) f.append('`router_port` int(11) DEFAULT 0') # protocol_type: 协议类型,0=?,1=SSH,2=RDP,3=TELNET @@ -737,13 +743,13 @@ class DatabaseInit: # id: 自增主键 f.append('`id` integer PRIMARY KEY {}'.format(self.db.auto_increment)) - # core_uuid: + # core_sn:(v7版新增) f.append('`core_sn` varchar(5) DEFAULT "0000"') # flag: 是否已审查/是否要永久保留,异或方式设置,0=初始,1=已审查,2=要永久保留 f.append('`flag` int(11) DEFAULT 0') - # reason: 本次运维的原因 + # reason: 本次运维的原因(v7版新增) f.append('`reason` varchar(255) DEFAULT ""') # sid: 会话ID diff --git a/server/www/teleport/webroot/app/base/database/upgrade.py b/server/www/teleport/webroot/app/base/database/upgrade.py new file mode 100644 index 0000000..6a8a886 --- /dev/null +++ b/server/www/teleport/webroot/app/base/database/upgrade.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- + +# from app.const import * +# from app.logic.auth.password import tp_password_generate_secret +# from app.base.utils import tp_timestamp_utc_now +from app.base.logger import log +# import shutil + + +class DatabaseUpgrade: + def __init__(self, db, step_begin, step_end): + self.db = db + self.step_begin = step_begin + self.step_end = step_end + + def do_upgrade(self): + for i in range(self.db.DB_VERSION): + if self.db.current_ver < i + 1: + _f_name = '_upgrade_to_v{}'.format(i + 1) + if _f_name in dir(self): + if self.__getattribute__(_f_name)(): + self.db.current_ver = i + 1 + else: + return False + + return True + + def _db_exec(self, msg, sql): + _step = self.step_begin(msg) + + ret = False + if type(sql) == str: + ret = self.db.exec(sql) + elif type(sql) == list or type(sql) == set: + for s in sql: + ret = self.db.exec(s) + if not ret: + break + else: + raise RuntimeError('[FAILED] internal error.') + + if not ret: + self.step_end(_step, -1) + raise RuntimeError('[FAILED] {}'.format(sql)) + else: + self.step_end(_step, 0) + + def _upgrade_to_v7(self): + # 注意:v2.x的最后版本时,数据库版本号为v6,但是v3.0.0技术预览版未升级数据库版本号,仍然为v6 + # 因此升级时要做检查,如果是当前数据库版本号为v6,要进一步判断是否为v2.x系列的数据库。 + # 服务端升级到v3.2.2时,数据库有部分调整 + _step = self.step_begin('检查数据库版本 v7...') + + try: + # 检查是否是 v2.x 版本的数据库(也是v6版数据库) + # 依据为,v3.x的服务端开始,数据库中有 tp_role 数据表。 + ret = self.db.is_table_exists('{}role'.format(self.db.table_prefix)) + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + self.step_end(_step, -1, '抱歉,不支持从v2.x升级到v3.x,数据库不兼容!请卸载旧版本,全新安装新版本!') + return True + except: + log.e('failed.\n') + self.step_end(_step, -1) + return False + + self.step_end(_step, 0, '需要升级') + + try: + # 1. 创建缺失的 core_server 表 + _step = self.step_begin(' - 检查 core_server 数据表...') + ret = self.db.is_table_exists('{}core_server'.format(self.db.table_prefix)) + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + _step = self.step_begin(' - 创建数据表 core_server...') + self._v7_create_core_server() + self._db_exec( + ' - 设置本机核心服务配置项...', + 'INSERT INTO `{}core_server` (`sn`, `secret`, `ip`, `port`, `state`) VALUES ' + '("0000", "", "127.0.0.1", 52080, 1);' + ''.format(self.db.table_prefix) + ) + self.step_end(_step, 0) + + # 2. 检查 user 表中是否有 ldap_dn/valid_from/valid_to 字段 + _step = self.step_begin(' - 检查 user 数据表 ldap_dn 字段...') + ret = self.db.is_field_exists('{}user'.format(self.db.table_prefix), 'ldap_dn') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}user` ADD `ldap_dn` VARCHAR(128) DEFAULT ""'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + else: + self.step_end(_step, 0) + + _step = self.step_begin(' - 检查 user 数据表 valid_from 字段...') + ret = self.db.is_field_exists('{}user'.format(self.db.table_prefix), 'valid_from') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}user` ADD `valid_from` INT(11) DEFAULT 0'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + else: + self.step_end(_step, 0) + + _step = self.step_begin(' - 检查 user 数据表 valid_to 字段...') + ret = self.db.is_field_exists('{}user'.format(self.db.table_prefix), 'valid_to') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}user` ADD `valid_to` INT(11) DEFAULT 0'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + else: + self.step_end(_step, 0) + + # 3. 检查 acc 表中是否有 host_ip/router_ip/router_port 字段 + _step = self.step_begin(' - 检查 acc 数据表 host_ip 字段...') + ret = self.db.is_field_exists('{}acc'.format(self.db.table_prefix), 'host_ip') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}acc` ADD `host_ip` VARCHAR(40) DEFAULT ""'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + self.step_end(_step, 0) + + _step = self.step_begin(' - 检查 acc 数据表 router_ip 字段...') + ret = self.db.is_field_exists('{}acc'.format(self.db.table_prefix), 'router_ip') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}acc` ADD `router_ip` VARCHAR(40) DEFAULT ""'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + self.step_end(_step, 0) + + _step = self.step_begin(' - 检查 acc 数据表 router_port 字段...') + ret = self.db.is_field_exists('{}acc'.format(self.db.table_prefix), 'router_port') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}acc` ADD `router_port` INT(11) DEFAULT 0'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + self.step_end(_step, 0) + + # 4. 检查 record 表中是否有 core_sn/reason 字段 + _step = self.step_begin(' - 检查 record 数据表 core_sn 字段...') + ret = self.db.is_field_exists('{}record'.format(self.db.table_prefix), 'core_sn') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}record` ADD `core_sn` VARCHAR(5) DEFAULT "0000"'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + self.step_end(_step, 0) + + _step = self.step_begin(' - 检查 record 数据表 reason 字段...') + ret = self.db.is_field_exists('{}record'.format(self.db.table_prefix), 'reason') + if ret is None: + self.step_end(_step, -1, '无法连接到数据库') + return False + elif not ret: + if not self.db.exec('ALTER TABLE `{}record` ADD `reason` VARCHAR(255) DEFAULT ""'.format(self.db.table_prefix)): + self.step_end(_step, -1, '失败') + return False + self.step_end(_step, 0) + + _step = self.step_begin(' - 更新数据库版本号...') + if not self.db.exec('UPDATE `{}config` SET `value`="7" WHERE `name`="db_ver";'.format(self.db.table_prefix)): + self.step_end(_step, -1, '无法更新数据库版本号') + return False + self.step_end(_step, 0) + + _step = self.step_begin('升级到 v7 完成') + self.step_end(_step, 0) + + return True + + except: + log.e('failed.\n') + self.step_end(_step, -1) + return False + + def _v7_create_core_server(self): + """ 核心服务(为分布式准备) + v7 新增 + 特别注意:分布式部署时,核心服务的RPC通讯端口仅允许来自web服务的IP访问 + """ + + f = list() + + # id: 自增主键 + f.append('`id` integer PRIMARY KEY {}'.format(self.db.auto_increment)) + # sn: 核心服务主机编号(4位数字构成的字符串,全0表示运行在与web服务同一台主机上) + f.append('`sn` varchar(5) NOT NULL') + # desc: 核心服务主机描述 + f.append('`desc` varchar(255) DEFAULT ""') + # secret: 核心服务主机密钥(核心服务主机需要配置此密钥才能连接web服务) + f.append('`secret` varchar(64) DEFAULT ""') + # ip: 核心服务主机的RPC服务IP和端口,用于合成RPC访问地址,例如 http://127.0.0.1:52080/rpc + f.append('`ip` varchar(128) NOT NULL') + f.append('`port` int(11) DEFAULT 0') + # state: 状态,1=正常,2=禁用,3=离线,4=重启中,5=版本不匹配 + f.append('`state` int(3) DEFAULT 1') + self._db_exec( + ' - 创建核心服务器表...', + 'CREATE TABLE `{}core_server` ({});'.format(self.db.table_prefix, ','.join(f)) + ) diff --git a/server/www/teleport/webroot/app/base/db.py b/server/www/teleport/webroot/app/base/db.py index 291964f..8608b21 100644 --- a/server/www/teleport/webroot/app/base/db.py +++ b/server/www/teleport/webroot/app/base/db.py @@ -12,7 +12,7 @@ from app.base.configs import tp_cfg from app.base.utils import AttrDict, tp_make_dir from app.base.logger import log from .database.create import DatabaseInit -# from .database.upgrade import DatabaseUpgrade +from .database.upgrade import DatabaseUpgrade from .database.export import export_database __all__ = ['get_db', 'SQL'] @@ -23,7 +23,8 @@ __all__ = ['get_db', 'SQL'] class TPDatabase: # 注意,每次调整数据库结构,必须增加版本号,并且在升级接口中编写对应的升级操作 - DB_VERSION = 6 + # 20190123: server-v3.2.2, db-v7 + DB_VERSION = 7 DB_TYPE_UNKNOWN = 0 DB_TYPE_SQLITE = 1 @@ -267,15 +268,15 @@ class TPDatabase: log.e('database create and initialize failed.\n') return False - # def upgrade_database(self, step_begin, step_end): - # log.v('start database upgrade process.\n') - # if DatabaseUpgrade(self, step_begin, step_end).do_upgrade(): - # log.v('database upgraded.\n') - # self.need_upgrade = False - # return True - # else: - # log.e('database upgrade failed.\n') - # return False + def upgrade_database(self, step_begin, step_end): + log.v('start database upgrade process.\n') + if DatabaseUpgrade(self, step_begin, step_end).do_upgrade(): + log.v('database upgraded.\n') + self.need_upgrade = False + return True + else: + log.e('database upgrade failed.\n') + return False def alter_table(self, table_names, field_names=None): """ diff --git a/server/www/teleport/webroot/app/controller/__init__.py b/server/www/teleport/webroot/app/controller/__init__.py index ca48d37..d121189 100755 --- a/server/www/teleport/webroot/app/controller/__init__.py +++ b/server/www/teleport/webroot/app/controller/__init__.py @@ -276,7 +276,7 @@ controllers = [ # - 初始安装设置(新安装,未创建数据库时自动跳转到此页面) (r'/maintenance/install', maintenance.InstallHandler), # - 升级(数据库版本发生变化时跳转到此页面) - # (r'/maintenance/upgrade', maintenance.UpgradeHandler), + (r'/maintenance/upgrade', maintenance.UpgradeHandler), # - [json] 维护过程中页面与后台的通讯接口 (r'/maintenance/rpc', maintenance.RpcHandler), diff --git a/server/www/teleport/webroot/app/controller/auth.py b/server/www/teleport/webroot/app/controller/auth.py index 2ca9d2a..b022dcd 100644 --- a/server/www/teleport/webroot/app/controller/auth.py +++ b/server/www/teleport/webroot/app/controller/auth.py @@ -17,8 +17,8 @@ class LoginHandler(TPBaseHandler): if tp_cfg().app_mode == APP_MODE_MAINTENANCE and get_db().need_create: _user = { 'id': 0, - 'username': 'installer', - 'surname': '安装程序', + 'username': 'maintainer', + 'surname': '系统维护-安装', 'role_id': 0, 'role': '', 'privilege': TP_PRIVILEGE_SYS_CONFIG, @@ -28,6 +28,20 @@ class LoginHandler(TPBaseHandler): self.redirect('/maintenance/install') return + if tp_cfg().app_mode == APP_MODE_MAINTENANCE and get_db().need_upgrade: + _user = { + 'id': 0, + 'username': 'maintainer', + 'surname': '系统维护-升级', + 'role_id': 0, + 'role': '', + 'privilege': TP_PRIVILEGE_SYS_CONFIG, + '_is_login': True + } + self.set_session('user', _user) + self.redirect('/maintenance/upgrade') + return + _user = self.get_current_user() _ref = quote(self.get_argument('ref', '/')) diff --git a/server/www/teleport/webroot/app/controller/ops.py b/server/www/teleport/webroot/app/controller/ops.py index d26faea..30f6985 100644 --- a/server/www/teleport/webroot/app/controller/ops.py +++ b/server/www/teleport/webroot/app/controller/ops.py @@ -144,6 +144,9 @@ class DoGetSessionIDHandler(TPBaseJsonHandler): if err != TPE_OK: return self.write_json(err) + if ops_auth['u_id'] != self._user['id']: + return self.write_json(TPE_PRIVILEGE) + policy_id = ops_auth['p_id'] acc_id = ops_auth['a_id'] host_id = ops_auth['h_id'] diff --git a/server/www/teleport/webroot/app/controller/system.py b/server/www/teleport/webroot/app/controller/system.py index 3eeb809..655f454 100644 --- a/server/www/teleport/webroot/app/controller/system.py +++ b/server/www/teleport/webroot/app/controller/system.py @@ -683,7 +683,6 @@ class DoLdapImportHandler(TPBaseJsonHandler): for u in user_list: if u['_id'] == 0 or len(u['email']) == 0: continue - u['email'] = 'apex.liu@qq.com' mail_body = '{surname} 您好!\n\n已为您创建teleport系统用户账号,现在可以使用以下信息登录teleport系统:\n\n' \ '登录用户名:{username}\n' \ diff --git a/server/www/teleport/webroot/app/model/user.py b/server/www/teleport/webroot/app/model/user.py index 1234656..b3688ce 100755 --- a/server/www/teleport/webroot/app/model/user.py +++ b/server/www/teleport/webroot/app/model/user.py @@ -604,8 +604,13 @@ def update_oath_secret(handler, user_id, oath_secret): sql = 'UPDATE `{dbtp}user` SET oath_secret="{secret}" WHERE id={user_id}' \ ''.format(dbtp=db.table_prefix, secret=oath_secret, user_id=user_id) if db.exec(sql): - syslog.sys_log({'username': username, 'surname': surname}, handler.request.remote_ip, TPE_OK, - "用户 {} 绑定了身份认证器".format(username)) + if len(oath_secret) > 0: + syslog.sys_log({'username': username, 'surname': surname}, handler.request.remote_ip, TPE_OK, + "用户 {} 更新了身份认证器绑定信息".format(username)) + else: + syslog.sys_log({'username': username, 'surname': surname}, handler.request.remote_ip, TPE_OK, + "用户 {} 清除了身份认证器绑定信息".format(username)) + return TPE_OK else: return TPE_DATABASE diff --git a/version.in b/version.in index 0d2f419..97313c2 100644 --- a/version.in +++ b/version.in @@ -10,8 +10,8 @@ Minor: 次版本号。如果两个程序集的名称和主版本号相同,而 Revision: 修订号。主版本号和次版本号都相同但修订号不同的程序集应是完全可互换的。 这适用于修复以前发布的程序集中的错误或安全漏洞。 -TP_SERVER 3.2.1 # 整个服务端打包的版本 +TP_SERVER 3.2.2 # 整个服务端打包的版本 TP_TPCORE 3.2.0 # 核心服务 tp_core 的版本 TP_TPWEB 3.1.0 # web服务 tp_web 的版本(一般除非升级Python,否则不会变化) -TP_ASSIST 3.2.0 # 助手版本 +TP_ASSIST 3.2.2 # 助手版本 TP_ASSIST_REQUIRE 3.1.0 # 适配的助手最低版本