mirror of https://github.com/rscmbbng/Border-Check
psy
11 years ago
9 changed files with 11162 additions and 73 deletions
@ -0,0 +1,11 @@ |
|||||
|
Border Check (BC) is an art project to visualize the physical infrastructure of the internet using free software tools. |
||||
|
Currently working on v.01 of the software and a better version of this text. |
||||
|
|
||||
|
GPLv3 - 2013 |
||||
|
|
||||
|
----------- |
||||
|
Contacts: |
||||
|
|
||||
|
Roel Roscam Abbing (roel@roelroscamabbing.nl) |
||||
|
psy (epsylon@riseup.net) |
||||
|
|
After Width: | Height: | Size: 1.1 MiB |
@ -0,0 +1,20 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding: iso-8859-15 -*- |
||||
|
""" |
||||
|
BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes. |
||||
|
GPLv3 - 2013 by psy (epsylon@riseup.net) |
||||
|
""" |
||||
|
from main import bc |
||||
|
|
||||
|
class NullOutput(object): |
||||
|
def write(self, text): |
||||
|
pass |
||||
|
def flush(self): |
||||
|
pass |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
app = bc() |
||||
|
options = app.create_options() |
||||
|
if options: |
||||
|
app.set_options(options) |
||||
|
app.run() |
@ -0,0 +1,20 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding: iso-8859-15 -*- |
||||
|
""" |
||||
|
BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes. |
||||
|
GPLv3 - 2013 by psy (epsylon@riseup.net) |
||||
|
""" |
||||
|
from main_gtk import GuiStarter, GuiUtils |
||||
|
|
||||
|
try: |
||||
|
import gtk, gtk.glade |
||||
|
except: |
||||
|
print ("\nError importing: Gtk/Glade libs. \n\nOn Debian based systems, please try like root:\n\n $ apt-get install python-gtk2\n") |
||||
|
sys.exit(2) |
||||
|
|
||||
|
class BCGTK(): |
||||
|
@staticmethod |
||||
|
def run(): |
||||
|
GuiStarter() |
||||
|
gtk.main() |
||||
|
|
@ -1,73 +0,0 @@ |
|||||
#!/usr/bin/python |
|
||||
|
|
||||
import sqlite3, os, time, pygeoip,re |
|
||||
from urlparse import urlparse |
|
||||
import subprocess, socket |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
def getURL(): |
|
||||
## function to get the last visited URL from the browser history database. This is only for Firefox. |
|
||||
## However the Chrome database works in a similar way, just with different tables. I believe it's not to hard |
|
||||
## to produce a function like this for every browser. The difficulty would be for a user to give the path to the |
|
||||
## history file. |
|
||||
|
|
||||
conn = sqlite3.connect('path/to/firefox/places.sqlite') |
|
||||
c = conn.cursor() |
|
||||
c.execute('select url, last_visit_date from moz_places ORDER BY last_visit_date DESC') |
|
||||
url = c.fetchone() |
|
||||
return url[0] |
|
||||
|
|
||||
|
|
||||
|
|
||||
## Location of the GeoIP database. Currently using this one: http://dev.maxmind.com/geoip/legacy/geolite/ |
|
||||
## Perhaps better databases are available. |
|
||||
geoip= pygeoip.GeoIP('path/to/geoipdatabase.dat') |
|
||||
|
|
||||
old_url="" |
|
||||
|
|
||||
## the main loop, always running, checks once in 5 seconds if there is a new URL in the browser history. |
|
||||
while True: |
|
||||
|
|
||||
## get the URL from the browser history, strip it down to the host, convert that to ip adress. |
|
||||
url = urlparse(getURL()).netloc |
|
||||
# url = url.replace('www.','') --> doing a tracert to for example.com and www.example.com yields different results most of the times. |
|
||||
url_ip = socket.gethostbyname(url) |
|
||||
if url != old_url: |
|
||||
count = 0 |
|
||||
print url |
|
||||
|
|
||||
## Run LFT (layer four traceroute, http://pwhois.org/lft/) on the ip as a subprocess and pipe back into script. |
|
||||
## In NL this has worked flawlessly for me |
|
||||
## however since i'm in the Laboral all tracerts using TCP fail and the one with UDP find a path, but |
|
||||
## fail to reach the destination. Perhaps it has to do with the network configuration here, but we should |
|
||||
## look into it. |
|
||||
|
|
||||
#a = subprocess.Popen(['lft', '-S', '-n', '-e', url_ip], stdout=subprocess.PIPE) -> using tcp |
|
||||
a = subprocess.Popen(['lft', '-S', '-n', '-u', url_ip], stdout=subprocess.PIPE) # -> using udp |
|
||||
logfile = open('logfile', 'a') |
|
||||
|
|
||||
for line in a.stdout: |
|
||||
#log results. |
|
||||
logfile.write(line) |
|
||||
|
|
||||
## Parsing the results from LFT. If it finds an ip adress compare it against the database and print the results |
|
||||
parts = line.split() |
|
||||
for ip in parts: |
|
||||
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip): |
|
||||
record = geoip.record_by_addr(ip) |
|
||||
#print record |
|
||||
if record.has_key('country_name') and record['city'] is not '': |
|
||||
country = record['country_name'] |
|
||||
city = record['city'] |
|
||||
print count, "While surfing you got to "+ip+" which is in "+city+", "+country |
|
||||
elif record.has_key('country_name'): |
|
||||
country = record['country_name'] |
|
||||
print count, "While surfing you got to "+ip+" which is in "+country |
|
||||
time.sleep(0.1) |
|
||||
count+=1 |
|
||||
old_url = url |
|
||||
print"old url =",old_url |
|
||||
logfile.close() |
|
||||
time.sleep(5) |
|
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<interface> |
||||
|
<!-- interface-requires gtk+ 2.12 --> |
||||
|
<!-- interface-naming-policy toplevel-contextual --> |
||||
|
<object class="GtkTextBuffer" id="textbuffer1"/> |
||||
|
<object class="GtkAction" id="action1"/> |
||||
|
<object class="GtkWindow" id="window"> |
||||
|
<property name="visible">True</property> |
||||
|
<property name="title" translatable="yes">Border Check - GTK Version</property> |
||||
|
<property name="window_position">center</property> |
||||
|
<child> |
||||
|
<object class="GtkImage" id="map1"> |
||||
|
<property name="visible">True</property> |
||||
|
<property name="pixbuf">WM1.svg</property> |
||||
|
</object> |
||||
|
</child> |
||||
|
</object> |
||||
|
</interface> |
@ -0,0 +1,196 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding: iso-8859-15 -*- |
||||
|
""" |
||||
|
BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes. |
||||
|
GPLv3 - 2013 by psy (epsylon@riseup.net) |
||||
|
""" |
||||
|
import os, sys, time, re, traceback |
||||
|
from urlparse import urlparse |
||||
|
try: |
||||
|
import pygeoip |
||||
|
except: |
||||
|
print "\nError importing: pygeoip lib. \n\nOn Debian based systems, please try like root:\n\n $ apt-get install python-geoip\n" |
||||
|
sys.exit(2) |
||||
|
try: |
||||
|
import sqlite3 |
||||
|
except: |
||||
|
print "\nError importing: sqlite3 lib. \n\nOn Debian based systems, please try like root:\n\n $ apt-get install sqlite3\n" |
||||
|
sys.exit(2) |
||||
|
|
||||
|
import subprocess, socket |
||||
|
from options import BCOptions |
||||
|
from bc_gtk import BCGTK |
||||
|
|
||||
|
# set to emit debug messages about errors (0 = off). |
||||
|
DEBUG = 1 |
||||
|
|
||||
|
class bc(object): |
||||
|
""" |
||||
|
BC main Class |
||||
|
""" |
||||
|
def __init__(self): |
||||
|
""" |
||||
|
Init defaults |
||||
|
""" |
||||
|
self.browser = "" # "F" Firefox / "C" Chrome |
||||
|
self.browser_path = "" |
||||
|
self.url = "" |
||||
|
self.old_url = "" |
||||
|
|
||||
|
def set_options(self, options): |
||||
|
""" |
||||
|
Set program options |
||||
|
""" |
||||
|
self.options = options |
||||
|
|
||||
|
def create_options(self, args=None): |
||||
|
""" |
||||
|
Create options for OptionParser |
||||
|
""" |
||||
|
self.optionParser = BCOptions() |
||||
|
self.options = self.optionParser.get_options(args) |
||||
|
if not self.options: |
||||
|
return False |
||||
|
return self.options |
||||
|
|
||||
|
def try_running(self, func, error, args=None): |
||||
|
""" |
||||
|
Try running a function and print some error if it fails and exists with a fatal error. |
||||
|
""" |
||||
|
options = self.options |
||||
|
args = args or [] |
||||
|
try: |
||||
|
return func(*args) |
||||
|
except Exception as e: |
||||
|
if options.url: |
||||
|
print("[Error] - Something wrong fetching urls. Aborting..."), "\n" |
||||
|
sys.exit(2) |
||||
|
else: |
||||
|
print(error, "error") |
||||
|
if DEBUG: |
||||
|
traceback.print_exc() |
||||
|
|
||||
|
def check_browser(self): |
||||
|
""" |
||||
|
Check for browser used by system |
||||
|
""" |
||||
|
b = subprocess.Popen(['locate', 'places.sqlite']) # check for Firefox |
||||
|
if b != "": |
||||
|
self.browser = "F" #Firefox |
||||
|
self.browser_path = "/home/psy/.mozilla/firefox/cq3sfq0e.default/places.sqlite" #automatic extracion of path |
||||
|
else: |
||||
|
self.browser = "C" #Chrome |
||||
|
self.browser_path = "" |
||||
|
|
||||
|
def getURL(self): |
||||
|
""" |
||||
|
Set urls to visit |
||||
|
""" |
||||
|
print "Browser database:", self.browser_path, "\n" |
||||
|
conn = sqlite3.connect(self.browser_path) |
||||
|
c = conn.cursor() |
||||
|
|
||||
|
if self.browser == "F": #Firefox history database |
||||
|
c.execute('select url, last_visit_date from moz_places ORDER BY last_visit_date DESC') |
||||
|
elif self.browser == "C": #Chrome history database |
||||
|
# Linux: /home/$USER/.config/google-chrome/ |
||||
|
# Linux: /home/$USER/.config/chromium/ |
||||
|
# Windows Vista (and Win 7): C:\Users\[USERNAME]\AppData\Local\Google\Chrome\ |
||||
|
# Windows XP: C:\Documents and Settings\[USERNAME]\Local Settings\Application Data\Google\Chrome\ |
||||
|
c.execute('select urls.url, urls.title, urls.visit_count, urls.typed_count, urls.last_visit_time, urls.hidden, visits.visit_time, visits.from_visit, visits.transition from urls, visits where urls.id = visits.url') |
||||
|
else: # Browser not allowed |
||||
|
print "\nSorry, you haven't a compatible browser\n\n" |
||||
|
exit(2) |
||||
|
url = c.fetchone() |
||||
|
self.url = url |
||||
|
print "Fetching URL:", self.url[0], "\n" |
||||
|
return url[0] |
||||
|
|
||||
|
def getGEO(self): |
||||
|
""" |
||||
|
Get Geolocation database (http://dev.maxmind.com/geoip/legacy/geolite/) |
||||
|
""" |
||||
|
# Download and extract database |
||||
|
try: |
||||
|
urllib.urlretrieve('http://xsser.sf.net/map/GeoLiteCity.dat.gz', |
||||
|
geo_db_path+'.gz', reportfunc) |
||||
|
except: |
||||
|
try: |
||||
|
urllib.urlretrieve('http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz', |
||||
|
geo_db_path+'.gz', reportfunc) |
||||
|
except: |
||||
|
print("[Error] - Something wrong fetching GeoIP maps from the Internet. Aborting..."), "\n" |
||||
|
sys.exit(2) |
||||
|
|
||||
|
# Set database |
||||
|
geoip= pygeoip.GeoIP('GeoLiteCity.dat') |
||||
|
|
||||
|
def run(self, opts=None): |
||||
|
""" |
||||
|
Run BorderCheck |
||||
|
""" |
||||
|
#eprint = sys.stderr.write |
||||
|
# set options |
||||
|
if opts: |
||||
|
options = self.create_options(opts) |
||||
|
self.set_options(options) |
||||
|
options = self.options |
||||
|
p = self.optionParser |
||||
|
# banner |
||||
|
print('='*75) |
||||
|
print(str(p.version)) |
||||
|
print('='*75) |
||||
|
# extract browser type and path |
||||
|
browser = self.try_running(self.check_browser, "\nInternal error checking browser files path.") |
||||
|
# extract url |
||||
|
url = self.try_running(self.getURL, "\nInternal error getting urls from browser's database.") |
||||
|
print "url:", self.url |
||||
|
# start gtk mode |
||||
|
BCGTK.run() |
||||
|
|
||||
|
while True: |
||||
|
url = urlparse(self.url[0]).netloc |
||||
|
url = url.replace('www.','') #--> doing a tracert to for example.com and www.example.com yields different results most of the times. |
||||
|
url_ip = socket.gethostbyname(url) |
||||
|
print url_ip |
||||
|
if url != self.old_url: |
||||
|
count = 0 |
||||
|
print url |
||||
|
|
||||
|
a = subprocess.Popen(['lft', '-S', '-n', '-E', url_ip], stdout=subprocess.PIPE) # -> using tcp |
||||
|
#a = subprocess.Popen(['lft', '-S', '-n', '-u', url_ip], stdout=subprocess.PIPE) # -> using udp |
||||
|
logfile = open('logfile', 'a') |
||||
|
|
||||
|
for line in a.stdout: |
||||
|
logfile.write(line) |
||||
|
parts = line.split() |
||||
|
for ip in parts: |
||||
|
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip): |
||||
|
record = geoip.record_by_addr(ip) |
||||
|
#print record |
||||
|
try: |
||||
|
if record.has_key('country_name') and record['city'] is not '': |
||||
|
country = record['country_name'] |
||||
|
city = record['city'] |
||||
|
print count, "While surfing you got to "+ip+" which is in "+city+", "+country |
||||
|
elif record.has_key('country_name'): |
||||
|
country = record['country_name'] |
||||
|
print count, "While surfing you got to "+ip+" which is in "+country |
||||
|
time.sleep(0.3) |
||||
|
count+=1 |
||||
|
except: |
||||
|
print "Not more records. Aborting...", "\n" |
||||
|
exit() |
||||
|
|
||||
|
self.old_url = url |
||||
|
print"old url =", self.old_url |
||||
|
logfile.close() |
||||
|
time.sleep(5) |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
app = bc() |
||||
|
options = app.create_options() |
||||
|
if options: |
||||
|
app.set_options(options) |
||||
|
app.run() |
||||
|
|
@ -0,0 +1,108 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding: iso-8859-15 -*- |
||||
|
""" |
||||
|
BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes. |
||||
|
GPLv3 - 2013 by psy (epsylon@riseup.net) |
||||
|
""" |
||||
|
import sys |
||||
|
try: |
||||
|
import gtk, gtk.glade |
||||
|
except: |
||||
|
print ("\nError importing: Gtk/Glade libs. \n\nOn Debian based systems, please try like root:\n\n $ apt-get install python-gtk2\n") |
||||
|
sys.exit(2) |
||||
|
|
||||
|
class GuiUtils(object): |
||||
|
@staticmethod |
||||
|
def GetBuilder(name): |
||||
|
builder = gtk.Builder() |
||||
|
if not builder.add_from_file('builder.xml'): |
||||
|
print 'XML file not found!' |
||||
|
sys.exit(1) |
||||
|
else: |
||||
|
return builder |
||||
|
|
||||
|
@staticmethod |
||||
|
def Error(title, text): |
||||
|
"""Show error popup""" |
||||
|
dialog = gtk.MessageDialog( |
||||
|
parent = None, |
||||
|
flags = gtk.DIALOG_DESTROY_WITH_PARENT, |
||||
|
type = gtk.MESSAGE_ERROR, |
||||
|
buttons = gtk.BUTTONS_OK, |
||||
|
message_format = text) |
||||
|
dialog.set_title(title) |
||||
|
dialog.connect('response', lambda dialog, response: dialog.destroy()) |
||||
|
dialog.show() |
||||
|
print text |
||||
|
|
||||
|
@staticmethod |
||||
|
def Info(title, text): |
||||
|
"""Show info popup""" |
||||
|
dialog = gtk.MessageDialog( |
||||
|
parent = None, |
||||
|
flags = gtk.DIALOG_DESTROY_WITH_PARENT, |
||||
|
type = gtk.MESSAGE_INFO, |
||||
|
buttons = gtk.BUTTONS_OK, |
||||
|
message_format = text) |
||||
|
dialog.set_title(title) |
||||
|
dialog.connect('response', lambda dialog, response: dialog.destroy()) |
||||
|
dialog.show() |
||||
|
|
||||
|
@staticmethod |
||||
|
def Loading(title, text): |
||||
|
"""Show loading popup""" |
||||
|
dialog = gtk.MessageDialog( |
||||
|
parent = None, |
||||
|
flags = gtk.DIALOG_DESTROY_WITH_PARENT, |
||||
|
type = gtk.MESSAGE_INFO, |
||||
|
buttons = gtk.BUTTONS_NONE, |
||||
|
message_format = text) |
||||
|
dialog.set_title(title) |
||||
|
dialog.connect('response', lambda dialog, response: dialog.destroy()) |
||||
|
dialog.show() |
||||
|
return dialog |
||||
|
|
||||
|
@staticmethod |
||||
|
def Warning(title, text): |
||||
|
"""Show warning popup""" |
||||
|
dialog = gtk.MessageDialog( |
||||
|
parent = None, |
||||
|
flags = gtk.DIALOG_DESTROY_WITH_PARENT, |
||||
|
type = gtk.MESSAGE_WARNING, |
||||
|
buttons = gtk.BUTTONS_OK, |
||||
|
message_format = text) |
||||
|
dialog.set_title(title) |
||||
|
dialog.connect('response', lambda dialog, response: dialog.destroy()) |
||||
|
dialog.show() |
||||
|
return dialog |
||||
|
|
||||
|
@staticmethod |
||||
|
def Question(title, text): |
||||
|
"""Show question popup""" |
||||
|
dialog = gtk.MessageDialog( |
||||
|
parent = None, |
||||
|
flags = gtk.DIALOG_DESTROY_WITH_PARENT, |
||||
|
type = gtk.MESSAGE_QUESTION, |
||||
|
buttons = gtk.BUTTONS_YES_NO, |
||||
|
message_format = text) |
||||
|
dialog.set_title(title) |
||||
|
dialog.connect('response', lambda dialog, response: dialog.destroy()) |
||||
|
dialog.show() |
||||
|
return dialog |
||||
|
|
||||
|
class GuiStarter(object): |
||||
|
""" |
||||
|
Init the starter GUI box. |
||||
|
""" |
||||
|
def __init__(self): |
||||
|
""" |
||||
|
Start the GUI up and set the connections with the components. |
||||
|
""" |
||||
|
builder = GuiUtils.GetBuilder('builder') |
||||
|
|
||||
|
# get objects |
||||
|
self.window = builder.get_object('builder') |
||||
|
|
||||
|
# defaults |
||||
|
|
||||
|
# signals |
@ -0,0 +1,21 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding: iso-8859-15 -*- |
||||
|
""" |
||||
|
BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes. |
||||
|
GPLv3 - 2013 by psy (epsylon@riseup.net) |
||||
|
""" |
||||
|
import optparse |
||||
|
|
||||
|
class BCOptions(optparse.OptionParser): |
||||
|
def __init__(self, *args): |
||||
|
optparse.OptionParser.__init__(self, |
||||
|
prog='bc.py', |
||||
|
version='\nBC (Border-Check) 0.1v - 2013 - (GPLv3.0) -> by psy\n', |
||||
|
usage= '\n\nbc [OPTIONS]') |
||||
|
|
||||
|
self.add_option("-d", "--debug", action="store_true", dest="debug", help="debug mode") |
||||
|
|
||||
|
def get_options(self, user_args=None): |
||||
|
(options, args) = self.parse_args(user_args) |
||||
|
return options |
||||
|
|
Loading…
Reference in new issue