2016-03-25 16:39:20 -07:00
|
|
|
# servprotect.py: Protects against KILL and nick collision floods
|
2019-05-13 16:59:57 +08:00
|
|
|
|
|
|
|
import threading
|
2016-03-25 16:39:20 -07:00
|
|
|
|
2019-07-14 15:12:29 -07:00
|
|
|
from pylinkirc import conf, utils
|
2016-06-20 18:18:54 -07:00
|
|
|
from pylinkirc.log import log
|
2016-03-25 16:39:20 -07:00
|
|
|
|
2019-05-13 16:59:57 +08:00
|
|
|
try:
|
|
|
|
from cachetools import TTLCache
|
|
|
|
except ImportError:
|
2020-04-10 11:15:54 -07:00
|
|
|
log.warning('servprotect: expiringdict support is deprecated as of PyLink 3.0; consider installing cachetools instead')
|
2019-05-13 16:59:57 +08:00
|
|
|
from expiringdict import ExpiringDict as TTLCache
|
|
|
|
|
2017-02-21 20:02:26 -05:00
|
|
|
# check for definitions
|
|
|
|
servprotect_conf = conf.conf.get('servprotect', {})
|
2017-08-03 10:10:28 -07:00
|
|
|
length = servprotect_conf.get('length', 10)
|
2017-02-21 20:02:26 -05:00
|
|
|
age = servprotect_conf.get('age', 10)
|
|
|
|
|
2019-05-13 16:59:57 +08:00
|
|
|
def _new_cache_dict():
|
|
|
|
return TTLCache(length, age)
|
|
|
|
|
|
|
|
savecache = _new_cache_dict()
|
|
|
|
killcache = _new_cache_dict()
|
|
|
|
lock = threading.Lock()
|
2016-03-25 16:39:20 -07:00
|
|
|
|
|
|
|
def handle_kill(irc, numeric, command, args):
|
|
|
|
"""
|
|
|
|
Tracks kills against PyLink clients. If too many are received,
|
|
|
|
automatically disconnects from the network.
|
|
|
|
"""
|
|
|
|
|
2017-06-29 23:01:39 -07:00
|
|
|
if (args['userdata'] and irc.is_internal_server(args['userdata'].server)) or irc.is_internal_client(args['target']):
|
2019-05-13 16:59:57 +08:00
|
|
|
with lock:
|
|
|
|
if killcache.setdefault(irc.name, 1) >= length:
|
|
|
|
log.error('(%s) servprotect: Too many kills received, aborting!', irc.name)
|
|
|
|
irc.disconnect()
|
2017-05-20 15:02:04 -07:00
|
|
|
|
2019-05-13 16:59:57 +08:00
|
|
|
log.debug('(%s) servprotect: Incrementing killcache by 1', irc.name)
|
|
|
|
killcache[irc.name] += 1
|
2016-03-25 16:39:20 -07:00
|
|
|
|
|
|
|
utils.add_hook(handle_kill, 'KILL')
|
|
|
|
|
|
|
|
def handle_save(irc, numeric, command, args):
|
|
|
|
"""
|
|
|
|
Tracks SAVEs (nick collision) against PyLink clients. If too many are received,
|
|
|
|
automatically disconnects from the network.
|
|
|
|
"""
|
2017-06-29 23:01:39 -07:00
|
|
|
if irc.is_internal_client(args['target']):
|
2019-05-13 16:59:57 +08:00
|
|
|
with lock:
|
|
|
|
if savecache.setdefault(irc.name, 0) >= length:
|
|
|
|
log.error('(%s) servprotect: Too many nick collisions, aborting!', irc.name)
|
|
|
|
irc.disconnect()
|
2016-03-25 16:39:20 -07:00
|
|
|
|
2019-05-13 16:59:57 +08:00
|
|
|
log.debug('(%s) servprotect: Incrementing savecache by 1', irc.name)
|
|
|
|
savecache[irc.name] += 1
|
2016-03-25 16:39:20 -07:00
|
|
|
|
|
|
|
utils.add_hook(handle_save, 'SAVE')
|