commit bc4e167f6a6a46aca79e84c39da867f6859fa082 Author: Joe Landers joe@joelanders.net Date: Tue Feb 24 02:36:24 2015 +0100
clean up ClientTransportPlugin logic --- ooni/nettests/blocking/bridge_reachability.py | 107 +++++++++---------------- ooni/tests/test_onion.py | 23 ++++++ ooni/utils/onion.py | 42 ++++++++++ 3 files changed, 103 insertions(+), 69 deletions(-)
diff --git a/ooni/nettests/blocking/bridge_reachability.py b/ooni/nettests/blocking/bridge_reachability.py index 864ae2a..aa1140a 100644 --- a/ooni/nettests/blocking/bridge_reachability.py +++ b/ooni/nettests/blocking/bridge_reachability.py @@ -2,7 +2,6 @@ import os import random import tempfile -from distutils.spawn import find_executable
from twisted.python import usage from twisted.internet import reactor, error @@ -71,9 +70,6 @@ class BridgeReachability(nettest.NetTestCase): self.bridge = self.input if self.input.startswith('Bridge'): self.bridge = self.input.replace('Bridge ', '') - self.pyobfsproxy_bin = onion.obfsproxy_details['binary'] - self.fteproxy_bin = find_executable('fteproxy') - self.obfs4proxy_bin = find_executable('obfs4proxy')
def postProcessor(self, measurements): if 'successes' not in self.summary: @@ -132,74 +128,47 @@ class BridgeReachability(nettest.NetTestCase): (self.bridge, onion.tor_details['version']))
transport_name = onion.transport_name(self.bridge) - - if transport_name: + if transport_name == None: + self.report['bridge_address'] = self.bridge.split(' ')[0] + else: + self.report['bridge_address'] = self.bridge.split(' ')[1] self.report['transport_name'] = transport_name - if transport_name == 'fte': - if self.fteproxy_bin: - config.ClientTransportPlugin = "%s exec %s --managed" % ( - transport_name, self.fteproxy_bin) - log.debug("Using fte from %s" % self.fteproxy_bin) - self.report['bridge_address'] = self.bridge.split(' ')[1] - else: - log.err("Unable to test bridge because fteproxy is not " - "installed") - self.report['error'] = 'missing-fteproxy' - return - elif ['scramblesuit', 'obfs2', 'obfs3'].count(transport_name) > 0: - if self.pyobfsproxy_bin: - config.ClientTransportPlugin = ("%s exec %s " - "--log-min-severity info --log-file %s managed") % \ - (transport_name, self.pyobfsproxy_bin, - self.obfsproxy_logfile) - if onion.OBFSProxyVersion('0.2') > \ - onion.obfsproxy_details['version']: - log.err( - "The obfsproxy version you are using appears to " - "be outdated." - ) - self.report['error'] = 'old-obfsproxy' - return - log.debug("Using pyobfsproxy from %s" % \ - self.pyobfsproxy_bin) - self.report['bridge_address'] = self.bridge.split(' ')[1] - else: - log.err( - "Unable to test bridge because pyobfsproxy is not " - "installed") - self.report['error'] = 'missing-pyobfsproxy' - return - elif transport_name == 'obfs4': - if self.obfs4proxy_bin: - config.ClientTransportPlugin = ("%s exec %s") % \ - (transport_name, self.obfs4proxy_bin) - log.debug("Using obfs4proxy from %s" % \ - self.obfs4proxy_bin) - self.report['bridge_address'] = self.bridge.split(' ')[1] - else: - log.err( - "Unable to test bridge because obfs4proxy is not " - "installed") - self.report['error'] = 'missing-obfs4proxy' - return - else: - log.err("Unable to test bridge because we don't handle %s" % \ - transport_name) - self.report['error'] = 'missing-transport' + + try: + config.ClientTransportPlugin = \ + onion.bridge_line(transport_name, self.obfsproxy_logfile) + except onion.UnrecognizedTransport: + log.err("Unable to test bridge because we don't recognize " + "the %s transport" % transport_name) + self.report['error'] = "unrecognized-transport" + return + except onion.UninstalledTransport: + bin_name = onion.transport_bin_name.get(transport_name) + log.err("Unable to test bridge because %s is not installed" % + bin_name) + self.report['error'] = "missing-%s" % bin_name return - else: - self.report['bridge_address'] = self.bridge.split(' ')[0]
- if transport_name and transport_name == 'scramblesuit' and \ - onion.TorVersion('0.2.5.1') > onion.tor_details['version']: - self.report['error'] = 'unsupported-tor-version' - log.err("Unsupported Tor version.") - return - elif transport_name and \ - onion.TorVersion('0.2.4.1') > onion.tor_details['version']: - self.report['error'] = 'unsupported-tor-version' - log.err("Unsupported Tor version.") - return + if onion.OBFSProxyVersion('0.2') > \ + onion.obfsproxy_details['version']: + log.err("The obfsproxy version you are using " \ + "appears to be outdated.") + self.report['error'] = 'old-obfsproxy' + return + + if transport_name == 'scramblesuit' and \ + onion.TorVersion('0.2.5.1') > onion.tor_details['version']: + log.err("Unsupported Tor version.") + self.report['error'] = 'unsupported-tor-version' + return + + if onion.TorVersion('0.2.4.1') > onion.tor_details['version']: + log.err("Unsupported Tor version.") + self.report['error'] = 'unsupported-tor-version' + return + + log.debug("Using ClientTransportPlugin '%s'" % \ + config.ClientTransportPlugin)
config.Bridge = self.bridge config.UseBridges = 1 diff --git a/ooni/tests/test_onion.py b/ooni/tests/test_onion.py index 94d9dd9..fa608d6 100644 --- a/ooni/tests/test_onion.py +++ b/ooni/tests/test_onion.py @@ -1,5 +1,13 @@ from twisted.trial import unittest from ooni.utils import onion +from mock import Mock + +sample_transport_lines = { + 'fte': 'fte exec /fakebin --managed', + 'scramblesuit': 'scramblesuit exec /fakebin --log-min-severity info --log-file /log.txt managed', + 'obfs2': 'obfs2 exec /fakebin --log-min-severity info --log-file /log.txt managed', + 'obfs3': 'obfs3 exec /fakebin --log-min-severity info --log-file /log.txt managed', + 'obfs4': 'obfs4 exec /fakebin' }
class TestOnion(unittest.TestCase): @@ -7,3 +15,18 @@ class TestOnion(unittest.TestCase): assert isinstance(onion.tor_details, dict) assert onion.tor_details['version'] assert onion.tor_details['binary'] + def test_transport_dicts(self): + self.assertEqual( set(onion.transport_bin_name.keys()), + set(onion._transport_line_templates.keys()) ) + def test_bridge_line(self): + self.assertRaises(onion.UnrecognizedTransport, + onion.bridge_line, 'rot13', '/log.txt') + + onion.find_executable = Mock(return_value=False) + self.assertRaises(onion.UninstalledTransport, + onion.bridge_line, 'fte', '/log.txt') + + onion.find_executable = Mock(return_value="/fakebin") + for transport, exp_line in sample_transport_lines.iteritems(): + self.assertEqual(onion.bridge_line(transport, '/log.txt'), + exp_line) diff --git a/ooni/utils/onion.py b/ooni/utils/onion.py index 09e104c..b0638f8 100644 --- a/ooni/utils/onion.py +++ b/ooni/utils/onion.py @@ -74,3 +74,45 @@ obfsproxy_details = { 'binary': find_executable('obfsproxy'), 'version': obfsproxy_version() } + +transport_bin_name = { 'fte': 'fteproxy', + 'scramblesuit': 'obfsproxy', + 'obfs2': 'obfsproxy', + 'obfs3': 'obfsproxy', + 'obfs4': 'obfs4proxy' } + +_pyobfsproxy_line = lambda transport, bin_loc, log_file: \ + "%s exec %s --log-min-severity info --log-file %s managed" % \ + (transport, bin_loc, log_file) + +_transport_line_templates = { + 'fte': lambda bin_loc, log_file : \ + "fte exec %s --managed" % bin_loc, + + 'scramblesuit': lambda bin_loc, log_file: \ + _pyobfsproxy_line('scramblesuit', bin_loc, log_file), + + 'obfs2': lambda bin_loc, log_file: \ + _pyobfsproxy_line('obfs2', bin_loc, log_file), + + 'obfs3': lambda bin_loc, log_file: \ + _pyobfsproxy_line('obfs3', bin_loc, log_file), + + 'obfs4': lambda bin_loc, log_file: \ + "obfs4 exec %s" % bin_loc } + +class UnrecognizedTransport(Exception): + pass +class UninstalledTransport(Exception): + pass + +def bridge_line(transport, log_file): + bin_name = transport_bin_name.get(transport) + if not bin_name: + raise UnrecognizedTransport + + bin_loc = find_executable(bin_name) + if not bin_loc: + raise UninstalledTransport + + return _transport_line_templates[transport](bin_loc, log_file)
tor-commits@lists.torproject.org