Example #1
0
    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")

        offset, request = conversion.decode_request(0, self.buffer)

        if request is None:
            return False

        self.buffer = self.buffer[offset:]

        assert isinstance(request, conversion.Request)
        self.state = ConnectionState.PROXY_REQUEST_RECEIVED

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

            elif request.cmd == conversion.REQ_CMD_BIND:
                response = conversion.encode_reply(
                    0x05, conversion.REP_SUCCEEDED, 0x00,
                    conversion.ADDRESS_TYPE_IPV4, "127.0.0.1", 1081)

                self.transport.write(response)
                self.state = ConnectionState.PROXY_REQUEST_ACCEPTED

            elif request.cmd == conversion.REQ_CMD_CONNECT:
                self._logger.info(
                    "TCP req to %s:%d support it. Returning HOST UNREACHABLE",
                    *request.destination)

                response = conversion.encode_reply(
                    0x05, conversion.REP_HOST_UNREACHABLE, 0x00,
                    conversion.ADDRESS_TYPE_IPV4, "0.0.0.0", 0)
                self.transport.write(response)

            else:
                self.deny_request(request, "CMD not recognized")

        except:
            response = conversion.encode_reply(
                0x05, conversion.REP_COMMAND_NOT_SUPPORTED, 0x00,
                conversion.ADDRESS_TYPE_IPV4, "0.0.0.0", 0)
            self.transport.write(response)
            self._logger.exception(
                "Exception thrown, returning unsupported command response")

        return True
Example #2
0
    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")

        offset, request = conversion.decode_request(0, self.buffer)

        if request is None:
            return False

        self.buffer = self.buffer[offset:]

        assert isinstance(request, conversion.Request)
        self.state = ConnectionState.PROXY_REQUEST_RECEIVED

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

            elif request.cmd == conversion.REQ_CMD_BIND:
                response = conversion.encode_reply(0x05, conversion.REP_SUCCEEDED, 0x00,
                                                   conversion.ADDRESS_TYPE_IPV4, "127.0.0.1", 1081)

                self.transport.write(response)
                self.state = ConnectionState.PROXY_REQUEST_ACCEPTED

            elif request.cmd == conversion.REQ_CMD_CONNECT:
                self._logger.info("TCP req to %s:%d support it. Returning HOST UNREACHABLE",
                                  *request.destination)

                response = conversion.encode_reply(0x05, conversion.REP_HOST_UNREACHABLE, 0x00,
                                                   conversion.ADDRESS_TYPE_IPV4, "0.0.0.0", 0)
                self.transport.write(response)

            else:
                self.deny_request(request, "CMD not recognized")

        except:
            response = conversion.encode_reply(0x05, conversion.REP_COMMAND_NOT_SUPPORTED, 0x00,
                                               conversion.ADDRESS_TYPE_IPV4, "0.0.0.0", 0)
            self.transport.write(response)
            self._logger.exception("Exception thrown, returning unsupported command response")

        return True
Example #3
0
    def deny_request(self, request, reason):
        """
        Deny SOCKS5 request
        @param Request request: the request to deny
        """
        self.state = ConnectionState.CONNECTED

        response = conversion.encode_reply(0x05, conversion.REP_COMMAND_NOT_SUPPORTED, 0x00,
                                           conversion.ADDRESS_TYPE_IPV4, "0.0.0.0", 0)

        self.transport.write(response)
        self._logger.error("DENYING SOCKS5 request, reason: %s" % reason)
Example #4
0
    def on_udp_associate_request(self, connection, 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_socket = SocksUDPConnection(self, request.destination)
        ip = self.transport.getHost().host
        port = self._udp_socket.get_listen_port()

        self._logger.info("Accepting UDP ASSOCIATE request to %s:%d", ip, port)

        response = conversion.encode_reply(0x05, conversion.REP_SUCCEEDED,
                                           0x00, conversion.ADDRESS_TYPE_IPV4,
                                           ip, port)
        self.transport.write(response)
Example #5
0
    def on_udp_associate_request(self, connection, request):
        if self.selection_strategy.has_options(self.hops):
            # 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_socket = SocksUDPConnection(self, request.destination)
            ip = self.transport.getHost().host
            port = self._udp_socket.get_listen_port()

            self._logger.info("Accepting UDP ASSOCIATE request to %s:%d", ip, port)

            response = conversion.encode_reply(
                0x05, conversion.REP_SUCCEEDED, 0x00, conversion.ADDRESS_TYPE_IPV4, ip, port)
            self.transport.write(response)

        else:
            reason = "not enough circuits"
            self.deny_request(request, reason)
            self.close(reason)