[or-cvs] r14437: An initial version of the TorCheck ported into simple python (in check/trunk: . cgi-bin)

ioerror at seul.org ioerror at seul.org
Thu Apr 24 01:53:14 UTC 2008


Author: ioerror
Date: 2008-04-23 21:53:14 -0400 (Wed, 23 Apr 2008)
New Revision: 14437

Added:
   check/trunk/cgi-bin/index.py
   check/trunk/tor-detector-apache2-python-conf
Log:
An initial version of the TorCheck ported into simple python with a very basic example of how mod_python can be used to drive everything.


Added: check/trunk/cgi-bin/index.py
===================================================================
--- check/trunk/cgi-bin/index.py	                        (rev 0)
+++ check/trunk/cgi-bin/index.py	2008-04-24 01:53:14 UTC (rev 14437)
@@ -0,0 +1,206 @@
+#!/usr/bin/env python
+
+#
+# https://check.torproject.org - rewritten in python
+# By Jacob Appelbaum <jacob at appelbaum.net>
+# Written at ToorCon Seattle 2008 (Thanks for the great time h1kari!)
+# Thanks to Crispen for a power outlet :-)
+# 
+# Best used with the Debian package libapache2-mod-python
+#
+
+# Unused for now
+# import antigravity
+import DNS 
+from mod_python import apache
+from mod_python import util
+import cgitb; cgitb.enable()
+import gettext
+
+# i18n with Unicode!
+# We need to make some TorCheck.{po,pot,mo} files
+gettext.install('TorCheck','.', unicode=1)
+gettext.bind_textdomain_codeset('TorCheck', 'en_US')
+_ = gettext.gettext
+
+# 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):
+    # This is the exit node ip address
+    # This is where we want to dynamically recieve this from Apache
+    splitIp=clientIp.split('.')
+    ELExitNode = splitIp[-1] + "." + splitIp[-2] + "." + splitIp[-3] + "." + splitIp[-4]
+
+    # We'll attempt to reach this port on the Target host
+    ELPort = "80"
+
+    # We'll try to reach this host
+    ElTarget = "217.247.237.209"
+
+    # 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
+    answer=request.req()
+
+    # 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":
+	print "NXDOMAIN"
+	UsingTor=1
+    else:
+	if answer.answers:
+	   for i in answer.answers:
+	       if i['data'] == "127.0.0.2":
+		   UsingTor=0
+	       else:
+		   # We're getting unexpected data - fail closed
+	           UsingTor=2
+	else:
+		# We're getting unexpected data - fail closed
+	        UsingTor=2
+
+    return UsingTor
+
+# Now that we know everything we need, lets print the website
+def handler(req):
+
+    # We need to parse the client address (and eventually the port)
+    # We'll use this to contstruct the query
+    UsingTor = isUsingTor(req.connection.remote_ip)
+
+    # This is where we need to parse out lang:
+    # req.subprocess_env['QUERY_STRING'] = fa-IR
+    # Then, depending on what we have, we should compare it to a tuple
+
+    # Here's where we'll make the query and save the result
+
+    req.send_http_header()
+    req.content_type = 'text/html ;charset=utf-8'
+
+    # First lets construct the simple webpage:
+    req.write('<html>\n')
+    req.write('<body>\n')
+
+    req.write('Debug info: <br>')
+    req.write('UsingTor is set to: %s<br>' % UsingTor )
+
+    queryString = req.subprocess_env['QUERY_STRING']
+    user_supplied_lang = None
+
+    if queryString :
+        queries = queryString.split('&')
+
+        for query in queries:
+            key,value = query.split('=')
+	    # Currently, we only care about the sjmurdoch supplied 'lang'
+            if key == 'lang':
+                user_supplied_lang = value
+
+    # These are the locales we're supporting currently
+    # If the user passes in a locale that matches it, great
+    # However, anything that we don't support will result in us using a default locale
+    
+    default_locale = "en_US"
+    locale = default_locale
+    locales = ( default_locale, 'fa-IR')
+    
+    req.write("We have %i possible locales.\n<br>\n" % len(locales))
+    req.write("Our internal and supported locales are: ")
+    for item in locales:
+            req.write(item + " ")
+    req.write("<br>")
+    
+    if user_supplied_lang :
+        req.write("You have selected the locale of: %s\n<br>\n" % user_supplied_lang)
+    else:
+        req.write("You have not selected a locale\n<br>\n")
+
+    for item in locales:
+        if item == user_supplied_lang:
+            locale = item 
+            req.write("We have selected the locale of: %s\n<br>\n" % locale)
+            break
+
+    if locale != user_supplied_lang: 
+        req.write("We have selected the locale of: %s \n<br>\n" % locale)
+
+    req.write("\n<br><br>\n")
+
+    req.write('<title>Are you using Tor?</title>\n')
+    req.write('<center>\n')
+
+    if UsingTor == 0:
+        req.write('\n')
+	req.write('<img src="https://check.torproject.org/tor-on.png">\n<br>')
+	req.write('<h1 style="color: #0A0">\n')
+	req.write(_('Congratulations. You are using Tor.<br><br>'))
+	req.write('ﻡژﺪﻫ. ﺶﻣﺍ (ﺎﺤﺘﻣﺍﻻ) ﺩﺭ ﺡﺎﻟ ﺎﺴﺘﻓﺍﺪﻫ ﺍﺯ ﺕُﺭ ﻡی ﺏﺎﺷیﺩ.')
+	req.write('<br>\n<br>\n')
+	req.write('</h1>\n')
+	req.write('Please refer to the <a href="https://www.torproject.org/">Tor website</a> for further information about using Tor safely.<br><br>\n')
+	req.write('ﺥﻭﺎﻬﺸﻤﻧﺩ ﺎﺴﺗ ﻡﺭﺎﺠﻌﻫ کﻥیﺩ ﺐﻫ <a href="https://www.torproject.org/">ﻮﺑ ﺱﺍیﺕ ﺕُﺭ</a>  ﺏﺭی ﺎﻃﻼﻋﺎﺗ ﺏیﺶﺗﺭ ﺩﺮﻣﻭﺭﺩ ﺎﺴﺘﻓﺪﻫ ﺍیﻢﻧ ﺍﺯ ﺕُﺭ<br><bbr>')
+    
+    # This is the case where we have an NXDOMAIN and they aren't using Tor
+    elif UsingTor == 1:
+        req.write('\n')
+        req.write('<img src="https://check.torproject.org/tor-off.png">\n<br>')
+        req.write('<h1 style="color: #A00">')
+        req.write('Sorry. You are not using Tor.\n<br><br>')
+        req.write('پﻭﺰﺷ. ﺶﻣﺍ (ﺎﺤﺘﻣﺍﻻ) ﺩﺭ ﺡﺎﻟ ﺎﺴﺘﻓﺍﺪﻫ ﺍﺯ ﺕُﺭ ﻦﻣی ﺏﺎﺷیﺩ.\n<br><br>')
+        req.write('</h1>')
+        req.write('If you are attempting to use a Tor client, please refer to the <a href="https://www.torproject.org/">Tor website</a> and specifically the <a href="https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#ItDoesntWork">instructions for configuring your Tor client</a>.<br><br>')
+        req.write('ﺍگﺭ ﺲﻋی ﺩﺭ ﺎﺴﺘﻓﺍﺪﻫ ﺍﺯ یک کﺍﺮﺧﻭﺎﻫ ﺕُﺭ ﺭﺍ ﺩﺍﺭیﺩ, ﺥﻭﺎﻬﺸﻤﻧﺩ ﺎﺴﺗ ﻡﺭﺎﺠﻌﻫ کﻥیﺩ ﺐﻫ ')
+        req.write('<a href="https://www.torproject.org/">')
+	req.write('ﻮﺑ ﺱﺍیﺕ ﺕُﺭ')
+        req.write('</a> ')
+        req.write('ﻭ ﺏﻭیژﻩ ')
+        req.write('<a href="https://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ItDoesntWork">')
+	req.write('ﺪﺴﺗﻭﺭﺎﺗ ﺏﺭﺍی پیکﺮﺒﻧﺩی کﺍﺮﺧﻭﺎﻫ ﺕُﺭ.')
+        req.write('</a><br><br>')
+
+    # 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('\n')
+        req.write('<img src="https://check.torproject.org/tor-off.png">\n<br>')
+        req.write('<h1 style="color: #A00">\n')
+        req.write('Sorry, your query failed or an unexpected response was received.\n<br>')
+	req.write('</h1>')
+        req.write('A temporary service outage prevents us from determining if your source IP address is a <a href="https://www.torproject.org/">Tor</a> node.  For other ways to test whether you are using Tor, please visit <a href="https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#IsMyConnectionPrivate">this FAQ entry</a>.<br><br>')
+
+
+    # Now we'll close up this html rat hole
+    req.write('\n')
+    req.write('<br>\n');
+    req.write('<small>\n')
+    req.write('<p><tt>')
+    req.write('Additional information:<br>\n')
+    req.write('ﺎﻃﻼﻋﺎﺗ ﺕکﻡیﻝی:<br>\n')
+    req.write('Your IP appears to be: <b>%s</b><br>\n' % req.connection.remote_ip )
+    req.write('ﺁﺩﺮﺳ ﺁی پی ﺶﻣﺍ: <b>%s</b><br>\n' % req.connection.remote_ip )
+    req.write('This small script is powered by <a href="http://exitlist.torproject.org/">tordnsel</a><br><br>')
+    req.write('ﺍیﻥ ﺪﺴﺗ<200c>ﻧﻮﺸﺘﻫ کﻭچک ﺍﺭﺎﺌﻫ ﻡی ﺵﻭﺩ ﺏﻮﺳیﻞﻫ <a href="http://exitlist.torproject.org/">tordnsel</a><br><br>')
+    req.write('This server does not log <i>any</i> information about visitors.<br>')
+    req.write('ﺍیﻥ پیﺵکﺍﺭ ﻩیچ ﺎﻃﻼﻋﺎﺗی ﺩﺮﻣﻭﺭﺩ کﺍﺮﺑﺭﺎﻧ ﻢﻬﻣﺎﻧ ﺭﺍ ﺚﺒﺗ ﻦﻣی کﻥﺩ.<br>')
+    req.write('\n<br>\n')
+    req.write('It appears that you\'re trying to instruct us to use the following l10n:' + req.subprocess_env['QUERY_STRING'])
+    req.write('</tt></p>')
+    req.write('</small>')
+    req.write('</center>\n')
+    req.write('</body>')
+    req.write('</html>')
+
+    # We'll i18n the output to make this cleaner
+    # lang=XX is what we need to parse
+    # For testing, we will support one lang option: ?lang=fa-IR
+    # We'll implement this as a check against a tuple
+    #req.write(req.subprocess_env['QUERY_STRING'] + "<br>\n")
+
+    return apache.OK


Property changes on: check/trunk/cgi-bin/index.py
___________________________________________________________________
Name: svn:executable
   + *

Added: check/trunk/tor-detector-apache2-python-conf
===================================================================
--- check/trunk/tor-detector-apache2-python-conf	                        (rev 0)
+++ check/trunk/tor-detector-apache2-python-conf	2008-04-24 01:53:14 UTC (rev 14437)
@@ -0,0 +1,26 @@
+NameVirtualHost *
+<VirtualHost *>
+	ServerAdmin webmaster at localhost
+	
+	DocumentRoot /var/www/
+	<Directory />
+		Options FollowSymLinks
+		AllowOverride None
+	</Directory>
+
+	# Required for python stuff
+        <Directory /var/www/cgi-bin/> 
+     	   AddHandler mod_python .py
+	   PythonHandler index
+     	   PythonDebug On 
+        </Directory>
+
+	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
+	<Directory "/usr/lib/cgi-bin">
+		AllowOverride None
+		Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
+		Order allow,deny
+		Allow from all
+	</Directory>
+
+</VirtualHost>



More information about the tor-commits mailing list