I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit e5aa2a49 authored by sponge's avatar sponge
Browse files

Add a more secure netDb app.

parent 7a85ca33
No related branches found
No related tags found
No related merge requests found
#
# Required software:
# sqlite3 3.6.23.1 or newer
# http://www.sqlite.org/
# unixodbc
# http://www.unixodbc.org/
# pyodbc-3.0.6 or newer
# http://www.ch-werner.de/sqliteodbc/
# werkzeug
# http://werkzeug.pocoo.org/
# python 2.6 or 2.7
# http://python.org/
#
# Modify as needed, or use a symlink.
netdbdir = 'netdb'
database = 'Driver=SQLite;DATABASE=I2PnetDb'
from werkzeug import BaseRequest, BaseResponse, ETagResponseMixin, escape, SharedDataMiddleware
from werkzeug.exceptions import HTTPException
import os
from time import time, gmtime
import calendar
#import time
from random import choice
import pyodbc
#
# Not needed?
#
#import sha
# db format
#
# table client ipaddress, time of access, file list index
#
# table html index, time of creation, html
#
# Init database if it does not exist.
#
def checkdatabase():
cnxn = pyodbc.connect(database)
cur = cnxn.cursor()
try:
cur.execute("select * from client")
except pyodbc.Error:
#cur.execute("create table peer (ip string, time string, index string)")
print ("Creating new table 'client'")
cur.execute("create table client (ip string, whn float)")
cnxn.commit()
try:
cur.execute("select * from entry")
except pyodbc.Error:
#cur.execute("create table peer (ip string, time string, index string)")
print ("Creating new table 'entry'")
cur.execute("create table entry (whn float, wht string)")
cnxn.commit()
cnxn.close()
# try:
# cur.execute("select * from html")
# except pyodbc.Error:
# cur.execute("create table client (index, time, html)")
# cur.execute("insert into foo values(1, 'Me')")
# cnxn.commit()
# cur.execute("select * from foo")
# cnxn.close()
class Request(BaseRequest):
"""Useful subclass of the default request that knows how to build urls."""
def __init__(self, environ):
BaseRequest.__init__(self, environ)
class Response(BaseResponse, ETagResponseMixin):
"""Subclass of base response that has a default mimetype of text/html."""
default_mimetype = 'text/html'
def app(environ, start_response):
"""The WSGI application that connects all together."""
req = Request(environ)
remote = req.remote_addr
now = time()
old = now - 3600
oldest = now - 7200
t = gmtime(now)
nowtag = calendar.timegm((t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, 0, 0, t.tm_wday, t.tm_yday, t.tm_isdst))
cnxn = pyodbc.connect(database)
cur = cnxn.cursor()
#
# Prune database from peers that are over 1 hour old
#
cur.execute("delete from client where whn < ?", old)
cnxn.commit()
#
# Prune database from entries that are over 2 hours old
#
cur.execute("delete from entry where whn < ?", oldest)
cnxn.commit()
#
# Get peer info
#
cur.execute("select * from client where ip = ?", remote)
info = cur.fetchall()
# page
path = req.path[1:]
if path == '':
page = u'<html><head><title>NetDB</title></head><body><ul>%s</ul></body></html>'
if len(info) == 0:
# tag the ip as new
cur.execute("insert into client values (?, ?)", (remote, now))
# see if we have a list already, and use that
# generate links
entries = os.listdir(netdbdir)
if len(entries) > 150:
# select some randomly
new = []
for i in range(100):
while True:
sel = choice(entries)
if not sel.startswith('routerInfo-'):
continue
if sel not in new:
new.append(sel)
cur.execute("insert into entry values (?, ?)", (nowtag, sel))
break
entries = new
else:
# use old list based on date in database, i.e. sends the same as before.
junk, last = info[0]
t = gmtime(last)
oldtag = calendar.timegm((t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, 0, 0, t.tm_wday, t.tm_yday, t.tm_isdst))
cur.execute("select * from entry where whn = ?", oldtag)
stuff = cur.fetchall()
entries = []
for junk,sel in stuff:
entries.append(sel)
res = ''
for entry in entries:
if not entry.startswith('routerInfo-'):
continue
res += '<li><a href="%s">%s</a></li>' % (entry, entry)
resp = Response(page % res, mimetype='text/html')
resp.add_etag()
elif path == 'robots.txt':
dat = u"User-agent: *\nDisallow: /routerInfo-*.dat$\n"
resp = Response(dat, mimetype='text/plain')
resp.add_etag()
else:
if len(info) == 0:
# 404 This is to prevent cross seed site scrapes
resp = Response("Hi! Having fun?", status=403, mimetype='text/plain')
else:
#
# zap badness from path
#
chkpath = path.replace("'","").replace("/","")
# check to see if we have this entry in the database at all.
cur.execute("select * from entry where wht = ?", chkpath)
chk = cur.fetchall()
if len(chk) == 0:
resp = Response("Do you not have anything better to do?", status=400, mimetype='text/plain')
else:
try:
# load file
f = open(os.path.join(netdbdir, path), 'rb')
resp = Response(f.read(), mimetype='application/octet-stream')
f.close()
resp.add_etag()
except IOError:
# 404
resp = Response("Owch! Could not find file!", status=404, mimetype='text/plain')
cnxn.commit()
cnxn.close()
return resp(environ, start_response)
checkdatabase()
if __name__ == '__main__':
from werkzeug import run_simple
run_simple('localhost', 5007, app)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment