blob: 3682b0e6166b42270bc9190be903fe19f5fa944e (
plain)
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
|
from collections import defaultdict
import signal
RATELIMIT_THRESHOLD = 20
GRAYLIST_LENGTH = 8
class SpamError(ValueError):
def __str__(self):
return ' '.join(self.args)
def loadlist(fn):
try:
with open(fn) as f:
return [ l for l in ( l.strip() for l in f.readlines() if not l.startswith('#')) if l ]
except:
return []
greenlist = set()
graylist = []
def do_graylist(msg):
global graylist
graylist = [msg] + graylist[:GRAYLIST_LENGTH-1]
blacklist = loadlist('blacklist')
badwords = loadlist('badwords')
def signal_handler(_signum, _frame):
global blacklist, badwords
blacklist = load_blacklist()
badwords = load_badwords()
signal.signal(signal.SIGHUP, signal_handler)
ratelimitdict = defaultdict(lambda: 0)
def empty_ratelimit(_signum, _frame):
global ratelimitdict
ratelimitdict = defaultdict(lambda: 0)
signal.signal(signal.SIGALRM, empty_ratelimit)
signal.setitimer(signal.ITIMER_REAL, 60)
def check_spam(addr, data):
ratelimitdict[addr] += 1
try:
if ratelimitdict[addr] > RATELIMIT_THRESHOLD:
raise SpamError('rate-limit')
if any(word in data.lower() for word in badwords):
raise SpamError('badwords filter')
if addr not in greenlist and data in graylist:
raise SpamError('graylist')
except SpamError as err:
do_graylist(data)
blacklist.append(addr)
raise err
greenlist.add(addr)
|