コード例 #1
0
ファイル: controller.py プロジェクト: felipedau/txtorcon
    def web_agent(self, pool=None, socks_endpoint=None):
        """
        :param socks_endpoint: If ``None`` (the default), a suitable
            SOCKS port is chosen from our config (or added). If supplied,
            should be a Deferred which fires an IStreamClientEndpoint
            (e.g. the return-value from
            :meth:`txtorcon.TorConfig.socks_endpoint`) or an immediate
            IStreamClientEndpoint You probably don't need to mess with
            this.

        :param pool: passed on to the Agent (as ``pool=``)
        """
        # local import since not all platforms have this
        from txtorcon import web

        if socks_endpoint is None:
            socks_endpoint = _create_socks_endpoint(self._reactor, self._protocol)
        if not isinstance(socks_endpoint, Deferred):
            if not IStreamClientEndpoint.providedBy(socks_endpoint):
                raise ValueError(
                    "'socks_endpoint' should be a Deferred or an IStreamClient"
                    "Endpoint (got '{}')".format(type(socks_endpoint))
                )
        return web.tor_agent(
            self._reactor,
            socks_endpoint,
            pool=pool,
        )
コード例 #2
0
ファイル: controller.py プロジェクト: vince06fr/txtorcon
    def web_agent(self, pool=None, socks_endpoint=None):
        """
        :param socks_endpoint: If ``None`` (the default), a suitable
            SOCKS port is chosen from our config (or added). If supplied,
            should be a Deferred which fires an IStreamClientEndpoint
            (e.g. the return-value from
            :meth:`txtorcon.TorConfig.socks_endpoint`) or an immediate
            IStreamClientEndpoint You probably don't need to mess with
            this.

        :param pool: passed on to the Agent (as ``pool=``)
        """
        # local import since not all platforms have this
        from txtorcon import web

        if socks_endpoint is None:
            socks_endpoint = _create_socks_endpoint(self._reactor,
                                                    self._protocol)
        if not isinstance(socks_endpoint, Deferred):
            if not IStreamClientEndpoint.providedBy(socks_endpoint):
                raise ValueError(
                    "'socks_endpoint' should be a Deferred or an IStreamClient"
                    "Endpoint (got '{}')".format(type(socks_endpoint)))
        return web.tor_agent(
            self._reactor,
            socks_endpoint,
            pool=pool,
        )
コード例 #3
0
    def _get_agent(self, request, timeout):
        bind_address = request.meta.get('bindaddress') or self._bindAddress
        proxy = os.environ.get("SOCKS_PROXY", request.meta.get('proxy'))
        _proxy_protocol, _proxy_hostport, proxy_host, proxy_port, _proxy_params = _parse(
            proxy)

        proxy_endpoint = TCP4ClientEndpoint(reactor,
                                            proxy_host,
                                            proxy_port,
                                            timeout=timeout,
                                            bindAddress=bind_address)
        agent = txtorcon_web.tor_agent(reactor, socks_endpoint=proxy_endpoint)

        return agent
コード例 #4
0
ファイル: circuit.py プロジェクト: jiivan/txtorcon
    def web_agent(self, reactor, socks_endpoint, pool=None):
        """
        :param socks_endpoint: create one with
            :meth:`txtorcon.TorConfig.create_socks_endpoint`. Can be a
            Deferred.

        :param pool: passed on to the Agent (as ``pool=``)
        """
        # local import because there isn't Agent stuff on some
        # platforms we support, so this will only error if you try
        # this on the wrong platform (pypy [??] and old-twisted)
        from txtorcon import web
        return web.tor_agent(
            reactor,
            socks_endpoint,
            circuit=self,
            pool=pool,
        )
コード例 #5
0
ファイル: circuit.py プロジェクト: felipedau/txtorcon
    def web_agent(self, reactor, socks_endpoint, pool=None):
        """
        :param socks_endpoint: create one with
            :meth:`txtorcon.TorConfig.create_socks_endpoint`. Can be a
            Deferred.

        :param pool: passed on to the Agent (as ``pool=``)
        """
        # local import because there isn't Agent stuff on some
        # platforms we support, so this will only error if you try
        # this on the wrong platform (pypy [??] and old-twisted)
        from txtorcon import web
        return web.tor_agent(
            reactor,
            socks_endpoint,
            circuit=self,
            pool=pool,
        )
コード例 #6
0
ファイル: test_web.py プロジェクト: felipedau/txtorcon
    def test_agent_with_circuit(self):
        reactor = Mock()
        circuit = Mock()
        socks_ep = Mock()
        proto = Mock()
        gold = object()
        proto.request = Mock(return_value=defer.succeed(gold))

        def getConnection(key, endpoint):
            self.assertTrue(isinstance(endpoint, TorCircuitEndpoint))
            target = endpoint._target_endpoint
            self.assertTrue(target._tls)
            self.assertEqual(target._host, u'meejah.ca')
            self.assertEqual(target._port, 443)
            return defer.succeed(proto)
        pool = Mock()
        pool.getConnection = getConnection

        agent = yield tor_agent(reactor, socks_ep, circuit=circuit, pool=pool)

        # apart from the getConnection asserts...
        res = yield agent.request(b'GET', b'https://meejah.ca')
        self.assertIs(res, gold)
コード例 #7
0
    def test_agent_with_circuit(self):
        reactor = Mock()
        circuit = Mock()
        socks_ep = Mock()
        proto = Mock()
        gold = object()
        proto.request = Mock(return_value=defer.succeed(gold))

        def getConnection(key, endpoint):
            self.assertTrue(isinstance(endpoint, TorCircuitEndpoint))
            target = endpoint._target_endpoint
            self.assertTrue(target._tls)
            self.assertEqual(target._host, u'meejah.ca')
            self.assertEqual(target._port, 443)
            return defer.succeed(proto)

        pool = Mock()
        pool.getConnection = getConnection

        agent = yield tor_agent(reactor, socks_ep, circuit=circuit, pool=pool)

        # apart from the getConnection asserts...
        res = yield agent.request(b'GET', b'https://meejah.ca')
        self.assertIs(res, gold)
コード例 #8
0
def send_payjoin(manager,
                 accept_callback=None,
                 info_callback=None,
                 tls_whitelist=None):
    """ Given a JMPayjoinManager object `manager`, initialised with the
    payment request data from the server, use its wallet_service to construct
    a payment transaction, with coins sourced from mixdepth `mixdepth`,
    then wait for the server response, parse the PSBT, perform checks and complete sign.
    The info and accept callbacks are to ask the user to confirm the creation of
    the original payment transaction (None defaults to terminal/CLI processing),
    and are as defined in `taker_utils.direct_send`.

    If `tls_whitelist` is a list of bytestrings, they are treated as hostnames
    for which tls certificate verification is ignored. Obviously this is ONLY for
    testing.

    Returns:
    (True, None) in case of payment setup successful (response will be delivered
     asynchronously) - the `manager` object can be inspected for more detail.
    (False, errormsg) in case of failure.
    """

    # wallet should already be synced before calling here;
    # we can create a standard payment, but have it returned as a PSBT.
    assert isinstance(manager, JMPayjoinManager)
    assert manager.wallet_service.synced
    payment_psbt = direct_send(manager.wallet_service,
                               manager.amount,
                               manager.mixdepth,
                               str(manager.destination),
                               accept_callback=accept_callback,
                               info_callback=info_callback,
                               with_final_psbt=True)
    if not payment_psbt:
        return (False, "could not create non-payjoin payment")

    manager.set_payment_tx_and_psbt(payment_psbt)

    # add delayed call to broadcast this after 1 minute
    reactor.callLater(60, fallback_nonpayjoin_broadcast, manager, b"timeout")

    # Now we send the request to the server, with the encoded
    # payment PSBT

    # First we create a twisted web Agent object:

    # TODO genericize/move out/use library function:
    def is_hs_uri(s):
        x = urlparse.urlparse(s)
        if x.hostname.endswith(".onion"):
            return (x.scheme, x.hostname, x.port)
        return False

    tor_url_data = is_hs_uri(manager.server)
    if tor_url_data:
        # note the return value is currently unused here
        socks5_host = jm_single().config.get("PAYJOIN", "onion_socks5_host")
        socks5_port = int(jm_single().config.get("PAYJOIN",
                                                 "onion_socks5_port"))
        # note: SSL not supported at the moment:
        torEndpoint = TCP4ClientEndpoint(reactor, socks5_host, socks5_port)
        agent = tor_agent(reactor, torEndpoint)
    else:
        if not tls_whitelist:
            agent = Agent(reactor)
        else:
            agent = Agent(
                reactor, contextFactory=WhitelistContextFactory(tls_whitelist))

    body = BytesProducer(payment_psbt.to_base64().encode("utf-8"))

    #Set the query parameters for the request:

    # construct the URI from the given parameters
    pj_version = jm_single().config.getint("PAYJOIN", "payjoin_version")
    params = {"v": pj_version}

    disable_output_substitution = "false"
    if manager.disable_output_substitution:
        disable_output_substitution = "true"
    else:
        if jm_single().config.getint("PAYJOIN",
                                     "disable_output_substitution") == 1:
            disable_output_substitution = "true"
    params["disableoutputsubstitution"] = disable_output_substitution

    # to determine the additionalfeeoutputindex in cases where we have
    # change and we are allowing fee bump, we examine the initial tx:
    if manager.change_out:
        params["additionalfeeoutputindex"] = manager.change_out_index
        params["maxadditionalfeecontribution"] = \
            get_max_additional_fee_contribution(manager)

    min_fee_rate = float(jm_single().config.get("PAYJOIN", "min_fee_rate"))
    params["minfeerate"] = min_fee_rate

    destination_url = manager.server.encode("utf-8")
    url_parts = list(urlparse.urlparse(destination_url))
    url_parts[4] = urlencode(params).encode("utf-8")
    destination_url = urlparse.urlunparse(url_parts)
    # TODO what to use as user agent?
    d = agent.request(b"POST",
                      destination_url,
                      Headers({
                          "User-Agent": ["Twisted Web Client Example"],
                          "Content-Type": ["text/plain"]
                      }),
                      bodyProducer=body)

    d.addCallback(receive_payjoin_proposal_from_server, manager)

    # note that the errback (here "noResponse") is *not* triggered
    # by a server rejection (which is accompanied by a non-200
    # status code returned), but by failure to communicate.
    def noResponse(failure):
        failure.trap(ResponseFailed, ConnectionRefusedError,
                     HostUnreachableError)
        log.error(failure.value)
        fallback_nonpayjoin_broadcast(manager, b"connection refused")

    d.addErrback(noResponse)
    return (True, None)
コード例 #9
0
def get_tor_agent(socks5_host, socks5_port):
    torEndpoint = TCP4ClientEndpoint(reactor, socks5_host, socks5_port)
    return tor_agent(reactor, torEndpoint)
コード例 #10
0
 def test_agent_no_socks(self):
     reactor = Mock()
     with self.assertRaises(Exception) as ctx:
         yield tor_agent(reactor, None)
     self.assertTrue('Must provide socks_endpoint' in str(ctx.exception))
コード例 #11
0
 def test_agent(self):
     reactor = Mock()
     socks_ep = Mock()
     yield tor_agent(reactor, socks_ep)
コード例 #12
0
ファイル: test_web.py プロジェクト: felipedau/txtorcon
 def test_agent_no_socks(self):
     reactor = Mock()
     with self.assertRaises(Exception) as ctx:
         yield tor_agent(reactor, None)
     self.assertTrue('Must provide socks_endpoint' in str(ctx.exception))
コード例 #13
0
ファイル: test_web.py プロジェクト: felipedau/txtorcon
 def test_agent(self):
     reactor = Mock()
     socks_ep = Mock()
     yield tor_agent(reactor, socks_ep)