1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from optparse import OptionParser
from emailinfo import EmailInfo
from emailmap import EmailMap
from locationverifier import LocationVerifier
import os
def main():
global options, parser
parser = OptionParser(usage="usage: %prog [options] file|directory [file|directory] [file|directory] ...", description="Analyzes email headers and extracts geographic information.")
parser.add_option("-p", "--print", action="store_true", help="Print geographic information about each encountered email.", dest="printinfo")
parser.add_option("-d", "--debug", action="store_true", help="Display when email parser has to dig a little deeper to find the correct IP.")
parser.add_option("-m", "--map", action="store", type="string", metavar="HTMLFILE", help="Generate visual representation of emails in a Google Map and write html to HTMLFILE. When combined with -v, --verify, only verified points are plotted.")
parser.add_option("-v", "--verify", action="store", type="string", metavar="CSVFILE", help="Verify accuracy of algorithm by comparing to CSV table with the first column of the first row the default country, then in the next rows, the first column the start date (mm/dd/yyyy), the second column the end date, and the remaining columns the countries visited. When combined with -m, --map, only verified points are plotted.")
(options, args) = parser.parse_args()
if options.debug == None and options.map == None and options.printinfo == None and options.verify == None:
options.printinfo = True
if len(args) == 0:
parser.error("at least one file or directory is required for analysis")
if options.map != None:
global mailmap
mailmap = EmailMap()
if options.verify != None:
global verification
locations = open(options.verify, "r")
verification = LocationVerifier(locations)
locations.close()
for file in args:
processPath(file)
if options.map != None:
outfile = open(options.map, "w")
mailmap.writeMap(outfile)
outfile.close()
print "Map written to %s" % options.map
if options.verify != None:
print verification
if len(verification.misses) > 0:
print "Non-verified Locations:"
verification.misses.sort()
for email in verification.misses:
print "\t%s sent %s from %s in %s" % (email.path, email.date.date(), email.ip, email.location()[1][2])
def traverseDirectory(directory):
for file in os.listdir(directory):
processPath(os.path.join(directory, file))
def processPath(path):
if os.path.isfile(path):
processFile(path)
elif os.path.isdir(path):
traverseDirectory(path)
elif not os.path.exists(path):
parser.error("%s does not exist" % path)
def processFile(fileName):
try:
examine = EmailInfo.parseFile(fileName)
except:
if options.debug:
print "unable to parse %s" % fileName
return
if options.debug and examine.debug:
print fileName + ":",
print examine.debug
if options.map != None and options.verify != None:
if verification.checkEmail(examine):
mailmap.addEmail(examine)
elif options.verify != None:
verification.checkEmail(examine)
elif options.map != None:
mailmap.addEmail(examine)
if options.printinfo:
print fileName + ":"
print "\tSent: %s at %s" % (examine.date.date(), examine.date.time())
print "\tIP: " + examine.ip
location = examine.location()
print ("\tCity: " + "%s, %s, %s" % location[1]).encode("utf-8")
print "\tCoordinates: %s, %s" % location[0]
if __name__ == '__main__':
main()
|