#!/usr/bin/env python
#
# Currently a Proof of Concept:  
# Script parses kismet *.xml log files for GPS data and creates a map of access points.
# output is URL for google maps API, requires maps API Key - http://code.google.com/apis/maps/signup.html
#
# N.B. Google maps appears to have limit to the length of URLs it can handle, 
#  for this reason the script is limited to plotting only the first 50 encounted access points
#
# Limit should be sufficient for site-surveys, not so good for outputting war drive findings
#
# Unsecured APs are green, WEP secured are yellow, and WPA are red
#
# Andrew Waite - www.infosanity.co.uk
#
# Version: 0.1b
# Date: 2009-07-01
#
# Modified original from http://perrygeo.googlecode.com/svn/trunk/gis-bin/kismet2kml.py by PerryGeo
# in turn: modified from http://www.larsen-b.com/Article/204.html by larson-b.com

import sys
try:
    from elementtree import ElementTree
except:
    from xml.etree import ElementTree

#Read Kismet log file (not *.gps)
try:
   file = sys.argv[1]
   data = open(file,'r').read()
except:
   print sys.argv[0] + " {kismet logfile}"
   sys.exit(1)

detection = ElementTree.XML(data)

#Setup google maps URL basics
url  = "http://maps.google.com/staticmap?"
url += "size=512x512"
# Place your API key here (remove chevrons)
url += "&key=<YOUR KEY HERE>"
url += "&markers="

#counter for number of plotted points
markers=0

for node in detection.getchildren():
#   try:
#      ssid = node.find('SSID').text
#   except AttributeError:
#      #hidden SSID
#      ssid = "{unknown SSID}"
#
#   bssid = node.find('BSSID').text
#   ssid = ssid.replace('&','')
#   channel = node.find('channel').text
#   maxrate = node.find('maxrate').text 

#   encryption = node.find('encryption').text

   #read all found encryption types used by AP
   encryptiontypes =  node.findall('encryption')

   # Security level (STATICS/GLOBALS????)
   OPEN = 0
   WEP = 1
   WPA = 2

   #Assume no security
   APenc = 0

   for enctype in encryptiontypes:
      if enctype.text == "WPA":
         APenc = 2
      elif ( enctype.text == "WEP" and APenc < 2 ):
         APenc = 1
      
   #If Kismet did recieve enough data on a given AP then max-lon or max-lat may be Null
   gps = node.find('gps-info')
   lon = gps.find('max-lon').text
   if lon == "0.000000":
      lon = gps.find('min-lon').text

   lat = gps.find('max-lat').text
   if lat == "0.000000":
      lat = gps.find('min-lon').text   

   # add pipe (|) seperator if not first marker
   if markers > 0:
      url += "|"

   # add marker
   url += lat + "," + lon

   # change marker colour depending on encryption level
   if APenc == 0:
      url += ",green"
   elif APenc == 1:
      url += ",yellow"
   elif APenc == 2:
      url += ",red"
   else:
      sys.stdout.write("Ooppps, APenc is %s\n" %APenc)
      sys.exit(1)

   markers += 1
   if markers > 50:
      break

sys.stdout.write(url + "\n")
sys.stdout.write("Number of markers: %i" %(markers))

