Beispiel #1
0
    def response_http(self, status):
        headers = [(
            "Content-Length",
            0,
        )]

        if status[0:3] == "101":
            headers += [(
                "Connection",
                "Upgrade",
            ), (
                "Upgrade",
                "websocket",
            )]
            headers += [("Sec-WebSocket-Accept",
                         wslib.gen_handshake_key(self.__http_ws_key))]
            headers += [("Sec-WebSocket-Protocol", "chat")]
            headers += [
                ("X-Auth-Id",
                 hashlib.sha256(self.__http_auth_id.encode()).hexdigest())
            ]
        s = httputils.build_http1x_resp_header(status, headers)

        self.add_evt_write(self.fileno)
        self.writer.write(s.encode("iso-8859-1"))
Beispiel #2
0
    def recv_handshake(self):
        size = self.reader.size()
        data = self.reader.read()

        p = data.find(b"\r\n\r\n")

        if p < 10 and size > 2048:
            logging.print_general("wrong_http_response_header", self.__server_address)
            self.delete_handler(self.fileno)
            return

        if p < 0:
            self.reader._putvalue(data)
            return
        p += 4

        self.reader._putvalue(data[p:])

        s = data[0:p].decode("iso-8859-1")

        try:
            resp, kv_pairs = httputils.parse_http1x_response_header(s)
        except httputils.Http1xHeaderErr:
            logging.print_general("wrong_http_reponse_header", self.__server_address)
            self.delete_handler(self.fileno)
            return

        version, status = resp

        if status.find("101") != 0:
            logging.print_general("https_handshake_error:%s" % status, self.__server_address)
            self.delete_handler(self.fileno)
            return

        accept_key = self.get_http_kv_pairs("sec-websocket-accept", kv_pairs)
        if wslib.gen_handshake_key(self.__http_handshake_key) != accept_key:
            logging.print_general("https_handshake_error:wrong websocket response key", self.__server_address)
            self.delete_handler(self.fileno)
            return

        auth_id = self.get_http_kv_pairs("x-auth-id", kv_pairs)
        if hashlib.sha256(self.__http_auth_id.encode()).hexdigest() != auth_id:
            logging.print_general("wrong_auth_id", self.__server_address)
            self.delete_handler(self.fileno)
            return

        self.__http_handshake_ok = True
        logging.print_general("http_handshake_ok", self.__server_address)
        # 发送还没有连接的时候堆积的数据包
        if self.__tmp_buf: self.add_evt_write(self.fileno)
        while 1:
            try:
                self.writer.write(self.__tmp_buf.pop(0))
            except IndexError:
                break
            ''''''
        ''''''
Beispiel #3
0
    def __do_handshake(self, byte_data):
        try:
            sts = byte_data.decode("iso-8859-1")
        except UnicodeDecodeError:
            self.response_error()
            return False

        try:
            rs = httputils.parse_htt1x_request_header(sts)
        except:
            self.response_error()
            return False

        req, headers = rs

        dic = {}
        for k, v in headers:
            k = k.lower()
            dic[k] = v

        if "sec-websocket-key" not in dic: return False
        ws_version = dic.get("sec-websocket-version", 0)

        is_err = False
        try:
            ws_version = int(ws_version)
            if ws_version != 13: is_err = True
        except ValueError:
            is_err = True
        if is_err:
            self.response_error()
            return False

        if not self.on_handshake(req, headers):
            self.response_error()
            return False

        sec_ws_key = dic["sec-websocket-key"]
        resp_sec_key = websocket.gen_handshake_key(sec_ws_key)

        resp_headers = [("Upgrade", "websocket"), ("Connection", "Upgrade"),
                        ("Sec-WebSocket-Accept", resp_sec_key)]

        resp_headers += self.__ext_handshake_resp_headers

        resp_sts = httputils.build_http1x_resp_header(
            "101 Switching Protocols", resp_headers, version="1.1")

        self.writer.write(resp_sts.encode("iso-8859-1"))
        self.add_evt_write(self.fileno)

        return True
Beispiel #4
0
    def __do_handshake(self, byte_data):
        try:
            sts = byte_data.decode("iso-8859-1")
        except UnicodeDecodeError:
            self.response_error()
            return False

        try:
            rs = httputils.parse_htt1x_request_header(sts)
        except:
            self.response_error()
            return False

        req, headers = rs

        dic = {}
        for k, v in headers:
            k = k.lower()
            dic[k] = v

        if "sec-websocket-key" not in dic: return False
        ws_version = dic.get("sec-websocket-version", 0)

        is_err = False
        try:
            ws_version = int(ws_version)
            if ws_version != 13: is_err = True
        except ValueError:
            is_err = True
        if is_err:
            self.response_error()
            return False

        if not self.on_handshake(req, headers):
            self.response_error()
            return False

        sec_ws_key = dic["sec-websocket-key"]
        resp_sec_key = websocket.gen_handshake_key(sec_ws_key)

        resp_headers = [("Upgrade", "websocket"), ("Connection", "Upgrade"), ("Sec-WebSocket-Accept", resp_sec_key)]

        resp_headers += self.__ext_handshake_resp_headers

        resp_sts = httputils.build_http1x_resp_header("101 Switching Protocols", resp_headers, version="1.1")

        self.writer.write(resp_sts.encode("iso-8859-1"))
        self.add_evt_write(self.fileno)

        return True
Beispiel #5
0
    def do_handshake(self):
        size = self.reader.size()
        rdata = self.reader.read()
        p = rdata.find(b"\r\n\r\n")

        if p < 5 and size > 2048:
            self.delete_handler(self.fileno)
            return

        s = rdata.decode("iso-8859-1")
        try:
            rq, kv = httputils.parse_htt1x_request_header(s)
        except httputils.Http1xHeaderErr:
            self.delete_handler(self.fileno)
            return

        m, uri, ver = rq

        if ver.lower() != "http/1.1":
            self.delete_handler(self.fileno)
            return

        if m != "GET":
            self.delete_handler(self.fileno)
            return

        upgrade = self.get_kv_value(kv, "upgrade")
        if not upgrade:
            self.send_403_response()
            return
        if upgrade.lower() != "websocket":
            self.send_403_response()
            return

        connection = self.get_kv_value(kv, "connection")
        if not connection:
            self.send_403_response()
            return
        if connection.lower() != "upgrade":
            self.send_403_response()
            return

        sec_ws_key = self.get_kv_value(kv, "sec-websocket-key")
        if not sec_ws_key:
            self.send_403_response()
            return

        origin = self.get_kv_value(kv, "origin")
        if not origin:
            self.send_403_response()
            return
        ws_ver = self.get_kv_value(kv, "sec-websocket-version")

        try:
            v = int(ws_ver)
        except ValueError:
            self.send_403_response()
            return

        if v != 13:
            self.send_403_response()
            return

        sec_ws_proto = self.get_kv_value(kv, "sec-websocket-protocol")
        if not sec_ws_proto:
            self.send_403_response()
            return

        auth_id = self.get_kv_value(kv, "x-auth-id")
        if not auth_id:
            self.send_403_response()
            return

        role = self.get_kv_value(kv, "x-role")
        if not role:
            self.send_403_response()
            return

        self.__role = role.lower()
        if self.__role not in ("cs", "ms",):
            self.send_403_response()
            return

        if self.__role == "ms":
            session_id = self.get_kv_value(kv, "x-session-id")
            if not session_id:
                self.send_403_response()
                return

        resp_headers = [
            ("Content-Length", "0"),
        ]

        resp_headers += [("Connection", "Upgrade",), ("Upgrade", "websocket",)]
        resp_headers += [("Sec-WebSocket-Accept", ws.gen_handshake_key(sec_ws_key))]
        resp_headers += [("Sec-WebSocket-Protocol", "socks2https")]

        logging.print_general("handshake_ok", self.__caddr)

        self.__handshake_ok = True
        self.send_response("101 Switching Protocols", resp_headers)
Beispiel #6
0
    def do_handshake(self):
        size = self.reader.size()
        rdata = self.reader.read()
        p = rdata.find(b"\r\n\r\n")

        if p < 5 and size > 2048:
            self.delete_handler(self.fileno)
            return

        s = rdata.decode("iso-8859-1")
        try:
            rq, kv = httputils.parse_htt1x_request_header(s)
        except httputils.Http1xHeaderErr:
            self.delete_handler(self.fileno)
            return

        m, uri, ver = rq

        if ver.lower() != "http/1.1":
            self.delete_handler(self.fileno)
            return

        if m != "GET":
            self.delete_handler(self.fileno)
            return

        upgrade = self.get_kv_value(kv, "upgrade")
        if not upgrade:
            if self.dispatcher.debug:
                sys.stderr.write("no upgrade field\r\n")
            self.send_403_response()
            return
        if upgrade.lower() != "websocket":
            if self.dispatcher.debug:
                sys.stderr.write("it is not websocket field\r\n")
            self.send_403_response()
            return

        connection = self.get_kv_value(kv, "connection")
        if not connection:
            if self.dispatcher.debug:
                sys.stderr.write("no connection field\r\n")
            self.send_403_response()
            return
        if connection.lower() != "upgrade":
            if self.dispatcher.debug:
                sys.stderr.write("connection is not upgrade\r\n")
            self.send_403_response()
            return

        sec_ws_key = self.get_kv_value(kv, "sec-websocket-key")
        if not sec_ws_key:
            if self.dispatcher.debug:
                sys.stderr.write("no websocket key\r\n")
            self.send_403_response()
            return

        origin = self.get_kv_value(kv, "origin")
        if not origin:
            if self.dispatcher.debug:
                sys.stderr.write("no origin key\r\n")
            self.send_403_response()
            return
        ws_ver = self.get_kv_value(kv, "sec-websocket-version")

        try:
            v = int(ws_ver)
        except ValueError:
            self.send_403_response()
            return

        if v != 13:
            if self.dispatcher.debug:
                sys.stderr.write("wrong websocket version\r\n")
            self.send_403_response()
            return

        sec_ws_proto = self.get_kv_value(kv, "sec-websocket-protocol")
        if not sec_ws_proto:
            if self.dispatcher.debug:
                sys.stderr.write("no sec-websocket-protocol\r\n")
            self.send_403_response()
            return

        auth_id = self.get_kv_value(kv, "x-auth-id")
        if not auth_id:
            if self.dispatcher.debug:
                sys.stderr.write("no auth-id field\r\n")
            self.send_403_response()
            return

        is_msg_tunnel = self.get_kv_value(kv, "x-msg-tunnel")
        if not is_msg_tunnel:
            sys.stderr.write("not found X-Msg-Tunnel value\r\n")
            self.send_403_response()
            return

        if not self.dispatcher.auth_id_exists(auth_id):
            if self.dispatcher.debug:
                sys.stderr.write("not found %s service\r\n" % auth_id)
            self.send_403_response()
            return

        if self.dispatcher.auth_id_exists(auth_id) and not is_msg_tunnel:
            self.send_403_response()
            return

        try:
            v = bool(int(is_msg_tunnel))
        except ValueError:
            sys.stderr.write("wrong X-Msg-Tunnel value type\r\n")
            self.send_403_response()
            return

        self.__is_msg_tunnel = v
        if v:
            s = self.get_kv_value(kv, "x-session-id")
            self.__session_id = base64.b64decode(s.encode())
            if not self.dispatcher.session_get(self.__session_id):
                sys.stderr.write("session id not exists\r\n")
                self.send_403_response()
                return
        else:
            self.dispatcher.reg_fwd_conn(auth_id, self.fileno)

        resp_headers = [
            ("Content-Length", "0"),
        ]

        resp_headers += [(
            "Connection",
            "Upgrade",
        ), (
            "Upgrade",
            "websocket",
        )]
        resp_headers += [("Sec-WebSocket-Accept",
                          ws.gen_handshake_key(sec_ws_key))]
        resp_headers += [("Sec-WebSocket-Protocol", "intranet_pass")]

        logging.print_general("handshake_ok", self.__caddr)

        self.__handshake_ok = True
        self.__auth_id = auth_id
        self.send_response("101 Switching Protocols", resp_headers)
        self.tcp_loop_read_num = 10

        if not v: return

        # 注意这里如果是消息隧道一定要等待握手协议发送完毕再告知连接成功,连接成功会发送堆积在服务器上的数据
        self.dispatcher.tell_listener_conn_ok(self.__session_id, self.fileno)