commit 90d39dab97309e0498e447d28cef1bd0b87aad86
Author: kudrom <kudrom(a)riseup.net>
Date: Thu Aug 7 00:45:44 2014 +0200
Fixed bug 11858: ooni might not look at requiresTor?
---
ooni/director.py | 12 ++++---
ooni/oonicli.py | 25 +++++++------
ooni/settings.py | 82 +++++++++++++++++++++----------------------
ooni/tests/test_settings.py | 77 ++++++++++++++++++++++------------------
4 files changed, 104 insertions(+), 92 deletions(-)
diff --git a/ooni/director.py b/ooni/director.py
index d48c18f..18b7cb2 100644
--- a/ooni/director.py
+++ b/ooni/director.py
@@ -122,11 +122,13 @@ class Director(object):
def start(self, start_tor=False):
self.netTests = self.getNetTests()
- if config.advanced.start_tor and start_tor:
- yield self.startTor()
- elif config.tor.control_port:
- log.msg("Connecting to Tor Control Port...")
- yield self.getTorState()
+ if start_tor:
+ yield config.check_tor()
+ if config.advanced.start_tor:
+ yield self.startTor()
+ elif config.tor.control_port:
+ log.msg("Connecting to Tor Control Port...")
+ yield self.getTorState()
if config.global_options['no-geoip']:
aux = [False]
diff --git a/ooni/oonicli.py b/ooni/oonicli.py
index cd9f4a9..cfc7ddc 100644
--- a/ooni/oonicli.py
+++ b/ooni/oonicli.py
@@ -111,13 +111,10 @@ def runWithDirector(logging=True, start_tor=True):
config.global_options = global_options
config.set_paths()
config.initialize_ooni_home()
- d = config.read_config_file(check_incoherences=True)
-
- @d.addErrback
- def shutdown(failure):
- failure.trap(errors.ConfigFileIncoherent)
- log.err("Shutting down until ooniprobe.conf is coherent.")
- reactor.callWhenRunning(reactor.stop)
+ try:
+ config.read_config_file(check_incoherences=True)
+ except errors.ConfigFileIncoherent:
+ sys.exit(6)
if global_options['verbose']:
config.advanced.debug = True
@@ -176,11 +173,11 @@ def runWithDirector(logging=True, start_tor=True):
deck = Deck()
deck.bouncer = global_options['bouncer']
- start_tor = deck.requiresTor
+ conditions_to_start_tor = [False]
if global_options['bouncer']:
- start_tor = True
+ conditions_to_start_tor.append(True)
if global_options['collector']:
- start_tor = True
+ conditions_to_start_tor.append(True)
try:
if global_options['testdeck']:
@@ -207,6 +204,8 @@ def runWithDirector(logging=True, start_tor=True):
log.err(e)
sys.exit(5)
+ conditions_to_start_tor.append(deck.requiresTor)
+ start_tor = any(conditions_to_start_tor)
d = director.start(start_tor=start_tor)
def setup_nettest(_):
@@ -223,7 +222,8 @@ def runWithDirector(logging=True, start_tor=True):
errors.CouldNotFindTestHelper,
errors.CouldNotFindTestCollector,
errors.ProbeIPUnknown,
- errors.InvalidInputFile)
+ errors.InvalidInputFile,
+ errors.ConfigFileIncoherent)
if isinstance(failure.value, errors.TorNotRunning):
log.err("Tor does not appear to be running")
@@ -260,6 +260,9 @@ def runWithDirector(logging=True, start_tor=True):
elif isinstance(failure.value, errors.InvalidInputFile):
log.err("Invalid input file \"%s\"" % failure.value)
+ elif isinstance(failure.value, errors.ConfigFileIncoherent):
+ log.err("Incoherent config file")
+
if config.advanced.debug:
log.exception(failure)
diff --git a/ooni/settings.py b/ooni/settings.py
index cbf96cb..6f95536 100644
--- a/ooni/settings.py
+++ b/ooni/settings.py
@@ -99,7 +99,6 @@ class OConfig(object):
else:
w.write(line)
- @defer.inlineCallbacks
def read_config_file(self, check_incoherences=False):
if not os.path.exists(self.config_file):
print "Configuration file does not exist."
@@ -116,61 +115,60 @@ class OConfig(object):
getattr(self, setting)[k] = v
self.set_paths()
- # The incoherent checks must be performed after OConfig is in a valid state to runWithDirector
if check_incoherences:
- coherent = yield self.check_incoherences(configuration)
- if not coherent:
- raise errors.ConfigFileIncoherent
+ self.check_incoherences(configuration)
- @defer.inlineCallbacks
def check_incoherences(self, configuration):
incoherent = []
- deferreds = []
- if not configuration['advanced']['start_tor']:
- if not 'socks_port' in configuration['tor']:
+ if configuration['advanced']['interface'] != 'auto' and configuration['advanced']['interface'] not in get_if_list():
+ incoherent.append('advanced:interface')
+
+ self.log_incoherences(incoherent)
+
+ def log_incoherences(self, incoherences):
+ if len(incoherences) > 0:
+ if len(incoherences) > 1:
+ incoherent_pretty = ", ".join(incoherences[:-1]) + ' and ' + incoherences[-1]
+ else:
+ incoherent_pretty = incoherences[0]
+ log.err("You must set properly %s in %s." % (incoherent_pretty, self.config_file))
+ raise errors.ConfigFileIncoherent
+
+ @defer.inlineCallbacks
+ def check_tor(self):
+ """
+ Called only when we must start tor by director.start
+ """
+ incoherent = []
+ d = defer.Deferred()
+
+ if not self.advanced.start_tor:
+ if self.tor.socks_port is None:
incoherent.append('tor:socks_port')
- if not 'control_port' in configuration['tor']:
+ if self.tor.control_port is None:
incoherent.append('tor:control_port')
- if 'socks_port' in configuration['tor'] and 'control_port' in configuration['tor']:
+ if self.tor.socks_port is not None and self.tor.control_port is not None:
# Check if tor is listening in these ports
- @defer.inlineCallbacks
- def cb(state):
- timeout_call.cancel()
- result = yield state.protocol.get_info("net/listeners/socks")
- if result["net/listeners/socks"].split(':')[1] != str(configuration['tor']['socks_port']):
- incoherent.append('tor:socks_port')
-
- def err(failure):
- incoherent.append('tor:socks_port')
- if timeout_call.active:
- timeout_call.cancel()
-
def timeout():
incoherent.append('tor:control_port')
if not d.called:
d.errback()
- connection = TCP4ClientEndpoint(reactor, "localhost", configuration['tor']['control_port'])
- d = txtorcon.build_tor_connection(connection)
- d.addCallback(cb)
- d.addErrback(err)
- deferreds.append(d)
+ connection = TCP4ClientEndpoint(reactor, "localhost", self.tor.control_port)
timeout_call = reactor.callLater(30, timeout)
-
- if configuration['advanced']['interface'] != 'auto' and configuration['advanced']['interface'] not in get_if_list():
- incoherent.append('advanced:interface')
-
- deferred_list = defer.DeferredList(deferreds)
- yield deferred_list
- if len(incoherent) > 0:
- if len(incoherent) > 1:
- incoherent_pretty = ", ".join(incoherent[:-1]) + ' and ' + incoherent[-1]
- else:
- incoherent_pretty = incoherent[0]
- log.err("You must set properly %s in %s." % (incoherent_pretty, self.config_file))
- defer.returnValue(False)
- defer.returnValue(True)
+ try:
+ d = txtorcon.build_tor_connection(connection)
+ state = yield d
+ result = yield state.protocol.get_info("net/listeners/socks")
+ if result["net/listeners/socks"].split(':')[1] != str(self.tor.socks_port):
+ incoherent.append('tor:socks_port')
+ except Exception:
+ incoherent.append('tor:socks_port')
+ finally:
+ if timeout_call.active:
+ timeout_call.cancel()
+ self.log_incoherences(incoherent)
def generate_pcap_filename(self, testDetails):
test_name, start_time = testDetails['test_name'], testDetails['start_time']
diff --git a/ooni/tests/test_settings.py b/ooni/tests/test_settings.py
index b28c1b2..efde7b4 100644
--- a/ooni/tests/test_settings.py
+++ b/ooni/tests/test_settings.py
@@ -7,10 +7,13 @@ from scapy.all import get_if_list
import txtorcon
from ooni.settings import OConfig
+from ooni import errors
+from bases import ConfigTestCase
-class TestSettings(unittest.TestCase):
+class TestSettings(ConfigTestCase):
def setUp(self):
+ super(ConfigTestCase, self).setUp()
self.conf = OConfig()
self.configuration = {'advanced': {'interface': 'auto',
'start_tor': True},
@@ -19,6 +22,7 @@ class TestSettings(unittest.TestCase):
self.tor_protocol = None
def tearDown(self):
+ super(ConfigTestCase, self).tearDown()
if self.silly_listener is not None:
self.silly_listener.stopListening()
@@ -29,8 +33,8 @@ class TestSettings(unittest.TestCase):
print '%s %s' % (prog, summary)
config = txtorcon.TorConfig()
- config.SocksPort = self.configuration['tor']['socks_port']
- config.ControlPort = self.configuration['tor']['control_port']
+ config.SocksPort = self.conf.tor.socks_port
+ config.ControlPort = self.conf.tor.control_port
d = txtorcon.launch_tor(config, reactor, progress_updates=progress)
return d
@@ -42,33 +46,39 @@ class TestSettings(unittest.TestCase):
class SillyFactory(Factory):
protocol = SillyProtocol
- self.silly_listener = reactor.listenTCP(self.configuration['tor']['socks_port'], SillyFactory())
+ self.silly_listener = reactor.listenTCP(self.conf.tor.socks_port, SillyFactory())
- @defer.inlineCallbacks
def test_vanilla_configuration(self):
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, True)
+ self.conf.check_incoherences(self.configuration)
@defer.inlineCallbacks
- def test_check_incoherences_start_tor_missing_options(self):
- self.configuration['advanced']['start_tor'] = False
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, False)
- self.configuration['tor'] = {'socks_port': 9999}
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, False)
- self.configuration['tor']['control_port'] = 9998
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, False)
+ def test_check_tor_missing_options(self):
+ self.conf.advanced.start_tor = False
+ try:
+ yield self.conf.check_tor()
+ except errors.ConfigFileIncoherent:
+ pass
+
+ self.conf.tor.socks_port = 9999
+ try:
+ yield self.conf.check_tor()
+ except errors.ConfigFileIncoherent:
+ pass
+
+ self.conf.tor.socks_port = None
+ self.conf.tor.control_port = 9998
+ try:
+ yield self.conf.check_tor()
+ except errors.ConfigFileIncoherent:
+ pass
@defer.inlineCallbacks
- def test_check_incoherences_start_tor_correct(self):
- self.configuration['advanced']['start_tor'] = False
- self.configuration['tor'] = {'socks_port': 9999}
- self.configuration['tor']['control_port'] = 9998
+ def test_check_tor_correct(self):
+ self.conf.advanced.start_tor = False
+ self.conf.tor.socks_port = 9999
+ self.conf.tor.control_port = 9998
self.tor_process = yield self.run_tor()
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, True)
+ yield self.conf.check_incoherences(self.configuration)
self.tor_process.transport.signalProcess('TERM')
d = defer.Deferred()
@@ -76,20 +86,19 @@ class TestSettings(unittest.TestCase):
yield d
@defer.inlineCallbacks
- def test_check_incoherences_start_tor_silly_listener(self):
- self.configuration['advanced']['start_tor'] = False
- self.configuration['tor'] = {'socks_port': 9999}
- self.configuration['tor']['control_port'] = 9998
+ def test_check_tor_silly_listener(self):
+ self.conf.advanced.start_tor = False
+ self.conf.tor.socks_port = 9999
+ self.conf.tor.control_port = 9998
self.run_silly_server()
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, False)
+ try:
+ yield self.conf.check_tor()
+ except errors.ConfigFileIncoherent:
+ pass
- @defer.inlineCallbacks
def test_check_incoherences_interface(self):
self.configuration['advanced']['interface'] = 'funky'
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, False)
+ self.assertRaises(errors.ConfigFileIncoherent, self.conf.check_incoherences, self.configuration)
self.configuration['advanced']['interface'] = random.choice(get_if_list())
- ret = yield self.conf.check_incoherences(self.configuration)
- self.assertEqual(ret, True)
+ self.conf.check_incoherences(self.configuration)