示例#1
0
    def run(self):
        # fix the first login 1 bug
        first_flag = True
        command = list()
        if self.elementid:
            logobj = Log.objects.get(channel=self.elementid)
        else:
            logobj = Log.objects.get(channel=self.message.reply_channel.name)
        while (not self._stop_event.is_set()):
            text = self.queue.get_message()
            if text:
                # deserialize data
                if isinstance(text['data'], (str, basestring, unicode)):
                    try:
                        data = ast.literal_eval(text['data'])
                    except Exception, e:
                        data = text['data']
                else:
                    data = text['data']
                if isinstance(data, (list, tuple)):
                    if data[0] == 'close':
                        logger.debug('close threading')
                        self.chan.close()
                        self.stop()
                    elif data[0] == 'set_size':
                        self.chan.resize_pty(width=data[3], height=data[4])
                        break
                    elif data[0] in ['stdin', 'stdout']:
                        if '\r' not in str(data[1]):
                            command.append(data[1])
                        else:
                            # fix command record duplicate
                            if len(data) >= 3 and data[2] == 'command':
                                CommandLog.objects.create(
                                    log=logobj,
                                    command=data[1].strip('r')[0:255])
                        self.chan.send(data[1])

                elif isinstance(data, (int, long)):
                    if data == 1 and first_flag:
                        first_flag = False
                    else:
                        self.chan.send(str(data))
                else:
                    try:
                        # get user command and block user action in the future
                        if '\r' not in str(data) or '\n' not in str(data):
                            command.append(str(data))
                        else:
                            record_command = CommandDeal().deal_command(
                                ''.join(command))
                            if len(record_command) != 0:
                                logger.debug(
                                    'command input {0}'.format(record_command))
                                command = list()
                        # vi bug need to be fixed
                        self.chan.send(str(data))
                    except socket.error:
                        logger.error('close threading error')
                        self.stop()
示例#2
0
    def run(self):
        #fix the first login 1 bug
        first_flag = True
        command = list()
        while (not self._stop_event.is_set()):
            text = self.queue.get_message()
            if text:
                #deserialize data
                if isinstance(text['data'], (str, basestring, unicode)):
                    try:
                        data = ast.literal_eval(text['data'])
                    except Exception, e:
                        data = text['data']
                else:
                    data = text['data']
                if isinstance(data, (list, tuple)):
                    if data[0] == 'close':
                        print('close threading')
                        self.chan.close()
                        self.stop()
                    elif data[0] == 'set_size':
                        self.chan.resize_pty(width=data[3], height=data[4])
                        break
                    elif data[0] in ['stdin', 'stdout']:
                        self.chan.send(data[1])

                elif isinstance(data, (int, long)):
                    if data == 1 and first_flag:
                        first_flag = False
                    else:
                        self.chan.send(str(data))
                else:
                    try:
                        #get user command and block user action in the future
                        if '\r' not in str(data):
                            command.append(str(data))
                        else:
                            record_command = CommandDeal().deal_command(
                                ''.join(command))
                            if len(record_command) != 0:
                                print('command input', record_command)
                                command = list()
                        #vi bug need to be fixed
                        self.chan.send(str(data))
                    except socket.error:
                        print('close threading error')
                        self.stop()
示例#3
0
def posix_shell(chan, channel, channelid):

    stdout = list()
    begin_time = time.time()
    last_write_time = {'last_activity_time': begin_time}
    command = list()
    logobj = Log.objects.get(log=channelid)
    vim_flag = False
    vim_data = ''

    try:
        directory_date_time = timezone.now()
        log_name = os.path.join(
            '{0}-{1}-{2}'.format(directory_date_time.year,
                                 directory_date_time.month,
                                 directory_date_time.day),
            '{0}'.format(channelid))
        from webterminal.asgi import channel_layer
        # terminate ssh session control
        redis_instance = get_redis_instance()
        redis_sub = redis_instance.pubsub()
        redis_sub.subscribe(logobj.channel)
        while True:

            text = redis_sub.get_message()
            if text:
                try:
                    if isinstance(text['data'], bytes):
                        text['data'] = smart_unicode(text['data'])
                    data = json.loads(text['data'])
                except:
                    data = []
                if len(data) >= 1 and str(data[0]) == 'close':
                    if not channel.closed:
                        channel.close()

            r, w, x = select.select([channel], [], [])
            if channel in r:
                data = channel.recv(1024 * 24)
                if len(data) == 0:
                    if not channel.closed:
                        channel.send('\r\n*** EOF\r\n')
                    break
                if data == "exit\r\n" or data == "logout\r\n" or data == 'logout':
                    channel.close()

                now = time.time()
                delay = now - last_write_time['last_activity_time']
                last_write_time['last_activity_time'] = now

                if vim_flag:
                    vim_data += data

                if '\r' not in smart_unicode(data):
                    command.append(smart_unicode(data))
                else:
                    command_result = CommandDeal().deal_command(
                        ''.join(command))
                    if len(command_result) != 0:
                        # vim command record patch
                        if command_result.strip().startswith(
                                'vi') or command_result.strip().startswith(
                                    'fg'):
                            CommandLog.objects.create(
                                log=logobj, command=command_result[0:255])
                            vim_flag = True
                        else:
                            if vim_flag:
                                if re.compile('\[.*@.*\][\$#]').search(
                                        vim_data):
                                    vim_flag = False
                                    vim_data = ''
                            else:
                                CommandLog.objects.create(
                                    log=logobj, command=command_result[0:255])
                    command = list()

                if isinstance(data, unicode):
                    stdout.append([delay, data])
                else:
                    stdout.append([
                        delay,
                        codecs.getincrementaldecoder('UTF-8')(
                            'replace').decode(data)
                    ])

                channel_layer.send_group(
                    smart_unicode('monitor-{0}'.format(channelid)),
                    {'text': json.dumps(['stdout',
                                         smart_unicode(data)])})
                if not chan.closed:
                    chan.send(data)
            else:
                print('else')
    finally:
        attrs = {
            "version":
            1,
            "width":
            180,
            "height":
            40,
            "duration":
            round(time.time() - begin_time, 6),
            "command":
            os.environ.get('SHELL', None),
            'title':
            None,
            "env": {
                "TERM": os.environ.get('TERM'),
                "SHELL": os.environ.get('SHELL', 'sh')
            },
            'stdout':
            list(map(lambda frame: [round(frame[0], 6), frame[1]], stdout))
        }
        mkdir_p('/'.join(os.path.join(MEDIA_ROOT, log_name).rsplit('/')[0:-1]))
        with open(os.path.join(MEDIA_ROOT, log_name), "a") as f:
            f.write(
                json.dumps(attrs,
                           ensure_ascii=True,
                           cls=CustomeFloatEncoder,
                           indent=2))

        logobj.is_finished = True
        logobj.end_time = timezone.now()
        logobj.save()

        chan.close()
        channel.close()
示例#4
0
def posix_shell(chan,
                channel,
                log_name=None,
                width=90,
                height=40,
                elementid=None):
    from webterminal.asgi import channel_layer
    stdout = list()
    begin_time = time.time()
    last_write_time = {'last_activity_time': begin_time}
    command = list()
    if elementid:
        logobj = Log.objects.get(channel=elementid)
    else:
        logobj = Log.objects.get(channel=channel)
    vim_flag = False
    vim_data = ''
    try:
        chan.settimeout(0.0)
        while True:
            try:
                x = u(chan.recv(1024))
                if len(x) == 0:
                    if elementid:
                        channel_layer.send(
                            channel, {
                                'text':
                                json.dumps([
                                    'disconnect',
                                    smart_unicode('\r\n*** EOF\r\n'),
                                    elementid.rsplit('_')[0]
                                ])
                            })
                    else:
                        channel_layer.send(
                            channel, {
                                'text':
                                json.dumps([
                                    'disconnect',
                                    smart_unicode('\r\n*** EOF\r\n')
                                ])
                            })
                    break
                now = time.time()
                delay = now - last_write_time['last_activity_time']
                last_write_time['last_activity_time'] = now
                if x == "exit\r\n" or x == "logout\r\n" or x == 'logout':
                    chan.close()
                else:
                    if vim_flag:
                        vim_data += x
                    logger.debug('raw data {0}'.format(command))
                    if '\r\n' not in x:
                        command.append(x)
                    else:
                        command = CommandDeal().deal_command(''.join(command))
                        if len(command) != 0:
                            #vim command record patch
                            logger.debug('command {0}'.format(command))
                            if command.strip().startswith(
                                    'vi') or command.strip().startswith('fg'):
                                CommandLog.objects.create(log=logobj,
                                                          command=command)
                                vim_flag = True
                            else:
                                if vim_flag:
                                    if re.compile('\[.*@.*\][\$#]').search(
                                            vim_data):
                                        vim_flag = False
                                        vim_data = ''
                                else:
                                    CommandLog.objects.create(log=logobj,
                                                              command=command)
                        command = list()

                    if isinstance(x, unicode):
                        stdout.append([delay, x])
                    else:
                        stdout.append([
                            delay,
                            codecs.getincrementaldecoder('UTF-8')(
                                'replace').decode(x)
                        ])
                if isinstance(x, unicode):
                    if elementid:
                        channel_layer.send(
                            channel, {
                                'text':
                                json.dumps(
                                    ['stdout', x,
                                     elementid.rsplit('_')[0]])
                            })
                    else:
                        channel_layer.send(channel,
                                           {'text': json.dumps(['stdout', x])})
                else:
                    if elementid:
                        channel_layer.send(
                            channel, {
                                'text':
                                json.dumps([
                                    'stdout',
                                    smart_unicode(x),
                                    elementid.rsplit('_')[0]
                                ])
                            })
                    else:
                        channel_layer.send(
                            channel,
                            {'text': json.dumps(['stdout',
                                                 smart_unicode(x)])})
                #send message to monitor group
                if log_name:
                    channel_layer.send_group(
                        u'monitor-{0}'.format(log_name.rsplit('/')[1]),
                        {'text': json.dumps(['stdout',
                                             smart_unicode(x)])})
            except socket.timeout:
                pass
            except Exception, e:
                logger.error(traceback.print_exc())
                if elementid:
                    channel_layer.send(
                        channel, {
                            'text':
                            json.dumps([
                                'stdout',
                                'A bug find,You can report it to me' +
                                smart_unicode(e),
                                elementid.rsplit('_')[0]
                            ])
                        })
                else:
                    channel_layer.send(
                        channel, {
                            'text':
                            json.dumps([
                                'stdout',
                                'A bug find,You can report it to me' +
                                smart_unicode(e)
                            ])
                        })

    finally:
        attrs = {
            "version":
            1,
            "width":
            width,  #int(subprocess.check_output(['tput', 'cols'])),
            "height":
            height,  #int(subprocess.check_output(['tput', 'lines'])),
            "duration":
            round(time.time() - begin_time, 6),
            "command":
            os.environ.get('SHELL', None),
            'title':
            None,
            "env": {
                "TERM": os.environ.get('TERM'),
                "SHELL": os.environ.get('SHELL', 'sh')
            },
            'stdout':
            list(map(lambda frame: [round(frame[0], 6), frame[1]], stdout))
        }
        mkdir_p('/'.join(os.path.join(MEDIA_ROOT, log_name).rsplit('/')[0:-1]))
        with open(os.path.join(MEDIA_ROOT, log_name), "a") as f:
            f.write(
                json.dumps(attrs,
                           ensure_ascii=True,
                           cls=CustomeFloatEncoder,
                           indent=2))

        if elementid:
            audit_log = Log.objects.get(channel=elementid,
                                        log=log_name.rsplit('/')[-1])
        else:
            audit_log = Log.objects.get(channel=channel,
                                        log=log_name.rsplit('/')[-1])
        audit_log.is_finished = True
        audit_log.end_time = timezone.now()
        audit_log.save()
        #hand ssh terminal exit
        queue = get_redis_instance()
        redis_channel = queue.pubsub()
        queue.publish(channel, json.dumps(['close']))
示例#5
0
    def run(self):
        # fix the first login 1 bug
        first_flag = True
        command = list()
        if self.elementid:
            logobj = Log.objects.get(channel=self.elementid)
        else:
            logobj = Log.objects.get(channel=self.message.reply_channel.name)
        while (not self._stop_event.is_set()):
            text = self.queue.get_message()
            if text:
                # deserialize data
                if isinstance(text['data'], (str, basestring, unicode, bytes)):
                    if isinstance(text['data'], bytes):
                        try:
                            data = ast.literal_eval(
                                text['data'].decode('utf8'))
                        except Exception as e:
                            data = text['data']
                    else:
                        try:
                            data = ast.literal_eval(text['data'])
                        except Exception as e:
                            data = text['data']
                else:
                    data = text['data']
                if isinstance(data, (list, tuple)):
                    if data[0] == 'close' or data[0] == "'close'":
                        logger.debug('close threading')
                        try:
                            self.chan.send('<<<close>>>')  # close flag
                        except OSError:
                            pass
                        time.sleep(3)
                        self.chan.transport.close()
                        self.chan.close()
                        self.stop()
                    elif data[0] == 'set_size':
                        try:
                            self.chan.resize_pty(width=data[3],
                                                 height=data[4],
                                                 width_pixels=data[1],
                                                 height_pixels=data[2])
                        except (TypeError, struct.error,
                                paramiko.SSHException):
                            pass
                    elif data[0] in ['stdin', 'stdout']:
                        if '\r' not in str(data[1]):
                            command.append(data[1])
                        else:
                            # fix command record duplicate
                            if len(data) >= 3 and data[2] == 'command':
                                CommandLog.objects.create(
                                    log=logobj,
                                    command=data[1].strip('r')[0:255])
                        self.chan.send(data[1])

                elif isinstance(data, (int, long)):
                    if data == 1 and first_flag:
                        first_flag = False
                    else:
                        if isinstance(data, bytes):
                            self.chan.send(data)
                        else:
                            self.chan.send(str(data))
                else:
                    try:
                        # get user command and block user action in the future
                        if '\r' not in str(data) or '\n' not in str(data):
                            command.append(str(data))
                        else:
                            record_command = CommandDeal().deal_command(
                                ''.join(command))
                            if len(record_command) != 0:
                                logger.debug(
                                    'command input {0}'.format(record_command))
                                command = list()
                        # vi bug need to be fixed
                        if isinstance(data, bytes):
                            self.chan.send(data)
                        else:
                            self.chan.send(str(data))
                    except socket.error:
                        logger.error('close threading error')
                        self.stop()
            # avoid cpu usage always 100%
            time.sleep(0.001)