pull/105/head
ApexLiu 2018-03-01 09:07:49 +08:00
parent 947332078b
commit 0d24b1834b
23 changed files with 231 additions and 60 deletions

View File

@ -114,7 +114,7 @@ class BuilderMacOS(BuilderBase):
utils.ensure_file_exists(os.path.join(out_file, 'Contents', 'Info.plist'))
def build_installer(self):
cc.i('build assist installer...')
cc.e('assist for macOS does not need an installer, you should make an .DMG file for release...')
# name = 'teleport-assist-{}-{}'.format(ctx.dist, VER_TP_ASSIST)
#

View File

@ -564,7 +564,7 @@ class BuilderMacOS(BuilderBase):
if not os.path.exists(self.OPENSSL_PATH_SRC):
os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
cc.n('build openssl static...')
cc.n('build openssl static...', end='')
if os.path.exists(os.path.join(self.PATH_RELEASE, 'lib', 'libssl.a')):
cc.w('already exists, skip.')
return
@ -579,7 +579,7 @@ class BuilderMacOS(BuilderBase):
os.chdir(old_p)
def _build_libuv(self, file_name):
cc.w('build libuv...')
cc.n('prepare libuv source code...', end='')
# return
if not os.path.exists(self.LIBUV_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, PATH_TMP))

View File

@ -140,6 +140,23 @@ class Builder:
plist_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'src', 'tp_assist-Info.plist')
self._update_ver_plist(plist_file, self.VER_TP_ASSIST)
ver_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'src', 'csrc', 'ts_ver.h')
ver_content = '#ifndef __TS_ASSIST_VER_H__\n#define __TS_ASSIST_VER_H__\n\n#define TP_ASSIST_VER\tL"{}"\n\n#endif // __TS_ASSIST_VER_H__\n'.format(self.VER_TP_ASSIST)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
def make_tpweb_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'ts_ver.h')
ver_content = '#ifndef __TS_SERVER_VER_H__\n#define __TS_SERVER_VER_H__\n\n#define TP_SERVER_VER\tL"{}"\n\n#endif // __TS_SERVER_VER_H__\n'.format(self.VER_TP_TPWEB)
@ -403,7 +420,7 @@ class Builder:
old_ver = '.'.join(v)
if old_ver == ver:
continue
lines[x] = '<string>{ver}</string>'.format(ver=ver)
lines[x] = '\t<string>{ver}</string>\n'.format(ver=ver)
bOK = True
if bOK:

View File

@ -319,7 +319,7 @@ def xcode_build(proj_file, proj_name, target, force_rebuild):
cmd = 'xcodebuild -project "{}" -target {} -configuration {}'.format(proj_file, proj_name, target)
ret, _ = sys_exec(cmd, direct_output=True)
if ret != 0:
raise RuntimeError('build MSVC project `{}` failed.'.format(proj_name))
raise RuntimeError('build XCode project `{}` failed.'.format(proj_name))
def nsis_build(nsi_file, _define=''):

View File

@ -1,3 +1,3 @@
# -*- coding: utf8 -*-
VER_TP_SERVER = "3.0.0.2"
VER_TP_ASSIST = "3.0.0.2"
VER_TP_SERVER = "3.0.0.3"
VER_TP_ASSIST = "3.0.0.3"

View File

@ -21,22 +21,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
@ -45,11 +45,11 @@ Sub main
crt.Screen.Send "SESSION-ID" & VbCr
crt.Screen.Synchronous = False
End Sub
------------------
---------Œƒº˛Ω· ¯---------
4. puttyIP
4. Œ¡À»puttyµƒ¥ø±Í«©œ æ˝£µƒIP£¨ø¢ ¡¨ΩπÛ£¨÷˜ØœÚ˛ŒÒÀ¢ÀÕœ¬¡¸¡Ó£
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@192.168.1.2: \w\a\]$PS1"
ubuntuLinuxSecureCRT
 ÷π§ ¡À£¨ubuntu˛ŒÒ˜ø£¨ª÷µ¿ «Òƒπª÷ß÷À˘µƒLinux°£SecureCRT¥À±Ì æˆ¬°£
*/
// #define RDP_CLIENT_SYSTEM_BUILTIN
@ -253,7 +253,7 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat
uri = &_uri[0];
#ifdef EX_DEBUG
char* dbg_method = NULL;
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))
@ -283,7 +283,7 @@ void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_dat
}
ex_astr temp;
int offset = uri.find("/", 1);
size_t offset = uri.find("/", 1);
if (offset > 0)
{
temp = uri.substr(1, offset-1);
@ -375,7 +375,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)
@ -388,7 +388,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)
@ -436,12 +436,12 @@ int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_as
if (func_args.length() > 0)
{
// 将参数进行 url-decode 解码
int len = func_args.length() * 2;
// Ω´≤Œ ˝Ω¯–– url-decode Ω‚¬Î
size_t 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))
if (-1 == ts_url_decode(func_args.c_str(), (int)func_args.length(), &sztmp[0], (int)len, 0))
return TPE_HTTP_URL_ENCODE;
func_args = &sztmp[0];
@ -487,7 +487,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;
@ -504,11 +504,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}
// »Î≤Œ£∫{"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;
@ -524,7 +524,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()
@ -565,8 +565,111 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
//==============================================
// sorry, RDP not supported yet for macOS.
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
return;
// _create_json_ret(buf, TPE_NOT_IMPLEMENT);
// return;
int rdp_w = 800;
int rdp_h = 640;
bool rdp_console = false;
if (!jsRoot["rdp_width"].isNull()) {
if (jsRoot["rdp_width"].isNumeric()) {
rdp_w = jsRoot["rdp_width"].asUInt();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
if (!jsRoot["rdp_height"].isNull()) {
if (jsRoot["rdp_height"].isNumeric()) {
rdp_h = jsRoot["rdp_height"].asUInt();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
if (!jsRoot["rdp_console"].isNull()) {
if (jsRoot["rdp_console"].isBool()) {
rdp_console = jsRoot["rdp_console"].asBool();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
size_t split_pos = sid.length() - 2;
ex_astr real_sid = sid.substr(0, split_pos);
ex_astr str_pwd_len = sid.substr(split_pos, sid.length());
size_t n_pwd_len = strtol(str_pwd_len.c_str(), NULL, 16);
n_pwd_len -= real_sid.length();
n_pwd_len -= 2;
char szPwd[256] = { 0 };
for (int i = 0; i < n_pwd_len; i++)
{
szPwd[i] = '*';
}
ex_astr2wstr(real_sid, w_sid);
//w_exe_path = _T("\"");
//w_exe_path += g_cfg.rdp_app + _T("\" ");
//w_exe_path += g_cfg.rdp_cmdline;
w_exe_path = _T("xfreerdp -u {user_name} {clipboard} {drives} ");
{
// w_exe_path += L"{size} {console} {clipboard} {drives} ";
// w_exe_path += g_cfg.rdp_cmdline;
ex_wstr w_screen;
if (rdp_w == 0 || rdp_h == 0) {
w_screen = _T("/f");
}
else {
char sz_size[64] = {0};
ex_strformat(sz_size, 63, "/size:%dx%d", rdp_w, rdp_h);
ex_astr2wstr(sz_size, w_screen);
}
const wchar_t* w_console = NULL;
if (rdp_console)
{
w_console = _T("/admin");
}
else
{
w_console = _T("");
}
ex_wstr w_password;
ex_astr2wstr(szPwd, w_password);
w_exe_path += _T(" -p ");
w_exe_path += w_password;
w_sid = _T("02") + w_sid;
//w_exe_path += _T(" /gdi:sw");
w_exe_path += _T(" {host_ip}:{host_port}");
ex_replace_all(w_exe_path, _T("{size}"), w_screen);
ex_replace_all(w_exe_path, _T("{console}"), w_console);
//ex_replace_all(w_exe_path, _T("{clipboard}"), L"+clipboard");
ex_replace_all(w_exe_path, _T("{clipboard}"), _T("/clipboard"));
ex_replace_all(w_exe_path, _T("{drives}"), _T("/drives"));
// }
// else {
// _create_json_ret(buf, TPE_FAILED);
// return;
}
}
else if (pro_type == TP_PROTOCOL_TYPE_SSH)
{
@ -606,6 +709,31 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
return;
}
ex_replace_all(w_exe_path, _T("{host_port}"), w_port);
ex_replace_all(w_exe_path, _T("{host_ip}"), w_teleport_ip.c_str());
ex_replace_all(w_exe_path, _T("{user_name}"), w_sid.c_str());
ex_replace_all(w_exe_path, _T("{real_ip}"), w_real_host_ip.c_str());
//ex_replace_all(w_exe_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str());
Json::Value root_ret;
ex_astr utf8_path;
ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8);
root_ret["path"] = utf8_path;
// if (!CreateProcess(NULL, (wchar_t *)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
// {
// EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str());
// root_ret["code"] = TPE_START_CLIENT;
// _create_json_ret(buf, root_ret);
// return;
// }
system(utf8_path.c_str());
root_ret["code"] = TPE_OK;
_create_json_ret(buf, root_ret);
}

View File

@ -1,6 +1,6 @@
#ifndef __TS_ASSIST_VER_H__
#define __TS_ASSIST_VER_H__
#define TP_ASSIST_VER L"3.0.0.1"
#endif // __TS_ASSIST_VER_H__
#ifndef __TS_ASSIST_VER_H__
#define __TS_ASSIST_VER_H__
#define TP_ASSIST_VER L"3.0.0.3"
#endif // __TS_ASSIST_VER_H__

View File

@ -17,17 +17,19 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0.0.2</string> <key>CFBundleSignature</key>
<string>3.0.0.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3.0.0.2</string> <key>LSApplicationCategoryType</key>
<string>3.0.0.3</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 EOMSOFT. All rights reserved.</string>
<string>Copyright © 2017~2018 EOMSOFT. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

Binary file not shown.

View File

@ -1,6 +1,6 @@
#ifndef __TS_ASSIST_VER_H__
#define __TS_ASSIST_VER_H__
#define TP_ASSIST_VER L"3.0.0.2"
#define TP_ASSIST_VER L"3.0.0.3"
#endif // __TS_ASSIST_VER_H__

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
#ifndef __TS_SERVER_VER_H__
#define __TS_SERVER_VER_H__
#define TP_SERVER_VER L"3.0.0.2"
#define TP_SERVER_VER L"3.0.0.3"
#endif // __TS_SERVER_VER_H__

View File

@ -1,2 +1,2 @@
# -*- coding: utf8 -*-
TP_SERVER_VER = "3.0.0.2"
TP_SERVER_VER = "3.0.0.3"

View File

@ -56,7 +56,7 @@ class TPCron(threading.Thread):
log.e('got exception when exec job: {}\n'.format(j))
def tp_corn():
def tp_cron():
"""
取得TPCron管理器的唯一实例

View File

@ -649,6 +649,22 @@ class DatabaseInit:
# gh_id: 主机组ID
f.append('`gh_id` int(11) DEFAULT 0')
# 后续字段仅用于显示
# u_name: 用户登录名
f.append('`u_name` varchar(32) DEFAULT ""')
# u_surname: 用户姓名
f.append('`u_surname` varchar(64) DEFAULT ""')
# h_name: 主机名称
f.append('`h_name` varchar(64) DEFAULT ""')
# ip: IP地址
f.append('`ip` varchar(40) NOT NULL')
# router_ip: 路由IP
f.append('`router_ip` varchar(40) DEFAULT ""')
# router_port: 路由端口
f.append('`router_port` int(11) DEFAULT 0')
self._db_exec(
'创建审计授权映射表...',
'CREATE TABLE `{}audit_map` ({});'.format(self.db.table_prefix, ','.join(f))

View File

@ -4,7 +4,7 @@ import datetime
import threading
from app.base.configs import tp_cfg
from app.base.cron import tp_corn
from app.base.cron import tp_cron
class SessionManager(object):
@ -28,7 +28,7 @@ class SessionManager(object):
def init(self):
self.update_default_expire()
tp_corn().add_job('session_expire', self._check_expire, first_interval_seconds=None, interval_seconds=60)
tp_cron().add_job('session_expire', self._check_expire, first_interval_seconds=None, interval_seconds=60)
return True
def update_default_expire(self):

View File

@ -4,7 +4,7 @@ import psutil
from app.base.utils import tp_utc_timestamp_ms
from app.const import *
from app.base.wss import tp_wss
from app.base.cron import tp_corn
from app.base.cron import tp_cron
from app.model import stats
@ -61,9 +61,9 @@ class TPStats(object):
self._counter_stats = c
# 每 5秒 采集一次系统状态统计数据
tp_corn().add_job('sys_status', self._check_sys_stats, first_interval_seconds=self._INTERVAL, interval_seconds=self._INTERVAL)
tp_cron().add_job('sys_status', self._check_sys_stats, first_interval_seconds=self._INTERVAL, interval_seconds=self._INTERVAL)
# 每 一小时 重新查询一次数据库,得到用户数/主机数/账号数/连接数,避免统计数量出现偏差
tp_corn().add_job('query_counter', self._query_counter, first_interval_seconds=60 * 60, interval_seconds=60 * 60)
tp_cron().add_job('query_counter', self._query_counter, first_interval_seconds=60 * 60, interval_seconds=60 * 60)
tp_wss().register_get_sys_status_callback(self.get_sys_stats)
tp_wss().register_get_stat_counter_callback(self.get_counter_stats)

View File

@ -16,7 +16,7 @@ from app.base.configs import tp_cfg
from app.base.db import get_db
from app.base.logger import log
from app.base.session import tp_session
from app.base.cron import tp_corn
from app.base.cron import tp_cron
from app.base.stats import tp_stats
@ -25,6 +25,7 @@ class WebApp:
import builtins
if '__web_app__' in builtins.__dict__:
raise RuntimeError('WebApp object exists, you can not create more than one instance.')
self._cfg_file = ''
def init(self, path_app_root, path_data):
log.initialize()
@ -39,8 +40,8 @@ class WebApp:
cfg.cfg_path = os.path.join(path_data, 'etc')
cfg.log_path = os.path.join(path_data, 'log')
_cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
if not cfg.load(_cfg_file):
self._cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
if not cfg.load(self._cfg_file):
return False
return True
@ -63,9 +64,10 @@ class WebApp:
def run(self):
log.i('\n')
log.i('###############################################################\n')
log.i('Web Server starting ...\n')
log.i('Load config file: {}\n'.format(self._cfg_file))
log.i('Teleport Web Server starting ...\n')
tp_corn().init()
tp_cron().init()
# 尝试通过CORE-JSON-RPC获取core服务的配置主要是ssh/rdp/telnet的端口以及录像文件存放路径
self._get_core_server_config()
@ -144,14 +146,14 @@ class WebApp:
return 0
# 启动定时任务调度器
tp_corn().start()
tp_cron().start()
try:
tornado.ioloop.IOLoop.instance().start()
except:
log.e('\n')
tp_corn().stop()
tp_cron().stop()
return 0

View File

@ -526,8 +526,10 @@ class ComandLogHandler(TPBaseHandler):
if ret != TPE_OK:
return
protocol = int(protocol)
param = dict()
header, err = record.read_record_head(record_id)
header, err = record.read_record_head(protocol, record_id)
if header is None:
# return self.write('操作失败![{}]'.format(err))
param['code'] = err
@ -543,7 +545,6 @@ class ComandLogHandler(TPBaseHandler):
param['code'] = TPE_OK
cmd_type = 0 # 0 = ssh, 1 = sftp
protocol = int(protocol)
if protocol == 1:
pass
elif protocol == 2:

View File

@ -553,6 +553,9 @@ class DoUpdateUserHandler(TPBaseJsonHandler):
args['password'] = tp_gen_password(8)
err, _ = user.create_user(self, args)
if err == TPE_OK:
if len(args['email']) == 0:
return self.write_json(TPE_OK)
# 对于创建成功的用户,发送密码邮件函
sys_smtp_password = tp_cfg().sys_smtp_password
if len(sys_smtp_password) > 0:

View File

@ -48,6 +48,8 @@ def get_records(handler, sql_filter, sql_order, sql_limit, sql_restrict, sql_exc
for h in s.recorder:
if h.h_id not in allow_hids:
allow_hids.append(h.h_id)
if len(allow_hids) == 0:
return TPE_OK, 0, []
if allow_uid == 0 and len(allow_hids) == 0:
return TPE_FAILED, 0, []

View File

@ -13,7 +13,7 @@ Revision 修订号。主版本号和次版本号都相同但修订号不同
Build 构建号。构建号用于表明此版本发布之前进行了多少次构建及测试。某些情况下此版本号可以省略。
TP_SERVER 3.0.0.2 # 整个服务端打包的版本
TP_TPCORE 3.0.0.2 # 核心服务 tp_core 的版本
TP_SERVER 3.0.0.3 # 整个服务端打包的版本
TP_TPCORE 3.0.0.3 # 核心服务 tp_core 的版本
TP_TPWEB 3.0.0.1 # web服务 tp_web 的版本一般除非升级Python否则不会变化
TP_ASSIST 3.0.0.2 # 助手版本
TP_ASSIST 3.0.0.3 # 助手版本