[tor-commits] [ooni-probe/master] First pass at implementing test for Facebook Messenger
art at torproject.org
art at torproject.org
Fri Jan 13 12:39:57 UTC 2017
commit 4d2a344a05ac4db2aa551d685e277748b87f40b3
Author: Arturo Filastò <arturo at filasto.net>
Date: Thu Sep 22 18:12:04 2016 +0200
First pass at implementing test for Facebook Messenger
---
ooni/nettests/blocking/facebook_messenger.py | 151 +++++++++++++++++++++++++++
1 file changed, 151 insertions(+)
diff --git a/ooni/nettests/blocking/facebook_messenger.py b/ooni/nettests/blocking/facebook_messenger.py
new file mode 100644
index 0000000..787d7ad
--- /dev/null
+++ b/ooni/nettests/blocking/facebook_messenger.py
@@ -0,0 +1,151 @@
+# -*- encoding: utf-8 -*-
+
+from twisted.internet import defer, reactor
+from twisted.python import usage
+from twisted.internet.endpoints import TCP4ClientEndpoint
+
+from ooni.geoip import ip_to_location
+from ooni.utils import log
+from ooni.common.tcp_utils import TCPConnectFactory
+from ooni.errors import failureToString
+
+from ooni.templates import httpt, dnst
+
+
+class UsageOptions(usage.Options):
+ pass
+
+
+FB_HOSTNAMES = {
+ 'stun': "stun.fbsbx.com",
+ 'b-api': "b-api.facebook.com",
+ 'b-graph': "b-graph.facebook.com",
+ 'edge': "edge-mqtt.facebook.com",
+ 'external-cdn': "external.xx.fbcdn.net",
+ 'scontent-cdn': "scontent.xx.fbcdn.net",
+ 'star': "star.c10r.facebook.com"
+}
+
+def is_facebook_ip(ip_address):
+ """
+ :return: True when the IP in questions belongs to the facebook ASN
+ """
+ try:
+ location = ip_to_location(ip_address)
+ return location['asn'] == 'AS32934'
+ except:
+ return False
+
+class FacebookMessengerTest(httpt.HTTPTest, dnst.DNSTest):
+ name = "Facebook Messenger"
+ description = ("This test checks to see if the servers used by Facebook "
+ "messenger are reachable")
+ author = "Arturo Filastò"
+ version = "0.1.0"
+
+ requiresRoot = False
+ requiresTor = False
+ followRedirects = True
+ usageOptions = UsageOptions
+
+ def setUp(self):
+ for key in FB_HOSTNAMES.keys():
+ self.report['facebook-{0}-dns-consistent'.format(key)] = None
+ self.report['facebook-{0}-reachable'.format(key)] = None
+
+ self.report['facebook-tcp-blocking'] = None
+ self.report['facebook-dns-blocking'] = None
+ self.report['tcp_connect'] = []
+
+ def _test_connect_to_port(self, address, port):
+ result = {
+ 'ip': address,
+ 'port': port,
+ 'status': {
+ 'success': None,
+ 'failure': None
+ }
+ }
+ point = TCP4ClientEndpoint(reactor, address, port, timeout=10)
+ d = point.connect(TCPConnectFactory())
+ @d.addCallback
+ def cb(p):
+ result['status']['success'] = True
+ result['status']['failure'] = False
+ self.report['tcp_connect'].append(result)
+
+ @d.addErrback
+ def eb(failure):
+ result['status']['success'] = False
+ result['status']['failure'] = failureToString(failure)
+ self.report['tcp_connect'].append(result)
+
+ return d
+
+ def _test_tcp_connect(self, consistent_addresses):
+ for key, addresses in consistent_addresses.items():
+ if key == 'stun':
+ # XXX we currently don't test stun
+ continue
+
+ dl = []
+ for address in addresses:
+ dl.append(self._test_connect_to_port(address, 443))
+ results = yield defer.DeferredList(dl, consumeErrors=True)
+ tcp_blocked = False
+ for success, result in results:
+ if success == False:
+ tcp_blocked = True
+
+ if tcp_blocked == True:
+ log.msg("{0} server is blocked based on TCP".format(key))
+ self.report['facebook-{0}-reachable'.format(key)] = not tcp_blocked
+
+ @defer.inlineCallbacks
+ def _test_dns_resolution(self):
+ consistent_addresses = {}
+ for key, hostname in FB_HOSTNAMES.items():
+ consistent_addresses[key] = []
+ consistent = False
+ try:
+ addresses = yield self.performALookup(hostname)
+ for address in addresses:
+ if is_facebook_ip(address):
+ consistent = True
+ consistent_addresses[key].append(address)
+ except Exception:
+ log.err("Failed to lookup {0}: {1}".format(key, hostname))
+ finally:
+ msg = "{0}: {1} appears to present ".format(key, hostname)
+ if consistent == True:
+ msg += "consistent DNS"
+ else:
+ msg += "inconsistent DNS"
+ log.msg(msg)
+ self.report['facebook-{0}-dns-consistent'.format(key)] = consistent
+
+ defer.returnValue(consistent_addresses)
+
+ @defer.inlineCallbacks
+ def test_endpoints(self):
+ consistent_addresses = yield self._test_dns_resolution()
+ yield self._test_tcp_connect(consistent_addresses)
+ dns_blocking = False
+ tcp_blocking = False
+ for key in FB_HOSTNAMES.keys():
+ if self.report['facebook-{0}-dns-consistent'.format(key)] == False:
+ dns_blocking = True
+ log.msg("{0} is blocked due to DNS blocking".format(key))
+ continue
+
+ # XXX We ignore stun reachability as it requires UDP
+ if key == 'stun':
+ continue
+ if self.report['facebook-{0}-reachable'.format(key)] == False:
+ tcp_blocking = True
+ log.msg("{0} is blocked due to TCP/IP blocking".format(key))
+ continue
+ log.msg("{0} no blocking detected".format(key))
+
+ self.report['facebook-tcp-blocking'] = tcp_blocking
+ self.report['facebook-dns-blocking'] = dns_blocking
More information about the tor-commits
mailing list