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
83
84
85
86
87
88
89
90
|
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
83
84
85
86
87
88
|
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
+
-
+
+
|
def check(self, site, ip_address):
if self._check_stmt == None:
self._check_stmt = self._db.prepare("select redirect_url, regexp from site_rule where site <@ tripdomain($1) and netmask >> $2::text::inet order by array_length(site, 1) desc")
return(self._check_stmt(site, ip_address))
def dump(self):
return(self._db.prepare("select untrip(site), tag, regexp from urls natural join site natural join tag order by site, tag")())
return(self._db.prepare("copy (select untrip(site) as site, tag, regexp from urls order by site, tag) to stdout csv header")())
def load(self, csv_data):
def load(self, data):
with self._db.xact():
if config.options.flush_db:
self._db.execute('delete from urls;')
if config.options.flush_site:
self._db.execute('delete from site;');
insertreg = self._db.prepare("select set($1, $2, $3)")
insert = self._db.prepare("select set($1, $2)")
for row in csv_data:
if len(row[2]) > 0:
insertreg(row[0], row[1], row[2])
insert = self._db.prepare("insert into urls (site, tag, regexp) values (tripdomain($1), $2::text::text[], $3)")
for row in data:
if len(row) == 2:
insert(row[0], row[1], None)
else:
insert(row[0], row[1])
self._db.execute('vacuum analyze site;')
insert(row[0], row[1], row[2])
self._db.execute("update urls set regexp = NULL where regexp = ''")
self._db.execute('vacuum analyze urls;')
def load_conf(self, csv_data):
with self._db.xact():
self._db.execute('delete from rules;')
insertconf = self._db.prepare("insert into rules (netmask, redirect_url, from_weekday, to_weekday, from_time, to_time, id_tag) values ($1::text::cidr, $2, $3, $4, $5::text::time, $6::text::time, get_tag($7::text::text[]))")
insertconf = self._db.prepare("insert into rules (netmask, redirect_url, from_weekday, to_weekday, from_time, to_time, tag) values ($1::text::cidr, $2, $3, $4, $5::text::time, $6::text::time, $7::text::text[])")
for row in csv_data:
insertconf(row[0], row[1], int(row[2]), int(row[3]), row[4], row[5], row[6])
self._db.execute('vacuum analyze rules;')
def dump_conf(self):
return(self._db.prepare("select netmask, redirect_url, from_weekday, to_weekday, from_time, to_time, tag from rules natural join tag")())
return(self._db.prepare("copy (select netmask, redirect_url, from_weekday, to_weekday, from_time, to_time, tag from rules) to stdout csv header")())
# abstract class with basic checking functionality
class Checker:
__slots__ = frozenset(['_db', '_log'])
__slots__ = frozenset(['_db', '_log', '_request'])
def __init__(self):
self._db = tagDB()
self._log = Logger()
self._log.info('started\n')
self._request = re.compile('^([0-9]+)\ (http|ftp):\/\/([-\w.:]+)\/([^ ]*)\ ([0-9.]+)\/(-|[\w\.]+)\ (-|\w+)\ (-|GET|HEAD|POST).*$')
def process(self, id, site, ip_address, url_path, line = None):
self._log.info('trying {}\n'.format(site))
result = self._db.check(site, ip_address)
reply = '-'
for row in result:
if row != None and row[0] != None:
|
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
|
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
-
-
-
|
default = '/usr/local/etc/squid-tagger.conf')
parser.add_option('-d', '--dump', dest = 'dump',
help = 'dump database', action = 'store_true', metavar = 'bool',
default = False)
parser.add_option('-f', '--flush-database', dest = 'flush_db',
help = 'flush previous database on load', default = False,
action = 'store_true', metavar = 'bool')
parser.add_option('-F', '--flush-site', dest = 'flush_site',
help = 'when flushing previous dtabase flush site index too',
action = 'store_true', default = False, metavar = 'bool')
parser.add_option('-l', '--load', dest = 'load',
help = 'load database', action = 'store_true', metavar = 'bool',
default = False)
parser.add_option('-D', '--dump-conf', dest = 'dump_conf',
help = 'dump filtering rules', default = False, metavar = 'bool',
action = 'store_true')
parser.add_option('-L', '--load-conf', dest = 'load_conf',
|
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
-
+
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
-
-
-
+
+
+
-
+
|
# initializing and reading in config file
config = Config()
if config.options.dump or config.options.load or config.options.dump_conf or config.options.load_conf:
import csv
tagdb = tagDB()
data_fields = ['site', 'tags', 'regexp']
data_fields = ['site', 'tag', 'regexp']
conf_fields = ['netmask', 'redirect_url', 'from_weekday', 'to_weekday', 'from_time', 'to_time', 'tag']
if config.options.dump or config.options.dump_conf:
csv_writer = csv.writer(sys.stdout)
if config.options.dump:
# dumping database
csv_writer.writerow(data_fields)
for row in tagdb.dump():
dump = tagdb.dump()
csv_writer.writerow([row[0], '{' + ','.join(row[1]) + '}', row[2]])
elif config.options.dump_conf:
# dumping rules
csv_writer.writerow(conf_fields)
for row in tagdb.dump_conf():
csv_writer.writerow([row[0], row[1], row[2], row[3], row[4], row[5], '{' + ','.join(row[6]) + '}'])
dump = tagdb.dump_conf()
for line in dump:
sys.stdout.write(line.decode('utf-8'))
elif config.options.load or config.options.load_conf:
csv_reader = csv.reader(sys.stdin)
first_row = next(csv_reader)
if config.options.load:
# loading database
assert first_row == data_fields, 'File must contain csv data with theese columns: ' + repr(data_fields)
tagdb.load(csv_reader)
fields = data_fields
load = tagdb.load
elif config.options.load_conf:
# loading database
assert first_row == conf_fields, 'File must contain csv data with theese columns: ' + repr(conf_fields)
fields = conf_fields
load = tagdb.load_conf
assert first_row == fields, 'File must contain csv data with theese columns: ' + repr(fields)
tagdb.load_conf(csv_reader)
load(csv_reader)
else:
# main loop
config.section('reactor')
if config['reactor'] == 'thread':
checker = CheckerThread()
elif config['reactor'] == 'plain':
checker = Checker()
elif config['reactor'] == 'kqueue':
checker = CheckerKqueue()
checker.loop()
|