commit 2972cb2234fba8d24c009e113541716326793629 Author: aagbsn aagbsn@extc.org Date: Wed Aug 27 23:58:26 2014 +0000
Apply Arturo's fix for 12747 --- oonib/oonibackend.py | 21 +++++--- oonib/runner.py | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 7 deletions(-)
diff --git a/oonib/oonibackend.py b/oonib/oonibackend.py index ca51f45..bc05331 100644 --- a/oonib/oonibackend.py +++ b/oonib/oonibackend.py @@ -7,6 +7,8 @@ # In here we start all the test helpers that are required by ooniprobe and # start the report collector
+from distutils.version import LooseVersion + from oonib.api import ooniBackend, ooniBouncer from oonib.config import config from oonib.onion import startTor @@ -20,6 +22,7 @@ from twisted.internet import reactor from twisted.names import dns
from txtorcon import TCPHiddenServiceEndpoint, TorConfig +from txtorcon import __version__ as txtorcon_version
if config.main.uid and config.main.gid: application = service.Application('oonibackend', uid=config.main.uid, @@ -89,17 +92,24 @@ if config.helpers['http-return-json-headers'].port: http_helpers.HTTPReturnJSONHeadersHelper()) multiService.addService(http_return_request_helper)
+ # add the tor collector service here if config.main.tor_hidden_service: torconfig = TorConfig() d = startTor(torconfig)
+ def getHSEndpoint(data_dir): + if LooseVersion(txtorcon_version) >= LooseVersion('0.10.0'): + return TCPHiddenServiceEndpoint(reactor, + torconfig, 80, hidden_service_dir=data_dir) + else: + return TCPHiddenServiceEndpoint(reactor, + torconfig, 80, data_dir=data_dir) + def addCollector(torControlProtocol): data_dir = os.path.join(torconfig.DataDirectory, 'collector') collector_service = internet.StreamServerEndpointService( - TCPHiddenServiceEndpoint(reactor, - torconfig, 80, - hidden_service_dir=data_dir), + getHSEndpoint(data_dir), ooniBackend) multiService.addService(collector_service) collector_service.startService() @@ -110,11 +120,8 @@ if config.main.tor_hidden_service: if ooniBouncer: def addBouncer(torControlProtocol): data_dir = os.path.join(torconfig.DataDirectory, 'bouncer') - bouncer_service = internet.StreamServerEndpointService( - TCPHiddenServiceEndpoint(reactor, - torconfig, 80, - hidden_service_dir=data_dir), + getHSEndpoint(data_dir), ooniBouncer) multiService.addService(bouncer_service) bouncer_service.startService() diff --git a/oonib/runner.py b/oonib/runner.py new file mode 100644 index 0000000..aa5cd1a --- /dev/null +++ b/oonib/runner.py @@ -0,0 +1,137 @@ +""" +In here we define a runner for the oonib backend system. +""" + +from __future__ import print_function + +from distutils.version import LooseVersion +import tempfile +import os + +from shutil import rmtree + +from twisted.internet import reactor, endpoints +from twisted.python.runtime import platformType + +from txtorcon import TCPHiddenServiceEndpoint, TorConfig +from txtorcon import launch_tor +from txtorcon import __version__ as txtorcon_version + +from oonib.api import ooniBackend, ooniBouncer +from oonib.config import config + +from oonib import oonibackend +from oonib import log + +from txtorcon import __version__ as txtorcon_version +if tuple(map(int, txtorcon_version.split('.'))) < (0, 9, 0): + """ + Fix for bug in txtorcon versions < 0.9.0 where TCPHiddenServiceEndpoint + listens on all interfaces by default. + """ + def create_listener(self, proto): + self._update_onion(self.hiddenservice.dir) + self.tcp_endpoint = endpoints.TCP4ServerEndpoint(self.reactor, + self.listen_port, + interface='127.0.0.1') + d = self.tcp_endpoint.listen(self.protocolfactory) + d.addCallback(self._add_attributes).addErrback(self._retry_local_port) + return d + TCPHiddenServiceEndpoint._create_listener = create_listener + +class OBaseRunner(object): + pass + +if platformType == "win32": + from twisted.scripts._twistw import WindowsApplicationRunner + + OBaseRunner = WindowsApplicationRunner + # XXX Currently we don't support windows for starting a Tor Hidden Service + log.warn( + "Apologies! We don't support starting a Tor Hidden Service on Windows.") + +else: + from twisted.scripts._twistd_unix import UnixApplicationRunner + class OBaseRunner(UnixApplicationRunner): + temporary_data_dir = None + + def txSetupFailed(self, failure): + log.err("Setup failed") + log.exception(failure) + + def setupHSEndpoint(self, tor_process_protocol, torconfig, endpoint): + endpointName = endpoint.settings['name'] + + def setup_complete(port): + print("Exposed %s Tor hidden service " + "on httpo://%s" % (endpointName, port.onion_uri)) + + public_port = 80 + data_dir = os.path.join(torconfig.DataDirectory, endpointName) + if LooseVersion(txtorcon_version) >= LooseVersion('0.10.0'): + hs_endpoint = TCPHiddenServiceEndpoint(reactor, + torconfig, + public_port, + hidden_service_dir=data_dir) + else: + hs_endpoint = TCPHiddenServiceEndpoint(reactor, + torconfig, + public_port, + data_dir=data_dir) + d = hs_endpoint.listen(endpoint) + d.addCallback(setup_complete) + d.addErrback(self.txSetupFailed) + return d + + def startTor(self, torconfig): + def updates(prog, tag, summary): + print("%d%%: %s" % (prog, summary)) + + torconfig.SocksPort = config.main.socks_port + if config.main.tor2webmode: + torconfig.Tor2webMode = 1 + torconfig.CircuitBuildTimeout = 60 + if config.main.tor_datadir is None: + self.temporary_data_dir = tempfile.mkdtemp() + log.warn("Option 'tor_datadir' in oonib.conf is unspecified!") + log.warn("Using %s" % self.temporary_data_dir) + torconfig.DataDirectory = self.temporary_data_dir + else: + torconfig.DataDirectory = config.main.tor_datadir + torconfig.save() + if config.main.tor_binary is not None: + d = launch_tor(torconfig, reactor, + tor_binary=config.main.tor_binary, + progress_updates=updates) + else: + d = launch_tor(torconfig, reactor, progress_updates=updates) + return d + + def postApplication(self): + """After the application is created, start the application and run + the reactor. After the reactor stops, clean up PID files and such. + """ + self.startApplication(self.application) + # This is our addition. The rest is taken from + # twisted/scripts/_twistd_unix.py 12.2.0 + if config.main.tor_hidden_service: + torconfig = TorConfig() + d = self.startTor(torconfig) + d.addCallback(self.setupHSEndpoint, torconfig, ooniBackend) + if ooniBouncer: + d.addCallback(self.setupHSEndpoint, torconfig, ooniBouncer) + else: + if ooniBouncer: + reactor.listenTCP(8888, ooniBouncer, interface="127.0.0.1") + reactor.listenTCP(8889, ooniBackend, interface="127.0.0.1") + self.startReactor(None, self.oldstdout, self.oldstderr) + self.removePID(self.config['pidfile']) + if self.temporary_data_dir: + log.msg("Removing temporary directory: %s" + % self.temporary_data_dir) + rmtree(self.temporary_data_dir, onerror=log.err) + + def createOrGetApplication(self): + return oonibackend.application + +OBaseRunner.loggerFactory = log.LoggerFactory
tor-commits@lists.torproject.org