コード例 #1
0
ファイル: connection.py プロジェクト: wsxy162/tribler
    def _try_request(self):
        """
        Try to consume a REQUEST message and respond whether we will accept the
        request.

        Will setup a TCP relay or an UDP socket to accommodate TCP RELAY and
        UDP ASSOCIATE requests. After a TCP relay is set up the handler will
        deactivate itself and change the Connection to a TcpRelayConnection.
        Further data will be passed on to that handler.

        :return: False if command could not been processes due to lack of bytes, True otherwise
        """
        self._logger.debug("Client has sent PROXY REQUEST")

        try:
            request, offset = socks5_serializer.unpack_serializable(
                CommandRequest, self.buffer)
        except PackError:
            return False

        self.buffer = self.buffer[offset:]

        self.state = ConnectionState.PROXY_REQUEST_RECEIVED

        try:
            if request.cmd == REQ_CMD_UDP_ASSOCIATE:
                ensure_future(self.on_udp_associate_request(request))

            elif request.cmd == REQ_CMD_BIND:
                payload = CommandResponse(SOCKS_VERSION, REP_SUCCEEDED, 0,
                                          ("127.0.0.1", 1081))
                response = socks5_serializer.pack_serializable(payload)
                self.transport.write(response)
                self.state = ConnectionState.PROXY_REQUEST_ACCEPTED

            elif request.cmd == REQ_CMD_CONNECT:
                self._logger.info("Accepting TCP CONNECT request to %s:%d",
                                  *request.destination)
                self.connect_to = request.destination
                payload = CommandResponse(SOCKS_VERSION, REP_SUCCEEDED, 0,
                                          ("127.0.0.1", 1081))
                response = socks5_serializer.pack_serializable(payload)
                self.transport.write(response)

            else:
                self.deny_request(request, "CMD not recognized")
        except:
            payload = CommandResponse(SOCKS_VERSION, REP_COMMAND_NOT_SUPPORTED,
                                      0, ("0.0.0.0", 0))
            response = socks5_serializer.pack_serializable(payload)
            self.transport.write(response)
            self._logger.exception(
                "Exception thrown, returning unsupported command response")

        return True
コード例 #2
0
ファイル: connection.py プロジェクト: wsxy162/tribler
    def _try_handshake(self):
        """
        Try to read a HANDSHAKE request

        :return: False if command could not been processes due to lack of bytes, True otherwise
        """
        try:
            request, offset = socks5_serializer.unpack_serializable(
                MethodsRequest, self.buffer)
        except PackError:
            # No (complete) HANDSHAKE received, so dont do anything
            return False

        # Consume the buffer
        self.buffer = self.buffer[offset:]

        # Only accept NO AUTH
        if request.version != SOCKS_VERSION or 0x00 not in request.methods:
            self._logger.error("Client has sent INVALID METHOD REQUEST")
            self.buffer = ''
            self.close()
        else:
            self._logger.info("Client has sent METHOD REQUEST")

            # Respond that we would like to use NO AUTHENTICATION (0x00)
            if self.state is not ConnectionState.CONNECTED:
                response = socks5_serializer.pack_serializable(
                    MethodsResponse(SOCKS_VERSION, 0))
                self.transport.write(response)

            # We are connected now, the next incoming message will be a REQUEST
            self.state = ConnectionState.CONNECTED
            return True
コード例 #3
0
    def on_incoming_from_tunnel(self, community, circuit, origin, data):
        """
        We received some data from the tunnel community. Dispatch it to the right UDP SOCKS5 socket.
        """
        if circuit.ctype in [
                CIRCUIT_TYPE_RP_DOWNLOADER, CIRCUIT_TYPE_RP_SEEDER
        ]:
            origin = (community.circuit_id_to_ip(circuit.circuit_id),
                      CIRCUIT_ID_PORT)

        try:
            connection = self.cid_to_con[circuit.circuit_id]
        except KeyError:
            session_hops = circuit.goal_hops if circuit.ctype != CIRCUIT_TYPE_RP_DOWNLOADER else circuit.goal_hops - 1
            if session_hops > len(
                    self.socks_servers) or not self.socks_servers[
                        session_hops - 1].sessions:
                self._logger.error("No connection found for %d hops",
                                   session_hops)
                return False
            connection = next(
                (s for s in self.socks_servers[session_hops - 1].sessions
                 if s.udp_connection and s.udp_connection.remote_udp_address),
                None)

        if connection is None or connection.udp_connection is None:
            self._logger.error(
                "Connection has closed or has not gotten an UDP associate")
            self.connection_dead(connection)
            return False

        packet = socks5_serializer.pack_serializable(
            UdpPacket(0, 0, origin, data))
        connection.udp_connection.send_datagram(packet)
        return True
コード例 #4
0
ファイル: client.py プロジェクト: viniciusjb/tribler
    async def _login(self):
        self.transport, _ = await get_event_loop().create_connection(
            lambda: self, *self.proxy_addr)

        request = MethodsRequest(SOCKS_VERSION, [SOCKS_AUTH_ANON])
        data = await self._send(socks5_serializer.pack_serializable(request))
        response, _ = socks5_serializer.unpack_serializable(
            MethodsResponse, data)

        if response.version != SOCKS_VERSION or response.method != SOCKS_AUTH_ANON:
            raise Socks5Error('Unsupported proxy server')
コード例 #5
0
def test_encode_decode_udp_packet():
    rsv = 0
    frag = 0
    address = DomainAddress('tracker1.good-tracker.com', 8084)
    data = b'0x000'
    encoded = socks5_serializer.pack_serializable(
        UdpPacket(rsv, frag, address, data))
    decoded, _ = socks5_serializer.unpack_serializable(UdpPacket, encoded)

    assert rsv == decoded.rsv
    assert frag == decoded.frag
    assert address == decoded.destination

    address = DomainAddress('tracker1.unicode-tracker\xc4\xe95\x11$\x00', 8084)
    encoded = socks5_serializer.pack_serializable(
        UdpPacket(rsv, frag, address, data))
    decoded, _ = socks5_serializer.unpack_serializable(UdpPacket, encoded)

    assert rsv == decoded.rsv
    assert frag == decoded.frag
    assert address == decoded.destination
コード例 #6
0
ファイル: connection.py プロジェクト: wsxy162/tribler
    def deny_request(self, request, reason):
        """
        Deny SOCKS5 request
        @param Request request: the request to deny
        """
        self.state = ConnectionState.CONNECTED

        payload = CommandResponse(SOCKS_VERSION, REP_COMMAND_NOT_SUPPORTED, 0,
                                  ("0.0.0.0", 0))
        response = socks5_serializer.pack_serializable(payload)
        self.transport.write(response)
        self._logger.error(f"DENYING SOCKS5 request, reason: {reason}")
コード例 #7
0
def test_encode_decode_command_request():
    rsv = 0
    address = DomainAddress('tracker1.good-tracker.com', 8084)
    rep = 0
    version = 5

    encoded = socks5_serializer.pack_serializable(
        CommandRequest(version, rep, rsv, address))
    decoded, _ = socks5_serializer.unpack_serializable(CommandRequest, encoded)

    assert version == decoded.version
    assert rsv == decoded.rsv
    assert address == decoded.destination

    address = DomainAddress('tracker1.unicode-tracker\xc4\xe95\x11$\x00', 8084)
    encoded = socks5_serializer.pack_serializable(
        CommandResponse(version, rep, rsv, address))
    decoded, _ = socks5_serializer.unpack_serializable(CommandResponse,
                                                       encoded)

    assert version == decoded.version
    assert rsv == decoded.rsv
    assert address == decoded.bind
コード例 #8
0
ファイル: connection.py プロジェクト: wsxy162/tribler
    async def on_udp_associate_request(self, request):
        # The DST.ADDR and DST.PORT fields contain the address and port that the client expects
        # to use to send UDP datagrams on for the association.  The server MAY use this information
        # to limit access to the association.
        self.udp_connection = SocksUDPConnection(self, request.destination)
        await self.udp_connection.open()
        ip, _ = self.transport.get_extra_info('sockname')
        port = self.udp_connection.get_listen_port()

        self._logger.info(
            "Accepting UDP ASSOCIATE request to %s:%d (BIND addr %s:%d)", ip,
            port, *request.destination)
        payload = CommandResponse(SOCKS_VERSION, REP_SUCCEEDED, 0, (ip, port))
        response = socks5_serializer.pack_serializable(payload)
        self.transport.write(response)
コード例 #9
0
ファイル: client.py プロジェクト: viniciusjb/tribler
    async def _connect_tcp(self, target_addr):
        try:
            socket.inet_aton(target_addr[0])
        except (ValueError, OSError):
            target_addr = DomainAddress(*target_addr)

        request = CommandRequest(SOCKS_VERSION, REQ_CMD_CONNECT, 0,
                                 target_addr)
        data = await self._send(socks5_serializer.pack_serializable(request))
        response, _ = socks5_serializer.unpack_serializable(
            CommandResponse, data)

        if response.version != SOCKS_VERSION:
            raise Socks5Error('Unsupported proxy server')

        if response.reply > 0:
            raise Socks5Error('TCP connect failed')

        self.connected_to = target_addr
コード例 #10
0
ファイル: client.py プロジェクト: viniciusjb/tribler
    async def _associate_udp(self, local_addr=None):
        local_addr = local_addr or ('127.0.0.1', 0)
        connection = Socks5ClientUDPConnection(self.callback)
        transport, _ = await get_event_loop().create_datagram_endpoint(
            lambda: connection, local_addr=local_addr)
        sock = transport.get_extra_info("socket")

        request = CommandRequest(SOCKS_VERSION, REQ_CMD_UDP_ASSOCIATE, 0,
                                 sock.getsockname())
        data = await self._send(socks5_serializer.pack_serializable(request))
        response, _ = socks5_serializer.unpack_serializable(
            CommandResponse, data)
        connection.proxy_udp_addr = response.bind

        if response.version != SOCKS_VERSION:
            raise Socks5Error('Unsupported proxy server')

        if response.reply > 0:
            raise Socks5Error('UDP associate failed')

        self.connection = connection
コード例 #11
0
ファイル: test_server.py プロジェクト: wsxy162/tribler
async def test_socks5_sendto_success(socks5_server):
    """
    Test if sending/receiving a UDP packet works correctly.
    """
    await socks5_server.start()
    data = b'\x00'
    target = ('127.0.0.1', 123)
    client = Socks5Client(('127.0.0.1', socks5_server.port), Mock())
    await client.associate_udp()

    client.sendto(data, target)
    await sleep(0.1)
    socks5_server.output_stream.on_socks5_udp_data.assert_called_once()
    connection = socks5_server.output_stream.on_socks5_udp_data.call_args[0][0]
    request = socks5_server.output_stream.on_socks5_udp_data.call_args[0][1]
    assert request.data == data
    assert request.destination == target

    packet = socks5_serializer.pack_serializable(UdpPacket(0, 0, target, data))
    client.callback.assert_not_called()
    connection.send_datagram(packet)
    await sleep(0.1)
    client.callback.assert_called_once_with(data, target)
コード例 #12
0
ファイル: client.py プロジェクト: viniciusjb/tribler
 def sendto(self, data, target_addr):
     packet = socks5_serializer.pack_serializable(
         UdpPacket(0, 0, target_addr, data))
     self.transport.sendto(packet, self.proxy_udp_addr)