[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [ooni-probe/master] Refactor reporter, config and onion



commit a17ea0cb44fc5d9f969e716ad5ddf8b7c164c5c8
Author: Arturo Filastò <arturo@xxxxxxxxxxx>
Date:   Wed Oct 24 16:12:23 2012 +0000

    Refactor reporter, config and onion
    * Stop using newstyle super method on oldstyle class
---
 ooni/reporter.py     |   17 ++++-------
 ooni/utils/config.py |   68 ++++++++++++++++++++++++++++++++++++++++++++-
 ooni/utils/onion.py  |   76 +++++++++++++++++++++++++-------------------------
 3 files changed, 111 insertions(+), 50 deletions(-)

diff --git a/ooni/reporter.py b/ooni/reporter.py
index fc5dde9..4d09729 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -191,9 +191,6 @@ class OONIReporter(OReporter):
                     tbformat=tbformat, realtime=realtime, publisher=publisher)
 
         self._tests = {}
-        self._publisher = publisher
-        if publisher is not None:
-            publisher.addObserver(self._observeWarnings)
 
     def getTestIndex(self, test):
         try:
@@ -261,8 +258,6 @@ class OONIReporter(OReporter):
         and L{_separator} are all implemented.
         """
         log.debug("Test run concluded")
-        if self._publisher is not None:
-            self._publisher.removeObserver(self._observeWarnings)
         if self._startTime is not None:
             self.report['startTime'] = self._startTime
             self.report['runTime'] = time.time() - self._startTime
@@ -274,11 +269,11 @@ class OONIReporter(OReporter):
         self.writeYamlLine(self.report)
 
     def addSuccess(self, test):
-        super(OONIReporter, self).addSuccess(test)
+        OONIReporter.addSuccess(self, test)
         #self.report['result'] = {'value': 'success'}
 
     def addError(self, test, exception):
-        super(OONIReporter, self).addError(test, exception)
+        OONIReporter.addError(self, test, exception)
         exc_type, exc_value, exc_traceback = exception
         log.err(exc_type)
         log.err(str(exc_value))
@@ -287,19 +282,19 @@ class OONIReporter(OReporter):
             log.err(line)
 
     def addFailure(self, *args):
-        super(OONIReporter, self).addFailure(*args)
+        OONIReporter.addFailure(self, *args)
         log.warn(args)
 
     def addSkip(self, *args):
-        super(OONIReporter, self).addSkip(*args)
+        OONIReporter.addSkip(self, *args)
         #self.report['result'] = {'value': 'skip', 'args': args}
 
     def addExpectedFailure(self, *args):
-        super(OONIReporter, self).addExpectedFailure(*args)
+        OONIReporter.addExpectedFailure(self, *args)
         #self.report['result'] = {'value': 'expectedFailure', 'args': args}
 
     def addUnexpectedSuccess(self, *args):
-        super(OONIReporter, self).addUnexpectedSuccess(*args)
+        OONIReporter.addUnexpectedSuccess(self, *args)
         #self.report['result'] = {'args': args, 'value': 'unexpectedSuccess'}
 
 
diff --git a/ooni/utils/config.py b/ooni/utils/config.py
index a5b32f8..5a0782d 100644
--- a/ooni/utils/config.py
+++ b/ooni/utils/config.py
@@ -1,7 +1,7 @@
 import ConfigParser
 import os
 
-from ooni.utils import Storage
+from ooni.utils import Storage, log
 
 class Config(Storage):
     """
@@ -53,3 +53,69 @@ class Config(Storage):
             self._cfgparser.write(cfgfile)
         finally:
             cfgfile.close()
+
+class ValueChecker(object):
+    """
+    A class for general purpose value checks on commandline parameters
+    passed to subclasses of :class:`twisted.python.usage.Options`.
+    """
+    def __init__(self, coerce_doc=None):
+        self.coerce_doc = coerce_doc
+
+    def port_check(self, port, range_min=1024, range_max=65535):
+        """
+        Check that given ports are in the allowed range for an unprivileged
+        user.
+
+        :param port:
+            The port to check.
+        :param range_min:
+            The minimum allowable port number.
+        :param range_max:
+            The minimum allowable port number.
+        :param coerce_doc:
+            The documentation string to show in the optParameters menu, see
+            :class:`twisted.python.usage.Options`.
+        """
+        if self.coerce_doc is not None:
+            coerceDoc = self.coerce_doc
+
+        assert type(port) is int
+        if port not in range(range_min, range_max):
+            raise ValueError("Port out of range")
+            log.err()
+
+    @staticmethod
+    def uid_check(error_message):
+        """
+        Check that we're not root. If we are, setuid(1000) to normal user if
+        we're running on a posix-based system, and if we're on Windows just
+        tell the user that we can't be run as root with the specified options
+        and then exit.
+
+        :param error_message:
+            The string to log as an error message when the uid check fails.
+        """
+        uid, gid = os.getuid(), os.getgid()
+        if uid == 0 and gid == 0:
+            log.msg(error_message)
+        if os.name == 'posix':
+            log.msg("Dropping privileges to normal user...")
+            os.setgid(1000)
+            os.setuid(1000)
+        else:
+            sys.exit(0)
+
+    @staticmethod
+    def dir_check(d):
+        """Check that the given directory exists."""
+        if not os.path.isdir(d):
+            raise ValueError("%s doesn't exist, or has wrong permissions"
+                             % d)
+
+    @staticmethod
+    def file_check(f):
+        """Check that the given file exists."""
+        if not os.path.isfile(f):
+            raise ValueError("%s does not exist, or has wrong permissions"
+                             % f)
diff --git a/ooni/utils/onion.py b/ooni/utils/onion.py
index 3326c75..9c80f62 100644
--- a/ooni/utils/onion.py
+++ b/ooni/utils/onion.py
@@ -67,7 +67,7 @@ def write_torrc(conf, data_dir=None):
     """
     Create a torrc in our data_dir. If we don't yet have a data_dir, create a
     temporary one. Any temporary files or folders are added to delete_list.
-    
+
     :param conf:
         A :class:`ooni.lib.txtorcon.TorConfig` object, with all configuration
         values saved.
@@ -82,12 +82,12 @@ def write_torrc(conf, data_dir=None):
         log.err(ie)
 
     delete_list = []
-    
+
     if data_dir is None:
         data_dir = mkdtemp(prefix='bridget-tordata')
         delete_list.append(data_dir)
     conf.DataDirectory = data_dir
-    
+
     (fd, torrc) = mkstemp(dir=data_dir)
     delete_list.append(torrc)
     write(fd, conf.create_torrc())
@@ -136,7 +136,7 @@ def remove_public_relays(state, bridges):
 
     XXX FIXME: There is a problem in that Tor needs a Bridge line to already be
     configured in order to bootstrap. However, after bootstrapping, we grab the
-    microdescriptors of all the relays and check if any of our bridges are 
+    microdescriptors of all the relays and check if any of our bridges are
     listed as public relays. Because of this, the first bridge does not get
     checked for being a relay.
     """
@@ -180,7 +180,7 @@ def state_complete(state):
     return state
 
 def updates(_progress, _tag, _summary):
-    """Log updates on the Tor bootstrapping process.""" 
+    """Log updates on the Tor bootstrapping process."""
     log.msg("%d%%: %s" % (_progress, _summary))
 
 def bootstrap(ctrl):
@@ -193,7 +193,7 @@ def bootstrap(ctrl):
     log.msg("Tor process connected, bootstrapping ...")
 
 def start_tor(reactor, config, control_port, tor_binary, data_dir,
-              report=None, progress=updates, 
+              report=None, progress=updates,
               process_cb=None, process_eb=None):
     """
     Use a txtorcon.TorConfig() instance, config, to write a torrc to a
@@ -223,11 +223,11 @@ def start_tor(reactor, config, control_port, tor_binary, data_dir,
         A non-blocking function to handle bootstrapping updates, which takes
         three parameters: _progress, _tag, and _summary.
     :param process_cb:
-        The function to callback to after 
+        The function to callback to after
         class:`ooni.lib.txtorcon.TorProcessProtocol` returns with the fully
         bootstrapped Tor process.
     :param process_eb:
-        The function to errback to if 
+        The function to errback to if
         class:`ooni.lib.txtorcon.TorProcessProtocol` fails.
     :return:
         The result of the callback of a
@@ -284,9 +284,9 @@ def start_tor(reactor, config, control_port, tor_binary, data_dir,
 def start_tor_filter_nodes(reactor, config, control_port, tor_binary,
                               data_dir, bridges):
     """
-    Bootstrap a Tor process and return a fully-setup 
+    Bootstrap a Tor process and return a fully-setup
     :class:`ooni.lib.txtorcon.TorState`. Then search for our bridges
-    to test in the list of known public relays, 
+    to test in the list of known public relays,
     :ivar:`ooni.lib.txtorcon.TorState.routers`, and remove any bridges
     which are known public relays.
 
@@ -296,7 +296,7 @@ def start_tor_filter_nodes(reactor, config, control_port, tor_binary,
         An instance of :class:`ooni.lib.txtorcon.TorConfig`.
     :param control_port:
         The port to use for Tor's ControlPort. If already configured in
-        the TorConfig instance, this can be given as 
+        the TorConfig instance, this can be given as
         TorConfig.config.ControlPort.
     :param tor_binary:
         The full path to the Tor binary to execute.
@@ -309,7 +309,7 @@ def start_tor_filter_nodes(reactor, config, control_port, tor_binary,
     :return:
         A fully initialized :class:`ooni.lib.txtorcon.TorState`.
     """
-    setup = yield start_tor(reactor, config, control_port, 
+    setup = yield start_tor(reactor, config, control_port,
                             tor_binary, data_dir,
                             process_cb=setup_done, process_eb=setup_fail)
     filter_nodes = yield remove_public_relays(setup, bridges)
@@ -333,7 +333,7 @@ def start_tor_with_timer(reactor, config, control_port, tor_binary, data_dir,
         An instance of :class:`ooni.lib.txtorcon.TorConfig`.
     :param control_port:
         The port to use for Tor's ControlPort. If already configured in
-        the TorConfig instance, this can be given as 
+        the TorConfig instance, this can be given as
         TorConfig.config.ControlPort.
     :param tor_binary:
         The full path to the Tor binary to execute.
@@ -347,7 +347,7 @@ def start_tor_with_timer(reactor, config, control_port, tor_binary, data_dir,
         The number of seconds to attempt to bootstrap the Tor process before
         raising a :class:`ooni.utils.timer.TimeoutError`.
     :return:
-        If the timeout limit is not exceeded, return a fully initialized 
+        If the timeout limit is not exceeded, return a fully initialized
         :class:`ooni.lib.txtorcon.TorState`, else return None.
     """
     error_msg = "Bootstrapping has exceeded the timeout limit..."
@@ -365,9 +365,9 @@ def start_tor_with_timer(reactor, config, control_port, tor_binary, data_dir,
     else:
         state = yield remove_public_relays(setup, bridges)
         defer.returnValue(state)
-    
+
 @defer.inlineCallbacks
-def start_tor_filter_nodes_with_timer(reactor, config, control_port, 
+def start_tor_filter_nodes_with_timer(reactor, config, control_port,
                                       tor_binary, data_dir, bridges, timeout):
     """
     Start bootstrapping a Tor process wrapped with an instance of the class
@@ -386,7 +386,7 @@ def start_tor_filter_nodes_with_timer(reactor, config, control_port,
         An instance of :class:`ooni.lib.txtorcon.TorConfig`.
     :param control_port:
         The port to use for Tor's ControlPort. If already configured in
-        the TorConfig instance, this can be given as 
+        the TorConfig instance, this can be given as
         TorConfig.config.ControlPort.
     :param tor_binary:
         The full path to the Tor binary to execute.
@@ -400,13 +400,13 @@ def start_tor_filter_nodes_with_timer(reactor, config, control_port,
         The number of seconds to attempt to bootstrap the Tor process before
         raising a :class:`ooni.utils.timer.TimeoutError`.
     :return:
-        If the timeout limit is not exceeded, return a fully initialized 
+        If the timeout limit is not exceeded, return a fully initialized
         :class:`ooni.lib.txtorcon.TorState`, else return None.
     """
     error_msg = "Bootstrapping has exceeded the timeout limit..."
     with_timeout = deferred_timeout(timeout, e=error_msg)(start_tor_filter_nodes)
     try:
-        state = yield with_timeout(reactor, config, control_port, 
+        state = yield with_timeout(reactor, config, control_port,
                                    tor_binary, data_dir, bridges)
     except TimeoutError, te:
         log.err(te)
@@ -416,16 +416,16 @@ def start_tor_filter_nodes_with_timer(reactor, config, control_port,
     #    defer.returnValue(None)
     else:
         defer.returnValue(state)
-    
+
 class CustomCircuit(CircuitListenerMixin):
     """
-    Utility class for controlling circuit building. See 
+    Utility class for controlling circuit building. See
     'attach_streams_by_country.py' in the txtorcon documentation.
 
     :param state:
         A fully bootstrapped instance of :class:`ooni.lib.txtorcon.TorState`.
     :param relays:
-        A dictionary containing a key 'all', which is a list of relays to 
+        A dictionary containing a key 'all', which is a list of relays to
         test connecting to.
     :ivar waiting_circuits:
         The list of circuits which we are waiting to attach to. You shouldn't
@@ -498,10 +498,10 @@ class CustomCircuit(CircuitListenerMixin):
 
     def check_circuit_route(self, router):
         """
-        Check if a relay is a hop in one of our already built circuits. 
+        Check if a relay is a hop in one of our already built circuits.
 
         :param router:
-            An item from the list 
+            An item from the list
             :func:`ooni.lib.txtorcon.TorState.routers.values()`.
         """
         for circ in self.state.circuits.values():
@@ -551,7 +551,7 @@ class CustomCircuit(CircuitListenerMixin):
             assert len(path) >= 3, \
                 "Circuit path must be at least three hops!"
 
-        log.msg("Requesting a circuit: %s" 
+        log.msg("Requesting a circuit: %s"
                 % '->'.join(map(lambda node: node, path)))
 
         class AppendWaiting:
@@ -575,7 +575,7 @@ class CustomCircuit(CircuitListenerMixin):
 class TxtorconImportError(ImportError):
     """
     Raised when ooni.lib.txtorcon cannot be imported from. Checks our current
-    working directory and the path given to see if txtorcon has been 
+    working directory and the path given to see if txtorcon has been
     initialized via /ooni/lib/Makefile.
     """
     from os import getcwd, path
@@ -609,25 +609,25 @@ class PTNotFoundException(Exception):
         return sys.exit()
 
 @defer.inlineCallbacks
-def __start_tor_with_timer__(reactor, config, control_port, tor_binary, 
+def __start_tor_with_timer__(reactor, config, control_port, tor_binary,
                              data_dir, bridges=None, relays=None, timeout=None,
                              retry=None):
     """
     A wrapper for :func:`start_tor` which wraps the bootstrapping of a Tor
-    process and its connection to a reactor with a 
-    :class:`twisted.internet.defer.Deferred` class decorator utility, 
+    process and its connection to a reactor with a
+    :class:`twisted.internet.defer.Deferred` class decorator utility,
     :func:`ooni.utils.timer.deferred_timeout`, and a mechanism for resets.
-    
+
     ## XXX fill me in
     """
     raise NotImplementedError
-    
+
     class RetryException(Exception):
-        pass    
+        pass
 
     import sys
     from ooni.utils.timer import deferred_timeout, TimeoutError
-    
+
     def __make_var__(old, default, _type):
         if old is not None:
             assert isinstance(old, _type)
@@ -635,15 +635,15 @@ def __start_tor_with_timer__(reactor, config, control_port, tor_binary,
         else:
             new = default
         return new
-    
+
     reactor = reactor
     timeout = __make_var__(timeout, 120, int)
     retry   = __make_var__(retry, 1, int)
 
     with_timeout = deferred_timeout(timeout)(start_tor)
-    
+
     @defer.inlineCallbacks
-    def __start_tor__(rc=reactor, cf=config, cp=control_port, tb=tor_binary, 
+    def __start_tor__(rc=reactor, cf=config, cp=control_port, tb=tor_binary,
                       dd=data_dir, br=bridges, rl=relays, cb=setup_done,
                       eb=setup_fail, af=remove_public_relays, retry=retry):
         try:
@@ -658,13 +658,13 @@ def __start_tor_with_timer__(reactor, config, control_port, tor_binary,
                 setup = yield eb(setup)
             else:
                 setup = setup
-    
+
             if br is not None:
                 state = af(setup,br)
             else:
                 state = setup
             defer.returnValue(state)
-    
+
     @defer.inlineCallbacks
     def __try_until__(tries):
         result = yield __start_tor__()



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits