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