[tor-commits] [oonib/master] Apply Arturo's fix for 12747

art at torproject.org art at torproject.org
Wed Sep 3 13:56:01 UTC 2014


commit 2972cb2234fba8d24c009e113541716326793629
Author: aagbsn <aagbsn at 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





More information about the tor-commits mailing list