diff --git a/README.md b/README.md index d14b3ae..49ff65b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ You can also find support via our IRC channels: `#PyLink @ irc.overdrivenetworks * Python 3.4+ * PyYAML (`pip install pyyaml`) -* *For the relay plugin*: expiringdict (`pip install expiringdict`) +* *For the servprotect plugin*: python3-expiringdict (`apt-get install python3-expiringdict`; not available in pip) * *For the changehost and opercmds plugins*: ircmatch (`pip install ircmatch`) ### Supported IRCds diff --git a/plugins/servprotect.py b/plugins/servprotect.py new file mode 100644 index 0000000..dd90ff6 --- /dev/null +++ b/plugins/servprotect.py @@ -0,0 +1,41 @@ +# servprotect.py: Protects against KILL and nick collision floods +import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from expiringdict import ExpiringDict + +import utils +from log import log + +# TODO: make length and time configurable +savecache = ExpiringDict(max_len=5, max_age_seconds=10) +killcache = ExpiringDict(max_len=5, max_age_seconds=10) + +def handle_kill(irc, numeric, command, args): + """ + Tracks kills against PyLink clients. If too many are received, + automatically disconnects from the network. + """ + if killcache.setdefault(irc.name, 1) >= 5: + log.error('(%s) servprotect: Too many kills received, aborting!', irc.name) + irc.disconnect() + + log.debug('(%s) servprotect: Incrementing killcache by 1', irc.name) + killcache[irc.name] += 1 + +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. + """ + if savecache.setdefault(irc.name, 0) >= 5: + log.error('(%s) servprotect: Too many nick collisions, aborting!', irc.name) + irc.disconnect() + + log.debug('(%s) servprotect: Incrementing savecache by 1', irc.name) + savecache[irc.name] += 1 + +utils.add_hook(handle_save, 'SAVE')