/[cvs]/eggdrop1.6/scripts/sentinel.tcl
ViewVC logotype

Annotation of /eggdrop1.6/scripts/sentinel.tcl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (hide annotations) (download) (as text)
Sun Feb 25 07:05:04 2001 UTC (18 years, 6 months ago) by guppy
Branch: MAIN
CVS Tags: eggdrop1_6_5, eggdrop1_6_7, eggdrop1_6_6
Changes since 1.1: +277 -122 lines
File MIME type: application/x-tcl
new sentinel version

1 guppy 1.2 # sentinel.tcl v2.50 (19 February 2001)
2     # copyright (c) 1998-2001 by slennox <slennox@egghelp.org>
3 guppy 1.1 # slennox's eggdrop page - http://www.egghelp.org/
4     #
5 guppy 1.2 # $Id$
6     #
7 guppy 1.1 # Flood protection system for eggdrop, with integrated BitchX CTCP
8     # simulation. This script is designed to provide strong protection for your
9     # bot and channels against large floodnets and proxy floods.
10     #
11 guppy 1.2 # Note that this script was developed on the eggdrop 1.3, 1.4, and 1.6
12     # series and may not work properly on other versions.
13     #
14 guppy 1.1 # v2.00 - New standalone release. Contains refinements and features from
15     # the netbots.tcl version of sentinel.tcl.
16 guppy 1.2 # v2.50 - Locktimes of less than 30 were erroneously allowed.
17     # putquick -next is now supported (eggdrop 1.5+) for faster channel
18     # lock.
19     # Ban mechanism now checks if flooders are coming from the same
20     # domain or ident and performs wildcard bans instead of banning
21     # each IP/host individually.
22     # Added tsunami detection to the avalanche flood detection system.
23     # Variables are now cleared after removing a channel.
24     # Removed unnecessary botonchan checks throughout components where
25     # botisop already checks for that.
26     # Removed all unnecessary use of parentheses.
27 guppy 1.1 #
28     # sentinel.tcl is centered around its channel lock mechanism. It sets the
29     # channel +mi (moderated and invite-only) whenever a substantial flood on
30     # the channel is detected. This ensures channel stability when flooded,
31     # allowing the bots to deal with the flood as smoothly as possible.
32     # sentinel.tcl detects the following types of floods:
33     #
34     # * Channel CTCP floods. This is the most common type of flood, and will
35     # often make users quit from the channel with 'Excess Flood'. A quick
36     # channel lock can prevent this.
37 guppy 1.2 # * Channel join-part floods. A common type of channel flood in which many
38     # floodbots cycle the channel.
39 guppy 1.1 # * Channel nick floods. Nick floods are unique in that they can occur even
40     # after a channel is locked. sentinel has special mechanisms to deal with
41     # this as effectively as possible.
42 guppy 1.2 # * Channel avalanche/tsunami floods. While the avalanche flood is quite
43     # uncommon these days, tsunami floods are often used to seriously lag
44     # mIRC and other clients using control codes (colour, bold, underline,
45     # etc.)
46 guppy 1.1 # * Channel text floods. Not small text floods - but when hundreds of
47     # messages are sent to the channel within a short period. Detected to
48 guppy 1.2 # stop really aggressive text floods and reduce the possibility of the
49     # bot crashing or consuming excessive CPU.
50 guppy 1.1 #
51     # sentinel also has additional protection features for the bot and channel:
52     #
53     # * Bogus username detection. Users with annoying bogus characters in their
54     # ident are banned. A channel lock is applied if multiple join in a short
55     # period.
56     # * Full ban list detection. During a serious flood, the ban list may
57     # become full. If this happens, the bots may start kick flooding since
58     # they cannot ban. If the ban list is full, the channel will be set +i.
59     # * Bot CTCP flood protection. Protects the bot if it is CTCP flooded.
60     # * Bot MSG flood protection. Protects the bot if it's flooded with MSGs or
61     # MSG commands.
62     # * Automatic bans and ignores. During a flood, sentinel will compile a
63 guppy 1.2 # list of the flooders, then kick-ban them after the channel has been
64 guppy 1.1 # locked.
65     # * BitchX simulation. This has been built-in mainly because you cannot use
66     # a third-party BitchX simulator with sentinel (only one script at a time
67     # can have control of CTCPs). sentinel provides accurate simulation of
68     # BitchX 75p1+ and 75p3+ CTCP replies and AWAY mode.
69     # * Public commands (lc and uc) and DCC commands (.lock and .unlock) for
70     # locking/unlocking channels.
71     # * DCC command .sentinel displays current settings.
72     #
73     # Important Notes:
74     # - Make sure no bots are enforcing channel mode -i and/or -m.
75     # - Bans are added to the bot's internal ban list, and expire after 24
76     # hours by default. If you have +dynamicbans set, the bans may be removed
77     # from the channel much sooner than this, but the ban will remain in the
78     # bot's internal ban list until it expires.
79     # - For greater protection against large channel floods, I recommend you
80 guppy 1.2 # also use a channel limiter script, such as chanlimit.tcl.
81 guppy 1.1 # - Where security is paramount, have one or two bots that aren't running
82     # sentinel.tcl. Since sentinel.tcl is a complex script with many
83     # automated and convenience features, there is a small potential for
84     # vulnerabilities.
85    
86     # The following flood settings are in number:seconds format, 0:0 to
87     # disable.
88    
89     # Bot CTCP flood.
90     set sl_bcflood 5:30
91 guppy 1.2
92 guppy 1.1 # Bot MSG flood.
93     set sl_bmflood 6:20
94 guppy 1.2
95 guppy 1.1 # Channel CTCP flood.
96     set sl_ccflood 5:20
97 guppy 1.2
98     # Channel avalanche/tsunami flood.
99 guppy 1.1 set sl_avflood 6:20
100 guppy 1.2
101 guppy 1.1 # Channel text flood.
102     set sl_txflood 80:30
103 guppy 1.2
104 guppy 1.1 # Channel bogus username join flood.
105     set sl_boflood 4:20
106 guppy 1.2
107 guppy 1.1 # Channel join-part flood.
108     set sl_jflood 6:20
109 guppy 1.2
110 guppy 1.1 # Channel nick flood.
111     set sl_nkflood 6:20
112    
113     # Flood setting notes:
114     # - Don't fiddle too much with the seconds field in the flood settings, as
115     # it can reduce the effectiveness of the script. The seconds field should
116     # set in the 20-60 seconds range.
117 guppy 1.2 # - Avalanche/tsunmami flood detection may be CPU intensive on a busy
118     # channel, although I don't think it's a big deal on most systems. If
119     # you're concerned about CPU usage you may wish to disable it, perhaps
120     # leaving it enabled on one bot. Disabling text flood protection can
121     # further reduce CPU usage.
122     # - On bots with avalanche/tsunami flood detection enabled, it's
123     # recommended that you also enable text flood detection to cap CPU usage
124     # during a flood.
125 guppy 1.1 # - If you enable nick flood detection, it's strongly recommended that it
126     # be enabled on all bots that have sentinel.tcl loaded. This is required
127     # for effective nick flood handling.
128    
129 guppy 1.2 # Specify the number of control characters that must be in a line before
130     # it's counted by the tsunami flood detector. For efficiency reasons,
131     # tsunami detection is implemented with avalanche detection, so sl_avflood
132     # must be enabled for tsunami detection to be active. Setting this to 0
133     # will disable tsunami detection.
134     set sl_tsunami 10
135     # Valid settings: 0 to disable, otherwise 1 or higher.
136    
137 guppy 1.1 # Length of time in minutes to ban channel flooders. This makes the bot
138     # perform kicks and bans on flooders after the channel lock. For the most
139     # effective protection, you should disable this on at least one bot.
140     set sl_ban 1440
141     # Valid settings: 0 to disable, otherwise 1 or higher.
142    
143     # Length of time in minutes of on-join bans for bogus usernames. For the
144     # most effective protection, you should disable this on at least one bot.
145     set sl_boban 1440
146     # Valid settings: 0 to disable, otherwise 1 or higher.
147    
148     # Set global bans on channel flooders and bogus usernames?
149     set sl_globalban 0
150     # Valid settings: 1 for global bans, 0 for channel-specific bans.
151    
152     # Maximum number of bans allowed in the bot's ban list before sentinel will
153     # stop adding new bans. This prevents the bot from adding hundreds of bans
154     # on really large floods. Note that this has nothing to do with the channel
155     # ban list.
156     set sl_banmax 100
157     # Valid settings: 1 or higher.
158    
159     # Length of time in minutes to ignore bot flooders. On bots with sl_ban
160     # active, channel flooders are also added to the ignore list.
161     set sl_igtime 240
162     # Valid settings: 1 or higher.
163    
164     # Length of time in seconds to set channel +i if flooded. If set to 0, +i
165     # will not be removed automatically.
166     set sl_ilocktime 120
167     # Valid settings: 0 to prevent +i being removed automatically, otherwise 30
168     # or higher.
169    
170     # Length of time in seconds to set channel +m if flooded. If set to 0, +m
171     # will not be removed automatically.
172     set sl_mlocktime 60
173     # Valid settings: 0 to prevent +m being removed automatically, otherwise 30
174     # or higher.
175    
176     # On small floods (two flooders or less), remove the +mi shortly after bans
177     # have been set, instead of waiting for the locktimes to expire? This
178     # prevents unnecessary extended locks on small floods. This setting is only
179     # used by bots with sl_ban enabled.
180     set sl_shortlock 0
181     # Valid settings: 0 to disable, 1 to enable.
182    
183     # Number of bans to allow in the channel ban list before setting the
184     # channel +i. If enabled, this should preferably be set to just below the
185     # maximum number of bans allowed.
186     set sl_bfmaxbans 19
187     # Valid settings: 0 to disable +i on full ban list, otherwise 1 or higher.
188    
189     # List of users to send a note to when channel is flooded, bot is flooded,
190     # or ban list becomes full.
191     set sl_note "YourNick"
192     # Valid settings: one user like "Tom", a list of users like
193     # "Tom Dick Harry", or "" to specify that no notes are sent.
194    
195     # Notice to send to channel when locked due to flood.
196     set sl_cfnotice "Channel locked temporarily due to flood, sorry for any inconvenience this may cause :-)"
197     # Valid settings: a text string, or set it to "" to disable.
198    
199     # Notice to send to channel when locked due to full ban list.
200     set sl_bfnotice "Channel locked temporarily due to full ban list, sorry for any inconvenience this may cause :-)"
201 guppy 1.2 # Valid settings: a text string, or set it to "" to disable.
202 guppy 1.1
203     # Enable 'lc' and 'uc' public commands for locking/unlocking channel?
204     set sl_lockcmds 2
205     # Valid settings: 0 to disable, 1 to enable, 2 to require user to be opped
206     # on the channel to use the command.
207    
208     # Users with these flags are allowed to use lc/uc public commands, and
209     # .lock/.unlock DCC commands.
210     set sl_lockflags "o"
211     # Valid settings: one flag like "n", or a list of flags like "fo" (means
212     # 'f OR o').
213    
214     # Enable BitchX CTCP and AWAY simulation?
215     set sl_bxsimul 0
216     # Valid settings: 1 to enable, 0 to disable.
217    
218    
219     # Don't edit below unless you know what you're doing.
220    
221     if {$numversion < 1032400} {
222 guppy 1.2 proc botonchan {chan} {
223     global botnick
224     if {![validchan $chan]} {
225     error "illegal channel: $chan"
226     } elseif {![onchan $botnick $chan]} {
227     return 0
228 guppy 1.1 }
229 guppy 1.2 return 1
230 guppy 1.1 }
231     proc putquick {text} {
232     putserv $text
233     }
234     }
235    
236     proc sl_ctcp {nick uhost hand dest key arg} {
237     global botnet-nick botnick realname sl_ban sl_bflooded sl_bcflood sl_bcqueue sl_bxjointime sl_bxmachine sl_bxonestack sl_bxsimul sl_bxsystem sl_bxversion sl_bxwhoami sl_ccbanhost sl_ccbannick sl_ccflood sl_ccqueue sl_flooded sl_locked sl_note
238     set chan [string tolower $dest]
239 guppy 1.2 if {[lsearch -exact $sl_ccflood 0] == -1 && [validchan $chan] && ![isop $nick $chan]} {
240 guppy 1.1 if {$nick == $botnick} {return 0}
241 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
242     lappend sl_ccbannick($chan) $nick ; lappend sl_ccbanhost($chan) [string tolower $uhost]
243 guppy 1.1 utimer [lindex $sl_ccflood 1] [split "sl_ccbanqueue $chan"]
244     }
245     if {$sl_flooded($chan)} {return 1}
246     incr sl_ccqueue($chan)
247     utimer [lindex $sl_ccflood 1] [split "sl_ccqueuereset $chan"]
248     if {$sl_ccqueue($chan) >= [lindex $sl_ccflood 0]} {
249     sl_lock $chan "CTCP flood" ${botnet-nick} ; return 1
250     }
251     if {$sl_bflooded} {return 1}
252 guppy 1.2 } elseif {[lindex $sl_bcflood 0] && $dest == $botnick} {
253 guppy 1.1 if {$sl_bflooded} {
254 guppy 1.2 sl_ignore [string tolower $uhost] $hand "CTCP flooder" ; return 1
255 guppy 1.1 }
256     incr sl_bcqueue
257     utimer [lindex $sl_bcflood 1] "incr sl_bcqueue -1"
258     if {$sl_bcqueue >= [lindex $sl_bcflood 0]} {
259     putlog "sentinel: CTCP flood detected on me! Stopped answering CTCPs temporarily."
260     set sl_bflooded 1
261     utimer [lindex $sl_bcflood 1] "set sl_bflooded 0"
262     if {[info commands sendnote] != ""} {
263     foreach recipient $sl_note {
264     if {[validuser $recipient]} {
265     sendnote SENTINEL $recipient "Bot was CTCP flooded."
266     }
267     }
268     }
269     return 1
270     }
271     }
272    
273     if {!$sl_bxsimul} {return 0}
274     if {$sl_bxonestack} {return 1}
275     set sl_bxonestack 1 ; utimer 2 "set sl_bxonestack 0"
276     switch -exact -- $key {
277     "CLIENTINFO" {
278     set bxcmd [string toupper $arg]
279     switch -exact -- $bxcmd {
280     "" {putserv "NOTICE $nick :\001CLIENTINFO SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information\001"}
281     "SED" {putserv "NOTICE $nick :\001CLIENTINFO SED contains simple_encrypted_data\001"}
282     "UTC" {putserv "NOTICE $nick :\001CLIENTINFO UTC substitutes the local timezone\001"}
283     "ACTION" {putserv "NOTICE $nick :\001CLIENTINFO ACTION contains action descriptions for atmosphere\001"}
284     "DCC" {putserv "NOTICE $nick :\001CLIENTINFO DCC requests a direct_client_connection\001"}
285     "CDCC" {putserv "NOTICE $nick :\001CLIENTINFO CDCC checks cdcc info for you\001"}
286     "BDCC" {putserv "NOTICE $nick :\001CLIENTINFO BDCC checks cdcc info for you\001"}
287     "XDCC" {putserv "NOTICE $nick :\001CLIENTINFO XDCC checks cdcc info for you\001"}
288     "VERSION" {putserv "NOTICE $nick :\001CLIENTINFO VERSION shows client type, version and environment\001"}
289     "CLIENTINFO" {putserv "NOTICE $nick :\001CLIENTINFO CLIENTINFO gives information about available CTCP commands\001"}
290     "USERINFO" {putserv "NOTICE $nick :\001CLIENTINFO USERINFO returns user settable information\001"}
291     "ERRMSG" {putserv "NOTICE $nick :\001CLIENTINFO ERRMSG returns error messages\001"}
292     "FINGER" {putserv "NOTICE $nick :\001CLIENTINFO FINGER shows real name, login name and idle time of user\001"}
293     "TIME" {putserv "NOTICE $nick :\001CLIENTINFO TIME tells you the time on the user's host\001"}
294     "PING" {putserv "NOTICE $nick :\001CLIENTINFO PING returns the arguments it receives\001"}
295     "ECHO" {putserv "NOTICE $nick :\001CLIENTINFO ECHO returns the arguments it receives\001"}
296     "INVITE" {putserv "NOTICE $nick :\001CLIENTINFO INVITE invite to channel specified\001"}
297     "WHOAMI" {putserv "NOTICE $nick :\001CLIENTINFO WHOAMI user list information\001"}
298     "OP" {putserv "NOTICE $nick :\001CLIENTINFO OP ops the person if on userlist\001"}
299     "OPS" {putserv "NOTICE $nick :\001CLIENTINFO OPS ops the person if on userlist\001"}
300     "UNBAN" {putserv "NOTICE $nick :\001CLIENTINFO UNBAN unbans the person from channel\001"}
301     "IDENT" {putserv "NOTICE $nick :\001CLIENTINFO IDENT change userhost of userlist\001"}
302     "XLINK" {putserv "NOTICE $nick :\001CLIENTINFO XLINK x-filez rule\001"}
303     "UPTIME" {putserv "NOTICE $nick :\001CLIENTINFO UPTIME my uptime\001"}
304     "default" {putserv "NOTICE $nick :\001ERRMSG CLIENTINFO: $arg is not a valid function\001"}
305     }
306     return 1
307     }
308     "VERSION" {
309     putserv "NOTICE $nick :\001VERSION \002BitchX-$sl_bxversion\002 by panasync \002-\002 $sl_bxsystem :\002 Keep it to yourself!\002\001"
310     return 1
311     }
312     "USERINFO" {
313     putserv "NOTICE $nick :\001USERINFO \001"
314     return 1
315     }
316     "FINGER" {
317     putserv "NOTICE $nick :\001FINGER $realname ($sl_bxwhoami@$sl_bxmachine) Idle [expr [unixtime] - $sl_bxjointime] seconds\001"
318     return 1
319     }
320     "PING" {
321     putserv "NOTICE $nick :\001PING $arg\001"
322     return 1
323     }
324     "ECHO" {
325     if {[validchan $chan]} {return 1}
326     putserv "NOTICE $nick :\001ECHO [string range $arg 0 59]\001"
327     return 1
328     }
329     "ERRMSG" {
330     if {[validchan $chan]} {return 1}
331     putserv "NOTICE $nick :\001ERRMSG [string range $arg 0 59]\001"
332     return 1
333     }
334     "INVITE" {
335 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
336 guppy 1.1 set chanarg [lindex [split $arg] 0]
337     if {((($sl_bxversion == "75p1+") && ([string trim [string index $chanarg 0] "#+&"] == "")) || (($sl_bxversion == "75p3+") && ([string trim [string index $chanarg 0] "#+&!"] == "")))} {
338     if {[validchan $chanarg]} {
339     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
340     } else {
341     putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
342     }
343     }
344     return 1
345     }
346     "WHOAMI" {
347     if {[validchan $chan]} {return 1}
348     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
349     return 1
350     }
351     "OP" -
352     "OPS" {
353 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
354 guppy 1.1 putserv "NOTICE $nick :\002BitchX\002: I'm not on [lindex [split $arg] 0], or I'm not opped"
355     return 1
356     }
357     "UNBAN" {
358 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
359 guppy 1.1 if {[validchan [lindex [split $arg] 0]]} {
360     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
361     } else {
362     putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
363     }
364     return 1
365     }
366     }
367     return 0
368     }
369    
370     proc sl_bmflood {nick uhost hand text} {
371     global sl_bmflood sl_bflooded sl_bmqueue sl_note
372 guppy 1.2 if {[matchattr $hand b] && [string tolower [lindex [split $text] 0]] == "go"} {return 0}
373 guppy 1.1 if {$sl_bflooded} {
374 guppy 1.2 sl_ignore [string tolower $uhost] $hand "MSG flooder" ; return 0
375 guppy 1.1 }
376     incr sl_bmqueue
377     utimer [lindex $sl_bmflood 1] "incr sl_bmqueue -1"
378     if {$sl_bmqueue >= [lindex $sl_bmflood 0]} {
379     putlog "sentinel: MSG flood detected on me! Stopped answering MSGs temporarily."
380     set sl_bflooded 1
381     utimer [lindex $sl_bmflood 1] "set sl_bflooded 0"
382     if {[info commands sendnote] != ""} {
383     foreach recipient $sl_note {
384     if {[validuser $recipient]} {
385     sendnote SENTINEL $recipient "Bot was MSG flooded."
386     }
387     }
388     }
389     }
390     return 0
391     }
392    
393     proc sl_avflood {from keyword arg} {
394     global botnet-nick botnick sl_ban sl_avbanhost sl_avbannick sl_avflood sl_avqueue sl_flooded sl_locked sl_txflood sl_txqueue
395     set arg [split $arg]
396     set chan [string tolower [lindex $arg 0]]
397     if {![validchan $chan]} {return 0}
398     set nick [lindex [split $from !] 0]
399 guppy 1.2 if {$nick == $botnick || $nick == "" || [string match *.* $nick]} {return 0}
400     if {![onchan $nick $chan] || [isop $nick $chan]} {return 0}
401     if {!$sl_flooded($chan) && [lsearch -exact $sl_txflood 0] == -1} {
402 guppy 1.1 incr sl_txqueue($chan)
403     if {$sl_txqueue($chan) >= [lindex $sl_txflood 0]} {
404     sl_lock $chan "TEXT flood" ${botnet-nick}
405     }
406     }
407     set text [join [lrange $arg 1 end]]
408 guppy 1.2 if {[sl_checkaval $text] && [lsearch -exact $sl_avflood 0] == -1} {
409 guppy 1.1 set uhost [string trimleft [getchanhost $nick $chan] "~+-^="]
410     set hand [nick2hand $nick $chan]
411 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
412     lappend sl_avbannick($chan) $nick ; lappend sl_avbanhost($chan) [string tolower $uhost]
413 guppy 1.1 utimer [lindex $sl_avflood 1] [split "sl_avbanqueue $chan"]
414     }
415     if {$sl_flooded($chan)} {return 0}
416     incr sl_avqueue($chan)
417     utimer [lindex $sl_avflood 1] [split "sl_avqueuereset $chan"]
418     if {$sl_avqueue($chan) >= [lindex $sl_avflood 0]} {
419 guppy 1.2 sl_lock $chan "AVALANCHE/TSUNAMI flood" ${botnet-nick}
420 guppy 1.1 }
421     }
422     return 0
423     }
424    
425     proc sl_checkaval {text} {
426 guppy 1.2 global sl_tsunami
427     if {[regsub -all -- "\001|\007" $text "" temp] >= 3} {return 1}
428     if {$sl_tsunami && [regsub -all -- "\002|\003|\017|\026|\037" $text "" temp] >= $sl_tsunami} {return 1}
429 guppy 1.1 return 0
430     }
431    
432     proc sl_nkflood {nick uhost hand chan newnick} {
433     global botnet-nick botnick sl_ban sl_banmax sl_flooded sl_globalban sl_locked sl_nickkick sl_nkbanhost sl_nkflood sl_nkflooding sl_nkqueue
434     set chan [string tolower $chan]
435     if {[isop $newnick $chan]} {return 0}
436 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
437     lappend sl_nkbanhost($chan) [string tolower $uhost]
438 guppy 1.1 utimer [lindex $sl_nkflood 1] [split "sl_nkbanqueue $chan"]
439     }
440 guppy 1.2 if {!$sl_nickkick && $sl_flooded($chan) && $sl_locked($chan)} {
441 guppy 1.1 putserv "KICK $chan $newnick :NICK flooder"
442     set sl_nickkick 1 ; set sl_nkflooding($chan) [unixtime]
443     if {$sl_ban} {
444     set bhost *!*[string tolower [string range $uhost [string first @ $uhost] end]]
445     if {$sl_globalban} {
446 guppy 1.2 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban *!$bhost]} {
447 guppy 1.1 newban $bhost sentinel "NICK flooder" $sl_ban
448     }
449     } else {
450 guppy 1.2 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban *!$bhost $chan]} {
451 guppy 1.1 newchanban $chan $bhost sentinel "NICK flooder" $sl_ban
452     }
453     }
454     }
455     utimer [expr [rand 2] + 3] "set sl_nickkick 0"
456     return 0
457     }
458     if {$sl_flooded($chan)} {return 0}
459     incr sl_nkqueue($chan)
460     utimer [lindex $sl_nkflood 1] [split "sl_nkqueuereset $chan"]
461     if {$sl_nkqueue($chan) >= [lindex $sl_nkflood 0]} {
462     sl_lock $chan "NICK flood" ${botnet-nick}
463     }
464     return 0
465     }
466    
467     proc sl_jflood {nick uhost hand chan} {
468     global botnet-nick botnick sl_ban sl_banmax sl_boban sl_bobanhost sl_bobannick sl_boflood sl_boqueue sl_flooded sl_globalban sl_jbanhost sl_jbannick sl_jflood sl_jqueue sl_locked sl_pqueue
469     if {$nick == $botnick} {
470     sl_setarray $chan
471     } else {
472     set ihost *!*[string tolower [string range $uhost [string first @ $uhost] end]]
473     if {[isignore $ihost]} {
474     killignore $ihost
475     }
476     set chan [string tolower $chan]
477 guppy 1.2 if {[lsearch -exact $sl_boflood 0] == -1 && [sl_checkbogus [lindex [split $uhost @] 0]]} {
478     if {!$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
479 guppy 1.1 set bhost *!*[string tolower [string range $uhost [string first @ $uhost] end]]
480 guppy 1.2 if {$sl_boban && [botisop $chan] && !$sl_flooded($chan)} {
481 guppy 1.1 putserv "KICK $chan $nick :BOGUS username"
482     if {$sl_globalban} {
483 guppy 1.2 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban *!$bhost]} {
484 guppy 1.1 newban $bhost sentinel "BOGUS username" $sl_boban
485     }
486     } else {
487 guppy 1.2 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban *!$bhost $chan]} {
488 guppy 1.1 newchanban $chan $bhost sentinel "BOGUS username" $sl_boban
489     }
490     }
491     }
492     if {$sl_ban} {
493 guppy 1.2 lappend sl_bobannick($chan) $nick ; lappend sl_bobanhost($chan) [string tolower $uhost]
494 guppy 1.1 utimer [lindex $sl_boflood 1] [split "sl_bobanqueue $chan"]
495     }
496     }
497     if {!$sl_flooded($chan)} {
498     incr sl_boqueue($chan)
499     utimer [lindex $sl_boflood 1] [split "sl_boqueuereset $chan"]
500     if {$sl_boqueue($chan) >= [lindex $sl_boflood 0]} {
501     sl_lock $chan "BOGUS joins" ${botnet-nick}
502     }
503     }
504     }
505     if {[lsearch -exact $sl_jflood 0] == -1} {
506 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
507     lappend sl_jbannick($chan) $nick ; lappend sl_jbanhost($chan) [string tolower $uhost]
508 guppy 1.1 utimer [lindex $sl_jflood 1] [split "sl_jbanqueue $chan"]
509     }
510     if {$sl_flooded($chan)} {return 0}
511     incr sl_jqueue($chan)
512     utimer [lindex $sl_jflood 1] [split "sl_jqueuereset $chan"]
513 guppy 1.2 if {$sl_jqueue($chan) >= [lindex $sl_jflood 0] && $sl_pqueue($chan) >= [lindex $sl_jflood 0]} {
514 guppy 1.1 sl_lock $chan "JOIN-PART flood" ${botnet-nick}
515     }
516     }
517     }
518     return 0
519     }
520    
521     proc sl_checkbogus {ident} {
522     if {[regsub -all -- "\[^\041-\176\]" $ident "" temp] >= 1} {return 1}
523     return 0
524     }
525    
526     proc sl_pflood {nick uhost hand chan {msg ""}} {
527     global botnick sl_ban sl_flooded sl_jflood sl_locked sl_pbanhost sl_pbannick sl_pqueue
528     if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
529 guppy 1.2 if {$nick == $botnick} {
530     if {![validchan $chan]} {
531     timer 5 [split "sl_unsetarray $chan"]
532     }
533     return 0
534     }
535 guppy 1.1 set chan [string tolower $chan]
536 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
537     lappend sl_pbannick($chan) $nick ; lappend sl_pbanhost($chan) [string tolower $uhost]
538 guppy 1.1 utimer [lindex $sl_jflood 1] [split "sl_pbanqueue $chan"]
539     }
540     if {$sl_flooded($chan)} {return 0}
541     incr sl_pqueue($chan)
542     utimer [lindex $sl_jflood 1] [split "sl_pqueuereset $chan"]
543     return 0
544     }
545    
546     proc sl_pfloodk {nick uhost hand chan kicked reason} {
547     global botnick sl_flooded sl_jflood sl_pqueue
548     if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
549     if {$kicked == $botnick} {return 0}
550     set chan [string tolower $chan]
551     if {$sl_flooded($chan)} {return 0}
552     incr sl_pqueue($chan)
553     utimer [lindex $sl_jflood 1] [split "sl_pqueuereset $chan"]
554     return 0
555     }
556    
557     proc sl_lock {chan flood detected} {
558     global botnet-nick sl_bflooded sl_cfnotice sl_flooded sl_ilocktime sl_mlocktime sl_note
559     if {$detected == ${botnet-nick}} {
560     set sl_flooded($chan) 1 ; set sl_bflooded 1
561     if {[botisop $chan]} {
562 guppy 1.2 sl_quicklock $chan
563 guppy 1.1 sl_killutimer "sl_unlock $chan *"
564     sl_killutimer "set sl_bflooded 0"
565     if {$sl_mlocktime} {
566     utimer $sl_mlocktime [split "sl_unlock $chan m"]
567     }
568     if {$sl_ilocktime} {
569     utimer $sl_ilocktime [split "sl_unlock $chan i"]
570     }
571     utimer 120 "set sl_bflooded 0"
572     putlog "sentinel: $flood detected on $chan! Channel locked temporarily."
573     if {$sl_cfnotice != ""} {
574     puthelp "NOTICE $chan :$sl_cfnotice"
575     }
576     } else {
577     putlog "sentinel: $flood detected on $chan! Cannot lock channel because I'm not opped."
578     utimer 120 "set sl_bflooded 0"
579     }
580     } else {
581     putlog "sentinel: $flood detected by $detected on $chan!"
582     }
583     if {[info commands sendnote] != ""} {
584     foreach recipient $sl_note {
585     if {[validuser $recipient]} {
586     if {$detected == ${botnet-nick}} {
587     sendnote SENTINEL $recipient "$flood detected on $chan."
588     } else {
589     sendnote SENTINEL $recipient "$flood detected by $detected on $chan."
590     }
591     }
592     }
593     }
594     return 0
595     }
596    
597     proc sl_unlock {chan umode} {
598     global sl_bflooded sl_bfmaxbans sl_flooded sl_ilocktime sl_mlocktime sl_nkflooding
599     if {[expr [unixtime] - $sl_nkflooding($chan)] < 12} {
600     putlog "sentinel: nick flooding still in progress on $chan - not removing +mi yet.."
601     set sl_flooded($chan) 1 ; set sl_bflooded 1
602     sl_killutimer "sl_unlock $chan *"
603     sl_killutimer "set sl_bflooded 0"
604     utimer $sl_mlocktime [split "sl_unlock $chan m"] ; utimer $sl_ilocktime [split "sl_unlock $chan i"]
605     utimer 120 "set sl_bflooded 0"
606     } else {
607     set sl_flooded($chan) 0
608     if {![botisop $chan]} {return 0}
609     if {$umode == "mi"} {
610     putlog "sentinel: flood was small, performing early unlock.."
611     }
612 guppy 1.2 if {[string match *i* $umode] && [string match *i* [lindex [split [getchanmode $chan]] 0]]} {
613     if {$sl_bfmaxbans && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
614 guppy 1.1 putlog "sentinel: not removing +i on $chan due to full ban list."
615     } else {
616     pushmode $chan -i
617     putlog "sentinel: removed +i on $chan"
618     }
619     }
620 guppy 1.2 if {[string match *m* $umode] && [string match *m* [lindex [split [getchanmode $chan]] 0]]} {
621 guppy 1.1 pushmode $chan -m
622     putlog "sentinel: removed +m on $chan"
623     }
624     }
625     return 0
626     }
627    
628     proc sl_mode {nick uhost hand chan mode victim} {
629     global botnick sl_ban sl_bfmaxbans sl_bfnotice sl_bfull sl_flooded sl_locked sl_note sl_unlocked
630     set chan [string tolower $chan]
631 guppy 1.2 if {$mode == "+b" && $sl_bfmaxbans && !$sl_bfull($chan) && ![string match *i* [lindex [split [getchanmode $chan]] 0]] && [botisop $chan] && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
632 guppy 1.1 putserv "MODE $chan +i"
633     set sl_bfull($chan) 1
634     utimer 5 [split "set sl_bfull($chan) 0"]
635     putlog "sentinel: locked $chan due to full ban list!"
636     if {$sl_bfnotice != ""} {
637     puthelp "NOTICE $chan :$sl_bfnotice"
638     }
639     if {[info commands sendnote] != ""} {
640     foreach recipient $sl_note {
641     if {[validuser $recipient]} {
642     sendnote SENTINEL $recipient "Locked $chan due to full ban list."
643     }
644     }
645     }
646 guppy 1.2 } elseif {$mode == "+i" && $sl_flooded($chan)} {
647 guppy 1.1 set sl_locked($chan) 1
648     if {$sl_ban} {
649     sl_killutimer "sl_*banqueue $chan"
650     utimer 7 [split "sl_dokicks $chan"] ; utimer 16 [split "sl_setbans $chan"]
651     }
652 guppy 1.2 } elseif {$mode == "-i" || $mode == "-m"} {
653 guppy 1.1 set sl_locked($chan) 0
654     set sl_unlocked($chan) [unixtime]
655     if {$sl_flooded($chan)} {
656     set sl_flooded($chan) 0
657     if {$mode == "-i"} {
658     sl_killutimer "sl_unlock $chan i"
659     } else {
660     sl_killutimer "sl_unlock $chan m"
661     }
662     sl_killutimer "sl_unlock $chan mi"
663     if {$nick != $botnick} {
664     putlog "sentinel: $chan unlocked by $nick"
665     }
666     }
667     }
668     return 0
669     }
670    
671     proc sl_dokicks {chan} {
672     global sl_avbannick sl_bobannick sl_ccbannick sl_kflooders sl_jbannick sl_pbannick
673 guppy 1.2 if {![botisop $chan]} {return 0}
674 guppy 1.1 set sl_kflooders 0
675     sl_kick $chan $sl_ccbannick($chan) "CTCP flooder" ; set sl_ccbannick($chan) ""
676 guppy 1.2 sl_kick $chan $sl_avbannick($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbannick($chan) ""
677 guppy 1.1 sl_kick $chan $sl_bobannick($chan) "BOGUS username" ; set sl_bobannick($chan) ""
678     set jklist $sl_jbannick($chan) ; set pklist $sl_pbannick($chan)
679 guppy 1.2 if {$jklist != "" && $pklist != ""} {
680 guppy 1.1 set klist ""
681     foreach nick $jklist {
682     if {[lsearch -exact $pklist $nick] != -1} {
683     lappend klist $nick
684     }
685     }
686     sl_kick $chan $klist "JOIN-PART flooder"
687     }
688     set sl_jbannick($chan) "" ; set sl_pbannick($chan) ""
689     return 0
690     }
691    
692     proc sl_kick {chan klist reason} {
693     global sl_kflooders sl_kicks
694     if {$klist != ""} {
695     set kicklist ""
696     foreach nick $klist {
697     if {[lsearch -exact $kicklist $nick] == -1} {
698     lappend kicklist $nick
699     }
700     }
701     unset nick
702     incr sl_kflooders [llength $kicklist]
703     foreach nick $kicklist {
704 guppy 1.2 if {[onchan $nick $chan] && ![onchansplit $nick $chan]} {
705 guppy 1.1 lappend ksend $nick
706     if {[llength $ksend] >= $sl_kicks} {
707     putserv "KICK $chan [join $ksend ,] :$reason"
708     unset ksend
709     }
710     }
711     }
712     if {[info exists ksend]} {
713     putserv "KICK $chan [join $ksend ,] :$reason"
714     }
715     }
716     return 0
717     }
718    
719     proc sl_setbans {chan} {
720 guppy 1.2 global sl_avbanhost sl_bobanhost sl_ccbanhost sl_kflooders sl_jbanhost sl_nkbanhost sl_pbanhost sl_shortlock sl_unlocked
721 guppy 1.1 if {![botonchan $chan]} {return 0}
722 guppy 1.2 set sl_ccbanhost($chan) [sl_dfilter $sl_ccbanhost($chan)]
723     set sl_avbanhost($chan) [sl_dfilter $sl_avbanhost($chan)]
724     set sl_nkbanhost($chan) [sl_dfilter $sl_nkbanhost($chan)]
725     set sl_bobanhost($chan) [sl_dfilter $sl_bobanhost($chan)]
726     set sl_jbanhost($chan) [sl_dfilter $sl_jbanhost($chan)]
727     set sl_pbanhost($chan) [sl_dfilter $sl_pbanhost($chan)]
728     set allbans [sl_dfilter [concat $sl_ccbanhost($chan) $sl_avbanhost($chan) $sl_nkbanhost($chan) $sl_bobanhost($chan) $sl_jbanhost($chan) $sl_pbanhost($chan)]]
729     sl_ban $chan [sl_dcheck $allbans] "IDENT/HOST flooders"
730 guppy 1.1 sl_ban $chan $sl_ccbanhost($chan) "CTCP flooder" ; set sl_ccbanhost($chan) ""
731 guppy 1.2 sl_ban $chan $sl_avbanhost($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbanhost($chan) ""
732 guppy 1.1 sl_ban $chan $sl_nkbanhost($chan) "NICK flooder" ; set sl_nkbanhost($chan) ""
733     sl_ban $chan $sl_bobanhost($chan) "BOGUS username" ; set sl_bobanhost($chan) ""
734 guppy 1.2 if {$sl_jbanhost($chan) != "" && $sl_pbanhost($chan) != ""} {
735 guppy 1.1 set blist ""
736 guppy 1.2 foreach bhost $sl_jbanhost($chan) {
737     if {[lsearch -exact $sl_pbanhost($chan) $bhost] != -1} {
738 guppy 1.1 lappend blist $bhost
739     }
740     }
741     sl_ban $chan $blist "JOIN-PART flooder"
742     }
743     set sl_jbanhost($chan) "" ; set sl_pbanhost($chan) ""
744 guppy 1.2 if {$sl_shortlock && $sl_kflooders <= 2 && [llength $allbans] <= 2 && [expr [unixtime] - $sl_unlocked($chan)] > 120} {
745 guppy 1.1 sl_killutimer "sl_unlock $chan *"
746     utimer 10 [split "sl_unlock $chan mi"]
747     }
748     return 0
749     }
750    
751 guppy 1.2 proc sl_dfilter {list} {
752     set newlist ""
753     foreach item $list {
754     if {[lsearch -exact $newlist $item] == -1} {
755     lappend newlist $item
756     }
757     }
758     return $newlist
759     }
760    
761     proc sl_dcheck {bhosts} {
762     set blist ""
763     foreach bhost $bhosts {
764     set baddr [string tolower [lindex [split [maskhost $bhost] "@"] 1]]
765     set bident [string trimleft [string tolower [lindex [split $bhost "@"] 0]] "~"]
766     if {![info exists baddrs($baddr)]} {
767     set baddrs($baddr) 1
768     } else {
769     incr baddrs($baddr)
770     }
771     if {![info exists bidents($bident)]} {
772     set bidents($bident) 1
773     } else {
774     incr bidents($bident)
775     }
776     }
777     foreach baddr [array names baddrs] {
778     if {$baddrs($baddr) >= 2} {
779     lappend blist *!@$baddr
780     }
781     }
782     foreach bident [array names bidents] {
783     if {$bidents($bident) >= 2} {
784     lappend blist *!*$bident@*
785     }
786     }
787     return $blist
788     }
789    
790 guppy 1.1 proc sl_ban {chan blist reason} {
791 guppy 1.2 global sl_ban sl_banmax sl_globalban
792 guppy 1.1 if {$blist != ""} {
793     if {$sl_globalban} {
794 guppy 1.2 foreach bhost $blist {
795     if {![string match *!* $bhost]} {
796     if {[matchban *!$bhost]} {continue}
797     set bhost *!*[string range $bhost [string first @ $bhost] end]
798     if {[isban $bhost]} {continue}
799     } else {
800     if {[isban $bhost]} {continue}
801     foreach ban [banlist] {
802     if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
803     killban $ban
804     }
805     }
806     }
807     if {[llength [banlist]] >= $sl_banmax || [isban $bhost]} {continue}
808 guppy 1.1 newban $bhost sentinel $reason $sl_ban
809     putlog "sentinel: banned $bhost ($reason)"
810     sl_ignore $bhost * $reason
811     }
812     } else {
813 guppy 1.2 foreach bhost $blist {
814     if {![string match *!* $bhost]} {
815     if {[matchban *!$bhost $chan]} {continue}
816     set bhost *!*[string range $bhost [string first @ $bhost] end]
817     if {[isban $bhost $chan]} {continue}
818     } else {
819     if {[isban $bhost $chan]} {continue}
820     foreach ban [banlist $chan] {
821     if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
822     killchanban $chan $ban
823     }
824     }
825     }
826     if {[llength [banlist $chan]] >= $sl_banmax || [isban $bhost $chan]} {continue}
827 guppy 1.1 newchanban $chan $bhost sentinel $reason $sl_ban
828     putlog "sentinel: banned $bhost on $chan ($reason)"
829     sl_ignore $bhost * $reason
830     }
831     }
832     }
833     return 0
834     }
835    
836 guppy 1.2 proc sl_ignore {ihost hand flood} {
837 guppy 1.1 global sl_igtime
838     if {$hand != "*"} {
839     foreach chan [channels] {
840     if {[matchattr $hand f|f $chan]} {return 0}
841     }
842     }
843 guppy 1.2 if {![string match *!* $ihost]} {
844     foreach ignore [ignorelist] {
845     if {[string match [string tolower [lindex $ignore 0]] [string tolower $ihost]]} {
846     return 0
847     }
848     }
849     set ihost *!*[string range $ihost [string first @ $ihost] end]
850     if {[isignore $ihost]} {return 0}
851     } else {
852     if {[isignore $ihost]} {return 0}
853     foreach ignore [ignorelist] {
854     if {[lindex $ignore 4] == "sentinel" && [string match $ihost [string tolower [lindex $ignore 0]]]} {
855     killignore $ignore
856     }
857     }
858     }
859 guppy 1.1 newignore $ihost sentinel $flood $sl_igtime
860     putlog "sentinel: added $ihost to ignore list ($flood)"
861 guppy 1.2 return 1
862 guppy 1.1 }
863    
864     proc sl_ccqueuereset {chan} {
865     global sl_ccqueue
866     incr sl_ccqueue($chan) -1
867     return 0
868     }
869    
870     proc sl_bcqueuereset {} {
871     global sl_bcqueue
872     incr sl_bcqueue -1
873     return 0
874     }
875    
876     proc sl_bmqueuereset {} {
877     global sl_bmqueue
878     incr sl_bmqueue -1
879     return 0
880     }
881    
882     proc sl_avqueuereset {chan} {
883     global sl_avqueue
884     incr sl_avqueue($chan) -1
885     return 0
886     }
887    
888     proc sl_txqueuereset {} {
889     global sl_txqueue sl_txflood
890     foreach chan [string tolower [channels]] {
891     if {[info exists sl_txqueue($chan)]} {
892     set sl_txqueue($chan) 0
893     }
894     }
895     utimer [lindex $sl_txflood 1] sl_txqueuereset
896     return 0
897     }
898    
899     proc sl_nkqueuereset {chan} {
900     global sl_nkqueue
901     incr sl_nkqueue($chan) -1
902     return 0
903     }
904    
905     proc sl_boqueuereset {chan} {
906     global sl_boqueue
907     incr sl_boqueue($chan) -1
908     return 0
909     }
910    
911     proc sl_jqueuereset {chan} {
912     global sl_jqueue
913     incr sl_jqueue($chan) -1
914     return 0
915     }
916    
917     proc sl_pqueuereset {chan} {
918     global sl_pqueue
919     incr sl_pqueue($chan) -1
920     return 0
921     }
922    
923     proc sl_ccbanqueue {chan} {
924     global sl_ccbanhost sl_ccbannick
925     set sl_ccbannick($chan) [lrange sl_ccbannick($chan) 1 end] ; set sl_ccbanhost($chan) [lrange sl_ccbanhost($chan) 1 end]
926     return 0
927     }
928    
929     proc sl_avbanqueue {chan} {
930     global sl_avbanhost sl_avbannick
931     set sl_avbannick($chan) [lrange sl_avbannick($chan) 1 end] ; set sl_avbanhost($chan) [lrange sl_avbanhost($chan) 1 end]
932     return 0
933     }
934    
935     proc sl_nkbanqueue {chan} {
936     global sl_nkbanhost
937     set sl_nkbanhost($chan) [lrange sl_nkbanhost($chan) 1 end]
938     return 0
939     }
940    
941     proc sl_bobanqueue {chan} {
942     global sl_bobanhost sl_bobannick
943     set sl_bobannick($chan) [lrange sl_bobannick($chan) 1 end] ; set sl_bobanhost($chan) [lrange sl_bobanhost($chan) 1 end]
944     return 0
945     }
946    
947     proc sl_jbanqueue {chan} {
948     global sl_jbanhost sl_jbannick
949     set sl_jbannick($chan) [lrange sl_jbannick($chan) 1 end] ; set sl_jbanhost($chan) [lrange sl_jbanhost($chan) 1 end]
950     return 0
951     }
952    
953     proc sl_pbanqueue {chan} {
954     global sl_pbanhost sl_pbannick
955     set sl_pbannick($chan) [lrange sl_pbannick($chan) 1 end] ; set sl_pbanhost($chan) [lrange sl_pbanhost($chan) 1 end]
956     return 0
957     }
958    
959     proc sl_flud {nick uhost hand type chan} {
960     global sl_flooded
961     set chan [string tolower $chan]
962 guppy 1.2 if {[validchan $chan] && $sl_flooded($chan)} {return 1}
963 guppy 1.1 return 0
964     }
965    
966     proc sl_lc {nick uhost hand chan arg} {
967     global sl_lockcmds
968     set chan [string tolower $chan]
969     if {![botisop $chan]} {return 0}
970 guppy 1.2 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
971     sl_quicklock $chan
972 guppy 1.1 putlog "sentinel: channel lock requested by $hand on $chan"
973     return 0
974     }
975    
976     proc sl_uc {nick uhost hand chan arg} {
977     global sl_lockcmds
978     set chan [string tolower $chan]
979     if {![botisop $chan]} {return 0}
980 guppy 1.2 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
981 guppy 1.1 putserv "MODE $chan -mi"
982     putlog "sentinel: channel unlock requested by $hand on $chan"
983     return 0
984     }
985    
986     proc sl_dcclc {hand idx arg} {
987     global sl_lockflags
988     putcmdlog "#$hand# lock $arg"
989     set chan [lindex [split $arg] 0]
990     if {$chan == "-all"} {
991     if {![matchattr $hand $sl_lockflags]} {
992     putidx $idx "You're not global +$sl_lockflags." ; return 0
993     }
994     set locklist ""
995     foreach chan [channels] {
996 guppy 1.2 if {[botisop $chan]} {
997     sl_quicklock $chan
998 guppy 1.1 lappend locklist $chan
999     }
1000     }
1001     putidx $idx "Locked [join $locklist ", "]"
1002     } else {
1003     if {$chan == ""} {
1004     set chan [lindex [console $idx] 0]
1005     }
1006     if {![validchan $chan]} {
1007     putidx $idx "No such channel." ; return 0
1008     } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
1009     putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
1010     } elseif {![botonchan $chan]} {
1011     putidx $idx "I'm not on $chan" ; return 0
1012     } elseif {![botisop $chan]} {
1013     putidx $idx "I'm not opped on $chan" ; return 0
1014     }
1015 guppy 1.2 sl_quicklock $chan
1016 guppy 1.1 putidx $idx "Locked $chan"
1017     }
1018     return 0
1019     }
1020    
1021     proc sl_dccuc {hand idx arg} {
1022     global sl_lockflags
1023     putcmdlog "#$hand# unlock $arg"
1024     set chan [lindex [split $arg] 0]
1025     if {$chan == "-all"} {
1026     if {![matchattr $hand $sl_lockflags]} {
1027     putidx $idx "You're not global +$sl_lockflags." ; return 0
1028     }
1029     set locklist ""
1030     foreach chan [channels] {
1031 guppy 1.2 if {[botisop $chan]} {
1032 guppy 1.1 putserv "MODE $chan -mi"
1033     lappend locklist $chan
1034     }
1035     }
1036     putidx $idx "Unlocked [join $locklist ", "]"
1037     } else {
1038     if {$chan == ""} {
1039     set chan [lindex [console $idx] 0]
1040     }
1041     if {![validchan $chan]} {
1042     putidx $idx "No such channel." ; return 0
1043     } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
1044     putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
1045     } elseif {![botonchan $chan]} {
1046     putidx $idx "I'm not on $chan" ; return 0
1047     } elseif {![botisop $chan]} {
1048     putidx $idx "I'm not opped on $chan" ; return 0
1049     }
1050     putserv "MODE $chan -mi"
1051     putidx $idx "Unlocked $chan"
1052     }
1053     return 0
1054     }
1055    
1056 guppy 1.2 proc sl_quicklock {chan} {
1057     global numversion
1058     if {$numversion < 1050000} {
1059     putquick "MODE $chan +mi"
1060     } else {
1061     putquick "MODE $chan +mi" -next
1062     }
1063     }
1064    
1065 guppy 1.1 proc sl_dcc {hand idx arg} {
1066 guppy 1.2 global sl_avflood sl_ban sl_banmax sl_bcflood sl_boban sl_boflood sl_bmflood sl_bxsimul sl_bfmaxbans sl_ccflood sl_globalban sl_igtime sl_jflood sl_kicks sl_lockcmds sl_lockflags sl_ilocktime sl_mlocktime sl_nkflood sl_note sl_shortlock sl_tsunami sl_txflood
1067 guppy 1.1 putcmdlog "#$hand# sentinel $arg"
1068     putidx $idx "This bot is protected by sentinel.tcl by slennox"
1069     putidx $idx "Current settings"
1070     if {[lsearch -exact $sl_bcflood 0] != -1} {
1071     putidx $idx "- Bot CTCP flood: Off"
1072     } else {
1073     putidx $idx "- Bot CTCP flood: [lindex $sl_bcflood 0] in [lindex $sl_bcflood 1] secs"
1074     }
1075     if {[lsearch -exact $sl_bmflood 0] != -1} {
1076     putidx $idx "- Bot MSG flood: Off"
1077     } else {
1078     putidx $idx "- Bot MSG flood: [lindex $sl_bmflood 0] in [lindex $sl_bmflood 1] secs"
1079     }
1080     if {[lsearch -exact $sl_ccflood 0] != -1} {
1081     putidx $idx "- Channel CTCP flood: Off"
1082     } else {
1083     putidx $idx "- Channel CTCP flood: [lindex $sl_ccflood 0] in [lindex $sl_ccflood 1] secs"
1084     }
1085     if {[lsearch -exact $sl_avflood 0] != -1} {
1086     putidx $idx "- Channel AVALANCHE flood: Off"
1087     } else {
1088     putidx $idx "- Channel AVALANCHE flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs"
1089     }
1090 guppy 1.2 if {[lsearch -exact $sl_avflood 0] != -1 || !$sl_tsunami} {
1091     putidx $idx "- Channel TSUNAMI flood: Off"
1092     } else {
1093     putidx $idx "- Channel TSUNAMI flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs ($sl_tsunami ctrl codes / line)"
1094     }
1095 guppy 1.1 if {[lsearch -exact $sl_txflood 0] != -1} {
1096     putidx $idx "- Channel TEXT flood: Off"
1097     } else {
1098     putidx $idx "- Channel TEXT flood: [lindex $sl_txflood 0] in [lindex $sl_txflood 1] secs"
1099     }
1100     if {[lsearch -exact $sl_boflood 0] != -1} {
1101     putidx $idx "- Channel BOGUS flood: Off"
1102     } else {
1103     putidx $idx "- Channel BOGUS flood: [lindex $sl_boflood 0] in [lindex $sl_boflood 1] secs"
1104     }
1105     if {[lsearch -exact $sl_jflood 0] != -1} {
1106     putidx $idx "- Channel JOIN-PART flood: Off"
1107     } else {
1108     putidx $idx "- Channel JOIN-PART flood: [lindex $sl_jflood 0] in [lindex $sl_jflood 1] secs"
1109     }
1110     if {[lsearch -exact $sl_nkflood 0] != -1} {
1111     putidx $idx "- Channel NICK flood: Off"
1112     } else {
1113     putidx $idx "- Channel NICK flood: [lindex $sl_nkflood 0] in [lindex $sl_nkflood 1] secs"
1114     }
1115     if {!$sl_ilocktime} {
1116     putidx $idx "- Channel +i locktime: Indefinite"
1117     } else {
1118     putidx $idx "- Channel +i locktime: $sl_ilocktime secs"
1119     }
1120     if {!$sl_mlocktime} {
1121     putidx $idx "- Channel +m locktime: Indefinite"
1122     } else {
1123     putidx $idx "- Channel +m locktime: $sl_mlocktime secs"
1124     }
1125 guppy 1.2 if {$sl_shortlock && $sl_ban} {
1126 guppy 1.1 putidx $idx "- Small flood short lock: Active"
1127     } else {
1128     putidx $idx "- Small flood short lock: Inactive"
1129     }
1130 guppy 1.2 if {$sl_ban && $sl_ban < 120} {
1131 guppy 1.1 putidx $idx "- Channel flood bans: $sl_ban mins"
1132     } elseif {$sl_ban >= 120} {
1133     putidx $idx "- Channel flood bans: [expr $sl_ban / 60] hrs"
1134     } else {
1135     putidx $idx "- Channel flood bans: Disabled"
1136     }
1137 guppy 1.2 if {!$sl_boban || [lsearch -exact $sl_boflood 0] != -1} {
1138 guppy 1.1 putidx $idx "- Bogus username bans: Disabled"
1139 guppy 1.2 } elseif {$sl_boban > 0 && $sl_boban < 120} {
1140 guppy 1.1 putidx $idx "- Bogus username bans: $sl_boban mins"
1141     } elseif {$sl_boban >= 120} {
1142     putidx $idx "- Bogus username bans: [expr $sl_boban / 60] hrs"
1143     }
1144 guppy 1.2 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1145 guppy 1.1 if {$sl_globalban} {
1146     putidx $idx "- Ban type: Global"
1147     } else {
1148     putidx $idx "- Ban type: Channel-specific"
1149     }
1150     }
1151 guppy 1.2 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1152 guppy 1.1 putidx $idx "- Maximum bans: $sl_banmax"
1153     }
1154 guppy 1.2 if {$sl_igtime > 0 && $sl_igtime < 120} {
1155 guppy 1.1 putidx $idx "- Flooder ignores: $sl_igtime mins"
1156     } elseif {$sl_igtime >= 120} {
1157     putidx $idx "- Flooder ignores: [expr $sl_igtime / 60] hrs"
1158     } else {
1159     putidx $idx "- Flooder ignores: Permanent"
1160     }
1161     if {$sl_ban} {
1162     putidx $idx "- Kicks per line: $sl_kicks"
1163     }
1164     if {!$sl_bfmaxbans} {
1165     putidx $idx "- Maximum channel bans: Disabled"
1166     } else {
1167     putidx $idx "- Maximum channel bans: $sl_bfmaxbans"
1168     }
1169     if {$sl_note != ""} {
1170     putidx $idx "- Flood notification: Notifying [join $sl_note ", "]"
1171     } else {
1172     putidx $idx "- Flood notification: Off"
1173     }
1174     if {!$sl_lockcmds} {
1175     putidx $idx "- Public lc/uc commands: Disabled"
1176     } elseif {$sl_lockcmds == 1} {
1177     putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops not required)"
1178     } elseif {$sl_lockcmds == 2} {
1179     putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops required)"
1180     }
1181     if {$sl_bxsimul} {
1182     putidx $idx "- BitchX simulation: On"
1183     } elseif {!$sl_bxsimul} {
1184     putidx $idx "- BitchX simulation: Off"
1185     }
1186     return 0
1187     }
1188    
1189     if {$sl_bxsimul} {
1190     bind raw - 001 sl_bxserverjoin
1191     if {![info exists sl_bxonestack]} {
1192     set sl_bxonestack 0
1193     }
1194     if {![info exists sl_bxversion]} {
1195     set sl_bxversion [lindex {75p1+ 75p3+} [rand 2]]
1196     }
1197     set sl_bxsystem "*IX" ; set sl_bxwhoami $username ; set sl_bxmachine ""
1198     catch {set sl_bxsystem [exec uname -s -r]}
1199     catch {set sl_bxwhoami [exec id -un]}
1200     catch {set sl_bxmachine [exec uname -n]}
1201     set sl_bxjointime [unixtime]
1202     proc sl_bxserverjoin {from keyword arg} {
1203     global sl_bxjointime sl_bxisaway
1204     set sl_bxjointime [unixtime] ; set sl_bxisaway 0
1205     return 0
1206     }
1207     proc sl_bxaway {} {
1208     global sl_bxjointime sl_bxisaway
1209     if {!$sl_bxisaway} {
1210     puthelp "AWAY :is away: (Auto-Away after 10 mins) \[\002BX\002-MsgLog [lindex {On Off} [rand 2]]\]"
1211     set sl_bxisaway 1
1212     } else {
1213     puthelp "AWAY"
1214     set sl_bxisaway 0 ; set sl_bxjointime [unixtime]
1215     }
1216     if {![string match *sl_bxaway* [timers]]} {
1217     timer [expr [rand 300] + 10] sl_bxaway
1218     }
1219     return 0
1220     }
1221     if {![info exists sl_bxisaway]} {
1222     set sl_bxisaway 0
1223     }
1224     if {![string match *sl_bxaway* [timers]]} {
1225     timer [expr [rand 300] + 10] sl_bxaway
1226     }
1227     }
1228    
1229     proc sl_setarray {chan} {
1230 guppy 1.2 global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
1231 guppy 1.1 set chan [string tolower $chan]
1232     sl_killutimer "incr sl_*queue($chan) -1"
1233     sl_killutimer "sl_*banqueue $chan"
1234 guppy 1.2 sl_killutimer "sl_*queuereset $chan"
1235 guppy 1.1 set sl_flooded($chan) 0 ; set sl_locked($chan) 0 ; set sl_unlocked($chan) [unixtime]
1236     set sl_nkflooding($chan) [unixtime]
1237     set sl_ccqueue($chan) 0 ; set sl_ccbanhost($chan) "" ; set sl_ccbannick($chan) ""
1238     set sl_avqueue($chan) 0 ; set sl_avbanhost($chan) "" ; set sl_avbannick($chan) ""
1239     set sl_txqueue($chan) 0
1240     set sl_nkqueue($chan) 0 ; set sl_nkbanhost($chan) ""
1241     set sl_boqueue($chan) 0 ; set sl_bobanhost($chan) "" ; set sl_bobannick($chan) ""
1242     set sl_jqueue($chan) 0 ; set sl_jbanhost($chan) "" ; set sl_jbannick($chan) ""
1243     set sl_pqueue($chan) 0 ; set sl_pbanhost($chan) "" ; set sl_pbannick($chan) ""
1244     set sl_bfull($chan) 0
1245     return 0
1246     }
1247    
1248 guppy 1.2 proc sl_unsetarray {chan} {
1249     global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
1250     set chan [string tolower $chan]
1251     if {![validchan $chan] && [info exists sl_flooded($chan)]} {
1252     unset sl_flooded($chan) ; unset sl_locked($chan) ; unset sl_unlocked($chan)
1253     unset sl_nkflooding($chan)
1254     unset sl_ccqueue($chan) ; unset sl_ccbanhost($chan) ; unset sl_ccbannick($chan)
1255     unset sl_avqueue($chan) ; unset sl_avbanhost($chan) ; unset sl_avbannick($chan)
1256     unset sl_txqueue($chan)
1257     unset sl_nkqueue($chan) ; unset sl_nkbanhost($chan)
1258     unset sl_boqueue($chan) ; unset sl_bobanhost($chan) ; unset sl_bobannick($chan)
1259     unset sl_jqueue($chan) ; unset sl_jbanhost($chan) ; unset sl_jbannick($chan)
1260     unset sl_pqueue($chan) ; unset sl_pbanhost($chan) ; unset sl_pbannick($chan)
1261     unset sl_bfull($chan)
1262     }
1263     return 0
1264     }
1265    
1266 guppy 1.1 proc sl_settimer {} {
1267     foreach chan [channels] {
1268     sl_setarray $chan
1269     }
1270     return 0
1271     }
1272    
1273     proc sl_killutimer {cmd} {
1274     set n 0
1275     regsub -all -- {\[} $cmd {\[} cmd ; regsub -all -- {\]} $cmd {\]} cmd
1276     foreach tmr [utimers] {
1277     if {[string match $cmd [join [lindex $tmr 1]]]} {
1278     killutimer [lindex $tmr 2]
1279     incr n
1280     }
1281     }
1282     return $n
1283     }
1284    
1285 guppy 1.2 if {![info exists sl_unlocked] && ![string match *sl_settimer* [utimers]]} {
1286 guppy 1.1 utimer 3 sl_settimer
1287     }
1288    
1289     if {![info exists sl_bflooded]} {
1290     set sl_bflooded 0
1291     }
1292     if {![info exists sl_bcqueue]} {
1293     set sl_bcqueue 0
1294     }
1295     if {![info exists sl_bmqueue]} {
1296     set sl_bmqueue 0
1297     }
1298     if {![info exists sl_nickkick]} {
1299     set sl_nickkick 0
1300     }
1301    
1302     set sl_bcflood [split $sl_bcflood :] ; set sl_bmflood [split $sl_bmflood :]
1303     set sl_ccflood [split $sl_ccflood :] ; set sl_avflood [split $sl_avflood :]
1304     set sl_txflood [split $sl_txflood :] ; set sl_boflood [split $sl_boflood :]
1305     set sl_jflood [split $sl_jflood :] ; set sl_nkflood [split $sl_nkflood :]
1306     set sl_note [split $sl_note]
1307    
1308 guppy 1.2 if {$sl_ilocktime > 0 && $sl_ilocktime < 30} {
1309 guppy 1.1 set sl_ilocktime 30
1310     }
1311 guppy 1.2 if {$sl_mlocktime > 0 && $sl_mlocktime < 30} {
1312 guppy 1.1 set sl_mlocktime 30
1313     }
1314    
1315     set trigger-on-ignore 0
1316     if {!${kick-method}} {
1317     set sl_kicks 8
1318     } else {
1319     set sl_kicks ${kick-method}
1320     }
1321    
1322 guppy 1.2 if {$numversion <= 1040400} {
1323     if {$numversion >= 1032100} {
1324     set kick-bogus 0
1325     }
1326     if {$numversion >= 1032400} {
1327     set ban-bogus 0
1328     }
1329 guppy 1.1 }
1330     if {$numversion >= 1032400} {
1331 guppy 1.2 set kick-fun 0 ; set ban-fun 0
1332 guppy 1.1 }
1333     if {$numversion >= 1032500} {
1334     set ctcp-mode 0
1335     }
1336    
1337 guppy 1.2 if {![string match *sl_txqueuereset* [utimers]] && [lsearch -exact $sl_txflood 0] == -1} {
1338 guppy 1.1 utimer [lindex $sl_txflood 1] sl_txqueuereset
1339     }
1340    
1341     bind pub $sl_lockflags|$sl_lockflags lc sl_lc
1342     bind pub $sl_lockflags|$sl_lockflags uc sl_uc
1343     bind dcc $sl_lockflags|$sl_lockflags lock sl_dcclc
1344     bind dcc $sl_lockflags|$sl_lockflags unlock sl_dccuc
1345     if {!$sl_lockcmds} {
1346     unbind pub $sl_lockflags|$sl_lockflags lc sl_lc
1347     unbind pub $sl_lockflags|$sl_lockflags uc sl_uc
1348     }
1349     bind dcc m|m sentinel sl_dcc
1350     bind raw - NOTICE sl_avflood
1351     bind raw - PRIVMSG sl_avflood
1352 guppy 1.2 if {[lsearch -exact $sl_avflood 0] != -1 && [lsearch -exact $sl_txflood 0] != -1} {
1353 guppy 1.1 unbind raw - NOTICE sl_avflood
1354     unbind raw - PRIVMSG sl_avflood
1355     }
1356     bind ctcp - CLIENTINFO sl_ctcp
1357     bind ctcp - USERINFO sl_ctcp
1358     bind ctcp - VERSION sl_ctcp
1359     bind ctcp - FINGER sl_ctcp
1360     bind ctcp - ERRMSG sl_ctcp
1361     bind ctcp - ECHO sl_ctcp
1362     bind ctcp - INVITE sl_ctcp
1363     bind ctcp - WHOAMI sl_ctcp
1364     bind ctcp - OP sl_ctcp
1365     bind ctcp - OPS sl_ctcp
1366     bind ctcp - UNBAN sl_ctcp
1367     bind ctcp - PING sl_ctcp
1368     bind ctcp - TIME sl_ctcp
1369     bind msgm - * sl_bmflood
1370     if {[lsearch -exact $sl_bmflood 0] != -1} {unbind msgm - * sl_bmflood}
1371     bind nick - * sl_nkflood
1372     if {[lsearch -exact $sl_nkflood 0] != -1} {unbind nick - * sl_nkflood}
1373     bind join - * sl_jflood
1374     bind part - * sl_pflood
1375     bind kick - * sl_pfloodk
1376     bind flud - * sl_flud
1377     bind mode - * sl_mode
1378    
1379 guppy 1.2 putlog "Loaded sentinel.tcl v2.50 by slennox"
1380 guppy 1.1
1381     return

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23