Exemplo n.º 1
0
    def run(self):
        """
        Listen to invoked script for any bugs to report
        """
        scriptName = self.parsingCommandLineArguments()['userScript']
        p = subprocess.Popen([scriptName],
                             stderr=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             shell=True)

        sel = selectors2.DefaultSelector()
        sel.register(p.stderr, selectors2.EVENT_READ)

        while True:
            for key, _ in sel.select():
                sleep(1.5)
                traceback = key.fileobj.read1().decode()
                if not traceback:
                    exit()
                # Visual / Demo purposes
                print(traceback, end="", file=sys.stderr)

                if str(traceback).find("ModuleNotFoundError:") != -1:
                    raise Exception(f'{scriptName}, module is not found!')
                elif str(traceback).find("No such file or directory") != -1:
                    raise Exception(f'{scriptName} script is not found!')
                # if bug encountered DOES NOT appear in black list data, you CAN send bug to server
                if not self.filterBugReport.blacklist_check(str(traceback)):
                    # send bug to server
                    respondCode = self.server.sendToServer(traceback)
                    if respondCode.status_code != 200:
                        logging.error(
                            "Unable to report bug to server, response code: " +
                            str(respondCode.status_code))
Exemplo n.º 2
0
    def bridge(self):
        # 桥接 客户终端 和 代理服务终端 交互
        transport_keepalive(self.chan_ser.transport)
        sel = selectors.DefaultSelector()  # Linux epol
        sel.register(self.chan_cli, selectors.EVENT_READ)
        sel.register(self.chan_ser, selectors.EVENT_READ)

        while self.chan_ser and self.chan_cli and not (self.chan_ser.closed or
                                                       self.chan_cli.closed):
            events = sel.select(timeout=60)
            # import ipdb; ipdb.set_trace()
            for key, n in events:
                if key.fileobj == self.chan_ser:
                    try:
                        x = self.chan_ser.recv(1024)
                        if len(x) == 0:
                            self.chan_cli.send("\r\n服务端已断开连接....\r\n")
                            return
                        self.chan_cli.send(x)
                    except socket.timeout:
                        pass
                if key.fileobj == self.chan_cli:
                    try:
                        x = self.chan_cli.recv(1024)
                        if len(x) == 0:
                            print("\r\n客户端断开了连接....\r\n")
                            return
                        self.chan_ser.send(x)
                    except socket.timeout:
                        pass
                    except socket.error:
                        break
    def begin(self):
        print "Attempt to listen for incoming on", self.addr, "at port", self.port
        
        while True:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                incoming = (self.addr, self.port)
                sock.bind(incoming)
            except socket.error as e:
                print "Socket listener connection failed", e
                print "Retrying"
            else:
                break
            finally:
                time.sleep(3)

        sock.listen(1)
        (connection, address) = sock.accept()
        sock.shutdown(socket.SHUT_RDWR)
        sock.close() # Close the initial socket.
        print "Listening to new socket on", address[0], "at port", address[1]
        self.sock = connection
        self.sock.setblocking(False)
        events = selectors.EVENT_READ
        self.selector = selectors.DefaultSelector()
        self.selector.register(self.sock, events, data=self)
Exemplo n.º 4
0
 def __init__(self):
     self.sock = self.daemon = self.locationStr = None
     if selectors is None:
         raise RuntimeError("This Python installation doesn't have the 'selectors2' or 'selectors34' module installed, " +
                            "which is required to use Pyro's multiplex server. Install it, or use the threadpool server instead.")
     self.selector = selectors.DefaultSelector()
     self.shutting_down = False
Exemplo n.º 5
0
 def __init__(self, fchan):
     self.fchan = fchan
     self.bchan = None
     self.is_first_input = True
     self.in_input_state = False
     self.ENTER_CHAR = ('\r', '\n', '\r\n')
     self.sel = selectors.DefaultSelector()
Exemplo n.º 6
0
    def __init__(self,
                 config_path=os.path.join(current_dir, os.pardir, "config",
                                          "client.ini")):
        """
        Initializtion
        ```python
        client = Client(config_path)
        ```
        
        Args:
            config_path (string, optional): Path to the file with configuration.  There also should be config specification file at `<config_path>\config\configspec_client.ini`. Defaults to `<current_dir>\os.pardir\config\client.ini`.
        """
        self.selector = selectors.DefaultSelector()
        self.client_socket = None

        self.server_connection = messaging.ConnectionManager()

        self.connected = False
        self.client_id = None

        # Init configs
        self.config = ConfigManager()
        self.config_path = config_path

        global active_client
        active_client = self
Exemplo n.º 7
0
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.logger = logging.getLogger(self.__class__.__name__)
        self.send_queue = queue.Queue()
        self.mysel = selectors.DefaultSelector()
        self.keep_running = True

        signal(SIGINT, self._handle_sigint)
Exemplo n.º 8
0
 def _create_all(self):
     self._selector = selectors.DefaultSelector()
     self._req_queue = queue.Queue()
     self._sync_req_timeout = 12
     self._thread = None
     now = datetime.now()
     self._last_activate_time = now
     self._last_check_req_time = now
     self._r_sock, self._w_sock = make_ctrl_socks()
     self._selector.register(self._r_sock, selectors.EVENT_READ)
 def connect(self, addr, port):
     server_addr = (str(addr), int(port))
     self.addr = server_addr
     print "starting connection to", server_addr
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.setblocking(False)
     sock.connect_ex(server_addr)
     self.sock = sock
     events = selectors.EVENT_READ | selectors.EVENT_WRITE
     self.selector = selectors.DefaultSelector()
     self.selector.register(sock, events, data=self)
Exemplo n.º 10
0
    def bridge(self):
        # 桥接 客户终端 和 代理服务终端 交互
        transport_keepalive(self.chan_ser.transport)
        sel = selectors.DefaultSelector()  # Linux epol
        sel.register(self.chan_cli, selectors.EVENT_READ)
        sel.register(self.chan_ser, selectors.EVENT_READ)

        sshlog = proxys.newlog(self, self.hostid, self.http_user)  # 终端日志
        stdouts = []  # 录像记录
        begin_time = last_activity_time = time.time()

        while self.chan_ser and self.chan_cli and not (self.chan_ser.closed or
                                                       self.chan_cli.closed):
            events = sel.select(timeout=60)
            # import ipdb; ipdb.set_trace()
            for key, n in events:
                if key.fileobj == self.chan_ser:
                    try:
                        x = self.chan_ser.recv(1024)
                        if len(x) == 0:
                            self.chan_cli.send("\r\n服务端已断开连接....\r\n")
                            time.sleep(1)
                            break
                        else:
                            self.chan_cli.send(x)
                            # 记录操作录像
                            now = time.time()
                            delay = round(now - last_activity_time, 6)
                            last_activity_time = now
                            # print[delay, x], 999
                            stdouts.append([delay, x])

                    except socket.timeout:
                        pass
                if key.fileobj == self.chan_cli:
                    try:
                        x = self.chan_cli.recv(1024)
                        if len(x) == 0:
                            print("\r\n客户端断开了连接....\r\n")
                            time.sleep(1)
                            break
                        else:
                            self.chan_ser.send(x)
                    except socket.timeout:
                        pass
                    except socket.error:
                        break
        # self.close()
        # sshlog.save()
        times = round(time.time() - begin_time, 6)  # 录像总时长
        # import ipdb; ipdb.set_trace()
        savelog(sshlog, times, stdouts, stdins=[])
Exemplo n.º 11
0
 def __init__(self):
     self._selector = selectors.DefaultSelector()
     self._is_polling = False
     self._next_conn_id = 1
     self._lock = threading.RLock()
     self._sync_req_timeout = 10
     self._thread = None
     self._use_count = 0
     self._owner_pid = 0
     self._connecting_sock_dict = {}  # sock -> conn_time
     now = datetime.now()
     self._last_activate_time = now
     self._last_check_req_time = now
Exemplo n.º 12
0
    def __init__(self, config_path="config/client.ini"):
        self.selector = selectors.DefaultSelector()
        self.client_socket = None

        self.server_connection = messaging.ConnectionManager()

        self.connected = False
        self.client_id = None

        # Init configs
        self.config = ConfigManager()
        self.config_path = config_path

        global active_client
        active_client = self
Exemplo n.º 13
0
    def __init__(self, server_addr):
        """IoT client with persistent connection
        Each message separated by b'\n'
        """
        sock = socket(AF_INET, SOCK_STREAM)
        sock.connect(server_addr)  # connect to server process
        rfile = sock.makefile('rb')  # file-like obj
        sel = selectors.DefaultSelector()
        sel.register(sock, selectors.EVENT_READ)

        self.sock = sock
        self.rfile = rfile
        self.sel = sel
        self.requests = {}      # messages sent but not yet received their responses
        self.time_to_expire = None
Exemplo n.º 14
0
 def __init__(self):
     self.selector = selectors.DefaultSelector()
     self.server = socket.socket()
     self.server.setblocking(False)
     # 存放文件路径
     self.file_path_dict = {}
     # 存放文件总大小
     self.file_size_dict = {}
     # 存放get文件对象
     self.get_fd_dict = {}
     # 存放put文件对象
     self.put_fd_dict = {}
     # 存放put收到文件大小
     self.put_file_size_dict = {}
     # 存放get发送文件大小
     self.get_file_size_dict = {}
     # 存放用户数据
     self.user_data = {}
Exemplo n.º 15
0
    def __init__(self, config_path="client_config.ini"):
        self.selector = selectors.DefaultSelector()
        self.client_socket = None

        self.server_connection = messaging.ConnectionManager("pi")

        self.server_host = None
        self.server_port = None
        self.broadcast_port = None

        self.connected = False
        self.client_id = None

        # Init configs
        self.config_path = config_path
        self.config = ConfigParser.ConfigParser()
        self.load_config()

        global active_client
        active_client = self
Exemplo n.º 16
0
 def bridge(self):
     # 桥接 客户终端 和 代理服务终端 交互
     # transport_keepalive(self.chan_ser.transport)
     sel = selectors.DefaultSelector()  # Linux epol
     sel.register(self.chan_cli, selectors.EVENT_READ)
     sel.register(self.chan_ser, selectors.EVENT_READ)
     while self.chan_ser and self.chan_cli and not (self.chan_ser.closed or self.chan_cli.closed):
         events = sel.select(timeout=60)
         for key, n in events:
             if key.fileobj == self.chan_ser:
                 try:
                     recv_message = self.chan_ser.recv(1024)
                     if len(recv_message) == 0:
                         self.chan_cli.send("\r\n服务端已断开连接....\r\n")
                         time.sleep(1)
                         break
                     else:
                         try:
                             # 发送数据给查看会话的 websocket 组
                             message = dict()
                             message['status'] = 0
                             message['message'] = recv_message.decode('utf-8')
                             channel_layer = get_channel_layer()
                             async_to_sync(channel_layer.group_send)(self.group, {
                                 "type": "chat.message",
                                 "text": message,
                             })
                         except:
                             pass
                         self.chan_cli.send(recv_message)
                         # 记录操作录像
                         try:
                             """
                             防止 sz rz 传输文件时的报错
                             """
                             delay = round(time.time() - self.start_time, 6)
                             self.res_asciinema.append(json.dumps([delay, 'o', recv_message.decode('utf-8')]))
                             # 250条结果或者指定秒数就保存一次,这个任务可以优化为使用 celery
                             if len(self.res_asciinema) > 250 or int(time.time() - self.last_save_time) > 30:
                                 tmp = list(self.res_asciinema)
                                 self.res_asciinema = []
                                 self.last_save_time = time.time()
                                 with open(settings.TERMINAL_LOGS + '/' + self.res_file, 'a+') as f:
                                     for line in tmp:
                                         f.write('{}\n'.format(line))
                         except BaseException:
                             pass
                 except socket.timeout:
                     pass
             if key.fileobj == self.chan_cli:
                 try:
                     send_message = self.chan_cli.recv(1024)
                     if len(send_message) == 0:
                         print("\r\n客户端断开了连接....\r\n")
                         time.sleep(1)
                         break
                     else:
                         self.chan_ser.send(send_message)
                 except socket.timeout:
                     pass
                 except socket.error:
                     break
Exemplo n.º 17
0
 def make_selector(self):
     s = selectors2.DefaultSelector()
     self.addCleanup(s.close)
     return s
Exemplo n.º 18
0
 def __init__(self, port):
     self.port = port
     self.selector = selectors.DefaultSelector()
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     self.start = False
Exemplo n.º 19
0
class clientListener:

    identDict = {}
    listenerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    mainSelector = selectors.DefaultSelector()

    def __init__(self):
        self.actClient = custClient.pyClient()
        clientListener.listenerSocket.bind((HOST, PORT))
        clientListener.listenerSocket.listen(6)
        clientListener.listenerSocket.setblocking(False)
        clientListener.mainSelector.register(clientListener.listenerSocket,
                                             selectors.EVENT_READ,
                                             data=None)

        while True:
            events = clientListener.mainSelector.select(timeout=None)
            for key, mask in events:
                if not key.data:
                    self.accept(key.fileobj)
                else:
                    if not key.data.handled: self.answer(key, mask)
                    clientListener.mainSelector.unregister(key.fileobj)
                    key.fileobj.close()
                    print("closed")

    def accept(self, sock):
        conn, addr = sock.accept()
        print("verbindung akzeptiert von: ")
        conn.setblocking(False)
        print(addr)
        d = reqData(addr, "")
        events = selectors.EVENT_READ | selectors.EVENT_WRITE
        clientListener.mainSelector.register(conn, events, data=d)

    def answer(self, key, mask):
        sock = key.fileobj
        data = key.data
        if mask & selectors.EVENT_READ:
            piRequest = sock.recv(1024).decode("utf-8")
            if not data.handled:
                data.piReq = piRequest
                data.handled = True
            else:
                clientListener.mainSelector.unregister(sock)
                print("closing socket ...")
                sock.close()

        if mask & selectors.EVENT_WRITE:
            handle = self.actClient.handle(data.piReq)
            if handle:
                answer = handle
                if isinstance(answer, str):
                    msgLen = "{:04d}".format(len(answer))
                    finmsg = str(msgLen) + answer
                    sock.sendall(finmsg.encode("utf-8"))
                else:
                    listLen = len(answer)

                    for msg in answer:
                        listLen = listLen - 1
                        msgLen = "{:04d}".format(
                            int(min(listLen, 1) * 1000 + len(msg)))
                        finmsg = str(msgLen) + msg
                        sock.sendall(finmsg.encode("utf-8"))
Exemplo n.º 20
0
    def bridge(self):
        # 桥接 客户终端 和 代理服务终端 交互
        # transport_keepalive(self.chan_ser.transport)
        sel = selectors.DefaultSelector()  # Linux epol
        sel.register(self.chan_cli, selectors.EVENT_READ)
        sel.register(self.chan_ser, selectors.EVENT_READ)
        try:
            while self.chan_ser and self.chan_cli and not (self.chan_ser.closed or self.chan_cli.closed):
                events = sel.select(timeout=terminal_exipry_time)    # 指定时间无数据输入或者无数据返回则断开连接
                if not events:
                    raise socket.timeout
                for key, n in events:
                    if key.fileobj == self.chan_ser:
                        try:
                            recv_message = self.chan_ser.recv(1024)

                            if self.zmodem:
                                if b'**\x18B0800000000022d\r\x8a' in recv_message:
                                    self.zmodem = False
                                    delay = round(time.time() - self.start_time, 6)
                                    self.res_asciinema.append(json.dumps([delay, 'o', '\r\n']))
                                    # logger.info("zmodem end")
                                self.chan_cli.send(recv_message)
                                continue
                            else:
                                if b'rz\r**\x18B00000000000000\r\x8a' in recv_message or b'rz waiting to receive.**\x18B0100000023be50\r\x8a' in recv_message:
                                    self.zmodem = True
                                    # logger.info("zmodem start")
                                    self.chan_cli.send(recv_message)
                                    continue

                            # logger.info(recv_message)

                            if len(recv_message) == 0:
                                self.chan_cli.send("\r\n\033[31m服务端已断开连接....\033[0m\r\n")
                                time.sleep(1)
                                break
                            else:
                                try:
                                    # 发送数据给查看会话的 websocket 组
                                    message = dict()
                                    message['status'] = 0
                                    message['message'] = recv_message.decode('utf-8')
                                    channel_layer = get_channel_layer()
                                    async_to_sync(channel_layer.group_send)(self.group, {
                                        "type": "chat.message",
                                        "text": message,
                                    })
                                except UnicodeDecodeError:
                                    try:
                                        recv_message += self.chan_ser.recv(1)
                                        message = dict()
                                        message['status'] = 0
                                        message['message'] = recv_message.decode('utf-8')
                                        channel_layer = get_channel_layer()
                                        async_to_sync(channel_layer.group_send)(self.group, {
                                            "type": "chat.message",
                                            "text": message,
                                        })
                                    except UnicodeDecodeError:
                                        try:
                                            recv_message += self.chan_ser.recv(1)
                                            message = dict()
                                            message['status'] = 0
                                            message['message'] = recv_message.decode('utf-8')
                                            channel_layer = get_channel_layer()
                                            async_to_sync(channel_layer.group_send)(self.group, {
                                                "type": "chat.message",
                                                "text": message,
                                            })
                                        except UnicodeDecodeError:
                                            logger.error(traceback.format_exc())
                                            message = dict()
                                            message['status'] = 0
                                            # 拼接2次后还是报错则证明结果是乱码,强制转换
                                            message['message'] = recv_message.decode('utf-8', 'ignore')
                                            channel_layer = get_channel_layer()
                                            async_to_sync(channel_layer.group_send)(self.group, {
                                                "type": "chat.message",
                                                "text": message,
                                            })

                                self.chan_cli.send(recv_message)

                                try:
                                    data = recv_message.decode('utf-8')
                                    if self.tab_mode:
                                        tmp = data.split(' ')
                                        # tab 只返回一个命令时匹配
                                        # print(tmp)
                                        if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '':
                                            self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode()
                                        elif len(tmp) == 1 and tmp[0].encode() != b'\x07':  # \x07 蜂鸣声
                                            self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode()
                                        self.tab_mode = False
                                    if self.history_mode:  # 不完善,只支持向上翻一个历史命令
                                        # print(data)
                                        if data.strip() != '':
                                            self.cmd_tmp = data
                                        self.history_mode = False
                                except Exception:
                                    pass
                                    # logger.error(traceback.format_exc())

                                # 记录操作录像
                                try:
                                    """
                                    防止 sz rz 传输文件时的报错
                                    """
                                    delay = round(time.time() - self.start_time, 6)
                                    self.res_asciinema.append(json.dumps([delay, 'o', recv_message.decode('utf-8')]))

                                    # 250条结果或者指定秒数就保存一次,这个任务可以优化为使用 celery
                                    if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 \
                                            or sys.getsizeof(self.res_asciinema) > 2097152:
                                        tmp = list(self.res_asciinema)
                                        self.res_asciinema = []
                                        self.last_save_time = time.time()
                                        res(self.res_file, tmp)

                                except Exception:
                                    pass
                                    # logger.error(traceback.format_exc())

                        except socket.timeout:
                            logger.error(traceback.format_exc())
                    if key.fileobj == self.chan_cli:
                        try:
                            send_message = self.chan_cli.recv(4096)
                            if len(send_message) == 0:
                                logger.info('客户端断开了连接 {}....'.format(self.client_addr))
                                # time.sleep(1)
                                break
                            else:
                                if not self.lock:
                                    self.chan_ser.send(send_message)
                                    if not self.zmodem:
                                        try:
                                            data = send_message.decode('utf-8')
                                            if data == '\r':  # 记录命令
                                                data = '\n'
                                                if self.cmd_tmp.strip() != '':
                                                    self.cmd_tmp += data
                                                    self.cmd += self.cmd_tmp
                                                    self.cmd_tmp = ''
                                            elif data.encode() == b'\x07':
                                                pass
                                            else:
                                                if data == '\t' or data.encode() == b'\x1b':  # \x1b 点击2下esc键也可以补全
                                                    self.tab_mode = True
                                                elif data.encode() == b'\x1b[A' or data.encode() == b'\x1b[B':
                                                    self.history_mode = True
                                                else:
                                                    self.cmd_tmp += data
                                        except Exception:
                                            pass
                                            # logger.error(traceback.format_exc())
                                else:
                                    # 红色提示文字
                                    self.chan_cli.send("\r\n\033[31m当前会话已被管理员锁定\033[0m\r\n")
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width - 1, self.height, 0, 0
                                    )
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width + 1, self.height, 0, 0
                                    )

                        except socket.timeout:
                            logger.error(traceback.format_exc())
                        except Exception:
                            logger.error(traceback.format_exc())
                            break
        except socket.timeout:
            self.chan_cli.send("\r\n\033[31m由于长时间没有操作或者没有数据返回,连接已断开!\033[0m\r\n")
            logger.info("后端主机 (%s@%s) 会话由于长时间没有操作或者没有数据返回,连接断开!" % (self.ssh_args[2], self.ssh_args[0]))
        except Exception:
            logger.error(traceback.format_exc())
Exemplo n.º 21
0
sheet1.write(0, 1, "RSSI")
sheet1.write(0, 2, "Lattitude")
sheet1.write(0, 3, "Longitude")
sheet1.write(0, 4, "Center Freq.")
sheet1.write(0, 5, "Date-time")
book_index = 0

# Charts are independent of worksheets
chart = book.add_chart({'type': 'line'})
chart.set_y_axis({'name': 'RSSI (dB)'})
chart.set_x_axis({'name': 'Center Frequency (MHz)'})
chart.set_title({'name': 'Frequency versus RSSI Plot'})

###################################################

mysel = selectors.DefaultSelector()
keep_running = True
sep = ' '


def read(connection, mask):
    "Callback for read events"
    global keep_running

    client_address = connection.getpeername()
    print('read({})'.format(client_address))
    data = connection.recv(1024)
    if data:
        # A readable client socket has data
        print('  received {!r}'.format(data))
        #   connection.sendall(data)
Exemplo n.º 22
0
    def bridge(self):
        # 桥接 客户终端 和 代理服务终端 交互
        # transport_keepalive(self.chan_ser.transport)
        sel = selectors.DefaultSelector(
        )  # 根据平台自动选择 IO 模式(kqueue, devpoll, epoll, poll, select)
        sel.register(self.chan_cli, selectors.EVENT_READ)
        sel.register(self.chan_ser, selectors.EVENT_READ)
        try:
            while self.chan_ser and self.chan_cli and not (
                    self.chan_ser.closed or self.chan_cli.closed):
                events = sel.select(
                    timeout=terminal_exipry_time)  # 指定时间无数据输入或者无数据返回则断开连接
                if not events:
                    raise socket.timeout
                for key, n in events:
                    if key.fileobj == self.chan_ser:
                        try:
                            recv_message = self.chan_ser.recv(BufferSize)
                            if self.zmodem:
                                if zmodemszend in recv_message or zmodemrzend in recv_message:
                                    self.zmodem = False
                                    delay = round(
                                        time.time() - self.start_time, 6)
                                    self.res_asciinema.append(
                                        json.dumps([delay, 'o', '\r\n']))
                                    # logger.info("zmodem end")
                                if zmodemcancel in recv_message:
                                    self.zmodem = False
                                    self.chan_ser.send(b'\n')
                                    # logger.info("zmodem cancel")
                                self.chan_cli.send(recv_message)
                                continue
                            else:
                                if zmodemszstart in recv_message or zmodemrzstart in recv_message or \
                                        zmodemrzestart in recv_message or zmodemrzsstart in recv_message or \
                                        zmodemrzesstart in recv_message:
                                    self.zmodem = True
                                    # logger.info("zmodem start")
                                    self.chan_cli.send(recv_message)
                                    continue

                            if len(recv_message) == 0:
                                self.chan_cli.send(
                                    "\r\n\033[31m服务端已断开连接....\033[0m\r\n")
                                time.sleep(1)
                                break
                            else:
                                message = dict()
                                message['status'] = 0
                                try:
                                    # 发送数据给查看会话的 websocket 组
                                    message['message'] = recv_message.decode(
                                        'utf-8')
                                except UnicodeDecodeError:
                                    try:
                                        recv_message += self.chan_ser.recv(1)
                                        message[
                                            'message'] = recv_message.decode(
                                                'utf-8')
                                    except UnicodeDecodeError:
                                        try:
                                            recv_message += self.chan_ser.recv(
                                                1)
                                            message[
                                                'message'] = recv_message.decode(
                                                    'utf-8')
                                        except UnicodeDecodeError:
                                            logger.error(
                                                traceback.format_exc())
                                            # 拼接2次后还是报错则证明结果是乱码,强制转换
                                            message[
                                                'message'] = recv_message.decode(
                                                    'utf-8', 'ignore')

                                self.chan_cli.send(recv_message)

                                channel_layer = get_channel_layer()
                                async_to_sync(channel_layer.group_send)(
                                    self.group, {
                                        "type": "chat.message",
                                        "text": message,
                                    })

                                delay = round(time.time() - self.start_time, 6)
                                self.res_asciinema.append(
                                    json.dumps([
                                        delay, 'o',
                                        recv_message.decode('utf-8')
                                    ]))

                                # 250条结果或者指定秒数就保存一次,这个任务可以优化为使用 celery
                                if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 \
                                        or sys.getsizeof(self.res_asciinema) > 2097152:
                                    tmp = list(self.res_asciinema)
                                    self.res_asciinema = []
                                    self.last_save_time = time.time()
                                    res(self.res_file, tmp)

                                try:
                                    data = recv_message.decode('utf-8')
                                    if self.enter:
                                        self.enter = False
                                        if not data.startswith(
                                                "\r\n"
                                        ):  # 回车后结果不以\r\n开头的肯定不是命令
                                            self.cmd_tmp = ''
                                        else:
                                            if re.match(
                                                    rb'^\r\n\s+\x1b.*$',
                                                    recv_message
                                            ):  # 终端为 xterm,linux 等显示颜色类型时在 vi 编辑模式下回车
                                                self.cmd_tmp = ''
                                            # elif x == b'\r\n':     # todo 正常模式下 vi 文件会返回 \r\n ,终端为 dumb 类型时在 vi 编辑模式下回车也会返回 \r\n,
                                            #     self.cmd_tmp = ''
                                            else:  # 记录真正命令, rl 不支持中文命令
                                                cmd_time = time.strftime(
                                                    "%Y-%m-%d %H:%M:%S",
                                                    time.localtime(
                                                        int(time.time())))
                                                cmd = self.rl.process_line(
                                                    self.cmd_tmp.encode(
                                                        "utf-8"))
                                                if not cmd:  # 有可能 rl 库会返回 None,重试一次
                                                    mp_readline.TESTING = True
                                                    self.rl = mp_readline.MpReadline(
                                                    )
                                                    cmd = self.rl.process_line(
                                                        self.cmd_tmp.encode(
                                                            "utf-8"))

                                                if cmd:
                                                    self.cmd += cmd_time + "\t" + remove_control_chars(
                                                        cmd) + '\n'
                                                else:
                                                    logger.error(
                                                        "recv from server: {} \nerror command: {}"
                                                        .format(
                                                            recv_message,
                                                            self.cmd_tmp.
                                                            encode("utf-8")))
                                                    self.cmd += cmd_time + "\t" + remove_control_chars(
                                                        self.cmd_tmp) + '\n'
                                                self.cmd_tmp = ''
                                    else:
                                        if self.tab_mode:  # todo 兼容有问题
                                            self.tab_mode = False
                                            tmp = data.split(' ')
                                            # tab 只返回一个命令时匹配
                                            # print(tmp)
                                            if len(tmp) == 2 and tmp[
                                                    1] == '' and tmp[0] != '':
                                                self.cmd_tmp = self.cmd_tmp + tmp[
                                                    0].encode().replace(
                                                        b'\x07', b'').decode()
                                            elif len(tmp
                                                     ) == 1 and tmp[0].encode(
                                                     ) != b'\x07':  # \x07 蜂鸣声
                                                self.cmd_tmp = self.cmd_tmp + tmp[
                                                    0].encode().replace(
                                                        b'\x07', b'').decode()

                                        # 多次上下箭头查找历史命令返回数据中可能会包含 \x1b[1P 导致 rl 无法解析命令,具体原因没有深究
                                        if self.history_mode:
                                            self.history_mode = False
                                            if recv_message != b'' and recv_message != b'\x07':
                                                recv_message = re.sub(
                                                    rb'\x1b\[\d+P', b'',
                                                    recv_message)
                                                self.cmd_tmp += recv_message.decode(
                                                    "utf-8")

                                        if self.ctrl_c:  # 取消命令
                                            self.ctrl_c = False
                                            # if x == b'^C\r\n':
                                            if re.match(
                                                    rb'^\^C\r\n[\s\S]*$',
                                                    recv_message) or re.match(
                                                        rb'^\r\n[\s\S]*$',
                                                        recv_message):
                                                self.cmd_tmp = ""
                                        if self.ctrl_z:
                                            self.ctrl_z = False
                                            if re.match(
                                                    rb'^[\s\S]*\[\d+\]\+\s+Stopped\s+\S+[\s\S]*$',
                                                    recv_message):
                                                self.cmd_tmp = ""
                                except Exception:
                                    logger.error(traceback.format_exc())
                        except socket.timeout:
                            logger.error(traceback.format_exc())
                    if key.fileobj == self.chan_cli:
                        try:
                            send_message = self.chan_cli.recv(BufferSize)
                            if len(send_message) == 0:
                                logger.info('客户端断开了连接 {}....'.format(
                                    self.client_addr))
                                # time.sleep(1)
                                break
                            else:
                                if not self.lock:
                                    self.chan_ser.send(send_message)
                                    if not self.zmodem:
                                        try:
                                            data = send_message.decode('utf-8')
                                            if data == '\r':  # 回车,开始根据服务端返回判断是否是命令,这种判断方式的特性就导致了无法是否禁止命令功能,当然想绝对禁止命令本身就是一个伪命题
                                                if self.cmd_tmp.strip() != '':
                                                    self.enter = True
                                            elif data.encode(
                                            ) == b'\x07':  # 响铃
                                                pass
                                            elif data == '\t' or data.encode(
                                            ) == b'\x1b':  # \x1b 点击2下esc键也可以补全
                                                self.tab_mode = True
                                            elif data.encode(
                                            ) == b'\x1b[A' or data.encode(
                                            ) == b'\x1b[B':
                                                self.history_mode = True
                                            elif data.encode(
                                            ) == b'\x03':  # 输入命令后先 ctrl + v,然后 ctrl + c 需要两次才能取消
                                                self.ctrl_c = True
                                            elif data.encode(
                                            ) == b'\x1a':  # ctrl + z
                                                self.ctrl_z = True
                                            else:
                                                self.cmd_tmp += data
                                        except Exception:
                                            logger.error(
                                                traceback.format_exc())
                                else:
                                    # 红色提示文字
                                    self.chan_cli.send(
                                        "\r\n\033[31m当前会话已被管理员锁定\033[0m\r\n")
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width - 1,
                                        self.height, 0, 0)
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width + 1,
                                        self.height, 0, 0)

                        except socket.timeout:
                            logger.error(traceback.format_exc())
                        except Exception:
                            logger.error(traceback.format_exc())
                            break
        except socket.timeout:
            self.chan_cli.send(
                "\r\n\033[31m由于长时间没有操作或者没有数据返回,连接已断开!\033[0m\r\n")
            logger.info("后端主机 (%s@%s) 会话由于长时间没有操作或者没有数据返回,连接断开!" %
                        (self.ssh_args[2], self.ssh_args[0]))
        except Exception:
            logger.error(traceback.format_exc())
Exemplo n.º 23
0
 def __init__(self, config):
     self.config = config
     self.selector = selectors.DefaultSelector()
Exemplo n.º 24
0
 def __init__(self):
     self.daemon = self.sock = self._socketaddr = self.locationStr = self.pool = None
     self.shutting_down = False
     self.housekeeper = None
     self._selector = selectors.DefaultSelector()
Exemplo n.º 25
0
    def bridge(self):
        # 桥接 客户终端 和 代理服务终端 交互
        # transport_keepalive(self.chan_ser.transport)
        sel = selectors.DefaultSelector()  # Linux epol
        sel.register(self.chan_cli, selectors.EVENT_READ)
        sel.register(self.chan_ser, selectors.EVENT_READ)
        try:
            while self.chan_ser and self.chan_cli and not (
                    self.chan_ser.closed or self.chan_cli.closed):
                events = sel.select(
                    timeout=terminal_exipry_time)  # 指定时间无数据输入或者无数据返回则断开连接
                if not events:
                    raise socket.timeout
                for key, n in events:
                    if key.fileobj == self.chan_ser:
                        try:
                            recv_message = self.chan_ser.recv(1024)
                            if len(recv_message) == 0:
                                self.chan_cli.send(
                                    "\r\n\033[31m服务端已断开连接....\033[0m\r\n")
                                time.sleep(1)
                                break
                            else:
                                try:
                                    # 发送数据给查看会话的 websocket 组
                                    message = dict()
                                    message['status'] = 0
                                    message['message'] = recv_message.decode(
                                        'utf-8')
                                    channel_layer = get_channel_layer()
                                    async_to_sync(channel_layer.group_send)(
                                        self.group, {
                                            "type": "chat.message",
                                            "text": message,
                                        })
                                except Exception:
                                    logger.error(traceback.format_exc())
                                self.chan_cli.send(recv_message)

                                try:
                                    data = recv_message.decode('utf-8')
                                    if self.tab_mode:
                                        tmp = data.split(' ')
                                        # tab 只返回一个命令时匹配
                                        # print(tmp)
                                        if len(tmp) == 2 and tmp[
                                                1] == '' and tmp[0] != '':
                                            self.cmd_tmp = self.cmd_tmp + tmp[
                                                0].encode().replace(
                                                    b'\x07', b'').decode()
                                        elif len(tmp) == 1 and tmp[0].encode(
                                        ) != b'\x07':  # \x07 蜂鸣声
                                            self.cmd_tmp = self.cmd_tmp + tmp[
                                                0].encode().replace(
                                                    b'\x07', b'').decode()
                                        self.tab_mode = False
                                    if self.history_mode:  # 不完善,只支持向上翻一个历史命令
                                        # print(data)
                                        if data.strip() != '':
                                            self.cmd_tmp = data
                                        self.history_mode = False
                                except Exception:
                                    pass
                                    # logger.error(traceback.format_exc())

                                # 记录操作录像
                                try:
                                    """
                                    防止 sz rz 传输文件时的报错
                                    """
                                    delay = round(
                                        time.time() - self.start_time, 6)
                                    self.res_asciinema.append(
                                        json.dumps([
                                            delay, 'o',
                                            recv_message.decode('utf-8')
                                        ]))

                                    # 250条结果或者指定秒数就保存一次,这个任务可以优化为使用 celery
                                    if len(self.res_asciinema) > 250 or int(
                                            time.time() -
                                            self.last_save_time) > 30:
                                        tmp = list(self.res_asciinema)
                                        self.res_asciinema = []
                                        self.last_save_time = time.time()
                                        if platform.system().lower(
                                        ) == 'linux':
                                            celery_save_res_asciinema.delay(
                                                settings.MEDIA_ROOT + '/' +
                                                self.res_file, tmp)
                                        else:
                                            with open(
                                                    settings.MEDIA_ROOT + '/' +
                                                    self.res_file, 'a+') as f:
                                                for line in tmp:
                                                    f.write(
                                                        '{}\n'.format(line))

                                except Exception:
                                    pass
                                    # logger.error(traceback.format_exc())

                        except socket.timeout:
                            logger.error(traceback.format_exc())
                    if key.fileobj == self.chan_cli:
                        try:
                            send_message = self.chan_cli.recv(1024)
                            if len(send_message) == 0:
                                logger.info('客户端断开了连接 {}....'.format(
                                    self.client_addr))
                                # time.sleep(1)
                                break
                            else:
                                if not self.lock:
                                    self.chan_ser.send(send_message)
                                    try:
                                        data = send_message.decode('utf-8')
                                        if data == '\r':  # 记录命令
                                            data = '\n'
                                            if self.cmd_tmp.strip() != '':
                                                self.cmd_tmp += data
                                                self.cmd += self.cmd_tmp

                                                # print('-----------------------------------')
                                                # print(self.cmd_tmp)
                                                # print(self.cmd_tmp.encode())
                                                # print('-----------------------------------')

                                                self.cmd_tmp = ''
                                        elif data.encode() == b'\x07':
                                            pass
                                        else:
                                            if data == '\t' or data.encode(
                                            ) == b'\x1b':  # \x1b 点击2下esc键也可以补全
                                                self.tab_mode = True
                                            elif data.encode(
                                            ) == b'\x1b[A' or data.encode(
                                            ) == b'\x1b[B':
                                                self.history_mode = True
                                            else:
                                                self.cmd_tmp += data
                                    except Exception:
                                        logger.error(traceback.format_exc())
                                else:
                                    # 红色提示文字
                                    self.chan_cli.send(
                                        "\r\n\033[31m当前会话已被管理员锁定\033[0m\r\n")
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width - 1,
                                        self.height, 0, 0)
                                    self.check_channel_window_change_request(
                                        self.chan_cli, self.width + 1,
                                        self.height, 0, 0)

                        except socket.timeout:
                            logger.error(traceback.format_exc())
                        except Exception:
                            logger.error(traceback.format_exc())
                            break
        except socket.timeout:
            self.chan_cli.send(
                "\r\n\033[31m由于长时间没有操作或者没有数据返回,连接已断开!\033[0m\r\n")
            logger.info("后端主机 (%s@%s) 会话由于长时间没有操作或者没有数据返回,连接断开!" %
                        (self.ssh_args[2], self.ssh_args[0]))
        except Exception:
            logger.error(traceback.format_exc())