commit db0e863b9133f7e0d17de365e55c432dbf448878 Author: Arturo Filastò hellais@torproject.org Date: Fri Jul 13 21:15:58 2012 +0200
Main concept of b0wser implemented --- ooni/example_plugins/examplescapy.py | 2 +- ooni/plugins/chinatrigger.py | 2 +- ooni/protocols/b0wser.py | 45 ++++++++++++++++++---------- ooni/protocols/scapy.py | 55 ---------------------------------- oonib/b0wser.py | 3 +- 5 files changed, 33 insertions(+), 74 deletions(-)
diff --git a/ooni/example_plugins/examplescapy.py b/ooni/example_plugins/examplescapy.py index 144afee..21a919d 100644 --- a/ooni/example_plugins/examplescapy.py +++ b/ooni/example_plugins/examplescapy.py @@ -6,7 +6,7 @@ from twisted.internet import protocol, defer from ooni.plugoo.tests import ITest, OONITest from ooni.plugoo.assets import Asset from ooni.utils import log -from ooni.protocols.scapy import ScapyTest +from ooni.protocols.scapyproto import ScapyTest
from ooni.lib.txscapy import txsr, txsend
diff --git a/ooni/plugins/chinatrigger.py b/ooni/plugins/chinatrigger.py index 538ef0b..9873518 100644 --- a/ooni/plugins/chinatrigger.py +++ b/ooni/plugins/chinatrigger.py @@ -10,7 +10,7 @@ from twisted.internet import protocol, defer from ooni.plugoo.tests import ITest, OONITest from ooni.plugoo.assets import Asset from ooni.utils import log -from ooni.protocols.scapy import ScapyTest +from ooni.protocols.scapyproto import ScapyTest
from ooni.lib.txscapy import txsr, txsend
diff --git a/ooni/protocols/b0wser.py b/ooni/protocols/b0wser.py index 94e535f..6a01d96 100644 --- a/ooni/protocols/b0wser.py +++ b/ooni/protocols/b0wser.py @@ -1,7 +1,11 @@ +from twisted.internet import protocol, defer +from twisted.internet.error import ConnectionDone + from ooni.utils import log +from ooni.plugoo import reports
import sys -from scapy.all import * # XXX recommended way of importing scapy? +from scapy.all import * import yaml
def get_b0wser_dictionary_from_pcap(filename): @@ -23,12 +27,12 @@ def get_b0wser_dictionary_from_pcap(filename): """ pcap assumptions:
- pcap only contains packets exchanged between a Tor client and a Tor - server. (This assumption makes sure that there are only two IP - addresses in the pcap file) + pcap only contains packets exchanged between a Tor client and a Tor server. + (This assumption makes sure that there are only two IP addresses in the + pcap file)
- The first packet of the pcap is sent from the client to the server. - (This assumption is used to get the IP address of the client.) + The first packet of the pcap is sent from the client to the server. (This + assumption is used to get the IP address of the client.)
All captured packets are TLS packets: that is TCP session establishment/teardown packets should be filtered out (no SYN/SYN+ACK) @@ -59,7 +63,7 @@ def get_b0wser_dictionary_from_pcap(filename): else: raise("Detected third IP address! pcap is corrupted.")
- return yaml.dump(messages) + return messages
class Mutator: idx = 0 @@ -115,7 +119,8 @@ class Mutator: returns True if another mutation is available. returns False if all the possible mutations have been done. """ - if self.step > len(self.steps): + if (self.step + 1) > len(self.steps): + # Hack to stop once we have gone through all the steps self.waiting = True return False
@@ -123,7 +128,10 @@ class Mutator: current_idx = self.idx current_step = self.step current_data = self.steps[current_step]['data'] - data_to_receive = self.steps[current_step]['wait'] + try: + data_to_receive = len(self.steps[current_step +1 ]['data']) + except: + print "No more data to receive"
if self.waiting and self.waiting_step == data_to_receive: log.debug("I am no longer waiting.") @@ -170,14 +178,14 @@ class B0wserProtocol(protocol.Protocol): For every instance of protocol there is only 1 mutation. Once the last step is reached the connection is closed on the serverside. """ - steps = [{'data': "STEP1", 'wait': 4}, - {'data': "STEP2", 'wait': 4}, - {'data': "STEP3", 'wait': 4}] + steps = [] mutator = None
+ role = 'client' state = 0 total_states = len(steps) - 1 received_data = 0 + to_receive_data = 0 report = reports.Report('b0wser', 'b0wser.yamlooni')
def next_state(self): @@ -185,8 +193,12 @@ class B0wserProtocol(protocol.Protocol): This is called once I have completed one step of the protocol and need to proceed to the next step. """ - data = self.mutator.get_mutation(self.state) - self.transport.write(data) + if self.role is self.steps[self.state]['sender']: + data = self.mutator.get_mutation(self.state) + self.transport.write(data) + self.to_receive_data = 0 + else: + self.to_receive_data = len(self.steps[self.state]['data']) self.state += 1 self.received_data = 0
@@ -204,8 +216,9 @@ class B0wserProtocol(protocol.Protocol): self.report(report) self.transport.loseConnection() return + self.received_data += len(data) - if self.received_data >= self.steps[self.state]['wait']: + if self.received_data >= self.to_receive_data: print "Moving to next state %s" % self.state self.next_state()
@@ -234,7 +247,7 @@ class B0wserProtocol(protocol.Protocol): or it may be because of a censorship event. """ report = {'reason': reason, 'proto_state': self.state, - 'mutator_state': self.mutator.state(), 'trigger': None} + 'trigger': None, 'mutator_state': self.mutator.state()}
if self.state < self.total_states: report['trigger'] = 'did not finish state walk' diff --git a/ooni/protocols/scapy.py b/ooni/protocols/scapy.py deleted file mode 100644 index 4166146..0000000 --- a/ooni/protocols/scapy.py +++ /dev/null @@ -1,55 +0,0 @@ -import random -from zope.interface import implements -from twisted.python import usage -from twisted.plugin import IPlugin -from twisted.internet import protocol, defer -from ooni.plugoo.tests import ITest, OONITest -from ooni.plugoo.assets import Asset -from ooni.utils import log - -from ooni.lib.txscapy import txsr, txsend - -class ScapyTest(OONITest): - """ - A utility class for writing scapy driven OONI tests. - """ - - receive = True - timeout = None - pcapfile = 'scapytest.pcap' - def initialize(self, reactor=None): - - if not self.reactor: - from twisted.internet import reactor - self.reactor = reactor - - self.request = {} - self.response = {} - - def experiment(self, args): - log.msg("Running experiment") - if self.receive: - log.msg("Sending and receiving packets.") - d = txsr(self.build_packets(), pcapfile=self.pcapfile, - timeout=self.timeout) - else: - log.msg("Sending packets.") - d = txsend(self.build_packets()) - - def finished(data): - log.msg("Finished sending") - return data - - d.addCallback(finished) - return d - - def build_packets(self): - """ - Override this method to build scapy packets. - """ - from scapy.all import IP, TCP - return IP()/TCP() - - def load_assets(self): - return {} - diff --git a/oonib/b0wser.py b/oonib/b0wser.py index 33501de..0bb89fb 100644 --- a/oonib/b0wser.py +++ b/oonib/b0wser.py @@ -25,6 +25,7 @@ class B0wserServer(protocol.ServerFactory): print "Moving on to next mutation" if not self.mutations[addr.host].next_mutation(): self.mutations.pop(addr.host) - p.mutator = self.mutations[addr.host] + else: + p.mutator = self.mutations[addr.host] return p
tor-commits@lists.torproject.org