commit 01058a96860b3d01e22438cf5e6568cdf606f3d0 Author: Arturo Filastò art@fuffa.org Date: Sat Mar 16 13:06:42 2013 -0400
Add support for pyobfsproxy based bridge testing --- nettests/experimental/bridget.py | 77 +++++++++++++++++++++++++++++--------- ooni/reporter.py | 3 +- 2 files changed, 61 insertions(+), 19 deletions(-)
diff --git a/nettests/experimental/bridget.py b/nettests/experimental/bridget.py index 8f31e80..1cb7b32 100644 --- a/nettests/experimental/bridget.py +++ b/nettests/experimental/bridget.py @@ -1,21 +1,23 @@ +# -*- encoding: utf-8 -*- import random +import string +import subprocess
from twisted.python import usage -from twisted.internet import defer +from twisted.internet import defer, reactor
import txtorcon -from txtorcon.torconfig import TorSetupTimeout
from ooni.utils import log from ooni import nettest
class UsageOptions(usage.Options): - optParameters = [['timeout', 't', 30, - 'Specify the timeout after which to consider the Tor bootstrapping process to have failed'] + optParameters = [['timeout', 't', 60, + 'Specify the timeout after which to consider the Tor bootstrapping process to have failed'], ]
class KeywordFiltering(nettest.NetTestCase): - name = "Bridget, at it's bare minimum" + name = "BridgetKISS" author = "Arturo Filastò" version = "0.1"
@@ -25,35 +27,74 @@ class KeywordFiltering(nettest.NetTestCase): 'File containing bridges to test reachability for (they should be one per line IP:ORPort)']
def setUp(self): + + def find_pyobfsproxy(): + try: + proc = subprocess.Popen(('type -p pyobfsproxy', ), stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=True) + except OSError: + pass + else: + stdout, _ = proc.communicate() + if proc.poll() == 0 and stdout != '': + return stdout.strip() + self.tor_progress = 0 self.timeout = int(self.localOptions['timeout']) self.report['timeout'] = self.timeout + self.bridge = self.input + self.pyobfsproxy_bin = find_pyobfsproxy()
def test_full_tor_connection(self): + def getTransport(address): + """ + If the address of the bridge starts with a valid c identifier then + we consider it to be a bridge. + Returns: + The transport_name if it's a transport. + None if it's not a obfsproxy bridge. + """ + transport_name = address.split(' ')[0] + transport_name_chars = string.ascii_letters + string.digits + if all(c in transport_name_chars for c in transport_name): + return transport_name + else: + return None + config = txtorcon.TorConfig() - config.OrPort = random.randint(2**14, 2**16) + config.ControlPort = random.randint(2**14, 2**16) config.SocksPort = random.randint(2**14, 2**16) - config.Bridge = self.input + + transport_name = getTransport(self.bridge) + if transport_name and self.pyobfsproxy_bin: + config.ClientTransportPlugin = "%s exec %s managed" % (transport_name, self.pyobfsproxy_bin) + self.report['transport_name'] = transport_name + elif transport_name and not self.pyobfsproxy_bin: + log.err("Unable to test bridge because pyobfsproxy is not installed") + self.report['success'] = None + return + + config.Bridge = self.bridge config.UseBridges = 1 + config.save()
def updates(prog, tag, summary): + print "Tor progress: %s%%" % prog self.report['tor_progress'] = int(prog) + self.report['tor_progress_tag'] = tag + self.report['tor_progress_summary'] = summary
- d = txtorcon.launch_tor(config, reactor, progress_updates=updates, self.timeout) + d = txtorcon.launch_tor(config, reactor, timeout=self.timeout, + progress_updates=updates) @d.addCallback def setup_complete(proto): - self.report['failed'] = False + print "Success" + self.report['success'] = True
@d.addErrback def setup_failed(failure): - failure.trap(TorSetupTimeout) - if isinstance(failure, TorSetupTimeout): - self.report['failure'] = 'timedout' - else: - self.report['failure'] = 'unknown' - self.report['failed'] = True + print "Failed" + log.exception(failure) + self.report['success'] = False
return d - - def test_connect_scan(self): - pass diff --git a/ooni/reporter.py b/ooni/reporter.py index 594c6b8..3da1eea 100644 --- a/ooni/reporter.py +++ b/ooni/reporter.py @@ -24,7 +24,8 @@ try: from scapy.packet import Packet except ImportError: log.err("Scapy is not installed.") - + class Packet(object): + pass
from ooni.errors import InvalidOONIBCollectorAddress from ooni.errors import ReportNotCreated, ReportAlreadyClosed