#!/usr/bin/python

import os

def collect_headers():
	log = ""
	for (k,v) in os.environ.iteritems():
		if k.find("HTTP_") != -1:
			log = log + k + ":" + v + ";+;"
		if k.find("REQUEST_URI") != -1:
			log = log + k + ":" + v + ";+;"
		if k.find("REMOTE_ADDR") != -1:
			log = log + k + ":" + v + ";+;"
	return log

def fromHex(v):
	b = int(v, 16)
	return b & 0xFF

def netrange(ip):
	if ip.find("209.167.") == 0:
		return "Verizon"
	if ip.find("193.35.") == 0:
		return "Orange"
	if ip.find("212.9.") == 0:
		return "Jersey Telecom"
	if ip.find("208.54.") == 0:
		return "T-Mobile USA"
	if ip.find("213.161.85.") == 0:
		return "Abovenet Communications Europe Ltd"
	if ip.find("213.161.") == 0:
		return "Elisa Oyj"
	if ip.find("203.196.") == 0:
		return "Tata Internet Services Ltd"
	if ip.find("84.23.") == 0:
		return "Ettihad Etisalat Corp"
	if ip.find("210.212.") == 0:
		return "BSNL Mobile MSC for west zone at Pune"
	if ip.find("124.124.") == 0:
		return "Reliance Communications Ltd"
	if ip.find("207.245.") == 0:
		return "Allstream Corp., Canada"
	if ip.find("213.26.") == 0:
		return "Telecom Italia SPA"
	if ip.find("203.145.") == 0:
		return "Idea Celular"
	if ip.find("139.7.") == 0:
		return "Vodafone D2 GmbH"
	if ip.find("205.205.") == 0:
		return "Rogers Wireless Inc."
	if ip.find("74.198.") == 0:
		return "Rogers Wireless Inc."
	if ip.find("200.255.") == 0:
		return "ATL TELECOM LESTE S.A., Brasil"
	if ip.find("196.207.") == 0:
		return "Vodacom Internet"
	if ip.find("94.16") == 0:
		return "H3G Italia S.p.A."
	else:
		return "-"

def countrycode(tno):
	msisdn = tno
	if len(tno) <= 0:
		return None
	if tno[0] == "+":
		msisdn = tno[1:]
	if tno.find("CSD,") == 0:
		msisdn = tno[4:]
	if msisdn.find("49") == 0:
		return "Germany"
	if msisdn.find("216") == 0:
		return "Tunisia"
	if msisdn.find("267") == 0:
		return "Botswana"
	if msisdn.find("965") == 0:
		return "Kuwait"
	if msisdn.find("20") == 0:
		return "Egypt"
	if msisdn.find("260") == 0:
		return "Zambia"
	if msisdn.find("592") == 0:
		return "Guyana"
	if msisdn.find("977") == 0:
		return "Nepal"
	if msisdn.find("380") == 0:
		return "Ukraine"
	if msisdn.find("228") == 0:
		return "Togo"
	if msisdn.find("31") == 0:
		return "Netherlands"
	if msisdn.find("374") == 0:
		return "Armenia"
	if msisdn.find("790") == 0:
		return "Tuvalu - Mobile"
	if msisdn.find("972") == 0:
		return "Israel"
	if msisdn.find("593") == 0:
		return "Ecuador"
	if msisdn.find("213") == 0:
		return "Algeria"
	if msisdn.find("507") == 0:
		return "Panama"
	if msisdn.find("962") == 0:
		return "Jordan"
	if msisdn.find("595") == 0:
		return "Paraguay"
	if msisdn.find("95") == 0:
		return "Myanmar"
	if msisdn.find("64") == 0:
		return "New Zealand"
	if msisdn.find("230") == 0:
		return "Mauritius"
	if msisdn.find("996") == 0:
		return "Kyrgyzstan"
	elif msisdn.find("44") == 0:
		return "United Kingdom"
	elif msisdn.find("58") == 0:
		return "Venezuela"
	elif msisdn.find("98") == 0:
		return "Iran"
	elif msisdn.find("92") == 0:
		return "Pakistan"
	elif msisdn.find("91") == 0:
		return "India"
	elif msisdn.find("998") == 0:
		return "Uzbekistan"
	elif msisdn.find("880") == 0:
		return "Bangladesh"
	elif msisdn.find("51") == 0:
		return "Peru"
	elif msisdn.find("796") == 0:
		return "Brazil - Belo Horizonte"
	elif msisdn.find("27") == 0:
		return "South Africa"
	elif msisdn.find("63") == 0:
		return "Philippines"
	elif msisdn.find("255") == 0:
		return "Tanzania"
	elif msisdn.find("65") == 0:
		return "Singapore"
	elif msisdn.find("218") == 0:
		return "Libya"
	elif msisdn.find("90") == 0:
		return "Turkey"
	elif msisdn.find("225") == 0:
		return "Ivory Coast"
	elif msisdn.find("84") == 0:
		return "Vietnam"
	elif msisdn.find("40") == 0:
		return "Romania"
	elif msisdn.find("86") == 0:
		return "China"
	elif msisdn.find("673") == 0:
		return "Brunei"
	elif msisdn.find("94") == 0:
		return "Sri Lanka"
	elif msisdn.find("39") == 0:
		return "Italy"
	elif msisdn.find("358") == 0:
		return "Finland"
	elif msisdn.find("353") == 0:
		return "Ireland"
	elif msisdn.find("590") == 0:
		return "Guadeloupe"
	elif msisdn.find("387") == 0:
		return "Bosnia and Herzegovina"
	elif msisdn.find("382") == 0:
		return "Montenegro"
	elif msisdn.find("33") == 0:
		return "France"
	elif msisdn.find("43") == 0:
		return "Austria"
	elif msisdn.find("234") == 0:
		return "Nigeria"
	elif msisdn.find("256") == 0:
		return "Uganda"
	elif msisdn.find("966") == 0:
		return "Saudi Arabia"
	elif msisdn.find("60") == 0:
		return "Malaysia"
	elif msisdn.find("598") == 0:
		return "Uruguay"
	elif msisdn.find("229") == 0:
		return "Benin"
	elif msisdn.find("55") == 0:
		return "Brazil"
	elif msisdn.find("61") == 0:
		return "Australia"
	elif msisdn.find("1") == 0:
		return "USA/Canada"
	return None

def getno(no):
	if no.find(" ") != -1:
		v = no.split(" ")
		for i in v:
			if i.find(".") == -1:
				return i
	else:
		return no

line = collect_headers()
lines = 0
loutl = ""
loutlnoip = ""
outlnoip = ""
alt = ""
lc = 0
countrycount = {}
double = {}
curmsisdn = ""
outl = ""
yes = 0
cc = None
while line != "":
	lines = lines + 1
	items = line.split(";+;")
	cr = ""
	for i in items:
		k = i.split(":",1)
		key = None
		value = None
		for j in k:
			if key == None:
				key = j
			else:
				if value != None:
					value = value + ":" + j
				else:
					value = j
		if key == "\n":
			continue	
		if value != None and len(value) < 5:
			continue
		if value == None:
			continue	
		
		if value.find("MSISDN") != -1 and key.find("AUTHMETHOD") == -1:
			outl = outl + "<b>MSISDN (" + key + "):<br> " + value + "</b> <br><br>"
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)
			if value.find("X-SDP-MSISDN") != -1:
				if cc == None:
					curmsisdn = getno(value[13:])
					cc = countrycode(curmsisdn)
		if value.find("msisdn") != -1 and value.find("User-Identity-Forward-msisdn") == -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)

		if value.find("msisdn") != -1 and value.find("User-Identity-Forward-msisdn") != -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			no = ""
			a = value.split("=")
			c = 0
			for i in a:
				if i.find("msisdn") != -1:
					cf = c + 1
				c = c + 1
			b = a[cf].split(";")
			if len(str(b[0])) > 12 and b[0].find("+") == -1:
				for i in range(0, len(b[0])/2):
					no = no + chr(fromHex(b[0][i*2:(i*2)+2]))
				outl = outl + "<b>Decoded MSISDN: " + no + "</b><br> "
				no = no
			else:
				no = str(b[0])
			curmsisdn = getno(no)
			if cc == None:
				cc = countrycode(curmsisdn)

		if key.find("RAPMIN") != -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)

		if key.find("JINNY_CID") != -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)

		if (key.find("CLID") != -1 or key.find("LSID") != -1) and value.find(".") == -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)

		if key.find("MSISDN") != -1:
			outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			no = ""
			if len(curmsisdn) > 12 and curmsisdn.find("+") == -1 and curmsisdn.find("MSP") == -1:
				for i in range(0, len(curmsisdn)/2):
					no = no + chr(fromHex(curmsisdn[i*2:(i*2)+2]))
				outl = outl + "<b>Decoded MSISDN: " + no + "</b><br> "
				curmsisdn = no
			if cc == None:
				cc = countrycode(curmsisdn)

		if key.find("UP_CALLING_LINE_ID") != -1 and value.find(".") == -1:
			outl = outl + "<b>MSISDN (" + key + "):<br> " + value + "</b><br> "
			yes = 1
			curmsisdn = getno(value)
			if cc == None:
				cc = countrycode(curmsisdn)

		if key.find("NETWORK_INFO") != -1 and value.count(".") >= 4:
			if value.find("TCP") == -1 and value.find("UDP") == -1 and value.find("UMTS") == -1 and value.find("GPRS") == -1:
				outl = outl + "<b>MSISDN (" + key + "): " + value + "</b><br> "
				yes = 1
				curmsisdn = getno(value)
				if cc == None:
					cc = countrycode(curmsisdn)

		if key.find("IMEI") != -1:
			outl = outl + "IMEI (" + key + "): " + value + "<br> "
			#yes = 1
		if key.find("APN") != -1:
			outl = outl + "APN (" + key + "): " + value + "<br> "
		if key.find("BEARER") != -1:
			outl = outl + "BEARER (" + key + "): " + value + "<br> "
		if key.find("IMSI") != -1:
			outl = outl + "IMSI (" + key + "): " + value + "<br> "
		if key.find("REMOTE_ADDR") != -1:
			outlnoip = outl
			#outl = outl + "IP: <a href=\"http://whois.domaintools.com/" + value + "\">" + value + "</a> "
			outl = outl + "IP: " + value + " "
			outl = outl + "(" + netrange(value) + ")<br> " 
		if key.find("HTTP_X_FORWARDED_FOR") != -1:
			val = value.split(",")
			val = val[0]
			#outl = outl + "IP (HTTP_X_FORWARED_FOR): <a href=\"http://whois.domaintools.com/" + val + "\">" + val + "</a> "
			outl = outl + "IP (HTTP_X_FORWARED_FOR): " + val + " "
			outl = outl + "(" + netrange(val) + ")<br> " 
		if key.find("AGENT") != -1:
			outlnoip = outlnoip + key + ":" + value + " "
			#val = value.split("/")
			#val = val[0]
			#outl = outl + key + ":" + value + " " + "<a href=\"http://www.google.com/search?q=" + val + "\">" + val + "</a> "
			outl = outl + key + ":" + value + "<br> "

	if yes == 1:
		if double.has_key(curmsisdn):
			double[curmsisdn] = double[curmsisdn] + 1		
		else:
			double[curmsisdn] = 1
			if cc != None:
				outl = outl + "<i>Country: " + cc + "</i>"
				if countrycount.has_key(cc):
					countrycount[cc] = countrycount[cc] + 1
				else:
					countrycount[cc] = 1 
				outl = outl + "\n"
				lc = lc + 1
			else:
				alt = alt + outl + "\n"
				lc = lc + 1

	#print line
	#print lc
	break


print "Content-Type: text/html\n"
if yes >= 1:
	print "<html><head><title>MNO Privacy Checker</title></head><body bgcolor=#770000>\n"
	print "<center><h1>MNO Privacy Checker</h1></center>"
	print "<br><center>by Collin Mulliner</center>"
	print "<br><center><a href=\"mailto:collin-mnopc[AT]mulliner.org\">collin-mnopc[at]mulliner.org</a></center>"
	print "<br><center><a href=\"http://www.mulliner.org/security/httpheaderprivacy.php\">HTTP Header Privacy info page</a></center>"
	print "<br>"
	print "<center>The data shown by the MNO Privacy Checker is not stored, however the visit to this website is stored for 24-48 hours.</center>"
	print "<br>"
	print "<center><h2>Looks like you have a problem</h2></center>"
	print "<br>"
	if cc == None: 
		print alt
	else:
		print outl
else:
	print "<html><head><title>MNO Privacy Checker</title></head><body bgcolor=#006600>\n"
	print "<center><h1>MNO Privacy Checker</h1></center>"
	print "<br><center>by Collin Mulliner</center>"
	print "<br><center><a href=\"mailto:collin-mnopc[AT]mulliner.org\">collin-mnopc[at]mulliner.org</a></center>"
	print "<br><center><a href=\"http://www.mulliner.org/security/httpheaderprivacy.php\">HTTP Header Privacy info page</a></center>"

	print "<br>"
	print "<center>The data shown by the MNO Privacy Checker is not stored, however the visit to this website is stored for 24-48 hours.</center>"
	print "<br>"
	print "<center><h2>No obvious problem detected</h2></center>"
	print "<br>"
print "<br>"
print "<br>"
print "<b>Your HTTP Headers as seen by us</b>"
print "<ul>"
print "<table border=0>"
for (k,v) in os.environ.iteritems():
	if k.find("HTTP_") != -1 or k.find("REQUEST_URI") != -1 or k.find("REMOTE_ADDR") != -1:
		print "<tr><td align=left>" + k + "</td><td align=left>" + v + "</td></tr>\n"
print "</table>"
print "</ul>"

print "</body></html>"
