Пример #1
0
    def _do_socks5_connect_response(self, data):
        # response:
        # +-----+-----+-------+------+----------+----------+
        # | VER | REP | RSV   | ATYP | BND.ADDR | BND.PORT |
        # +-----+-----+-------+------+----------+----------+
        # | 1   | 1   | X'00' | 1    | Variable | 2        |
        # +-----+-----+-------+------+----------+----------+
        #
        if len(data) < 10:
            settings.PROTO_LOG.error(constants.ERROR_MSG_NOT_ENOUGHT_DATA_FOR.format('socks5 method connect response'))
            self.transport.close()
            return False

        version, reply_code, _ = STRUCT_BBB.unpack_from(data)
        if reply_code == constants.SOCKS5_REPLY_SUCCEEDED:
            try:
                addr = Socks5AddrHeader()
                length = addr.from_bytes(data[STRUCT_BBB.size:])
                return True
            except ValueError:
                settings.PROTO_LOG.exception('Fail to parse addr')
                self.transport.close()
                return False
        else:
            # When a reply (REP value other than X'00') indicates a failure, the
            # SOCKS server MUST terminate the TCP connection shortly after sending
            # the reply. Here we close the client too.
            settings.PROTO_LOG.error('error code for connect response:%d', reply_code)
            self.transport.close()
            return False
Пример #2
0
                def conn_completed(future):
                    # socks5 states: In the reply to a CONNECT, BND.PORT contains the port number that
                    # the server assigned to connect to the target host, while BND.ADDR contains the associated IP address.
                    ret, (foward_addr, foward_port) = future.result()
                    if not ret:
                        self._write_error_socks_response_with_reply_code(
                            constants.SOCKS5_REPLY_NETWORK_UNREACHABLE)
                        return False
                    else:
                        # If the reply code (REP value of X'00') indicates a success,
                        # and the request was either a BIND or a CONNECT, the client may now start passing data.
                        self._write_succeed_socks_response_with_addr(
                            Socks5AddrHeader(
                                addr=foward_addr,
                                port=foward_port,
                                addr_type=what_type_of_the_address(
                                    foward_addr),
                            ))

                        if cmd == constants.SOCKS5_CMD_CONNECT:
                            self.state = STAGE_SOCKS5_TCP_RELAY
                        elif cmd == constants.SOCKS5_CMD_UDP_ASSOCIATE:
                            self.state = STAGE_SOCKS5_UDP_ASSOCIATE
                            # close the connection and go to the UDP relay server for data relay
                            self.transport.close()
Пример #3
0
    def _send_socks5_connect_request(self):
        #
        # resquest:
        # +-----+-----+-------+------+----------+----------+
        # | VER | CMD | RSV   | ATYP | DST.ADDR | DST.PORT |
        # +-----+-----+-------+------+----------+----------+
        # | 1   | 1   | X'00' | 1    | Variable | 2        |
        # +-----+-----+-------+------+----------+----------+
        #
        addr = Socks5AddrHeader()
        addr.addr = self.target_host
        addr.port = self.target_port
        addr.addr_type = what_type_of_the_address(self.target_host)

        data = STRUCT_BBB.pack(constants.SOCKS5_VERSION,
                               constants.SOCKS5_CMD_CONNECT,
                               constants.SOCKS5_RESERVED_BYTE,
                               ) + addr.to_bytes()

        self.transport.write(data)
        return True
Пример #4
0
    def _parse_socks_request(self, data):
        """
        return the CMD and address(extract from DST.addr DST.port),
        if ERROR, close the transport and return (False, None, None)
        """

        if len(data) < 10:
            settings.PROTO_LOG.error('no enough data for SOCKS request')
            self.transport.close()
            return False

        version, cmd, _ = STRUCT_BBB.unpack_from(data)
        addr = Socks5AddrHeader()

        try:
            length = addr.from_bytes(data[STRUCT_BBB.size:])
        except ValueError:
            settings.PROTO_LOG.exception('Fail to get addr')
            self._write_error_socks_response_with_reply_code(constants.SOCKS_REPLY_ADDRESS_TYPE_NOT_SUPPORTED)
            return False, None, None
        else:
            return True, cmd, addr