3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 01:09:22 +01:00

relay: KILL war protection (#23)

TODO: possibly integrate this into core?
This commit is contained in:
James Lu 2015-09-12 17:41:49 -07:00
parent 1fcacd0d7c
commit b3902c7711

View File

@ -24,6 +24,7 @@ relayusers = defaultdict(dict)
relayservers = defaultdict(dict) relayservers = defaultdict(dict)
spawnlocks = defaultdict(threading.RLock) spawnlocks = defaultdict(threading.RLock)
savecache = ExpiringDict(max_len=5, max_age_seconds=10) savecache = ExpiringDict(max_len=5, max_age_seconds=10)
killcache = ExpiringDict(max_len=5, max_age_seconds=10)
def relayWhoisHandler(irc, target): def relayWhoisHandler(irc, target):
user = irc.users[target] user = irc.users[target]
@ -697,26 +698,34 @@ def handle_kill(irc, numeric, command, args):
# We don't allow killing over the relay, so we must respawn the affected # We don't allow killing over the relay, so we must respawn the affected
# client and rejoin it to its channels. # client and rejoin it to its channels.
del relayusers[realuser][irc.name] del relayusers[realuser][irc.name]
remoteirc = world.networkobjects[realuser[0]] if killcache.setdefault(irc.name, 0) <= 5:
for remotechan in remoteirc.channels.copy(): remoteirc = world.networkobjects[realuser[0]]
localchan = findRemoteChan(remoteirc, irc, remotechan) for remotechan in remoteirc.channels.copy():
if localchan: localchan = findRemoteChan(remoteirc, irc, remotechan)
modes = getPrefixModes(remoteirc, irc, localchan, realuser[1]) if localchan:
log.debug('(%s) relay handle_kill: userpair: %s, %s', irc.name, modes, realuser) modes = getPrefixModes(remoteirc, irc, localchan, realuser[1])
client = getRemoteUser(remoteirc, irc, realuser[1]) log.debug('(%s) relay handle_kill: userpair: %s, %s', irc.name, modes, realuser)
irc.proto.sjoinServer(getRemoteSid(irc, remoteirc), localchan, [(modes, client)]) client = getRemoteUser(remoteirc, irc, realuser[1])
if userdata and numeric in irc.users: irc.proto.sjoinServer(getRemoteSid(irc, remoteirc), localchan, [(modes, client)])
log.info('(%s) Relay claim: Blocked KILL (reason %r) from %s to relay client %s/%s.', if userdata and numeric in irc.users:
irc.name, args['text'], irc.users[numeric].nick, log.info('(%s) Relay claim: Blocked KILL (reason %r) from %s to relay client %s/%s.',
remoteirc.users[realuser[1]].nick, realuser[0]) irc.name, args['text'], irc.users[numeric].nick,
irc.msg(numeric, "Your kill to %s has been blocked " remoteirc.users[realuser[1]].nick, realuser[0])
"because PyLink does not allow killing" irc.msg(numeric, "Your kill to %s has been blocked "
" users over the relay at this time." % \ "because PyLink does not allow killing"
userdata.nick, notice=True) " users over the relay at this time." % \
userdata.nick, notice=True)
else:
log.info('(%s) Relay claim: Blocked KILL (reason %r) from server %s to relay client %s/%s.',
irc.name, args['text'], irc.servers[numeric].name,
remoteirc.users[realuser[1]].nick, realuser[0])
else: else:
log.info('(%s) Relay claim: Blocked KILL (reason %r) from server %s to relay client %s/%s.', log.error('(%s) Too many kills received for target %s, aborting!',
irc.name, args['text'], irc.servers[numeric].name, irc.name, userdata.nick)
remoteirc.users[realuser[1]].nick, realuser[0]) irc.aborted.set()
killcache[irc.name] += 1
log.debug('killcache: %s', irc.name, killcache)
# Target user was local. # Target user was local.
else: else:
# IMPORTANT: some IRCds (charybdis) don't send explicit QUIT messages # IMPORTANT: some IRCds (charybdis) don't send explicit QUIT messages