Index: privacybadge.html =================================================================== --- privacybadge.html (revision 0) +++ privacybadge.html (revision 0) @@ -0,0 +1,44 @@ + + +
+
+

+
+ + Index: cgi-bin/JSONPCheck.py =================================================================== --- cgi-bin/JSONPCheck.py (revision 0) +++ cgi-bin/JSONPCheck.py (revision 0) @@ -0,0 +1,149 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" + TorCheck.py + + https://check.torproject.org - originally in perl, rewritten in python + + By Jacob Appelbaum + Written at ToorCon Seattle 2008 (Thanks for the great time h1kari!) + Thanks to Crispen for a power outlet :-) + + Additional python suggestions from nickm + + Best used with the Debian packages: + python-dns + libapache2-mod-python + locales-all + +""" + +__program__ = 'TorCheck.py' +__version__ = '20100429.01' +__url__ = 'https://svn.torproject.org/svn/check/' +__author__ = 'Jacob Appelbaum ' +__copyright__ = 'Copyright (c) 2008, Jacob Appelbaum' +__license__ = 'See LICENSE for licensing information' + +try: + from future import antigravity +except ImportError: + antigravity = None + +import cgi +import DNS +from DNS import DNSError +# This is pydns and can be downloaded from http://pydns.sourceforge.net/ +# Or use the Debian package listed above +import cgitb; cgitb.enable() +import gettext +import locale +import os + +#os.environ['LOCPATH']='/usr/share/locale:/srv/check.torproject.org/trunk/i18n/locale' +localedir ='/srv/check.torproject.org/trunk/i18n/locale' + +# We could also explictly query the remote EL server +# This is not as good as using a cache for obvious reasons +DNS.DiscoverNameServers() + +def isUsingTor(clientIp, ELPort): + # This is the exit node ip address + # This is where we want to dynamically recieve this from Apache + splitIp = clientIp.split('.') + splitIp.reverse() + ELExitNode = ".".join(splitIp) + + # We'll attempt to reach this port on the Target host + # ELPort is now set by the caller + + # We'll try to reach this host + ElTarget = "38.229.70.31" + + # This is the ExitList DNS server we want to query + ELHost = "ip-port.exitlist.torproject.org" + + # Prepare the question as an A record request + ELQuestion = ELExitNode + "." + ELPort + "." + ElTarget + "." + ELHost + request = DNS.DnsRequest(name=ELQuestion,qtype='A') + + # Ask the question and load the data into our answer + try: + answer=request.req() + except DNSError: + return 2 + + # Parse the answer and decide if it's allowing exits + # 127.0.0.2 is an exit and NXDOMAIN is not + if answer.header['status'] == "NXDOMAIN": + # We're not exiting from a Tor exit + return 1 + else: + if not answer.answers: + # We're getting unexpected data - fail closed + return 2 + for a in answer.answers: + if a['data'] != "127.0.0.2": + return 2 + # If we're here, we've had a positive exit answer + return 0 + + +def isUpToDate(queryString): + """ + determine if TBB is aware of newer versions + """ + if 'uptodate=1' in queryString.lower(): + return True + if 'uptodate=0' in queryString.lower(): + return False + # This will be true until Torbutton 1.4.4 is released + if 'small=1' in queryString.lower(): + return False + + # The default case; No update information to provide + return True + +def handler(req, environ, start_response): + # Make a DNS request to the EL and decide what to tell the user + UsingTor = isUsingTor(environ['REMOTE_ADDR'], "80") + # Try to hit a cornercase where the user can exit to 443 but not 80 + if UsingTor != 0: + UsingTor = isUsingTor(environ['REMOTE_ADDR'], "443") + + # figure out if the client passed uptodate=0 or uptodate=1 + # defaults to 1 if uptodate was not present in the query string + UpToDate = isUpToDate(environ['QUERY_STRING']) + + response_headers = [('Content-type', 'text/html; charset=utf-8')] + start_response('200 OK', response_headers) + + data = cgi.FieldStorage() + callback = data.getvalue('callback') + + if callback: + if UsingTor == 0: + req.write(callback + "({'Tor': True});") + # This is the case where we have an NXDOMAIN and they aren't using Tor + elif UsingTor == 1: + req.write(callback + "({'Tor': False});") + # This means we have some strange data response we don't understand + # It's better that we fail closed and let the user know everything went wrong + elif UsingTor == 2: + req.write(callback + "({'Tor': 'Error'});") + + else: + req.write("No callback set") + +class FakeReq(list): + def write(self, str): + self.append(str) + +def application(environ, start_response): + req = FakeReq() + handler(req, environ, start_response) + return req + +# vim:set ts=4: +# vim:set et: +# vim:set shiftwidth=4: Property changes on: cgi-bin/JSONPCheck.py ___________________________________________________________________ Added: svn:executable + *