Esempio n. 1
0
    def posix_shell(self):
        """
        Use paramiko channel connect server interactive.
        使用paramiko模块的channel,连接后端,进入交互式
        """
        log_file_f, log_time_f, log = self.get_log()
        termlog = TermLogRecorder(User.objects.get(id=self.user.id))
        termlog.setid(log.id)
        old_tty = termios.tcgetattr(sys.stdin)
        pre_timestamp = time.time()
        data = ''
        input_str = ''
        input_mode = False
        try:
            tty.setraw(sys.stdin.fileno())
            tty.setcbreak(sys.stdin.fileno())
            self.channel.settimeout(0.0)

            while True:
                try:
                    r, w, e = select.select([self.channel, sys.stdin], [], [])
                    flag = fcntl.fcntl(sys.stdin, fcntl.F_GETFL, 0)
                    fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, flag|os.O_NONBLOCK)
                except Exception:
                    pass

                if self.channel in r:
                    try:
                        x = self.channel.recv(10240)
                        if len(x) == 0:
                            break
                        if self.vim_flag:
                            self.vim_data += x
                        index = 0
                        len_x = len(x)
                        while index < len_x:
                            try:
                                n = os.write(sys.stdout.fileno(), x[index:])
                                sys.stdout.flush()
                                index += n
                            except OSError as msg:
                                if msg.errno == errno.EAGAIN:
                                    continue
                        now_timestamp = time.time()
                        termlog.write(x)
                        termlog.recoder = False
                        log_time_f.write('%s %s\n' % (round(now_timestamp-pre_timestamp, 4), len(x)))
                        log_time_f.flush()
                        log_file_f.write(x)
                        log_file_f.flush()
                        pre_timestamp = now_timestamp
                        log_file_f.flush()

                        if input_mode and not self.is_output(x):
                            data += x

                        input_str = ''

                    except socket.timeout:
                        pass

                if sys.stdin in r:
                    try:
                        x = os.read(sys.stdin.fileno(), 4096)
                    except OSError:
                        pass
                    termlog.recoder = True
                    input_mode = True
                    input_str += x
                    if str(x) in ['\r', '\n', '\r\n']:
                        # 这个是用来处理用户的复制操作
                        if input_str != x:
                            data += input_str
                        if self.vim_flag:
                            match = self.vim_end_pattern.findall(self.vim_data)
                            if match:
                                if self.vim_end_flag or len(match) == 2:
                                    self.vim_flag = False
                                    self.vim_end_flag = False
                                else:
                                    self.vim_end_flag = True
                        else:
                            data = self.deal_command(data)[0:200]
                            if len(data) > 0:
                                TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save()
                        data = ''
                        input_str = ''
                        self.vim_data = ''
                        input_mode = False

                    if len(x) == 0:
                        break
                    self.channel.send(x)

        finally:
            termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
            log_file_f.write('End time is %s' % datetime.datetime.now())
            log_file_f.close()
            log_time_f.close()
            termlog.save()
            log.filename = termlog.filename
            log.is_finished = True
            log.end_time = datetime.datetime.now()
            log.save()
Esempio n. 2
0
    def posix_shell(self):
        """
        Use paramiko channel connect server interactive.
        使用paramiko模块的channel,连接后端,进入交互式
        """
        log_file_f, log_time_f, log = self.get_log()
        termlog = TermLogRecorder(User.objects.get(id=self.user.id))
        termlog.setid(log.id)
        old_tty = termios.tcgetattr(sys.stdin)
        pre_timestamp = time.time()
        data = ''
        input_mode = False
        try:
            tty.setraw(sys.stdin.fileno())
            tty.setcbreak(sys.stdin.fileno())
            self.channel.settimeout(0.0)

            while True:
                try:
                    r, w, e = select.select([self.channel, sys.stdin], [], [])
                    flag = fcntl.fcntl(sys.stdin, fcntl.F_GETFL, 0)
                    fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL,
                                flag | os.O_NONBLOCK)
                except Exception:
                    pass

                if self.channel in r:
                    try:
                        x = self.channel.recv(10240)
                        if len(x) == 0:
                            break

                        index = 0
                        len_x = len(x)
                        while index < len_x:
                            try:
                                n = os.write(sys.stdout.fileno(), x[index:])
                                sys.stdout.flush()
                                index += n
                            except OSError as msg:
                                if msg.errno == errno.EAGAIN:
                                    continue
                        now_timestamp = time.time()
                        termlog.write(x)
                        termlog.recoder = False
                        log_time_f.write(
                            '%s %s\n' %
                            (round(now_timestamp - pre_timestamp, 4), len(x)))
                        log_time_f.flush()
                        log_file_f.write(x)
                        log_file_f.flush()
                        pre_timestamp = now_timestamp
                        log_file_f.flush()

                        self.vim_data += x
                        if input_mode:
                            data += x

                    except socket.timeout:
                        pass

                if sys.stdin in r:
                    try:
                        x = os.read(sys.stdin.fileno(), 4096)
                    except OSError:
                        pass
                    termlog.recoder = True
                    input_mode = True
                    if self.is_output(str(x)):
                        # 如果len(str(x)) > 1 说明是复制输入的
                        if len(str(x)) > 1:
                            data = x
                        match = self.vim_end_pattern.findall(self.vim_data)
                        if match:
                            if self.vim_flag or len(match) == 2:
                                self.vim_flag = False
                            else:
                                self.vim_flag = True
                        elif not self.vim_flag:
                            self.vim_flag = False
                            data = self.deal_command(data)[0:200]
                            if data is not None:
                                TtyLog(log=log,
                                       datetime=datetime.datetime.now(),
                                       cmd=data).save()
                        data = ''
                        self.vim_data = ''
                        input_mode = False

                    if len(x) == 0:
                        break
                    self.channel.send(x)

        finally:
            termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
            log_file_f.write('End time is %s' % datetime.datetime.now())
            log_file_f.close()
            log_time_f.close()
            termlog.save()
            log.filename = termlog.filename
            log.is_finished = True
            log.end_time = datetime.datetime.now()
            log.save()
Esempio n. 3
0
        def start_shell():
            global q
            """
            Use paramiko channel connect server interactive.
            使用paramiko模块的channel,连接后端,进入交互式
            """
            log_file_f, log_time_f, log = self.get_log()
            termlog = TermLogRecorder(self.user)
            termlog.setid(log.id)
            old_tty = termios.tcgetattr(sys.stdin)
            pre_timestamp = time.time()
            data = ''
            input_mode = False
            try:
                tty.setraw(sys.stdin.fileno())
                tty.setcbreak(sys.stdin.fileno())
                self.channel.settimeout(0.0)

                cache_line = ""

                RECORD_CMD_FLAG = True
                while True:
                    try:
                        r, w, e = select.select([self.channel, sys.stdin], [],
                                                [])
                        flag = fcntl.fcntl(sys.stdin, fcntl.F_GETFL, 0)
                        fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL,
                                    flag | os.O_NONBLOCK)
                    except Exception:
                        pass

                    if self.channel in r:
                        try:
                            y = self.channel.recv(10240)
                            if len(y) == 0:
                                break

                            index = 0
                            len_y = len(y)
                            f = open(RECORD_PATH, "a+")
                            while index < len_y:
                                try:
                                    n = os.write(sys.stdout.fileno(),
                                                 y[index:])
                                    if self.role == "rd" and RECORD_CMD_FLAG:
                                        f.write(y[index:])
                                    sys.stdout.flush()
                                    index += n
                                except OSError as msg:
                                    if msg.errno == errno.EAGAIN:
                                        continue
                            f.close()
                            now_timestamp = time.time()
                            termlog.write(y)
                            termlog.recoder = False
                            log_time_f.write('%s %s\n' % (round(
                                now_timestamp - pre_timestamp, 4), len(y)))
                            log_time_f.flush()
                            log_file_f.write(y)
                            log_file_f.flush()
                            pre_timestamp = now_timestamp
                            log_file_f.flush()

                            self.vim_data += y
                            if input_mode:
                                data += y

                        except socket.timeout:
                            pass

                    if sys.stdin in r:
                        RECORD_CMD_FLAG = True
                        try:
                            x = os.read(sys.stdin.fileno(), 4096)
                            q.put(x)
                        except OSError:
                            pass
                        termlog.recoder = True
                        input_mode = True
                        if self.is_output(str(x)):
                            # 如果len(str(x)) > 1 说明是复制输入的
                            if len(str(x)) > 1:
                                data = x
                            match = self.vim_end_pattern.findall(self.vim_data)
                            if match:
                                if self.vim_flag or len(match) == 2:
                                    self.vim_flag = False
                                else:
                                    self.vim_flag = True
                            elif not self.vim_flag:
                                self.vim_flag = False
                                data = self.deal_command(data)[0:200]
                                if data is not None:
                                    TtyLog(log=log,
                                           datetime=datetime.datetime.now(),
                                           cmd=data).save()
                            data = ''
                            self.vim_data = ''
                            input_mode = False

                        if len(x) == 0:
                            break

                        if x in ['\x03', '\r\n', '\n', '\x0D']:
                            f = open(RECORD_PATH, "r")
                            lines = f.readlines()
                            cmd = ""
                            if lines:
                                cmd = lines[-1]
                            f.close()
                            f = open(RECORD_PATH, "w")
                            f.close()
                            cmds_str = re.compile('\[?.*@.*\]?[\$#]\s').split(
                                cmd)
                            logger.info("get command from log file is: %s",
                                        cmds_str)
                            if len(cmds_str) == 2:
                                cmds = cmds_str[1]
                                logger.info("command >>>: %s", cmds.split("|"))
                                cmd = set([
                                    i.split()[0].strip()
                                    for i in cmds.split("|") if i.split()
                                ])
                                logger.info("command set>>>: %s", cmd)
                                if self.role == "rd" and not ALLOW_CMD.issuperset(
                                        cmd):
                                    x = '\x03'
                                if "tail" in cmd or "cat" in cmd:
                                    RECORD_CMD_FLAG = False
                            else:
                                RECORD_CMD_FLAG = True
                            cache_line = ""
                        self.channel.send(x)

                        if self.kill_shell:
                            break

            finally:
                termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
                log_file_f.write('End time is %s' % datetime.datetime.now())
                log_file_f.close()
                log_time_f.close()
                termlog.save()
                log.filename = termlog.filename
                log.is_finished = True
                log.end_time = datetime.datetime.now()
                log.save()
                if os.path.isfile(RECORD_PATH):
                    os.remove(RECORD_PATH)
                sys.exit(0)