示例#1
0
    def auth(cls,
             user,
             password,
             version=None,
             mm_version=None,
             os_type=None,
             arch=None):
        """
        Process Auth
        :param user:
        :param password:
        :param version:
        :param mm_version: major/minor software version
        :param os_type:
        :param arch:
        :return: (err, msg, client_id)
        """
        try:

            # user = auth_req['Payload'].get('User')
            # pwd = auth_req['Payload'].get('Password')

            # err, msg, result = UserController.login(user, '', pwd)

            # if err != Err.ERR_SUCCESS:
            #     return err, msg, result

            now = time.time()
            client_id = md5(str(now))
            return ERR_SUCCESS, get_err_msg(ERR_SUCCESS), client_id
        except Exception as ex:
            logger.exception("Exception in process auth:", exc_info=ex)
            return ERR_FAILED, get_err_msg(ERR_FAILED), None
示例#2
0
    async def __write_handler(self):
        """
            处理写回调。
            :return:
            """
        if len(self.resp_list) == 0 and self.writing_resp is None:
            return

        try:

            if self.writing_resp is None:
                self.writing_resp = self.resp_list[0]
                self.resp_list = self.resp_list[1:]

            sent_bytes = self.conn.send(self.writing_resp)
            if sent_bytes < len(self.writing_resp):
                self.writing_resp = self.writing_resp[sent_bytes:]
            else:
                self.writing_resp = None
                self.loop.remove_writer(self.fd)
                self.loop.add_reader(self.fd, self.read_handler)

        except ssl.SSLWantReadError as ex:
            logger.debug("SSLWantReadError")
        except Exception as ex:
            logger.exception("Exception in write_handler:", exc_info=ex)
            asyncio.ensure_future(self.process_error(), loop=self.loop)
示例#3
0
    async def __continue_read_handler(self):
        """
        处理read回调。用来处理请求过大没有一次接收完的。
        :return:
        """
        try:
            data = self.conn.recv(DEFAULT_BUF_SIZE)

        except ssl.SSLWantReadError as ex:
            logger.debug("SSLWantReadError")
            return

        if not data:
            self.loop.remove_reader(self.conn.fileno())
            self.conn.close()
        else:
            request_size = tolen(self.binary_data[:8])
            try:
                self.binary_data.extend(data)
            except Exception as ex:
                logger.exception("test:", exc_info=ex)
            if request_size > len(self.binary_data[8:]):
                # 请求没接收全,继续接受
                pass
            elif request_size < len(self.binary_data[8:]):
                # 请求的大小,小于收到的大小,有TCP粘包

                # 获取本次请求
                request_data = self.binary_data[8:8 + request_size]

                logger.debug("receive control request: %s", request_data)

                await self.process_request(request_data)

                # 移除已处理请求的数据
                self.binary_data = self.binary_data[8 + request_size:]

                # 移除继续读的read回调
                self.loop.remove_reader(self.fd)
            else:
                # 请求接受全
                request_data = self.binary_data[8:]
                logger.debug("receive control request: %s", request_data)

                await self.process_request(request_data)

                self.binary_data = None

                # 移除继续读的read回调
                self.loop.remove_reader(self.fd)
示例#4
0
 def reg_proxy(client_id):
     """
     判断这个client_id是否已经登录的client_id
     :param client_id:
     :return:
     """
     try:
         if client_id not in GLOBAL_CACHE.TUNNEL_LIST:
             return ERR_CLIENT_ID_NOT_EXIST, get_err_msg(
                 ERR_CLIENT_ID_NOT_EXIST), None
         else:
             return ERR_SUCCESS, get_err_msg(ERR_SUCCESS), None
     except Exception as ex:
         logger.exception("exception in process reg_proxy:", exc_info=ex)
         return ERR_FAILED, get_err_msg(ERR_FAILED), None
示例#5
0
    async def process_error(self):
        """
        处理错误,关闭客户端连接,移除所有事件监听。比如:解析命令出错等
        :return:
        """
        try:
            self.loop.remove_reader(self.fd)
            self.loop.remove_writer(self.fd)

            # GLOBAL_CACHE.pop_client_id(self.client_id)

            if not self.is_proxy:
                tunnels = GLOBAL_CACHE.pop_tunnel(self.client_id)

                if self.client_id in GLOBAL_CACHE.SEND_REQ_PROXY_LIST:
                    asyncio.ensure_future(GLOBAL_CACHE.SEND_REQ_PROXY_LIST[
                        self.client_id].put('close'),
                                          loop=self.loop)

                if tunnels is not None:
                    for url in tunnels['http']:
                        GLOBAL_CACHE.pop_host(url)

                    for url in tunnels['https']:
                        GLOBAL_CACHE.pop_host(url)

                if self.client_id in GLOBAL_CACHE.SEND_REQ_PROXY_LIST:
                    send_req_proxy_queue = GLOBAL_CACHE.SEND_REQ_PROXY_LIST.pop(
                        self.client_id)
                    await send_req_proxy_queue.put('close')

                if self.client_id in GLOBAL_CACHE.PROXY_URL_ADDR_LIST:
                    queue = GLOBAL_CACHE.PROXY_URL_ADDR_LIST.pop(
                        self.client_id)

                    if queue is not None:
                        queue.put('close')
            else:
                # 检查queue是否存在并尝试通知http连接关闭
                if self.control_http_queue:
                    await self.control_http_queue.put('close')

                GLOBAL_CACHE.del_http_commu_queue_map(
                    self.communicate_identify)

            self.conn.close()
        except Exception as ex:
            logger.exception("Exception in process error:", exc_info=ex)
示例#6
0
    async def process_error(self):
        """
            处理错误,关闭客户端连接,移除所有事件监听。比如:解析命令出错等
            :return:
            """

        self.loop.remove_reader(self.fd)
        self.loop.remove_writer(self.fd)

        # 检查queue是否存在并尝试通知proxy连接关闭
        if self.control_proxy_queue:
            await self.control_proxy_queue.put('close')

        GLOBAL_CACHE.del_http_commu_queue_map(self.communicate_identify)
        try:
            self.conn.close()
        except Exception as ex:
            logger.exception("Exception in process error:", exc_info=ex)
示例#7
0
    async def process_request(self, request_data):
        """
        处理读取到的请求命令
        :param request_data: 读取到的请求数据,会在本函数中转为json格式
        :return:
        """
        try:
            request = json.loads(str(request_data, 'utf-8'))
        except Exception as ex:
            logger.exception("Exception in process_request, load request:",
                             exc_info=ex)
            asyncio.ensure_future(self.process_error(), loop=self.loop)
            return

        req_type = request.get('Type', None)

        if req_type == 'Auth':
            err, msg, resp = self.auth_process(request)
        elif req_type == 'ReqTunnel':
            err, msg, resp = self.req_tunnel_process(request)
        elif req_type == 'RegProxy':
            err, msg, resp = await self.reg_proxy_process(request)
        elif req_type == 'Ping':
            err, msg, resp = self.ping_process()
        else:
            # unknown req type, close this connection
            err, msg, resp = ERR_UNKNOWN_REQUEST, get_err_msg(
                ERR_UNKNOWN_REQUEST), None

        if err in (ERR_UNKNOWN_REQUEST, ERR_CLOSE_SOCKET):
            asyncio.ensure_future(self.process_error(), loop=self.loop)
        elif err == ERR_SUCCESS:
            self.resp_list.append(resp)

            if req_type == 'RegProxy':
                # self.http_start_proxy()
                http_req = await self.get_http_req_from_queue()
                self.resp_list.append(http_req)

            self.loop.remove_reader(self.fd)
            self.loop.add_writer(self.fd, self.write_handler)
示例#8
0
    def req_tunnel_http(req_id,
                        protocol,
                        hostname=None,
                        subdomain=None,
                        http_auth=None):
        """
        process ReqTunnel with http/https tunnel
        :param req_id:
        :param protocol:
        :param hostname:
        :param subdomain:
        :param http_auth:
        :return: (err, msg, url)
        """

        try:
            if hostname is not None and hostname.strip() != '':
                domain_name = hostname
            else:
                if subdomain is None or subdomain.strip() == '':
                    subdomain = get_rand_char(5)
                domain_name = subdomain + '.' + DEFAULT_SERVER_DOMAIN

            if protocol == 'http' and DEFAULT_SERVER_HTTP != 80:
                url = 'http://' + domain_name + ':' + str(DEFAULT_SERVER_HTTP)
            elif protocol == 'https' and DEFAULT_SERVER_HTTP != 443:
                url = 'https://' + domain_name + ':' + str(
                    DEFAULT_SERVER_HTTPS)
            else:
                url = protocol + '://' + domain_name

            return ERR_SUCCESS, get_err_msg(ERR_SUCCESS), url
        except Exception as ex:
            logger.exception("exception in process req_tunnel_http:",
                             exc_info=ex)
            return ERR_FAILED, get_err_msg(ERR_FAILED), None