commit 198a635527a8afd4bbd9606c0925f740ae6f0df9 Author: Arturo Filastò art@torproject.org Date: Sat Jul 21 02:41:55 2012 +0200
Add support for config file for OONIB. Refactor backend code. --- ooni/utils/config.py | 2 +- oonib/backends/daphn3.py | 33 +++++++++++++++++++ oonib/backends/dns.py | 16 +++++++++ oonib/backends/http.py | 74 ++++++++++++++++++++++++++++++++++++++++++++ oonib/daphn3.py | 33 ------------------- oonib/dnsbackend.py | 16 --------- oonib/httpbackend.py | 74 -------------------------------------------- oonib/oonibackend.conf | 7 ++++ oonib/oonibackend.py | 21 ++++++++---- 9 files changed, 145 insertions(+), 131 deletions(-)
diff --git a/ooni/utils/config.py b/ooni/utils/config.py index 42a14f6..ab43e66 100644 --- a/ooni/utils/config.py +++ b/ooni/utils/config.py @@ -1,5 +1,5 @@ import ConfigParser -from utils import Storage +from ooni.utils import Storage
class Config(Storage): """ diff --git a/oonib/backends/__init__.py b/oonib/backends/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oonib/backends/daphn3.py b/oonib/backends/daphn3.py new file mode 100644 index 0000000..a8290e3 --- /dev/null +++ b/oonib/backends/daphn3.py @@ -0,0 +1,33 @@ +from twisted.internet import protocol +from twisted.internet.error import ConnectionDone + +from ooni.plugoo import reports +from ooni.protocols.daphn3 import Mutator, Daphn3Protocol + +class Daphn3Server(protocol.ServerFactory): + """ + This is the main class that deals with the daphn3 server side component. + We keep track of global state of every client here. + Every client is identified by their IP address and the state of mutation is + stored by using their IP address as a key. This may lead to some bugs if + two different clients are sharing the same IP, but hopefully the + probability of such thing is not that likely. + """ + protocol = Daphn3Protocol + mutations = {} + def buildProtocol(self, addr): + p = self.protocol() + p.factory = self + + if addr.host not in self.mutations: + self.mutations[addr.host] = Mutator(p.steps) + else: + print "Moving on to next mutation" + if not self.mutations[addr.host].next_mutation(): + self.mutations.pop(addr.host) + try: + p.mutator = self.mutations[addr.host] + except: + pass + return p + diff --git a/oonib/backends/dns.py b/oonib/backends/dns.py new file mode 100644 index 0000000..689d1a4 --- /dev/null +++ b/oonib/backends/dns.py @@ -0,0 +1,16 @@ +from twisted.internet.protocol import Factory, Protocol +from twisted.internet import reactor +from twisted.names import dns +from twisted.names import client, server + +class ProxyDNSServer(server.DNSServerFactory): + def __init__(self, authorities = None, + caches = None, clients = None, + verbose = 0): + resolver = client.Resolver(servers=[('8.8.8.8', 53)]) + server.DNSServerFactory.__init__(self, authorities = authorities, + caches = caches, clients = [resolver], + verbose = verbose) + def handleQuery(self, message, protocol, address): + print message, protocol, address + server.DNSServerFactory.handleQuery(self, message, protocol, address) diff --git a/oonib/backends/http.py b/oonib/backends/http.py new file mode 100644 index 0000000..79a487b --- /dev/null +++ b/oonib/backends/http.py @@ -0,0 +1,74 @@ +import json +import random +import string + +from twisted.application import internet, service +from twisted.internet import protocol, reactor, defer +from twisted.protocols import basic +from twisted.web import resource, server, static +from twisted.web.microdom import escape + +server.version = "Apache" + +class HTTPRandomPage(resource.Resource): + """ + This generates a random page of arbitrary length and containing the string + selected by the user. + The format is the following: + /random/<length>/<keyword> + """ + isLeaf = True + def _gen_random_string(self, length): + return ''.join(random.choice(string.letters) for x in range(length)) + + def genRandomPage(self, length=100, keyword=None): + data = self._gen_random_string(length/2) + if keyword: + data += keyword + data += self._gen_random_string(length - length/2) + data += '\n' + return data + + def render(self, request): + length = 100 + keyword = None + path_parts = request.path.split('/') + if len(path_parts) > 2: + length = int(path_parts[2]) + if length > 100000: + length = 100000 + + if len(path_parts) > 3: + keyword = escape(path_parts[3]) + + return self.genRandomPage(length, keyword) + +class HTTPReturnHeaders(resource.Resource): + """ + This returns the headers being sent by the client in JSON format. + """ + isLeaf = True + def render(self, request): + req_headers = request.getAllHeaders() + return json.dumps(req_headers) + +class HTTPSendHeaders(resource.Resource): + """ + This sends to the client the headers that they send inside of the POST + request encoded in json. + """ + isLeaf = True + def render_POST(self, request): + headers = json.loads(request.content.read()) + for header, value in headers.items(): + request.setHeader(str(header), str(value)) + return '' + +class HTTPBackend(resource.Resource): + def __init__(self): + resource.Resource.__init__(self) + self.putChild('random', HTTPRandomPage()) + self.putChild('returnheaders', HTTPReturnHeaders()) + self.putChild('sendheaders', HTTPSendHeaders()) + + diff --git a/oonib/daphn3.py b/oonib/daphn3.py deleted file mode 100644 index 22aef49..0000000 --- a/oonib/daphn3.py +++ /dev/null @@ -1,33 +0,0 @@ -from twisted.internet import protocol -from twisted.internet.error import ConnectionDone - -from ooni.plugoo import reports -from ooni.protocols.daphn3 import Mutator, daphn3Protocol - -class daphn3Server(protocol.ServerFactory): - """ - This is the main class that deals with the daphn3 server side component. - We keep track of global state of every client here. - Every client is identified by their IP address and the state of mutation is - stored by using their IP address as a key. This may lead to some bugs if - two different clients are sharing the same IP, but hopefully the - probability of such thing is not that likely. - """ - protocol = daphn3Protocol - mutations = {} - def buildProtocol(self, addr): - p = self.protocol() - p.factory = self - - if addr.host not in self.mutations: - self.mutations[addr.host] = Mutator(p.steps) - else: - print "Moving on to next mutation" - if not self.mutations[addr.host].next_mutation(): - self.mutations.pop(addr.host) - try: - p.mutator = self.mutations[addr.host] - except: - pass - return p - diff --git a/oonib/dnsbackend.py b/oonib/dnsbackend.py deleted file mode 100644 index 689d1a4..0000000 --- a/oonib/dnsbackend.py +++ /dev/null @@ -1,16 +0,0 @@ -from twisted.internet.protocol import Factory, Protocol -from twisted.internet import reactor -from twisted.names import dns -from twisted.names import client, server - -class ProxyDNSServer(server.DNSServerFactory): - def __init__(self, authorities = None, - caches = None, clients = None, - verbose = 0): - resolver = client.Resolver(servers=[('8.8.8.8', 53)]) - server.DNSServerFactory.__init__(self, authorities = authorities, - caches = caches, clients = [resolver], - verbose = verbose) - def handleQuery(self, message, protocol, address): - print message, protocol, address - server.DNSServerFactory.handleQuery(self, message, protocol, address) diff --git a/oonib/httpbackend.py b/oonib/httpbackend.py deleted file mode 100644 index 79a487b..0000000 --- a/oonib/httpbackend.py +++ /dev/null @@ -1,74 +0,0 @@ -import json -import random -import string - -from twisted.application import internet, service -from twisted.internet import protocol, reactor, defer -from twisted.protocols import basic -from twisted.web import resource, server, static -from twisted.web.microdom import escape - -server.version = "Apache" - -class HTTPRandomPage(resource.Resource): - """ - This generates a random page of arbitrary length and containing the string - selected by the user. - The format is the following: - /random/<length>/<keyword> - """ - isLeaf = True - def _gen_random_string(self, length): - return ''.join(random.choice(string.letters) for x in range(length)) - - def genRandomPage(self, length=100, keyword=None): - data = self._gen_random_string(length/2) - if keyword: - data += keyword - data += self._gen_random_string(length - length/2) - data += '\n' - return data - - def render(self, request): - length = 100 - keyword = None - path_parts = request.path.split('/') - if len(path_parts) > 2: - length = int(path_parts[2]) - if length > 100000: - length = 100000 - - if len(path_parts) > 3: - keyword = escape(path_parts[3]) - - return self.genRandomPage(length, keyword) - -class HTTPReturnHeaders(resource.Resource): - """ - This returns the headers being sent by the client in JSON format. - """ - isLeaf = True - def render(self, request): - req_headers = request.getAllHeaders() - return json.dumps(req_headers) - -class HTTPSendHeaders(resource.Resource): - """ - This sends to the client the headers that they send inside of the POST - request encoded in json. - """ - isLeaf = True - def render_POST(self, request): - headers = json.loads(request.content.read()) - for header, value in headers.items(): - request.setHeader(str(header), str(value)) - return '' - -class HTTPBackend(resource.Resource): - def __init__(self): - resource.Resource.__init__(self) - self.putChild('random', HTTPRandomPage()) - self.putChild('returnheaders', HTTPReturnHeaders()) - self.putChild('sendheaders', HTTPSendHeaders()) - - diff --git a/oonib/oonibackend.conf b/oonib/oonibackend.conf new file mode 100644 index 0000000..864df1e --- /dev/null +++ b/oonib/oonibackend.conf @@ -0,0 +1,7 @@ +[main] +http_port = 8080 +dns_udp_port = 5354 +dns_tcp_port = 8002 +daphn3_port = 9666 +[daphn3] +pcap_file = 'server.pcap' diff --git a/oonib/oonibackend.py b/oonib/oonibackend.py index 22a8728..2ad7f34 100755 --- a/oonib/oonibackend.py +++ b/oonib/oonibackend.py @@ -16,23 +16,30 @@ from twisted.web import resource, server, static from twisted.web.microdom import escape from twisted.names import dns
-from oonib.httpbackend import HTTPBackend -from oonib.dnsbackend import ProxyDNSServer -from oonib.daphn3 import Daphn3Server +from ooni.utils import Storage +from ooni.utils.config import Config + +from oonib.backends.http import HTTPBackend +from oonib.backends.dns import ProxyDNSServer +from oonib.backends.daphn3 import Daphn3Server + +config = Storage() +config.main = Config('main', 'oonibackend.conf') +config.daphn3 = Config('daphn3', 'oonibackend.conf')
# This tells twisted to set the server.version = "Apache"
application = service.Application('oonibackend') serviceCollection = service.IServiceCollection(application) -internet.TCPServer(2000, server.Site(HTTPBackend())).setServiceParent(serviceCollection) +internet.TCPServer(int(config.main.http_port), server.Site(HTTPBackend())).setServiceParent(serviceCollection)
# Start the DNS Server related services TCPDNSServer = ProxyDNSServer() -internet.TCPServer(8002, TCPDNSServer).setServiceParent(serviceCollection) +internet.TCPServer(int(config.main.dns_tcp_port), TCPDNSServer).setServiceParent(serviceCollection) UDPFactory = dns.DNSDatagramProtocol(TCPDNSServer) -internet.UDPServer(5354, UDPFactory).setServiceParent(serviceCollection) +internet.UDPServer(int(config.main.dns_udp_port), UDPFactory).setServiceParent(serviceCollection)
# Start the ooni backend thing daphn3 = Daphn3Server() -internet.TCPServer(9666, daphn3).setServiceParent(serviceCollection) +internet.TCPServer(int(config.main.daphn3_port), daphn3).setServiceParent(serviceCollection)
tor-commits@lists.torproject.org