fall backs to SOCKS if we can't reach control port
This commit is contained in:
parent
46a9c9eeb9
commit
269faf190a
|
@ -4,7 +4,7 @@ from twisted.trial import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.internet.error import ConnectError
|
from twisted.internet.error import ConnectError
|
||||||
|
|
||||||
from ..tor_manager import get_tor
|
from ..tor_manager import get_tor, SocksOnlyTor
|
||||||
from ..errors import NoTorError
|
from ..errors import NoTorError
|
||||||
from .._interfaces import ITorManager
|
from .._interfaces import ITorManager
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class Tor(unittest.TestCase):
|
||||||
tor = self.successResultOf(d)
|
tor = self.successResultOf(d)
|
||||||
self.assertIs(tor, my_tor)
|
self.assertIs(tor, my_tor)
|
||||||
self.assert_(ITorManager.providedBy(tor))
|
self.assert_(ITorManager.providedBy(tor))
|
||||||
self.assertEqual(stderr.getvalue(), " using Tor\n")
|
self.assertEqual(stderr.getvalue(), " using Tor via control port\n")
|
||||||
|
|
||||||
def test_connect_fails(self):
|
def test_connect_fails(self):
|
||||||
reactor = object()
|
reactor = object()
|
||||||
|
@ -74,7 +74,27 @@ class Tor(unittest.TestCase):
|
||||||
d = get_tor(reactor, tor_control_port=tcp, stderr=stderr)
|
d = get_tor(reactor, tor_control_port=tcp, stderr=stderr)
|
||||||
self.assertNoResult(d)
|
self.assertNoResult(d)
|
||||||
self.assertEqual(connect.mock_calls, [mock.call(reactor, tcp)])
|
self.assertEqual(connect.mock_calls, [mock.call(reactor, tcp)])
|
||||||
connect_d.errback(ConnectError())
|
|
||||||
self.failureResultOf(d, ConnectError)
|
connect_d.errback(ConnectError())
|
||||||
self.assertEqual(stderr.getvalue(),
|
tor = self.successResultOf(d)
|
||||||
" unable to find control port, bailing\n")
|
self.assertIsInstance(tor, SocksOnlyTor)
|
||||||
|
self.assert_(ITorManager.providedBy(tor))
|
||||||
|
self.assertEqual(tor._reactor, reactor)
|
||||||
|
self.assertEqual(stderr.getvalue(),
|
||||||
|
" unable to find Tor control port, using SOCKS\n")
|
||||||
|
|
||||||
|
class SocksOnly(unittest.TestCase):
|
||||||
|
def test_tor(self):
|
||||||
|
reactor = object()
|
||||||
|
sot = SocksOnlyTor(reactor)
|
||||||
|
fake_ep = object()
|
||||||
|
with mock.patch("wormhole.tor_manager.txtorcon.TorClientEndpoint",
|
||||||
|
return_value=fake_ep) as tce:
|
||||||
|
ep = sot.stream_via("host", "port")
|
||||||
|
self.assertIs(ep, fake_ep)
|
||||||
|
self.assertEqual(tce.mock_calls, [mock.call("host", "port",
|
||||||
|
socks_endpoint=None,
|
||||||
|
tls=False,
|
||||||
|
reactor=reactor)])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
import sys
|
import sys
|
||||||
|
from attr import attrs, attrib
|
||||||
from zope.interface.declarations import directlyProvides
|
from zope.interface.declarations import directlyProvides
|
||||||
from twisted.internet.defer import inlineCallbacks, returnValue
|
from twisted.internet.defer import inlineCallbacks, returnValue
|
||||||
try:
|
try:
|
||||||
|
@ -9,6 +10,18 @@ except ImportError:
|
||||||
from . import _interfaces, errors
|
from . import _interfaces, errors
|
||||||
from .timing import DebugTiming
|
from .timing import DebugTiming
|
||||||
|
|
||||||
|
@attrs
|
||||||
|
class SocksOnlyTor(object):
|
||||||
|
_reactor = attrib()
|
||||||
|
|
||||||
|
def stream_via(self, host, port, tls=False):
|
||||||
|
return txtorcon.TorClientEndpoint(
|
||||||
|
host, port,
|
||||||
|
socks_endpoint=None, # tries localhost:9050 and 9150
|
||||||
|
tls=tls,
|
||||||
|
reactor=self._reactor,
|
||||||
|
)
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def get_tor(reactor, launch_tor=False, tor_control_port=None,
|
def get_tor(reactor, launch_tor=False, tor_control_port=None,
|
||||||
timing=None, stderr=sys.stderr):
|
timing=None, stderr=sys.stderr):
|
||||||
|
@ -18,14 +31,15 @@ def get_tor(reactor, launch_tor=False, tor_control_port=None,
|
||||||
connections (and inbound onion-service listeners, if necessary).
|
connections (and inbound onion-service listeners, if necessary).
|
||||||
|
|
||||||
Otherwise if tor_control_port is provided, I will attempt to connect
|
Otherwise if tor_control_port is provided, I will attempt to connect
|
||||||
to an existing Tor's control port at the endpoint it specifies. I'll
|
to an existing Tor's control port at the endpoint it specifies. I'll
|
||||||
ask that Tor for its SOCKS port.
|
ask that Tor for its SOCKS port.
|
||||||
|
|
||||||
With no arguments, I will try to connect to an existing Tor's control
|
With no arguments, I will try to connect to an existing Tor's control
|
||||||
port at the usual places: [unix:/var/run/tor/control,
|
port at the usual places: [unix:/var/run/tor/control,
|
||||||
tcp:127.0.0.1:9051, tcp:127.0.0.1:9151]. If any are successful, I'll
|
tcp:127.0.0.1:9051, tcp:127.0.0.1:9151]. If any are successful, I'll
|
||||||
ask that Tor for its SOCKS port. If none are successful, I'll attempt
|
ask that Tor for its SOCKS port. If none are successful, I'll
|
||||||
to do SOCKS to tcp:127.0.0.1:9050.
|
attempt to do SOCKS to the usual places: [tcp:127.0.0.1:9050,
|
||||||
|
tcp:127.0.0.1:9150].
|
||||||
|
|
||||||
If I am unable to make a SOCKS connection, the initial connection to
|
If I am unable to make a SOCKS connection, the initial connection to
|
||||||
the Rendezvous Server will fail, and the program will terminate.
|
the Rendezvous Server will fail, and the program will terminate.
|
||||||
|
@ -69,17 +83,17 @@ def get_tor(reactor, launch_tor=False, tor_control_port=None,
|
||||||
else:
|
else:
|
||||||
with timing.add("find tor"):
|
with timing.add("find tor"):
|
||||||
try:
|
try:
|
||||||
|
# If tor_control_port is None (the default), txtorcon
|
||||||
|
# will look through a list of usual places. If it is set,
|
||||||
|
# it will look only in the place we tell it to.
|
||||||
tor = yield txtorcon.connect(reactor, tor_control_port)
|
tor = yield txtorcon.connect(reactor, tor_control_port)
|
||||||
print(" using Tor", file=stderr)
|
print(" using Tor via control port", file=stderr)
|
||||||
except Exception:
|
except Exception:
|
||||||
#socks_desc = "tcp:127.0.0.1:9050" # fallback
|
# TODO: make this more specific. I think connect() is
|
||||||
#print(" using Tor (SOCKS port %s)" % socks_desc,
|
# likely to throw a reactor.connectTCP -type error, like
|
||||||
# file=stderr)
|
# ConnectionFailed or ConnectionRefused or something
|
||||||
print(" unable to find control port, bailing",
|
print(" unable to find Tor control port, using SOCKS",
|
||||||
file=stderr)
|
file=stderr)
|
||||||
# TODO: something nicer. I think connect() is likely to throw
|
tor = SocksOnlyTor(reactor)
|
||||||
# a reactor.connectTCP -type error, like ConnectionFailed or
|
|
||||||
# ConnectionRefused or something
|
|
||||||
raise
|
|
||||||
directlyProvides(tor, _interfaces.ITorManager)
|
directlyProvides(tor, _interfaces.ITorManager)
|
||||||
returnValue(tor)
|
returnValue(tor)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user