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

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

        app_cfg().core_server_rpc = param['rpc']

        # 获取core服务的配置信息
        req = {'method': 'get_config', 'param': []}
        _yr = async_post_http(req)
        return_data = yield _yr
        if return_data is None:
            return self.write_json(-1, 'get config from core service failed.')
        if 'code' not in return_data:
            return self.write_json(
                -2, 'get config from core service return invalid data.')
        if return_data['code'] != 0:
            return self.write_json(
                -3, 'get config from core service return code: {}'.format(
                    return_data['code']))

        app_cfg().update_core(return_data['data'])

        return self.write_json(0)
Example #2
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(app_cfg().core.replay_path, 'ssh', '{:06d}'.format(log_id))
                if os.path.exists(record_path):
                    shutil.rmtree(record_path)
                record_path = os.path.join(app_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
Example #3
0
    def get(self):
        if not app_cfg().core.detected:
            total_size = 0
            free_size = 0
        else:
            total_size, free_size = get_free_space_bytes(app_cfg().core.replay_path)

        param = {
            'user_list': user.get_user_list(with_admin=True),
            'total_size': total_size,
            'free_size': free_size,
        }

        self.render('log/index.mako', page_param=json.dumps(param))
Example #4
0
def verify_user(name, password):
    cfg = app_cfg()
    db = get_db()

    sql = 'SELECT `account_id`, `account_type`, `account_name`, `account_pwd`, `account_lock` FROM `{}account` WHERE `account_name`="{}";'.format(db.table_prefix, name)
    db_ret = db.query(sql)
    if db_ret is None:
        # 特别地,如果无法取得数据库连接,有可能是新安装的系统,尚未建立数据库,此时应该处于维护模式
        # 因此可以特别地处理用户验证:用户名admin,密码admin可以登录为管理员
        if cfg.app_mode == APP_MODE_MAINTENANCE:
            if name == 'admin' and password == 'admin':
                return 1, 100, 'admin', 0
        return 0, 0, '', 0

    if len(db_ret) != 1:
        return 0, 0, '', 0

    user_id = db_ret[0][0]
    account_type = db_ret[0][1]
    name = db_ret[0][2]
    locked = db_ret[0][4]
    if locked == 1:
        return 0, 0, '', locked

    if not sec_verify_password(password, db_ret[0][3]):
        # 按新方法验证密码失败,可能是旧版本的密码散列格式,再尝试一下
        if db_ret[0][3] != hashlib.sha256(password.encode()).hexdigest():
            return 0, 0, '', locked
        else:
            # 发现此用户的密码散列格式还是旧的,更新成新的吧!
            _new_sec_password = sec_generate_password(password)
            sql = 'UPDATE `{}account` SET `account_pwd`="{}" WHERE `account_id`={}'.format(db.table_prefix, _new_sec_password, int(user_id))
            db.exec(sql)

    return user_id, account_type, name, locked
Example #5
0
    def post(self):
        code = self.get_session('captcha')
        if code is None:
            return self.write_json(-1, '验证码已失效')

        self.del_session('captcha')

        args = self.get_argument('args', None)
        if args is not None:
            args = json.loads(args)
            captcha = args['captcha']
            username = args['username']
            userpwd = args['userpwd']
            remember = args['remember']
        else:
            return self.write_json(-1, '参数错误')

        if code.lower() != captcha.lower():
            return self.write_json(-1, '验证码错误')

        try:
            user_id, account_type, nickname, locked = user.verify_user(
                username, userpwd)
            if locked == 1:
                return self.write_json(-1, '账号被锁定,请联系管理员!')
            if user_id == 0:
                if app_cfg().app_mode == APP_MODE_MAINTENANCE:
                    return self.write_json(-2, '系统维护中,请稍候再试!')
                else:
                    return self.write_json(-1, '用户名/密码错误!')

            _user = self.get_session('user')
            if _user is None:
                _user = dict()
                _user['id'] = 0
                _user['name'] = 'guest'
                _user['nick_name'] = '访客'
                _user['status'] = 0
                _user['phone_num'] = '110'
                _user['type'] = 0
                _user['permission'] = 0
                _user['is_login'] = False

            _user['id'] = user_id
            _user['is_login'] = True
            _user['name'] = username
            _user['nick_name'] = nickname
            _user['type'] = account_type

            if remember:
                self.set_session('user', _user, 12 * 60 * 60)
            else:
                self.set_session('user', _user)
            return self.write_json(0)

        except:
            log.e('can not set session.')
            return self.write_json(-1, '发生异常,无法登录!')
Example #6
0
def read_record_info(record_id, file_id):
    record_path = os.path.join(app_cfg().core.replay_path, 'ssh',
                               '{:06d}'.format(int(record_id)))
    file_info = os.path.join(record_path, 'tp-ssh.{:03d}'.format(int(file_id)))
    file = None
    try:
        file = open(file_info, 'rb')
        data = file.read()
        total_size = len(data)

        offset = 0
        data_size, = struct.unpack_from('I', data, offset)
        offset += 4

        data_list = list()
        while True:
            action, = struct.unpack_from('B', data, offset)
            offset += 1

            _size, = struct.unpack_from('I', data, offset)
            offset += 4

            _time, = struct.unpack_from('I', data, offset)
            offset += 4

            # skip reserved 3 bytes.
            offset += 3

            _format = '{}s'.format(_size)
            _data, = struct.unpack_from(_format, data, offset)
            offset += _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:
                _data = _data.decode()
                # this is ssh data.
                temp['d'] = _data
            else:
                return None

            data_list.append(temp)
            if offset == total_size:
                break

    except Exception as e:
        log.e('failed to read record file: {}\n'.format(file_info))
        return None
    finally:
        if file is not None:
            file.close()
    return data_list
Example #7
0
    def get(self):
        total_size, free_size = get_free_space_bytes(app_cfg().data_path)

        param = {
            'user_list': user.get_user_list(with_admin=True),
            'total_size': total_size,
            'free_size': free_size,
        }

        self.render('log/index.mako', page_param=json.dumps(param))
Example #8
0
    def get(self, protocol, record_id):

        header = record.read_record_head(record_id)
        if header is None:
            return self.write_json(-3, '操作失败')

        # ret = dict()
        # ret['header'] = header
        # return self.write_json(0, data=ret)

        param = dict()
        param['header'] = header
        param['count'] = 0
        param['op'] = list()

        cmd_type = 0  # 0 = ssh, 1 = sftp
        protocol = int(protocol)
        if protocol == 1:
            pass
        elif protocol == 2:
            record_path = os.path.join(app_cfg().core.replay_path, 'ssh', '{:06d}'.format(int(record_id)))
            file_info = os.path.join(record_path, 'tp-ssh-cmd.txt')
            try:
                file = open(file_info, 'r')
                data = file.readlines()
                for i in range(len(data)):
                    if 0 == i:
                        cmd = data[i][22:-1]
                        if 'SFTP INITIALIZE' == cmd:
                            cmd_type = 1
                            continue
                    if cmd_type == 0:
                        param['op'].append({'t': data[i][1:20], 'c': data[i][22:-1]})
                    else:
                        cmd_info = data[i][22:-1].split(':')
                        if len(cmd_info) != 4:
                            continue
                        param['op'].append({'t': data[i][1:20], 'c': cmd_info[0], 'p1': cmd_info[2], 'p2': cmd_info[3]})
            except:
                pass
            param['count'] = len(param['op'])

        if cmd_type == 0:
            self.render('log/record-ssh-cmd.mako', page_param=json.dumps(param))
        else:
            self.render('log/record-sftp-cmd.mako', page_param=json.dumps(param))
Example #9
0
    def init(self):
        cfg = app_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', 'ts_db.db'))
            if not self._init_sqlite(cfg.database.sqlite_file):
                return False
        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

        # 看看数据库中是否存在指定的数据表(如果不存在,可能是一个空数据库文件),则可能是一个新安装的系统
        # ret = self.query('SELECT COUNT(*) FROM `sqlite_master` WHERE `type`="table" AND `name`="{}account";'.format(self._table_prefix))
        ret = self.is_table_exists('{}group'.format(self._table_prefix))
        if ret is None or not ret:
            log.w('database need create.\n')
            self.need_create = True
            return True

        # 尝试从配置表中读取当前数据库版本号(如果不存在,说明是比较旧的版本了)
        ret = self.query(
            'SELECT `value` FROM `{}config` WHERE `name`="db_ver";'.format(
                self._table_prefix))
        if ret is None or 0 == len(ret):
            self.current_ver = 1
        else:
            self.current_ver = int(ret[0][0])

        if self.current_ver < self.DB_VERSION:
            log.w('database need upgrade.\n')
            self.need_upgrade = True
            return True

        # DO TEST
        # self.alter_table('ts_account', [['account_id', 'id'], ['account_type', 'type']])

        return True
Example #10
0
    def get(self, protocol, record_id):

        param = dict()
        param['count'] = 0
        param['op'] = list()

        protocol = int(protocol)
        if protocol == 1:
            pass
        elif protocol == 2:
            record_path = os.path.join(app_cfg().core.replay_path, 'ssh', '{:06d}'.format(int(record_id)))
            file_info = os.path.join(record_path, 'tp-ssh-cmd.txt')
            try:
                file = open(file_info, 'r')
                data = file.readlines()
                for i in range(len(data)):
                    param['op'].append({'t': data[i][1:20], 'c': data[i][22:-1]})
            except:
                pass
            param['count'] = len(param['op'])

        self.render('log/record-ssh-cmd.mako', page_param=json.dumps(param))
Example #11
0
import time
import csv
import os
import json
import threading
import tornado.gen
import tornado.httpclient

from eom_app.app.configs import app_cfg
from eom_app.app.util import *
from eom_app.module import host
from eom_common.eomcore.logger import *
from eom_app.app.session import web_session
from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseUserAuthJsonHandler, TPBaseAdminAuthJsonHandler

cfg = app_cfg()

# 临时认证ID的基数,每次使用时均递减
tmp_auth_id_base = -1
tmp_auth_id_lock = threading.RLock()


class IndexHandler(TPBaseUserAuthHandler):
    def get(self):
        _user = self.get_session('user')
        if _user is None:
            return self.write(-1)

        param = dict()

        param['core'] = {
Example #12
0
 def initialize(self, path, default_filename=None):
     super().initialize(path, default_filename)
     self.root = app_cfg().core.replay_path
Example #13
0
def read_record_head(record_id):
    record_path = os.path.join(app_cfg().core.replay_path, 'ssh', '{:06d}'.format(int(record_id)))
    header_file_path = os.path.join(record_path, 'tp-ssh.tpr')
    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
        protocol, = struct.unpack_from('H', data, offset)
        offset += 2
        time_start, = struct.unpack_from('Q', data, offset)
        offset += 8
        pkg_count, = struct.unpack_from('I', data, offset)
        offset += 4
        time_used, = struct.unpack_from('I', data, offset)
        offset += 4
        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

        account, = struct.unpack_from('16s', data, offset)
        account = account.decode()
        offset += 16
        user_name, = struct.unpack_from('16s', data, offset)
        user_name = user_name.decode()
        offset += 16
        ip, = struct.unpack_from('18s', data, offset)
        ip = ip.decode()
        offset += 18
        port, = struct.unpack_from('H', data, offset)
        offset += 2

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

    header = dict()
    header['start'] = time_start
    header['file_count'] = file_count
    header['time_used'] = time_used
    header['width'] = width
    header['height'] = height
    header['account'] = account
    header['user_name'] = user_name
    header['ip'] = ip
    header['port'] = port

    return header