initial changes of v2, which will include integration of sigyn's permanent patterns system, separated plugin for handling hostmasks and features shared between Sigyn and ChanTracker

This commit is contained in:
Nicolas Coevoet 2018-01-23 20:50:44 +01:00
parent 560fc423c7
commit 90b968cfb6
2 changed files with 5 additions and 89 deletions

View File

@ -45,9 +45,6 @@ ChanTracker = conf.registerPlugin('ChanTracker')
conf.registerGlobalValue(ChanTracker, 'pool', conf.registerGlobalValue(ChanTracker, 'pool',
registry.Integer(-1, """delay between two checks about mode removal, in seconds. Note, check is also based on irc activity, so removal may be delayed a bit, -1 to disable delay""")) registry.Integer(-1, """delay between two checks about mode removal, in seconds. Note, check is also based on irc activity, so removal may be delayed a bit, -1 to disable delay"""))
conf.registerGlobalValue(ChanTracker, 'CAPS',
registry.CommaSeparatedListOfStrings(['account-notify','extended-join'], """CAP asked to the IRCd, that way bot can track username and account changes, without any additional request"""))
conf.registerGlobalValue(ChanTracker, 'logsSize', conf.registerGlobalValue(ChanTracker, 'logsSize',
registry.PositiveInteger(60, """number of messages to keep in logs. Note, this is per nick - not per nick per channel""")) registry.PositiveInteger(60, """number of messages to keep in logs. Note, this is per nick - not per nick per channel"""))
@ -191,9 +188,6 @@ conf.registerChannelValue(ChanTracker, 'checkEvade',
conf.registerChannelValue(ChanTracker, 'useChanServForQuiets', conf.registerChannelValue(ChanTracker, 'useChanServForQuiets',
registry.Boolean(False,"""if bot is not opped, use services for quiet / unquiets""")) registry.Boolean(False,"""if bot is not opped, use services for quiet / unquiets"""))
conf.registerChannelValue(ChanTracker, 'skynet',
registry.Integer(-1,"""when positive, bot could use some experimental features against user's marked as bad, the value represents number of bad users to trigger it"""))
# related to channel's protection # related to channel's protection
#clone #clone

View File

@ -276,7 +276,7 @@ def floatToGMT (t):
return time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(f)) return time.strftime('%Y-%m-%d %H:%M:%S GMT',time.gmtime(f))
class Ircd (object): class Ircd (object):
__slots__ = ('irc', 'name', 'channels', 'nicks', 'caps', 'queue', 'lowQueue', 'logsSize', 'askedItems') __slots__ = ('irc', 'name', 'channels', 'nicks', 'queue', 'lowQueue', 'logsSize', 'askedItems')
# define an ircd, keeps Chan and Nick items # define an ircd, keeps Chan and Nick items
def __init__(self,irc,logsSize): def __init__(self,irc,logsSize):
object.__init__(self) object.__init__(self)
@ -284,7 +284,6 @@ class Ircd (object):
self.name = irc.network self.name = irc.network
self.channels = ircutils.IrcDict() self.channels = ircutils.IrcDict()
self.nicks = ircutils.IrcDict() self.nicks = ircutils.IrcDict()
self.caps = ircutils.IrcDict()
# contains IrcMsg, kicks, modes, etc # contains IrcMsg, kicks, modes, etc
self.queue = utils.structures.smallqueue() self.queue = utils.structures.smallqueue()
# contains less important IrcMsgs ( sync, logChannel ) # contains less important IrcMsgs ( sync, logChannel )
@ -1939,14 +1938,10 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
elif len(modesToAsk): elif len(modesToAsk):
for m in modesToAsk: for m in modesToAsk:
i.lowQueue.enqueue(ircmsgs.IrcMsg('MODE %s %s' % (channel,m))) i.lowQueue.enqueue(ircmsgs.IrcMsg('MODE %s %s' % (channel,m)))
# schedule that for later
# prevent the bot to disconnect itself is server takes too much time to answer # prevent the bot to disconnect itself is server takes too much time to answer
i.lowQueue.enqueue(ircmsgs.ping(channel)) i.lowQueue.enqueue(ircmsgs.ping(channel))
# loads extended who # loads extended who
i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO ' + channel +' %tnuhiar,42')) # some ircd may not like this # i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO ' + channel +' %tnuhiar,42')) # some ircd may not like this
# fallback, TODO maybe uneeded as supybot do it by itself on join, but necessary on plugin reload ...
# i.lowQueue.enqueue(ircmsgs.ping(channel))
# i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO %s' % channel))
self.forceTickle = True self.forceTickle = True
return i.getChan (irc,channel) return i.getChan (irc,channel)
@ -2281,8 +2276,8 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
def do354 (self,irc,msg): def do354 (self,irc,msg):
# WHO $channel %tnuhiar,42 # WHO $channel %tnuhiar,42
# irc.nick 42 ident ip host nick account realname # irc.nick 42 ident ip host nick account realname
if len(msg.args) == 8 and msg.args[1] == '42': if len(msg.args) == 9 and msg.args[1] == '1':
(garbage,digit,ident,ip,host,nick,account,realname) = msg.args (garbage,digit,ident,ip,host,nick,status,account,realname) = msg.args
if account == '0': if account == '0':
account = None account = None
n = self.getNick(irc,nick) n = self.getNick(irc,nick)
@ -2394,7 +2389,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
n = self.getNick(irc,msg.nick) n = self.getNick(irc,msg.nick)
n.setPrefix(msg.prefix) n.setPrefix(msg.prefix)
i = self.getIrc(irc) i = self.getIrc(irc)
if 'LIST' in i.caps and 'extended-join' in i.caps['LIST'] and len(msg.args) == 3: if len(msg.args) == 3:
n.setRealname(msg.args[2]) n.setRealname(msg.args[2])
n.setAccount(msg.args[1]) n.setAccount(msg.args[1])
if msg.nick == irc.nick: if msg.nick == irc.nick:
@ -2750,42 +2745,6 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
self._tickle(irc) self._tickle(irc)
def doCap (self,irc,msg): def doCap (self,irc,msg):
# handles CAP messages
i = self.getIrc(irc)
command = msg.args[1]
l = msg.args[2].split(' ')
if command == 'LS':
# retreived supported CAP
i.caps['LS'] = l
# checking actives CAP, reload, etc
irc.queueMsg(ircmsgs.IrcMsg('CAP LIST'))
elif command == 'LIST':
i.caps['LIST'] = l
if 'LS' in i.caps:
r = []
# 'identify-msg' removed due to unability for default supybot's drivers to handles it correctly
# ['account-notify','extended-join']
# targeted caps
CAPS = self.registryValue('caps')
for cap in CAPS:
# len(cap) == 1 prevents weired behaviour with CommaSeparatedListOfStrings
if len(cap) != 1 and cap in i.caps['LS'] and not cap in i.caps['LIST']:
r.append(cap)
if len(r):
if not hasattr(irc.state, 'capabilities_ack'):
# apply missed caps
irc.queueMsg(ircmsgs.IrcMsg('CAP REQ :%s' % ' '.join(r)))
else:
r = []
self.log.debug('CAP :: %s :: %s :: %s' % (irc.state.capabilities_ack,irc.state.capabilities_ls,irc.state.capabilities_nak))
for cap in CAPS:
if len(cap) and cap in i.caps['LS'] and not cap in irc.state.capabilities_ack:
r.append(cap)
if len(r):
irc.queueMsg(ircmsgs.IrcMsg('CAP REQ :%s' % ' '.join(r)))
elif command == 'ACK' or command == 'NAK':
# retrieve current caps
irc.queueMsg(ircmsgs.IrcMsg('CAP LIST'))
self._tickle(irc) self._tickle(irc)
def doAccount (self,irc,msg): def doAccount (self,irc,msg):
@ -3493,43 +3452,6 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
if self._isSomething(irc,channel,channel,'attack') and not chan.attacked: if self._isSomething(irc,channel,channel,'attack') and not chan.attacked:
# if number of bad users raise the allowed limit, bot has to set channel attackmode # if number of bad users raise the allowed limit, bot has to set channel attackmode
# todo retreive all wrong users and find the best pattern to use against them # todo retreive all wrong users and find the best pattern to use against them
if self.registryValue('skynet',channel=channel) > 0:
L = []
for n in chan.nicks:
n = self.getNick(irc,n)
pattern = getBestPattern(n,irc,self.registryValue('useIpForGateway',channel=channel),self.registryValue('resolveIp'))[0]
if chan.isWrong(pattern):
L.append(n)
self.log.debug('founds bads %s' % ' '.join(L))
if self.registryValue('skynet',channel=channel) > len(L):
idents = {}
users = {}
for n in L:
(nick,ident,host) = ircutils.splitHostmask(n.prefix)
if not ident in idents:
idents[ident] = []
idents[ident].append(n)
if n.realname and not n.realname in users:
users[n.realname] = []
if n.realname:
users[n.realname].append(n)
fident = None
for ident in idents:
if not fident:
fident = ident
if len(idents[fident]) < len(idents[ident]):
fident = ident
user = None
for u in users:
if not user:
user = u
if len(users[user]) < len(users[u]):
user = u
self.log.debug('computed $r:%s and *!%s@*' % (user,fident))
r = []
if fident and user:
self._act (irc,channel,'b','*!%s@*' % fident,self.registryValue('attackDuration',channel=channel),'skynet powered')
self._act (irc,channel,'b','$r:%s' % user.replace(' ','?').replace('$','?'),self.registryValue('attackDuration',channel=channel),'skynet powered')
chan.attacked = True chan.attacked = True
if self.registryValue('attackMode',channel=channel) == 'd': if self.registryValue('attackMode',channel=channel) == 'd':
if self.registryValue('useColorForAnnounces',channel=channel): if self.registryValue('useColorForAnnounces',channel=channel):