Example #1
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
Example #2
0
 def sendto(self, data, target_addr):
     try:
         ipaddress.IPv4Address(target_addr[0])
     except ipaddress.AddressValueError:
         target_addr = DomainAddress(*target_addr)
     packet = socks5_serializer.pack_serializable(UdpPacket(0, 0, target_addr, data))
     self.transport.sendto(packet, self.proxy_udp_addr)
Example #3
0
    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')
Example #4
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
Example #5
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
Example #6
0
    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
Example #7
0
    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
Example #8
0
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)