示例#1
0
文件: user.py 项目: eomsoft/teleport
    def get(self):
        param = {
            'mode': 0,  # mode=0, unknown mode.
            'token': '',
            'code': TPE_OK
        }

        _token = self.get_argument('token', None)
        if _token is None:
            # 如果尚未设置SMTP或者系统限制,不允许发送密码重置邮件
            if len(tp_cfg().sys.smtp.server) == 0:
                param['mode'] = 2  # mode=2, show 'error' page
                param['code'] = TPE_NETWORK
            elif not tp_cfg().sys.password.allow_reset:
                param['mode'] = 2  # mode=2, show 'error' page
                param['code'] = TPE_PRIVILEGE
            else:
                param['mode'] = 1  # mode=1, show 'find-my-password' page.
        else:
            err, _ = user.check_reset_token(_token)

            param['code'] = err
            param['token'] = _token

            if err != TPE_OK:
                param['mode'] = 2  # mode=2, show 'error' page
            else:
                param['mode'] = 3  # mode=3, show 'set-new-password' page
                param['force_strong'] = tp_cfg().sys.password.force_strong

        self.render('user/reset-password.mako', page_param=json.dumps(param))
示例#2
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            if len(tp_cfg().sys_ldap_password) == 0:
                return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
            else:
                _password = tp_cfg().sys_ldap_password
            _server = tp_cfg().sys.ldap.server
            _port = tp_cfg().sys.ldap.port
            _admin = tp_cfg().sys.ldap.admin
            _base_dn = tp_cfg().sys.ldap.base_dn
            _filter = tp_cfg().sys.ldap.filter
            _attr_username = tp_cfg().sys.ldap.attr_username
            _attr_surname = tp_cfg().sys.ldap.attr_surname
            _attr_email = tp_cfg().sys.ldap.attr_email
        except:
            return self.write_json(TPE_PARAM)

        try:
            ldap = Ldap(_server, _port, _base_dn)
            ret, data, err_msg = ldap.list_users(_admin, _password, _filter,
                                                 _attr_username, _attr_surname,
                                                 _attr_email)
            if ret != TPE_OK:
                return self.write_json(ret, message=err_msg)

            exists_users = user.get_users_by_type(TP_USER_TYPE_LDAP)
            bound_users = []
            if exists_users is not None:
                for u in exists_users:
                    h = hashlib.sha1()
                    h.update(u['ldap_dn'].encode())
                    bound_users.append(h.hexdigest())

            ret_data = []
            for u in data:
                h = hashlib.sha1()
                h.update(u.encode())
                _id = h.hexdigest()
                if _id in bound_users:
                    continue

                _user = data[u]
                _user['id'] = h.hexdigest()
                ret_data.append(_user)
            return self.write_json(ret, data=ret_data)
        except:
            log.e('')
            return self.write_json(TPE_PARAM)
示例#3
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            dn_hash_list = args['ldap_users']

            if len(tp_cfg().sys_ldap_password) == 0:
                return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
            else:
                _password = tp_cfg().sys_ldap_password
            _server = tp_cfg().sys.ldap.server
            _port = tp_cfg().sys.ldap.port
            _admin = tp_cfg().sys.ldap.admin
            _base_dn = tp_cfg().sys.ldap.base_dn
            _filter = tp_cfg().sys.ldap.filter
            _attr_username = tp_cfg().sys.ldap.attr_username
            _attr_surname = tp_cfg().sys.ldap.attr_surname
            _attr_email = tp_cfg().sys.ldap.attr_email
        except:
            return self.write_json(TPE_PARAM)

        try:
            ldap = Ldap(_server, _port, _base_dn)
            ret, data, err_msg = ldap.list_users(_admin, _password, _filter,
                                                 _attr_username, _attr_surname,
                                                 _attr_email)

            if ret != TPE_OK:
                return self.write_json(ret, message=err_msg)

            need_import = []
            for u in data:
                h = hashlib.sha1()
                h.update(u.encode())

                dn_hash = h.hexdigest()
                for x in dn_hash_list:
                    if x == dn_hash:
                        _user = data[u]
                        _user['dn'] = u
                        need_import.append(_user)
                        break

            if len(need_import) == 0:
                return self.write_json(ret, message='没有可以导入的LDAP用户')

            return self._do_import(need_import)
        except:
            log.e('')
            return self.write_json(TPE_PARAM)
示例#4
0
    def get(self):
        param = {
            'mode': 0,  # mode=0, unknown mode.
            'token': '',
            'code': TPE_OK
        }

        _token = self.get_argument('token', None)
        if _token is None:
            # 如果尚未设置SMTP或者系统限制,不允许发送密码重置邮件
            if len(tp_cfg().sys.smtp.server) == 0:
                param['mode'] = 2  # mode=2, show 'error' page
                param['code'] = TPE_NETWORK
            elif not tp_cfg().sys.password.allow_reset:
                param['mode'] = 2  # mode=2, show 'error' page
                param['code'] = TPE_PRIVILEGE
            else:
                param['mode'] = 1  # mode=1, show 'find-my-password' page.
        else:
            err, _ = user.check_reset_token(_token)

            param['code'] = err
            param['token'] = _token

            if err != TPE_OK:
                param['mode'] = 2  # mode=2, show 'error' page
            else:
                param['mode'] = 3  # mode=3, show 'set-new-password' page
                param['force_strong'] = tp_cfg().sys.password.force_strong

        self.render('user/reset-password.mako', page_param=json.dumps(param))
示例#5
0
def delete_log(log_list):
    try:
        where = list()
        for item in log_list:
            where.append(' `id`={}'.format(item))

        db = get_db()
        sql = 'DELETE FROM `{}log` WHERE{};'.format(db.table_prefix,
                                                    ' OR'.join(where))
        ret = db.exec(sql)
        if not ret:
            return False

        # TODO: 此处应该通过json-rpc接口通知core服务来删除重放文件。
        for item in log_list:
            log_id = int(item)
            try:
                record_path = os.path.join(tp_cfg().core.replay_path, 'ssh',
                                           '{:06d}'.format(log_id))
                if os.path.exists(record_path):
                    shutil.rmtree(record_path)
                record_path = os.path.join(tp_cfg().core.replay_path, 'rdp',
                                           '{:06d}'.format(log_id))
                if os.path.exists(record_path):
                    shutil.rmtree(record_path)
            except Exception:
                pass

        return True
    except:
        return False
示例#6
0
    def _register_core(self, param):
        # 因为core服务启动了(之前可能非正常终止了),做一下数据库中会话状态的修复操作
        record.session_fix()

        if 'rpc' not in param:
            return self.write_json(TPE_PARAM, 'invalid param.')

        tp_cfg().common.core_server_rpc = param['rpc']

        # 获取core服务的配置信息
        req = {'method': 'get_config', 'param': []}
        _yr = core_service_async_post_http(req)
        code, ret_data = yield _yr
        if code != TPE_OK:
            return self.write_json(code, 'get config from core-service failed.')

        log.d('update base server config info.\n')
        tp_cfg().update_core(ret_data)

        # 将运行时配置发送给核心服务
        req = {'method': 'set_config', 'param': {'noop_timeout': tp_cfg().sys.session.noop_timeout}}
        _yr = core_service_async_post_http(req)
        code, ret_data = yield _yr
        if code != TPE_OK:
            return self.write_json(code, 'set runtime-config to core-service failed.')

        return self.write_json(TPE_OK)
示例#7
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            cfg = args['ldap']
            cfg['port'] = int(cfg['port'])
            if len(cfg['password']) == 0:
                if len(tp_cfg().sys_ldap_password) == 0:
                    return self.write_json(TPE_PARAM, message='需要设置LDAP管理员密码')
                else:
                    cfg['password'] = tp_cfg().sys_ldap_password
        except:
            return self.write_json(TPE_PARAM)

        try:
            ldap = Ldap(cfg['server'], cfg['port'], cfg['base_dn'])
            ret, data, err_msg = ldap.get_all_attr(cfg['admin'], cfg['password'], cfg['filter'])
            if ret != TPE_OK:
                return self.write_json(ret, message=err_msg)
            else:
                return self.write_json(ret, data=data)
        except:
            log.e('')
            return self.write_json(TPE_PARAM)
示例#8
0
def delete_log(log_list):
    try:
        where = list()
        for item in log_list:
            where.append(' `id`={}'.format(item))

        db = get_db()
        sql = 'DELETE FROM `{}log` WHERE{};'.format(db.table_prefix, ' OR'.join(where))
        ret = db.exec(sql)
        if not ret:
            return False

        # TODO: 此处应该通过json-rpc接口通知core服务来删除重放文件。
        for item in log_list:
            log_id = int(item)
            try:
                record_path = os.path.join(tp_cfg().core.replay_path, 'ssh', '{:06d}'.format(log_id))
                if os.path.exists(record_path):
                    shutil.rmtree(record_path)
                record_path = os.path.join(tp_cfg().core.replay_path, 'rdp', '{:06d}'.format(log_id))
                if os.path.exists(record_path):
                    shutil.rmtree(record_path)
            except Exception:
                pass

        return True
    except:
        return False
示例#9
0
文件: db.py 项目: eomsoft/teleport
    def load_system_config(self):
        sys_cfg = dict()
        db_ret = self.query('SELECT `name`, `value` FROM `{}config`;'.format(self._table_prefix))
        for item in db_ret:
            sys_cfg[item[0]] = item[1]

        if len(sys_cfg) > 0:
            tp_cfg().update_sys(sys_cfg)
示例#10
0
    def load_system_config(self):
        sys_cfg = dict()
        db_ret = self.query('SELECT `name`, `value` FROM `{}config`;'.format(self._table_prefix))
        for item in db_ret:
            sys_cfg[item[0]] = item[1]

        if len(sys_cfg) > 0:
            tp_cfg().update_sys(sys_cfg)
示例#11
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            dn_hash_list = args['ldap_users']

            if len(tp_cfg().sys_ldap_password) == 0:
                return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
            else:
                _password = tp_cfg().sys_ldap_password
            _server = tp_cfg().sys.ldap.server
            _port = tp_cfg().sys.ldap.port
            _admin = tp_cfg().sys.ldap.admin
            _base_dn = tp_cfg().sys.ldap.base_dn
            _filter = tp_cfg().sys.ldap.filter
            _attr_username = tp_cfg().sys.ldap.attr_username
            _attr_surname = tp_cfg().sys.ldap.attr_surname
            _attr_email = tp_cfg().sys.ldap.attr_email
        except:
            return self.write_json(TPE_PARAM)

        try:
            ldap = Ldap(_server, _port, _base_dn)
            ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_username, _attr_surname, _attr_email)

            if ret != TPE_OK:
                return self.write_json(ret, message=err_msg)

            need_import = []
            for u in data:
                h = hashlib.sha1()
                h.update(u.encode())

                dn_hash = h.hexdigest()
                for x in dn_hash_list:
                    if x == dn_hash:
                        _user = data[u]
                        _user['dn'] = u
                        need_import.append(_user)
                        break

            if len(need_import) == 0:
                return self.write_json(ret, message='没有可以导入的LDAP用户')

            return self._do_import(need_import)
        except:
            log.e('')
            return self.write_json(TPE_PARAM)
示例#12
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            if len(tp_cfg().sys_ldap_password) == 0:
                return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
            else:
                _password = tp_cfg().sys_ldap_password
            _server = tp_cfg().sys.ldap.server
            _port = tp_cfg().sys.ldap.port
            _admin = tp_cfg().sys.ldap.admin
            _base_dn = tp_cfg().sys.ldap.base_dn
            _filter = tp_cfg().sys.ldap.filter
            _attr_username = tp_cfg().sys.ldap.attr_username
            _attr_surname = tp_cfg().sys.ldap.attr_surname
            _attr_email = tp_cfg().sys.ldap.attr_email
        except:
            return self.write_json(TPE_PARAM)

        try:
            ldap = Ldap(_server, _port, _base_dn)
            ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_username, _attr_surname, _attr_email)
            if ret != TPE_OK:
                return self.write_json(ret, message=err_msg)

            exits_users = user.get_users_by_type(TP_USER_TYPE_LDAP)
            bound_users = []
            for u in exits_users:
                h = hashlib.sha1()
                h.update(u['ldap_dn'].encode())
                bound_users.append(h.hexdigest())

            ret_data = []
            for u in data:
                h = hashlib.sha1()
                h.update(u.encode())
                _id = h.hexdigest()
                if _id in bound_users:
                    continue

                _user = data[u]
                _user['id'] = h.hexdigest()
                ret_data.append(_user)
            return self.write_json(ret, data=ret_data)
        except:
            log.e('')
            return self.write_json(TPE_PARAM)
示例#13
0
def tp_captcha_generate_image(h):
    if h >= 32:
        captcha_image_t = captcha(
            width=136,
            height=36,
            drawings=[
                background(color='#eeeeee'),
                curve(color='#bbbbbb', width=6, number=12),
                curve(color=_random_color_line, width=2, number=30),
                curve(color='#cccccc', width=7, number=13),
                curve(color='#dddddd', width=8, number=14),
                text(fonts=[
                    os.path.join(tp_cfg().res_path, 'fonts', '001.ttf')
                ],
                    font_sizes=(h-5, h-2, h, h+2),
                    color=_random_color_font,
                    squeeze_factor=1.05,
                    drawings=[
                        warp(dx_factor=0.03, dy_factor=0.03),
                        rotate(angle=20),
                        offset()
                    ]),
                smooth(),
            ])
    else:
        captcha_image_t = captcha(
            width=int(h*3)+8,
            height=h,
            drawings=[
                background(color='#eeeeee'),
                noise(number=40, color='#dddddd', level=3),
                smooth(),
                text(fonts=[
                    os.path.join(tp_cfg().res_path, 'fonts', '001.ttf')
                ],
                    font_sizes=(h-3, h-2, h-1, h),
                    color=_random_color_font,
                    squeeze_factor=0.95,
                    drawings=[
                        warp(dx_factor=0.03, dy_factor=0.03),
                        rotate(angle=15),
                        offset()
                    ]),
                smooth(),
            ])

    chars_t = random.sample(_captcha_chars, 4)
    image = captcha_image_t(chars_t)

    out = io.BytesIO()
    image.save(out, "jpeg", quality=80)
    return ''.join(chars_t), out.getvalue()
示例#14
0
文件: auth.py 项目: zydudu/teleport
    def get(self):
        from app.base.db import get_db
        if tp_cfg().app_mode == APP_MODE_MAINTENANCE and get_db().need_create:
            _user = {
                'id': 0,
                'username': '******',
                'surname': '系统维护-安装',
                'role_id': 0,
                'role': '',
                'privilege': TP_PRIVILEGE_SYS_CONFIG,
                '_is_login': True
            }
            self.set_session('user', _user)
            self.redirect('/maintenance/install')
            return

        if tp_cfg().app_mode == APP_MODE_MAINTENANCE and get_db().need_upgrade:
            _user = {
                'id': 0,
                'username': '******',
                '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', '/'))

        if _user['_is_login']:
            self.redirect(_ref)
            return

        if _user['id'] == 0:
            username = self.get_cookie('username')
            if username is None:
                username = ''
        else:
            username = _user['username']

        default_auth_type = tp_cfg().sys.login.auth
        param = {
            'ref': _ref,
            'username': username,
            'default_auth': default_auth_type
        }
        self.render('auth/login.mako', page_param=json.dumps(param))
示例#15
0
    def get(self):

        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        is_sys_smtp = False
        if tp_cfg().sys.loaded:
            smtp = tp_cfg().sys.smtp
            if len(smtp.server) > 0:
                is_sys_smtp = True

        param = {'sys_smtp': is_sys_smtp, 'sys_cfg': tp_cfg().sys}

        self.render('user/user-list.mako', page_param=json.dumps(param))
示例#16
0
    def init(self):
        if not tp_cfg().common.check_host_alive:
            return True

        icmp_protocol = socket.getprotobyname('icmp')
        try:
            self._socket_ping = socket.socket(socket.AF_INET, socket.SOCK_RAW,
                                              icmp_protocol)
        except PermissionError:
            print('To use PING to check host state, must run as root.')
            log.e('To use PING to check host state, must run as root.\n')
            return False

        # 加载所有主机IP
        hosts = host.get_all_hosts_for_check_state()
        for h in hosts:
            if h['router_ip'] != '':
                self.add_host(h['router_ip'], HostAlive.METHOD_PING)
            else:
                self.add_host(h['ip'], HostAlive.METHOD_PING)

        self._thread_recv_ping_result = threading.Thread(
            target=self._thread_func_recv_ping_result)
        self._thread_recv_ping_result.start()

        tp_cron().add_job('host_check_alive',
                          self._check_alive,
                          first_interval_seconds=10,
                          interval_seconds=HostAlive.PING_INTERVAL)

        # for test:
        # tp_cron().add_job('host_show_alive', self._show_alive, first_interval_seconds=20, interval_seconds=HostAlive.PING_INTERVAL)

        return True
示例#17
0
    def stop(self):
        if not tp_cfg().common.check_host_alive:
            return

        self._need_stop = True
        if self._thread_recv_ping_result is not None:
            self._thread_recv_ping_result.join()
示例#18
0
    def add_host(self, host_ip, method=0, param=None, check_now=False):
        if not tp_cfg().common.check_host_alive:
            return True

        if param is None:
            param = {}

        # now we support PING only
        if method != HostAlive.METHOD_PING:
            log.e('Unknown method for check host state: {}\n'.format(method))
            return False

        with self._lock:
            if host_ip not in self._states:
                self._states[host_ip] = {
                    'last_online': 0,
                    'last_check': 0,
                    'method': method,
                    'param': param
                }
            else:
                self._states[host_ip]['method'] = method
                self._states[host_ip]['param'] = param

            if check_now:
                if method == HostAlive.METHOD_PING:
                    self._ping(host_ip)
                else:
                    log.w('Warning: check alive method not implement.\n')
示例#19
0
文件: index.py 项目: tp4a/teleport
    def get(self):
        if self.request.uri == tp_cfg().random_exit_uri:
            tornado.ioloop.IOLoop.instance().stop()
            self.write('EXIT')
            return

        log.w('catch all, GET: {}\n'.format(self.request.uri))
        self.show_error_page(TPE_HTTP_404_NOT_FOUND)
示例#20
0
    def remove_host(self, host_ip):
        if not tp_cfg().common.check_host_alive:
            return

        with self._lock:
            if host_ip not in self._states:
                return
            del self._states[host_ip]
示例#21
0
文件: audit.py 项目: eomsoft/teleport
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_OPS_AUZ | TP_PRIVILEGE_AUDIT_AUZ | TP_PRIVILEGE_AUDIT)
        if ret != TPE_OK:
            return

        if not tp_cfg().core.detected:
            total_size = 0
            free_size = 0
        else:
            total_size, free_size = get_free_space_bytes(tp_cfg().core.replay_path)

        param = {
            'total_size': total_size,
            'free_size': free_size,
        }

        self.render('audit/record.mako', page_param=json.dumps(param))
示例#22
0
文件: user.py 项目: eomsoft/teleport
    def get(self):

        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        is_sys_smtp = False
        if tp_cfg().sys.loaded:
            smtp = tp_cfg().sys.smtp
            if len(smtp.server) > 0:
                is_sys_smtp = True

        param = {
            'sys_smtp': is_sys_smtp,
            'sys_cfg': tp_cfg().sys
        }

        self.render('user/user-list.mako', page_param=json.dumps(param))
示例#23
0
文件: webapp.py 项目: tp4a/teleport
 def stop(self):
     if self._need_stop:
         return
     self._need_stop = True
     cfg = tp_cfg()
     try:
         c = urllib.request.urlopen('http://127.0.0.1:{}{}'.format(cfg.common.port, cfg.random_exit_uri))
         c.read()
     except:
         log.e('\n')
示例#24
0
    def get(self):
        _username = urllib.unquote(self.get_argument('username', None))
        if _username is None:
            return self.redirect('/')

        param = {
            'username': _username,
            'force_strong': tp_cfg().sys.password.force_strong
        }
        self.render('user/change-expired-password.mako',
                    page_param=json.dumps(param))
示例#25
0
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_OPS | TP_PRIVILEGE_OPS_AUZ
                                   | TP_PRIVILEGE_AUDIT_AUZ
                                   | TP_PRIVILEGE_AUDIT)
        if ret != TPE_OK:
            return

        if not tp_cfg().core.detected:
            total_size = 0
            free_size = 0
        else:
            total_size, free_size = get_free_space_bytes(
                tp_cfg().core.replay_path)

        param = {
            'total_size': total_size,
            'free_size': free_size,
        }

        self.render('audit/record.mako', page_param=json.dumps(param))
示例#26
0
文件: stats.py 项目: eomsoft/teleport
def update_temp_locked_user_state():
    sys_cfg = tp_cfg().sys
    if sys_cfg.login.lock_timeout == 0:
        return

    _lock_time = tp_timestamp_utc_now() - (sys_cfg.login.lock_timeout * 60)
    db = get_db()
    if db.need_create or db.need_upgrade:
        return

    sql = 'UPDATE `{}user` SET state={new_state}, lock_time=0, fail_count=0 WHERE (state={old_state} AND lock_time<{lock_time});' \
          ''.format(db.table_prefix, new_state=TP_STATE_NORMAL, old_state=TP_STATE_LOCKED, lock_time=_lock_time)
    db.exec(sql)
示例#27
0
def update_temp_locked_user_state():
    sys_cfg = tp_cfg().sys
    if sys_cfg.login.lock_timeout == 0:
        return

    _lock_time = tp_timestamp_utc_now() - (sys_cfg.login.lock_timeout * 60)
    db = get_db()
    if db.need_create or db.need_upgrade:
        return

    sql = 'UPDATE `{}user` SET state={new_state}, lock_time=0, fail_count=0 WHERE (state={old_state} AND lock_time<{lock_time});' \
          ''.format(db.table_prefix, new_state=TP_STATE_NORMAL, old_state=TP_STATE_LOCKED, lock_time=_lock_time)
    db.exec(sql)
示例#28
0
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_OPS)
        if ret != TPE_OK:
            return

        err, groups = group.get_host_groups_for_user(
            self.current_user['id'], self.current_user['privilege'])
        param = {'host_groups': groups, 'core_cfg': tp_cfg().core}

        # param = {
        #     'core_cfg': tp_cfg().core
        # }

        self.render('ops/remote-list.mako', page_param=json.dumps(param))
示例#29
0
文件: auth.py 项目: eomsoft/teleport
    def get(self):
        from app.base.db import get_db
        if tp_cfg().app_mode == APP_MODE_MAINTENANCE and get_db().need_create:
            _user = {
                'id': 0,
                'username': '******',
                'surname': '安装程序',
                'role_id': 0,
                'role': '',
                'privilege': TP_PRIVILEGE_SYS_CONFIG,
                '_is_login': True
            }
            self.set_session('user', _user)
            self.redirect('/maintenance/install')
            return

        _user = self.get_current_user()
        _ref = quote(self.get_argument('ref', '/'))

        if _user['_is_login']:
            self.redirect(_ref)
            return

        if _user['id'] == 0:
            username = self.get_cookie('username')
            if username is None:
                username = ''
        else:
            username = _user['username']

        default_auth_type = tp_cfg().sys.login.auth
        param = {
            'ref': _ref,
            'username': username,
            'default_auth': default_auth_type
        }
        self.render('auth/login.mako', page_param=json.dumps(param))
示例#30
0
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_ASSET_CREATE
                                   | TP_PRIVILEGE_ASSET_DELETE
                                   | TP_PRIVILEGE_ASSET_GROUP)
        if ret != TPE_OK:
            return

        err, groups = group.get_host_groups_for_user(
            self.current_user['id'], self.current_user['privilege'])
        param = {
            'host_groups': groups,
            '_check_host_alive': tp_cfg().common.check_host_alive
        }

        self.render('asset/host-list.mako', page_param=json.dumps(param))
示例#31
0
    def init(self):
        cfg = tp_cfg()
        cfg_file = os.path.join(cfg.cfg_path, 'extsrv.json')
        # 如果配置文件不存在,则不支持第三方服务调用TP-API
        if not os.path.exists(cfg_file):
            return True

        log.i('Loading external server configuration...\n')
        with open(cfg_file, encoding='utf_8') as f:
            c = f.read()
            try:
                sc = json.loads(c)
            except:
                return False

        if 'version' not in sc:
            return False
        if 'ext_srv' not in sc:
            return False

        srv = sc['ext_srv']

        try:
            for i in range(len(srv)):
                srv_name = srv[i]['name']
                srv_desc = srv[i]['desc']
                for j in range(len(srv[i]['access'])):
                    key = srv[i]['access'][j]['key']
                    secret = srv[i]['access'][j]['secret']
                    privilege = int(srv[i]['access'][j]['privilege'])

                    if key in self._cfg:
                        log.e(
                            'Invalid extsrv.json, duplicated key: {}\n'.format(
                                key))
                        return False

                    self._cfg[key] = {
                        'name': srv_name,
                        'desc': srv_desc,
                        'secret': secret,
                        'privilege': privilege
                    }
        except:
            log.e('Invalid extsrv.json\n')
            return False

        return True
示例#32
0
 def _get_core_server_config(self):
     cfg = tp_cfg()
     try:
         req = {'method': 'get_config', 'param': []}
         req_data = json.dumps(req)
         data = urllib.parse.quote(req_data).encode('utf-8')
         req = urllib.request.Request(url=cfg.common.core_server_rpc, data=data)
         rep = urllib.request.urlopen(req, timeout=3)
         body = rep.read().decode()
         x = json.loads(body)
         if 'code' not in x or x['code'] != 0:
             log.e('connect core-server for get config info failed.\n')
         else:
             cfg.update_core(x['data'])
             log.d('get config info of core-server succeeded.\n')
     except:
         log.w('can not connect to core-server to get config, maybe it not start yet, ignore.\n')
示例#33
0
文件: webapp.py 项目: tp4a/teleport
 def _get_core_server_config(self):
     cfg = tp_cfg()
     try:
         req = {'method': 'get_config', 'param': []}
         req_data = json.dumps(req)
         data = urllib.parse.quote(req_data).encode('utf-8')
         req = urllib.request.Request(url=cfg.common.core_server_rpc, data=data)
         rep = urllib.request.urlopen(req, timeout=3)
         body = rep.read().decode()
         x = json.loads(body)
         if 'code' not in x or x['code'] != 0:
             log.e('connect core-server for get config info failed.\n')
         else:
             cfg.update_core(x['data'])
             log.d('get config info of core-server succeeded.\n')
     except:
         log.w('can not connect to core-server to get config, maybe it not start yet, ignore.\n')
示例#34
0
    def init(self, path_app_root, path_data):
        log.initialize()

        cfg = tp_cfg()
        cfg.app_path = path_app_root
        cfg.static_path = os.path.join(path_app_root, 'static')
        cfg.template_path = os.path.join(path_app_root, 'view')
        cfg.res_path = os.path.join(path_app_root, 'res')

        cfg.data_path = path_data
        cfg.cfg_path = os.path.join(path_data, 'etc')
        cfg.log_path = os.path.join(path_data, 'log')

        self._cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
        if not cfg.load(self._cfg_file):
            return False

        return True
示例#35
0
文件: ops.py 项目: eomsoft/teleport
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_OPS)
        if ret != TPE_OK:
            return

        err, groups = group.get_host_groups_for_user(self.current_user['id'], self.current_user['privilege'])
        _cfg = tp_cfg()
        param = {
            'host_groups': groups,
            'core_cfg': _cfg.core,
            'url_proto': _cfg.sys.glob.url_proto
        }

        # param = {
        #     'core_cfg': tp_cfg().core
        # }

        self.render('ops/remote-list.mako', page_param=json.dumps(param))
示例#36
0
文件: session.py 项目: net5/tpyaudit
    def set(self, s_id, value, expire=None):
        """
        设置一个会话数据,如果expire为负数,则立即删除已经存在的名为s_id的会话,如果expire为0,则此会话数据永不过期。expire的单位为秒。
        @param s_id: string
        @param value: string
        @param expire: integer
        @return: None
        """

        if expire is None:
            expire = tp_cfg().sys.login.session_timeout * 60

        if expire < 0:
            with self._lock:
                if s_id in self._session_dict:
                    del self._session_dict[s_id]
        else:
            self._session_dict[s_id] = {'v': value, 't': int(datetime.datetime.utcnow().timestamp()), 'e': expire}
示例#37
0
    def init(self):
        cfg = tp_cfg()
        if 'sqlite' == cfg.database.type:
            if cfg.database.sqlite_file is None:
                cfg.set_default('database::sqlite-file', os.path.join(cfg.data_path, 'db', 'teleport.db'))
            if not self._init_sqlite(cfg.database.sqlite_file):
                return False
            if self.need_create:
                return True
        elif 'mysql' == cfg.database.type:
            if not self._init_mysql(cfg.database.mysql_host, cfg.database.mysql_port,
                                    cfg.database.mysql_db, cfg.database.mysql_prefix,
                                    cfg.database.mysql_user, cfg.database.mysql_password):
                return False
        else:
            log.e('unknown database type `{}`, support sqlite/mysql now.\n'.format(cfg.database.type))
            return False

        return True
示例#38
0
文件: db.py 项目: eomsoft/teleport
    def init(self):
        cfg = tp_cfg()
        if 'sqlite' == cfg.database.type:
            if cfg.database.sqlite_file is None:
                cfg.set_default('database::sqlite-file', os.path.join(cfg.data_path, 'db', 'teleport.db'))
            if not self._init_sqlite(cfg.database.sqlite_file):
                return False
            if self.need_create:
                return True
        elif 'mysql' == cfg.database.type:
            if not self._init_mysql(cfg.database.mysql_host, cfg.database.mysql_port,
                                    cfg.database.mysql_db, cfg.database.mysql_prefix,
                                    cfg.database.mysql_user, cfg.database.mysql_password):
                return False
        else:
            log.e('unknown database type `{}`, support sqlite/mysql now.\n'.format(cfg.database.type))
            return False

        return True
示例#39
0
    def get_states(self, host_ip_list):
        if not tp_cfg().common.check_host_alive:
            return {}

        with self._lock:
            ret = dict()
            time_now = int(time.time())
            for k in host_ip_list:
                if k not in self._states:
                    ret[k] = {
                        'state': HostAlive.STATE_UNKNOWN,
                        'last_online': 0,
                        'last_check': 0
                    }
                    continue
                if self._states[k]['last_check'] == 0:
                    ret[k] = {
                        'state': HostAlive.STATE_UNKNOWN,
                        'last_online': 0,
                        'last_check': time_now - self._states[k]['last_check']
                    }
                    continue
                if self._states[k]['last_online'] == 0:
                    ret[k] = {
                        'state': HostAlive.STATE_WARNING,
                        'last_online': 0,
                        'last_check': time_now - self._states[k]['last_check']
                    }

                if time_now - self._states[k]['last_online'] > 2 * 60:
                    _state = HostAlive.STATE_OFFLINE
                elif time_now - self._states[k]['last_online'] > 60:
                    _state = HostAlive.STATE_WARNING
                else:
                    _state = HostAlive.STATE_ONLINE
                ret[k] = {
                    'state': _state,
                    'last_online': self._states[k]['last_online'],
                    'last_check': time_now - self._states[k]['last_check']
                }

        return ret
示例#40
0
    def _init_sqlite(self, db_file):
        self.db_type = self.DB_TYPE_SQLITE
        self.auto_increment = 'AUTOINCREMENT'
        self.place_holder = '?'
        self.sqlite_file = db_file

        self._table_prefix = tp_cfg().database.mysql_prefix
        self._conn_pool = TPSqlitePool(db_file)

        if not os.path.exists(db_file):

            p = os.path.dirname(os.path.abspath(db_file))
            if not os.path.exists(p):
                os.makedirs(p)

            log.w('database need create.\n')
            self.need_create = True
            return True

        return True
示例#41
0
    def init(self, path_app_root, path_data):
        log.initialize()

        asyncio.set_event_loop_policy(tornado.platform.asyncio.AnyThreadEventLoopPolicy())

        cfg = tp_cfg()
        cfg.app_path = path_app_root
        cfg.static_path = os.path.join(path_app_root, 'static')
        cfg.template_path = os.path.join(path_app_root, 'view')
        cfg.res_path = os.path.join(path_app_root, 'res')

        cfg.data_path = path_data
        cfg.cfg_path = os.path.join(path_data, 'etc')
        cfg.log_path = os.path.join(path_data, 'log')

        self._cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
        if not cfg.load(self._cfg_file):
            return False

        return True
示例#42
0
    def init(self, path_app_root, path_data):
        log.initialize()

        asyncio.set_event_loop_policy(tornado.platform.asyncio.AnyThreadEventLoopPolicy())

        cfg = tp_cfg()
        cfg.app_path = path_app_root
        cfg.static_path = os.path.join(path_app_root, 'static')
        cfg.template_path = os.path.join(path_app_root, 'view')
        cfg.res_path = os.path.join(path_app_root, 'res')

        cfg.data_path = path_data
        cfg.cfg_path = os.path.join(path_data, 'etc')
        cfg.log_path = os.path.join(path_data, 'log')

        self._cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
        if not cfg.load(self._cfg_file):
            return False

        return True
示例#43
0
def update_fail_count(handler, user_info):
    db = get_db()
    sys_cfg = tp_cfg().sys
    sql_list = []
    is_locked = False
    fail_count = user_info.fail_count + 1

    sql = 'UPDATE `{}user` SET fail_count={count} WHERE id={uid};' \
          ''.format(db.table_prefix, count=fail_count, uid=user_info.id)
    sql_list.append(sql)

    if sys_cfg.login.retry != 0 and fail_count >= sys_cfg.login.retry:
        is_locked = True
        sql = 'UPDATE `{}user` SET state={state}, lock_time={lock_time} WHERE id={uid};' \
              ''.format(db.table_prefix, state=TP_STATE_LOCKED, lock_time=tp_timestamp_utc_now(), uid=user_info.id)
        sql_list.append(sql)

    if db.transaction(sql_list):
        return TPE_OK, is_locked
    else:
        return TPE_DATABASE, is_locked
示例#44
0
文件: user.py 项目: eomsoft/teleport
def update_fail_count(handler, user_info):
    db = get_db()
    sys_cfg = tp_cfg().sys
    sql_list = []
    is_locked = False
    fail_count = user_info.fail_count + 1

    sql = 'UPDATE `{}user` SET fail_count={count} WHERE id={uid};' \
          ''.format(db.table_prefix, count=fail_count, uid=user_info.id)
    sql_list.append(sql)

    if sys_cfg.login.retry != 0 and fail_count >= sys_cfg.login.retry:
        is_locked = True
        sql = 'UPDATE `{}user` SET state={state}, lock_time={lock_time} WHERE id={uid};' \
              ''.format(db.table_prefix, state=TP_STATE_LOCKED, lock_time=tp_timestamp_utc_now(), uid=user_info.id)
        sql_list.append(sql)

    if db.transaction(sql_list):
        return TPE_OK, is_locked
    else:
        return TPE_DATABASE, is_locked
示例#45
0
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
        if ret != TPE_OK:
            return

        cfg = tp_cfg()

        # core_detected = False
        req = {'method': 'get_config', 'param': []}
        _yr = core_service_async_post_http(req)
        code, ret_data = yield _yr
        if code != TPE_OK:
            cfg.update_core(None)
        else:
            cfg.update_core(ret_data)

        if not tp_cfg().core.detected:
            total_size = 0
            free_size = 0
        else:
            total_size, _, free_size = shutil.disk_usage(
                tp_cfg().core.replay_path)

        _db = get_db()
        db = {'type': _db.db_type}
        if _db.db_type == _db.DB_TYPE_SQLITE:
            db['sqlite_file'] = _db.sqlite_file
        elif _db.db_type == _db.DB_TYPE_MYSQL:
            db['mysql_host'] = _db.mysql_host
            db['mysql_port'] = _db.mysql_port
            db['mysql_db'] = _db.mysql_db
            db['mysql_user'] = _db.mysql_user

        param = {
            'total_size': total_size,
            'free_size': free_size,
            'core_cfg': tp_cfg().core,
            'sys_cfg': tp_cfg().sys,
            'web_cfg': {
                'version': TP_SERVER_VER,
                'core_server_rpc': tp_cfg().common.core_server_rpc,
                'db': db
            }
        }

        self.render('system/config.mako', page_param=json.dumps(param))
示例#46
0
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
        if ret != TPE_OK:
            return

        cfg = tp_cfg()

        # core_detected = False
        req = {'method': 'get_config', 'param': []}
        _yr = core_service_async_post_http(req)
        code, ret_data = yield _yr
        if code != TPE_OK:
            cfg.update_core(None)
        else:
            cfg.update_core(ret_data)

        if not tp_cfg().core.detected:
            total_size = 0
            free_size = 0
        else:
            total_size, _, free_size = shutil.disk_usage(tp_cfg().core.replay_path)

        _db = get_db()
        db = {'type': _db.db_type}
        if _db.db_type == _db.DB_TYPE_SQLITE:
            db['sqlite_file'] = _db.sqlite_file
        elif _db.db_type == _db.DB_TYPE_MYSQL:
            db['mysql_host'] = _db.mysql_host
            db['mysql_port'] = _db.mysql_port
            db['mysql_db'] = _db.mysql_db
            db['mysql_user'] = _db.mysql_user

        param = {
            'total_size': total_size,
            'free_size': free_size,
            'core_cfg': tp_cfg().core,
            'sys_cfg': tp_cfg().sys,
            'web_cfg': {
                'version': TP_SERVER_VER,
                'core_server_rpc': tp_cfg().common.core_server_rpc,
                'db': db
            }
        }

        self.render('system/config.mako', page_param=json.dumps(param))
示例#47
0
# -*- coding: utf-8 -*-

import json
import threading

from app.const import *
from app.base.configs import tp_cfg
from app.base.controller import TPBaseHandler, TPBaseJsonHandler
from app.base.db import get_db

cfg = tp_cfg()


class IndexHandler(TPBaseHandler):
    def get(self):
        self.render('maintenance/index.mako')


class InstallHandler(TPBaseHandler):
    def get(self):
        ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
        if ret != TPE_OK:
            return

        if get_db().need_create:
            cfg.reload()

            _db = get_db()
            _db.init()

            db = {'type': _db.db_type}
示例#48
0
文件: user.py 项目: eomsoft/teleport
def login(handler, username, password=None, oath_code=None, check_bind_oath=False):
    sys_cfg = tp_cfg().sys

    err, user_info = get_by_username(username)
    if err != TPE_OK:
        # if err == TPE_NOT_EXISTS:
        #     syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS,
        #                    '用户身份验证失败,用户`{}`不存在'.format(username))
        return err, None

    if user_info.privilege == 0:
        # 尚未为此用户设置角色
        return TPE_PRIVILEGE, None

    if check_bind_oath and len(user_info['oath_secret']) != 0:
        return TPE_OATH_ALREADY_BIND, None

    if user_info['state'] == TP_STATE_LOCKED:
        # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
        if sys_cfg.login.lock_timeout != 0:
            if tp_timestamp_utc_now() - user_info.lock_time > sys_cfg.login.lock_timeout * 60:
                user_info.fail_count = 0
                user_info.state = TP_STATE_NORMAL
        if user_info['state'] == TP_STATE_LOCKED:
            syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被临时锁定')
            return TPE_USER_LOCKED, None
    elif user_info['state'] == TP_STATE_DISABLED:
        syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用')
        return TPE_USER_DISABLED, None
    elif user_info['state'] != TP_STATE_NORMAL:
        syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, '登录失败,用户状态异常')
        return TPE_FAILED, None

    err_msg = ''
    if password is not None:
        if user_info['type'] == TP_USER_TYPE_LOCAL:
            # 如果系统配置了密码有效期,则检查用户的密码是否失效
            if sys_cfg.password.timeout != 0:
                _time_now = tp_timestamp_utc_now()
                if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_now:
                    syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,用户密码已过期')
                    return TPE_USER_AUTH, None

            if not tp_password_verify(password, user_info['password']):
                err, is_locked = update_fail_count(handler, user_info)
                if is_locked:
                    err_msg = ',用户已被临时锁定'
                syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg))
                return TPE_USER_AUTH, None
        elif user_info['type'] == TP_USER_TYPE_LDAP:
            try:
                if len(tp_cfg().sys_ldap_password) == 0:
                    syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置,需要管理员密码')
                    return TPE_USER_AUTH, None
                else:
                    _ldap_password = tp_cfg().sys_ldap_password
                _ldap_server = tp_cfg().sys.ldap.server
                _ldap_port = tp_cfg().sys.ldap.port
                _ldap_base_dn = tp_cfg().sys.ldap.base_dn
            except:
                syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置')
                return TPE_USER_AUTH, None

            try:
                ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn)
                ret, err_msg = ldap.valid_user(user_info['ldap_dn'], password)
                if ret != TPE_OK:
                    if ret == TPE_USER_AUTH:
                        err, is_locked = update_fail_count(handler, user_info)
                        if is_locked:
                            err_msg = ',用户已被临时锁定'
                        syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH,
                                       'LDAP用户登录失败,密码错误{}'.format(err_msg))
                        return TPE_USER_AUTH, None
                    else:
                        syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH,
                                       'LDAP用户登录失败,{}'.format(err_msg))
                        return TPE_USER_AUTH, None
            except:
                syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,发生内部错误')
                return TPE_USER_AUTH, None

        else:
            syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,系统内部错误')
            return TPE_USER_AUTH, None

    if oath_code is not None:
        # use oath
        if len(user_info['oath_secret']) == 0:
            return TPE_OATH_MISMATCH, None

        if not tp_oath_verify_code(user_info['oath_secret'], oath_code):
            err, is_locked = update_fail_count(handler, user_info)
            if is_locked:
                err_msg = ',用户已被临时锁定!'
            syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH,
                           "登录失败,身份验证器动态验证码错误{}".format(err_msg))
            return TPE_OATH_MISMATCH, None

    del user_info['password']
    del user_info['oath_secret']

    if len(user_info['surname']) == 0:
        user_info['surname'] = user_info['username']
    return TPE_OK, user_info
示例#49
0
文件: user.py 项目: eomsoft/teleport
    def post(self):
        """
        csv导入规则:
        每一行的数据格式:  用户账号,用户姓名,登录认证方式,email地址,Mobile,QQ,WeChat,所属组,描述
        在导入时:
          0. 以“#”作为行注释。
          1. 用户账号是必须填写的,其他均为可选。
          2. 一个用户属于多个组,可以用“|”将组分隔,如果某个组并不存在,则会创建这个组。
          3. 空行跳过,数据格式不正确的跳过。
        """

        ret = dict()
        ret['code'] = TPE_OK
        ret['message'] = ''

        rv = self.check_privilege(TP_PRIVILEGE_USER_CREATE | TP_PRIVILEGE_USER_GROUP, need_process=False)
        if rv != TPE_OK:
            ret['code'] = rv
            ret['code'] = rv
            if rv == TPE_NEED_LOGIN:
                ret['message'] = '需要登录!'
            elif rv == TPE_PRIVILEGE:
                ret['message'] = '权限不足!'
            else:
                ret['message'] = '未知错误!'
            return self.write(json.dumps(ret).encode('utf8'))

        success = list()
        failed = list()
        group_failed = list()
        csv_filename = ''

        try:
            upload_path = os.path.join(tp_cfg().data_path, 'tmp')  # 文件的暂存路径
            if not os.path.exists(upload_path):
                os.mkdir(upload_path)
            file_metas = self.request.files['csvfile']  # 提取表单中‘name’为‘file’的文件元数据
            for meta in file_metas:
                now = time.localtime(time.time())
                tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.csv'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
                csv_filename = os.path.join(upload_path, tmp_name)
                with open(csv_filename, 'wb') as f:
                    f.write(meta['body'])

            # file encode maybe utf8 or gbk... check it out.
            file_encode = None
            with open(csv_filename, encoding='gbk') as f:
                try:
                    f.readlines()
                    file_encode = 'gbk'
                except:
                    pass

            if file_encode is None:
                log.v('file `{}` is not gbk, try utf8\n'.format(csv_filename))
                with open(csv_filename, encoding='utf_8_sig') as f:
                    try:
                        f.readlines()
                        file_encode = 'utf_8_sig'
                    except:
                        pass

            if file_encode is None:
                os.remove(csv_filename)
                log.e('file `{}` unknown encode, neither GBK nor UTF8.\n'.format(csv_filename))
                ret['code'] = TPE_FAILED
                ret['message'] = '文件无法解码:不是GBK编码或者UTF8编码!'
                return self.write(json.dumps(ret).encode('utf8'))

            group_list = dict()
            user_list = list()

            # 解析csv文件
            with open(csv_filename, encoding=file_encode) as f:
                username_list = []  # 用于检查是否有重复的用户被添加
                csv_reader = csv.reader(f)
                line = 0
                for csv_recorder in csv_reader:
                    line += 1

                    # 跳过空行和注释
                    if len(csv_recorder) == 0 or csv_recorder[0].strip().startswith('#'):
                        continue

                    # 格式错误则记录在案,然后继续
                    if len(csv_recorder) != 8:
                        failed.append({'line': line, 'error': '格式错误,字段数量不匹配。'})
                        continue

                    # check
                    _username = csv_recorder[self.IDX_USERNAME].strip()
                    if len(_username) == 0:
                        failed.append({'line': line, 'error': '格式错误,用户账号必须填写。'})
                        continue

                    _email = csv_recorder[self.IDX_EMAIL].strip()

                    _group = csv_recorder[self.IDX_GROUP].split('|')

                    u = dict()
                    u['_line'] = line
                    u['_id'] = 0
                    u['username'] = _username
                    u['surname'] = csv_recorder[self.IDX_SURNAME].strip()
                    # u['auth'] = _auth
                    u['email'] = _email
                    u['mobile'] = csv_recorder[self.IDX_MOBILE].strip()
                    u['qq'] = csv_recorder[self.IDX_QQ].strip()
                    u['wechat'] = csv_recorder[self.IDX_WECHAT].strip()
                    u['desc'] = csv_recorder[self.IDX_DESC].strip()

                    u['password'] = tp_gen_password(8)

                    # fix
                    if len(u['surname']) == 0:
                        u['surname'] = _username
                    u['username'] = _username.lower()
                    if u['username'] in username_list:
                        failed.append({'line': line, 'error': '上传文件中用户 `{}` 重复。'.format(u['username'])})
                        continue
                    else:
                        username_list.append(u['username'])

                    u['_group'] = list()
                    for i in range(len(_group)):
                        x = _group[i].strip()
                        if len(x) > 0:
                            u['_group'].append(x)

                    # 更新一下组列表,以备后续为用户与所在组创建映射
                    for i in range(len(u['_group'])):
                        if u['_group'][i] not in group_list:
                            group_list[u['_group'][i]] = 0

                    user_list.append(u)

            if os.path.exists(csv_filename):
                os.remove(csv_filename)

            # 检查一下
            if len(user_list) == 0:
                ret['code'] = TPE_FAILED
                ret['message'] = '上传的 csv 文件中没有可用于导入的用户!'
                ret['data'] = failed
                return self.write(json.dumps(ret).encode('utf8'))

            # 已经有了用户组列表,查询组数据库,有则更新用户组列表中组对应的id,无则创建组
            if len(group_list) > 0:
                err = group.make_groups(self, TP_GROUP_USER, group_list, group_failed)
                if len(group_failed) > 0:
                    ret['code'] = TPE_FAILED
                    ret['message'] += '无法创建用户组 {}。'.format(','.join(group_failed))
                    return self.write(json.dumps(ret).encode('utf8'))

            # 对用户列表中的每一项,创建用户
            user.create_users(self, user_list, success, failed)

            # 对创建成功的用户,在用户组映射表中设定其对应关系
            gm = list()
            for u in user_list:
                if u['_id'] == 0:
                    continue
                for ug in u['_group']:
                    for g in group_list:
                        if group_list[g] == 0 or ug != g:
                            continue
                        gm.append({'type': TP_GROUP_USER, 'gid': group_list[g], 'mid': u['_id']})

            group.make_group_map(TP_GROUP_USER, gm)

            # 对于创建成功的用户,发送密码邮件函
            sys_smtp_password = tp_cfg().sys_smtp_password
            if len(sys_smtp_password) > 0:
                web_url = '{}://{}'.format(self.request.protocol, self.request.host)
                for u in user_list:
                    if u['_id'] == 0 or len(u['email']) == 0:
                        continue
                    err, msg = yield mail.tp_send_mail(
                        u['email'],
                        '{surname} 您好!\n\n已为您创建teleport系统用户账号,现在可以使用以下信息登录teleport系统:\n\n'
                        '登录用户名:{username}\n'
                        '密码:{password}\n'
                        '地址:{web_url}\n\n\n\n'
                        '[本邮件由teleport系统自动发出,请勿回复]'
                        '\n\n'
                        ''.format(surname=u['surname'], username=u['username'], password=u['password'], web_url=web_url),
                        subject='用户密码函'
                    )
                    if err != TPE_OK:
                        failed.append({'line': u['_line'], 'error': '无法发送密码函到邮箱 {},错误:{}。'.format(u['email'], msg)})

            # 统计结果
            total_success = 0
            total_failed = 0
            for u in user_list:
                if u['_id'] == 0:
                    total_failed += 1
                else:
                    total_success += 1

            # 生成最终结果信息
            if len(failed) == 0:
                ret['code'] = TPE_OK
                ret['message'] = '共导入 {} 个用户账号!'.format(total_success)
                return self.write(json.dumps(ret).encode('utf8'))
            else:
                ret['code'] = TPE_FAILED
                if total_success > 0:
                    ret['message'] = '{} 个用户账号导入成功,'.format(total_success)
                if total_failed > 0:
                    ret['message'] += '{} 个用户账号未能导入!'.format(total_failed)

                ret['data'] = failed
                return self.write(json.dumps(ret).encode('utf8'))
        except:
            log.e('got exception when import user.\n')
            ret['code'] = TPE_FAILED
            if len(success) > 0:
                ret['message'] += '{} 个用户账号导入后发生异常!'.format(len(success))
            else:
                ret['message'] = '发生异常!'

            ret['data'] = failed
            return self.write(json.dumps(ret).encode('utf8'))
示例#50
0
文件: user.py 项目: eomsoft/teleport
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            args['id'] = int(args['id'])
            args['role'] = int(args['role'])
            args['auth_type'] = int(args['auth_type'])
            args['username'] = args['username'].strip().lower()
            args['surname'] = args['surname'].strip()
            args['email'] = args['email'].strip()
            args['mobile'] = args['mobile'].strip()
            args['qq'] = args['qq'].strip()
            args['wechat'] = args['wechat'].strip()
            args['desc'] = args['desc'].strip()
        except:
            return self.write_json(TPE_PARAM)

        if len(args['username']) == 0:
            return self.write_json(TPE_PARAM)

        if args['id'] == -1:
            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:
                    web_url = '{}://{}'.format(self.request.protocol, self.request.host)
                    err, msg = yield mail.tp_send_mail(
                        args['email'],
                        '{surname} 您好!\n\n已为您创建teleport系统用户账号,现在可以使用以下信息登录teleport系统:\n\n'
                        '登录用户名:{username}\n'
                        '密码:{password}\n'
                        '地址:{web_url}\n\n\n\n'
                        '[本邮件由teleport系统自动发出,请勿回复]'
                        '\n\n'
                        ''.format(surname=args['surname'], username=args['username'], password=args['password'], web_url=web_url),
                        subject='用户密码函'
                    )
                    if err != TPE_OK:
                        return self.write_json(TPE_OK, '用户账号创建成功,但发送密码函失败:{}'.format(msg))
                    else:
                        return self.write_json(TPE_OK)
            else:
                return self.write_json(err)
        else:
            err = user.update_user(self, args)
            self.write_json(err)
示例#51
0
文件: user.py 项目: eomsoft/teleport
    def post(self):

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            mode = int(args['mode'])
        except:
            return self.write_json(TPE_PARAM)

        password = ''

        if mode == 1:
            # 管理员直接在后台给用户发送密码重置邮件
            err = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
            if err != TPE_OK:
                return self.write_json(err)

            try:
                user_id = int(args['id'])
            except:
                return self.write_json(TPE_PARAM)

        elif mode == 2:
            # 管理员直接在后台为用户重置密码
            err = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
            if err != TPE_OK:
                return self.write_json(err)

            try:
                user_id = int(args['id'])
                password = args['password']
            except:
                return self.write_json(TPE_PARAM)

        elif mode == 3:
            # 用户自行找回密码,需要填写用户名、邮箱、验证码
            try:
                username = args['username']
                email = args['email']
                captcha = args['captcha']
            except:
                return self.write_json(TPE_PARAM)

            code = self.get_session('captcha')
            if code is None:
                return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效')
            if code.lower() != captcha.lower():
                return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误')

            self.del_session('captcha')
            err, user_info = user.get_by_username(username)
            if err != TPE_OK:
                return self.write_json(err)
            if user_info.email != email:
                return self.write_json(TPE_NOT_EXISTS)

            user_id = user_info.id

        elif mode == 4:
            # 用户通过密码重置邮件中的链接(有token验证),在页面上设置新密码,需要提供token、新密码
            try:
                token = args['token']
                password = args['password']
            except:
                return self.write_json(TPE_PARAM)

            err, user_id = user.check_reset_token(token)
            if err != TPE_OK:
                return self.write_json(err)

        elif mode == 5:
            # 用户输入当前密码和新密码进行设置
            try:
                current_password = args['current_password']
                password = args['password']
            except:
                return self.write_json(TPE_PARAM)

            err, user_info = user.get_by_username(self.get_current_user()['username'])
            if err != TPE_OK:
                return self.write_json(err)
            if not tp_password_verify(current_password, user_info['password']):
                return self.write_json(TPE_USER_AUTH)
            user_id = user_info['id']

        else:
            return self.write_json(TPE_PARAM)

        if user_id == 0:
            return self.write_json(TPE_PARAM)

        if mode == 1 or mode == 3:
            err, email, token = user.generate_reset_password_token(self, user_id)

            # generate an URL for reset password, valid in 24hr.
            reset_url = '{}://{}/user/reset-password?token={}'.format(self.request.protocol, self.request.host, token)

            err, msg = yield mail.tp_send_mail(
                email,
                'Teleport用户,您好!\n\n请访问以下链接以重设您的teleport登录密码。此链接将于本邮件寄出24小时之后失效。\n'
                '访问此链接,将会为您打开密码重置页面,然后您可以设定新密码。\n\n'
                '如果您并没有做重设密码的操作,请忽略本邮件,请及时联系您的系统管理员!\n\n'
                '{reset_url}\n\n\n\n'
                '[本邮件由teleport系统自动发出,请勿回复]'
                '\n\n'
                ''.format(reset_url=reset_url),
                subject='密码重置确认函'
            )

            return self.write_json(err, msg)

        elif mode == 2 or mode == 4 or mode == 5:
            if len(password) == 0:
                return self.write_json(TPE_PARAM)

            # 根据需要进行弱密码检测
            if tp_cfg().sys.password.force_strong:
                if not tp_check_strong_password(password):
                    return self.write_json(TPE_FAILED, '密码强度太弱!强密码需要至少8个英文字符,必须包含大写字母、小写字母和数字。')

            password = tp_password_generate_secret(password)
            err = user.set_password(self, user_id, password)

            if mode == 4 and err == TPE_OK:
                user.remove_reset_token(token)

            # 非用户自行修改密码的情况,都默认重置身份认证
            if mode != 5 and err == TPE_OK:
                print("reset oath secret")
                user.update_oath_secret(self, user_id, '')

            self.write_json(err)

        else:
            self.write_json(TPE_PARAM)
示例#52
0
def cleanup_storage(handler):
    # storage config
    sto = tp_cfg().sys.storage

    db = get_db()
    _now = tp_timestamp_utc_now()
    msg = []
    have_error = False

    s = SQL(db)
    chk_time = _now - sto.keep_log * 24 * 60 * 60

    if sto.keep_log > 0:
        # find out all sys-log to be remove
        s.select_from('syslog', ['id'], alt_name='s')
        s.where('s.log_time<{chk_time}'.format(chk_time=chk_time))
        err = s.query()
        if err != TPE_OK:
            have_error = True
            msg.append('清理系统日志时发生错误:无法获取系统日志信息!')
            # return err, msg
        else:
            removed_log = len(s.recorder)
            if 0 == removed_log:
                msg.append('没有满足条件的系统日志需要清除!')
            else:
                s.reset().delete_from('syslog').where('log_time<{chk_time}'.format(chk_time=chk_time))
                err = s.exec()
                if err != TPE_OK:
                    have_error = True
                    msg.append('清理系统日志时发生错误:无法清除指定的系统日志!')
                else:
                    msg.append('{} 条系统日志已清除!'.format(removed_log))

    if sto.keep_record > 0:
        core_cfg = tp_cfg().core
        if not core_cfg.detected:
            have_error = True
            msg.append('清除指定会话录像失败:未能检测到核心服务!')
        else:
            replay_path = core_cfg.replay_path
            if not os.path.exists(replay_path):
                have_error = True
                msg.append('清除指定会话录像失败:会话录像路径不存在({})!'.format(replay_path))
            else:
                # find out all record to be remove
                s.reset().select_from('record', ['id', 'protocol_type'], alt_name='r')
                s.where('r.time_begin<{chk_time}'.format(chk_time=chk_time))
                err = s.query()
                if err != TPE_OK:
                    have_error = True
                    msg.append('清除指定会话录像失败:无法获取会话录像信息!')
                elif len(s.recorder) == 0:
                    msg.append('没有满足条件的会话录像需要清除!')
                else:
                    record_removed = 0
                    for r in s.recorder:
                        if r.protocol_type == TP_PROTOCOL_TYPE_RDP:
                            path_remove = os.path.join(replay_path, 'rdp', '{:09d}'.format(r.id))
                        elif r.protocol_type == TP_PROTOCOL_TYPE_SSH:
                            path_remove = os.path.join(replay_path, 'ssh', '{:09d}'.format(r.id))
                        elif r.protocol_type == TP_PROTOCOL_TYPE_TELNET:
                            path_remove = os.path.join(replay_path, 'telnet', '{:09d}'.format(r.id))
                        else:
                            have_error = True
                            msg.append('会话录像记录编号 {},未知远程访问协议!'.format(r.id))
                            continue

                        if os.path.exists(path_remove):
                            # print('remove path', path_remove)
                            try:
                                shutil.rmtree(path_remove)
                            except:
                                have_error = True
                                msg.append('会话录像记录 {} 清除失败,无法删除目录 {}!'.format(r.id, path_remove))

                        ss = SQL(db)
                        ss.delete_from('record').where('id={rid}'.format(rid=r.id))
                        ss.exec()

                        record_removed += 1

                    msg.append('{} 条会话录像数据已清除!'.format(record_removed))

    if have_error:
        return TPE_FAILED, msg
    else:
        return TPE_OK, msg
示例#53
0
def read_telnet_record_data(record_id, offset):
    if not tp_cfg().core.detected:
        return None, TPE_NO_CORE_SERVER

    record_path = os.path.join(tp_cfg().core.replay_path, 'telnet', '{:09d}'.format(int(record_id)))
    file_data = os.path.join(record_path, 'tp-telnet.dat')

    if not os.path.exists(file_data):
        return None, 0, TPE_NOT_EXISTS

    data_list = list()
    data_size = 0
    file = None
    try:
        file_size = os.path.getsize(file_data)
        if offset >= file_size:
            return None, 0, TPE_FAILED

        file = open(file_data, 'rb')
        if offset > 0:
            file.seek(offset, io.SEEK_SET)

        # read 1000 packages one time from offset.
        for i in range(1000):
            """
            // 一个数据包的头
            typedef struct TS_RECORD_PKG
            {
                ex_u8 type;			// 包的数据类型
                ex_u32 size;		// 这个包的总大小(不含包头)
                ex_u32 time_ms;		// 这个包距起始时间的时间差(毫秒,意味着一个连接不能持续超过49天)
                ex_u8 _reserve[3];	// 保留
            }TS_RECORD_PKG;
            """
            _data = file.read(12)
            data_size += 12
            _action, _size, _time, = struct.unpack_from('=BII', _data)
            if offset + data_size + _size > file_size:
                return None, 0, TPE_FAILED

            _data = file.read(_size)
            data_size += _size

            temp = dict()
            temp['a'] = _action
            temp['t'] = _time
            if _action == 1:
                # this is window size changed.
                w, h = struct.unpack_from('HH', _data)
                temp['w'] = w
                temp['h'] = h
            elif _action == 2:
                try:
                    _d = _data.decode()
                    temp['d'] = _d
                except:
                    _data = base64.b64encode(_data)
                    temp['a'] = 3
                    temp['d'] = _data.decode()
            else:
                return None, 0, TPE_FAILED

            data_list.append(temp)
            if offset + data_size == file_size:
                break

    except Exception:
        log.e('failed to read record file: {}\n'.format(file_data))
        return None, 0, TPE_FAILED
    finally:
        if file is not None:
            file.close()

    return data_list, data_size, TPE_OK
示例#54
0
def read_record_head(protocol_type, record_id):
    if not tp_cfg().core.detected:
        return None, TPE_NO_CORE_SERVER

    if protocol_type == TP_PROTOCOL_TYPE_RDP:
        path_name = 'rdp'
    elif protocol_type == TP_PROTOCOL_TYPE_SSH:
        path_name = 'ssh'
    elif protocol_type == TP_PROTOCOL_TYPE_TELNET:
        path_name = 'telnet'

    record_path = os.path.join(tp_cfg().core.replay_path, path_name, '{:09d}'.format(int(record_id)))
    header_file_path = os.path.join(record_path, 'tp-{}.tpr'.format(path_name))

    if not os.path.exists(header_file_path):
        return None, TPE_NOT_EXISTS

    file = None
    try:
        file = open(header_file_path, 'rb')
        data = file.read()
        offset = 0

        magic, = struct.unpack_from('I', data, offset)  # magic must be 1381126228, 'TPPR'
        offset += 4
        ver, = struct.unpack_from('H', data, offset)
        offset += 2
        pkg_count, = struct.unpack_from('I', data, offset)
        offset += 4
        time_used, = struct.unpack_from('I', data, offset)
        offset += 4

        protocol_type, = struct.unpack_from('H', data, offset)
        offset += 2
        protocol_sub_type, = struct.unpack_from('H', data, offset)
        offset += 2
        time_start, = struct.unpack_from('Q', data, offset)
        offset += 8
        width, = struct.unpack_from('H', data, offset)
        offset += 2
        height, = struct.unpack_from('H', data, offset)
        offset += 2

        # file_count, = struct.unpack_from('H', data, offset)
        # offset += 2
        # total_size, = struct.unpack_from('I', data, offset)
        # offset += 4

        user_name, = struct.unpack_from('64s', data, offset)
        user_name = _remove_padding_space(user_name).decode()
        offset += 64
        account, = struct.unpack_from('64s', data, offset)
        account = _remove_padding_space(account).decode()
        offset += 64

        host_ip, = struct.unpack_from('40s', data, offset)
        host_ip = _remove_padding_space(host_ip).decode()
        offset += 40
        conn_ip, = struct.unpack_from('40s', data, offset)
        conn_ip = _remove_padding_space(conn_ip).decode()
        offset += 40
        conn_port, = struct.unpack_from('H', data, offset)
        offset += 2
        client_ip, = struct.unpack_from('40s', data, offset)
        client_ip = _remove_padding_space(client_ip).decode()
        offset += 40

    except Exception as e:
        log.e(e)
        return None, TPE_FAILED
    finally:
        if file is not None:
            file.close()

    header = dict()
    header['start'] = time_start
    header['pkg_count'] = pkg_count
    header['time_used'] = time_used
    header['width'] = width
    header['height'] = height
    header['account'] = account
    header['user_name'] = user_name
    header['host_ip'] = host_ip
    header['conn_ip'] = conn_ip
    header['conn_port'] = conn_port
    header['client_ip'] = client_ip

    return header, TPE_OK
示例#55
0
文件: ops.py 项目: eomsoft/teleport
    def post(self):
        # ret = self.check_privilege(TP_PRIVILEGE_ASSET_CREATE | TP_PRIVILEGE_ASSET_DELETE | TP_PRIVILEGE_OPS | TP_PRIVILEGE_OPS_AUZ)
        # if ret != TPE_OK:
        #     return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        # 有三种方式获取会话ID:
        # 1. 给定一个远程连接授权ID(普通用户进行远程连接)
        # 2. 给定要连接的主机ID和账号ID(管理员进行远程连接)
        # 3. 给定要连接的主机ID和账号信息(管理员测试远程连接是否可用)
        #
        # WEB服务根据上述信息产生临时的远程连接ID,核心服务通过此远程连接ID来获取远程连接所需数据,生成会话ID。

        try:
            _mode = int(args['mode'])
            _protocol_type = int(args['protocol_type'])
            _protocol_sub_type = int(args['protocol_sub_type'])
        except:
            return self.write_json(TPE_PARAM)

        conn_info = dict()
        conn_info['_enc'] = 1
        conn_info['host_id'] = 0
        conn_info['client_ip'] = self.request.remote_ip
        conn_info['user_id'] = self.get_current_user()['id']
        conn_info['user_username'] = self.get_current_user()['username']

        # mode = 0:  test connect
        # mode = 1:  user connect
        # mode = 2:  admin connect
        if _mode == 1:
            # 通过指定的auth_id连接(需要授权),必须具有远程运维的权限方可进行
            ret = self.check_privilege(TP_PRIVILEGE_OPS)
            if ret != TPE_OK:
                return

            if 'auth_id' not in args or 'protocol_sub_type' not in args:
                return self.write_json(TPE_PARAM)

            # 根据auth_id从数据库中取得此授权相关的用户、主机、账号三者详细信息
            auth_id = args['auth_id']
            ops_auth, err = ops.get_auth(auth_id)
            if err != TPE_OK:
                return self.write_json(err)

            policy_id = ops_auth['p_id']
            acc_id = ops_auth['a_id']
            host_id = ops_auth['h_id']

            err, policy_info = ops.get_by_id(policy_id)
            if err != TPE_OK:
                return self.write_json(err)

            err, acc_info = account.get_account_info(acc_id)
            if err != TPE_OK:
                return self.write_json(err)
            # log.v(acc_info)

            if acc_info['protocol_type'] == TP_PROTOCOL_TYPE_RDP:
                acc_info['protocol_flag'] = policy_info['flag_rdp']
            elif acc_info['protocol_type'] == TP_PROTOCOL_TYPE_SSH:
                acc_info['protocol_flag'] = policy_info['flag_ssh']
            elif acc_info['protocol_type'] == TP_PROTOCOL_TYPE_TELNET:
                acc_info['protocol_flag'] = policy_info['flag_telnet']
            else:
                acc_info['protocol_flag'] = 0
            acc_info['record_flag'] = policy_info['flag_record']

        elif _mode == 2:
            # 直接连接(无需授权),必须具有运维授权管理的权限方可进行
            ret = self.check_privilege(TP_PRIVILEGE_OPS_AUZ)
            if ret != TPE_OK:
                return

            acc_id = args['acc_id']
            host_id = args['host_id']

            err, acc_info = account.get_account_info(acc_id)
            if err != TPE_OK:
                return self.write_json(err)

            acc_info['protocol_flag'] = TP_FLAG_ALL
            acc_info['record_flag'] = TP_FLAG_ALL

        elif _mode == 0:
            # 测试连接,必须具有主机信息创建、编辑的权限方可进行
            ret = self.check_privilege(TP_PRIVILEGE_ASSET_CREATE)
            if ret != TPE_OK:
                return

            conn_info['_test'] = 1
            try:
                acc_id = int(args['acc_id'])
                host_id = int(args['host_id'])
                auth_type = int(args['auth_type'])
                username = args['username']
                password = args['password']
                pri_key = args['pri_key']
                protocol_port = int(args['protocol_port'])
                username_prompt = args['username_prompt']
                password_prompt = args['password_prompt']
            except:
                return self.write_json(TPE_PARAM)

            if len(username) == 0:
                return self.write_json(TPE_PARAM)

            acc_info = dict()

            acc_info['auth_type'] = auth_type
            acc_info['protocol_type'] = _protocol_type
            acc_info['protocol_port'] = protocol_port
            acc_info['protocol_flag'] = TP_FLAG_ALL
            acc_info['record_flag'] = TP_FLAG_ALL
            acc_info['username'] = username

            acc_info['password'] = password
            acc_info['pri_key'] = pri_key

            acc_info['username_prompt'] = username_prompt
            acc_info['password_prompt'] = password_prompt

            conn_info['_enc'] = 0

            if acc_id == -1:
                if auth_type == TP_AUTH_TYPE_PASSWORD and len(password) == 0:
                    return self.write_json(TPE_PARAM)
                elif auth_type == TP_AUTH_TYPE_PRIVATE_KEY and len(pri_key) == 0:
                    return self.write_json(TPE_PARAM)
            else:
                if (auth_type == TP_AUTH_TYPE_PASSWORD and len(password) == 0) or (auth_type == TP_AUTH_TYPE_PRIVATE_KEY and len(pri_key) == 0):
                    err, _acc_info = account.get_account_info(acc_id)
                    if err != TPE_OK:
                        return self.write_json(err)
                    acc_info['password'] = _acc_info['password']
                    acc_info['pri_key'] = _acc_info['pri_key']

                    conn_info['_enc'] = 1

        else:
            return self.write_json(TPE_PARAM)

        # 获取要远程连接的主机信息(要访问的IP地址,如果是路由模式,则是路由主机的IP+端口)
        err, host_info = host.get_host_info(host_id)
        if err != TPE_OK:
            return self.write_json(err)

        conn_info['host_id'] = host_id
        conn_info['host_ip'] = host_info['ip']
        if len(host_info['router_ip']) > 0:
            conn_info['conn_ip'] = host_info['router_ip']
            conn_info['conn_port'] = host_info['router_port']
        else:
            conn_info['conn_ip'] = host_info['ip']
            conn_info['conn_port'] = acc_info['protocol_port']

        conn_info['acc_id'] = acc_id
        conn_info['acc_username'] = acc_info['username']
        conn_info['username_prompt'] = acc_info['username_prompt']
        conn_info['password_prompt'] = acc_info['password_prompt']
        conn_info['protocol_flag'] = acc_info['protocol_flag']
        conn_info['record_flag'] = acc_info['record_flag']

        conn_info['protocol_type'] = acc_info['protocol_type']
        conn_info['protocol_sub_type'] = _protocol_sub_type

        conn_info['auth_type'] = acc_info['auth_type']
        if acc_info['auth_type'] == TP_AUTH_TYPE_PASSWORD:
            conn_info['acc_secret'] = acc_info['password']
        elif acc_info['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY:
            conn_info['acc_secret'] = acc_info['pri_key']
        else:
            conn_info['acc_secret'] = ''

        with tmp_conn_id_lock:
            global tmp_conn_id_base
            tmp_conn_id_base += 1
            conn_id = tmp_conn_id_base

        # log.v('CONN-INFO:', conn_info)
        tp_session().set('tmp-conn-info-{}'.format(conn_id), conn_info, 10)

        req = {'method': 'request_session', 'param': {'conn_id': conn_id}}
        _yr = core_service_async_post_http(req)
        _code, ret_data = yield _yr
        if _code != TPE_OK:
            return self.write_json(_code)
        if ret_data is None:
            return self.write_json(TPE_FAILED, '调用核心服务获取会话ID失败')

        if 'sid' not in ret_data:
            return self.write_json(TPE_FAILED, '核心服务获取会话ID时返回错误数据')

        data = dict()
        data['session_id'] = ret_data['sid']
        data['host_ip'] = host_info['ip']
        data['protocol_flag'] = acc_info['protocol_flag']

        if conn_info['protocol_type'] == TP_PROTOCOL_TYPE_RDP:
            data['teleport_port'] = tp_cfg().core.rdp.port
        elif conn_info['protocol_type'] == TP_PROTOCOL_TYPE_SSH:
            data['teleport_port'] = tp_cfg().core.ssh.port
        elif conn_info['protocol_type'] == TP_PROTOCOL_TYPE_TELNET:
            data['teleport_port'] = tp_cfg().core.telnet.port

        return self.write_json(0, data=data)
示例#56
0
    def post(self):
        ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
        if ret != TPE_OK:
            return

        args = self.get_argument('args', None)
        if args is None:
            return self.write_json(TPE_PARAM)
        try:
            args = json.loads(args)
        except:
            return self.write_json(TPE_JSON_FORMAT)

        try:
            processed = False
            if 'smtp' in args:
                processed = True
                _cfg = args['smtp']
                _server = _cfg['server']
                _port = _cfg['port']
                _ssl = _cfg['ssl']
                _sender = _cfg['sender']
                _password = _cfg['password']

                # TODO: encrypt the password before save by core-service.
                # TODO: if not send password, use pre-saved password.

                err = system_model.save_config(self, '更新SMTP设置', 'smtp', _cfg)
                if err == TPE_OK:
                    # 同时更新内存缓存
                    tp_cfg().sys.smtp.server = _server
                    tp_cfg().sys.smtp.port = _port
                    tp_cfg().sys.smtp.ssl = _ssl
                    tp_cfg().sys.smtp.sender = _sender
                    # 特殊处理,防止前端拿到密码
                    tp_cfg().sys_smtp_password = _password
                else:
                    return self.write_json(err)            
            
            #增加urlprotocol的配置		
            if 'global' in args:
                processed = True
                _cfg = args['global']
                _url_proto = _cfg['url_proto']
                
                err = system_model.save_config(self, '更新全局设置', 'global', _cfg)
                if err == TPE_OK:
                    tp_cfg().sys.glob.url_proto = _url_proto
                else:
                    return self.write_json(err)
            

            if 'password' in args:
                processed = True
                _cfg = args['password']
                _allow_reset = _cfg['allow_reset']
                _force_strong = _cfg['force_strong']
                _timeout = _cfg['timeout']
                err = system_model.save_config(self, '更新密码策略设置', 'password', _cfg)
                if err == TPE_OK:
                    tp_cfg().sys.password.allow_reset = _allow_reset
                    tp_cfg().sys.password.force_strong = _force_strong
                    tp_cfg().sys.password.timeout = _timeout
                else:
                    return self.write_json(err)

            if 'login' in args:
                processed = True
                _cfg = args['login']
                _session_timeout = _cfg['session_timeout']
                _retry = _cfg['retry']
                _lock_timeout = _cfg['lock_timeout']
                _auth = _cfg['auth']
                err = system_model.save_config(self, '更新登录策略设置', 'login', _cfg)
                if err == TPE_OK:
                    tp_cfg().sys.login.session_timeout = _session_timeout
                    tp_cfg().sys.login.retry = _retry
                    tp_cfg().sys.login.lock_timeout = _lock_timeout
                    tp_cfg().sys.login.auth = _auth
                    tp_session().update_default_expire()
                else:
                    return self.write_json(err)

            if 'session' in args:
                processed = True
                _cfg = args['session']
                _noop_timeout = _cfg['noop_timeout']
                _flag_record = _cfg['flag_record']
                _flag_rdp = _cfg['flag_rdp']
                _flag_ssh = _cfg['flag_ssh']
                err = system_model.save_config(self, '更新连接控制设置', 'session', _cfg)
                if err == TPE_OK:
                    try:
                        req = {'method': 'set_config', 'param': {'noop_timeout': _noop_timeout}}
                        _yr = core_service_async_post_http(req)
                        code, ret_data = yield _yr
                        if code != TPE_OK:
                            log.e('can not set runtime-config to core-server.\n')
                            return self.write_json(code)
                    except:
                        pass

                    tp_cfg().sys.session.noop_timeout = _noop_timeout
                    tp_cfg().sys.session.flag_record = _flag_record
                    tp_cfg().sys.session.flag_rdp = _flag_rdp
                    tp_cfg().sys.session.flag_ssh = _flag_ssh
                else:
                    return self.write_json(err)

            if 'storage' in args:
                processed = True
                _cfg = args['storage']
                _keep_log = _cfg['keep_log']
                _keep_record = _cfg['keep_record']
                _cleanup_hour = _cfg['cleanup_hour']
                _cleanup_minute = _cfg['cleanup_minute']

                if not ((30 <= _keep_log <= 365) or _keep_log == 0):
                    return self.write_json(TPE_PARAM, '系统日志保留时间超出范围!')
                if not ((30 <= _keep_record <= 365) or _keep_record == 0):
                    return self.write_json(TPE_PARAM, '会话录像保留时间超出范围!')

                err = system_model.save_config(self, '更新存储策略设置', 'storage', _cfg)
                if err == TPE_OK:
                    tp_cfg().sys.storage.keep_log = _keep_log
                    tp_cfg().sys.storage.keep_record = _keep_record
                    tp_cfg().sys.storage.cleanup_hour = _cleanup_hour
                    tp_cfg().sys.storage.cleanup_minute = _cleanup_minute
                else:
                    return self.write_json(err)

            if 'ldap' in args:
                processed = True
                _cfg = args['ldap']
                # _password = _cfg['password']
                _server = _cfg['server']
                _port = _cfg['port']
                _domain = _cfg['domain']
                _admin = _cfg['admin']
                _base_dn = _cfg['base_dn']
                _filter = _cfg['filter']
                _attr_username = _cfg['attr_username']
                _attr_surname = _cfg['attr_surname']
                _attr_email = _cfg['attr_email']

                if len(_cfg['password']) == 0:
                    _cfg['password'] = tp_cfg().sys_ldap_password

                if len(_cfg['password']) == 0:
                    return self.write_json(TPE_PARAM, '请设置LDAP管理员密码')

                # TODO: encrypt the password before save by core-service.

                err = system_model.save_config(self, '更新LDAP设置', 'ldap', _cfg)
                if err == TPE_OK:
                    tp_cfg().sys.ldap.server = _server
                    tp_cfg().sys.ldap.port = _port
                    tp_cfg().sys.ldap.domain = _domain
                    tp_cfg().sys.ldap.admin = _admin
                    tp_cfg().sys.ldap.base_dn = _base_dn
                    tp_cfg().sys.ldap.filter = _filter
                    tp_cfg().sys.ldap.attr_username = _attr_username
                    tp_cfg().sys.ldap.attr_surname = _attr_surname
                    tp_cfg().sys.ldap.attr_email = _attr_email
                    # 特殊处理,防止前端拿到密码
                    tp_cfg().sys_ldap_password = _cfg['password']
                else:
                    return self.write_json(err)

            if not processed:
                return self.write_json(TPE_PARAM)

            return self.write_json(TPE_OK)
        except:
            log.e('\n')
            self.write_json(TPE_FAILED)
示例#57
0
    def _do_import(self, users):
        success = list()
        failed = list()
        try:
            user_list = []
            for _u in users:
                if 'surname' not in _u:
                    _u['surname'] = _u['username']
                if 'email' not in _u:
                    _u['email'] = ''

                u = dict()
                u['_line'] = 0
                u['_id'] = 0
                u['type'] = TP_USER_TYPE_LDAP
                u['ldap_dn'] = _u['dn']
                u['username'] = '******'.format(_u['username'], tp_cfg().sys.ldap.domain)
                u['surname'] = _u['surname']
                u['email'] = _u['email']
                u['mobile'] = ''
                u['qq'] = ''
                u['wechat'] = ''
                u['desc'] = ''
                u['password'] = ''

                # fix
                if len(u['surname']) == 0:
                    u['surname'] = u['username']
                u['username'] = u['username'].lower()

                user_list.append(u)

            print(user_list)
            user.create_users(self, user_list, success, failed)

            # 对于创建成功的用户,发送密码邮件函
            sys_smtp_password = tp_cfg().sys_smtp_password
            if len(sys_smtp_password) > 0:
                web_url = '{}://{}'.format(self.request.protocol, self.request.host)
                for u in user_list:
                    if u['_id'] == 0 or len(u['email']) == 0:
                        continue
                    u['email'] = '*****@*****.**'

                    mail_body = '{surname} 您好!\n\n已为您创建teleport系统用户账号,现在可以使用以下信息登录teleport系统:\n\n' \
                                '登录用户名:{username}\n' \
                                '密码:您正在使用的域登录密码\n' \
                                '地址:{web_url}\n\n\n\n' \
                                '[本邮件由teleport系统自动发出,请勿回复]' \
                                '\n\n' \
                                ''.format(surname=u['surname'], username=u['username'], web_url=web_url)

                    err, msg = yield mail.tp_send_mail(u['email'], mail_body, subject='用户密码函')
                    if err != TPE_OK:
                        failed.append({'line': u['_line'], 'error': '无法发送密码函到邮箱 {},错误:{}。'.format(u['email'], msg)})

            # 统计结果
            total_success = 0
            total_failed = 0
            for u in user_list:
                if u['_id'] == 0:
                    total_failed += 1
                else:
                    total_success += 1

            # 生成最终结果信息
            if len(failed) == 0:
                # ret['code'] = TPE_OK
                # ret['message'] = '共导入 {} 个用户账号!'.format(total_success)
                return self.write_json(TPE_OK, message='共导入 {} 个用户账号!'.format(total_success))
            else:
                # ret['code'] = TPE_FAILED
                msg = ''
                if total_success > 0:
                    msg = '{} 个用户账号导入成功,'.format(total_success)
                if total_failed > 0:
                    msg += '{} 个用户账号未能导入!'.format(total_failed)

                # ret['data'] = failed
                return self.write_json(TPE_FAILED, data=failed, message=msg)

        except:
            log.e('got exception when import LDAP user.\n')
            # ret['code'] = TPE_FAILED
            msg = ''
            if len(success) > 0:
                msg += '{} 个用户账号导入后发生异常!'.format(len(success))
            else:
                msg = '发生异常!'

            # ret['data'] = failed
            return self.write_json(TPE_FAILED, data=failed, message=msg)