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

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

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


Revision 1.2 - (show annotations) (download) (as text)
Sun Feb 25 07:05:04 2001 UTC (18 years, 7 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 # sentinel.tcl v2.50 (19 February 2001)
2 # copyright (c) 1998-2001 by slennox <slennox@egghelp.org>
3 # slennox's eggdrop page - http://www.egghelp.org/
4 #
5 # $Id$
6 #
7 # 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 # 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 # v2.00 - New standalone release. Contains refinements and features from
15 # the netbots.tcl version of sentinel.tcl.
16 # 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 #
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 # * Channel join-part floods. A common type of channel flood in which many
38 # floodbots cycle the channel.
39 # * 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 # * 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 # * 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 # stop really aggressive text floods and reduce the possibility of the
49 # bot crashing or consuming excessive CPU.
50 #
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 # list of the flooders, then kick-ban them after the channel has been
64 # 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 # also use a channel limiter script, such as chanlimit.tcl.
81 # - 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
92 # Bot MSG flood.
93 set sl_bmflood 6:20
94
95 # Channel CTCP flood.
96 set sl_ccflood 5:20
97
98 # Channel avalanche/tsunami flood.
99 set sl_avflood 6:20
100
101 # Channel text flood.
102 set sl_txflood 80:30
103
104 # Channel bogus username join flood.
105 set sl_boflood 4:20
106
107 # Channel join-part flood.
108 set sl_jflood 6:20
109
110 # 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 # - 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 # - 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 # 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 # 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 # Valid settings: a text string, or set it to "" to disable.
202
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 proc botonchan {chan} {
223 global botnick
224 if {![validchan $chan]} {
225 error "illegal channel: $chan"
226 } elseif {![onchan $botnick $chan]} {
227 return 0
228 }
229 return 1
230 }
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 if {[lsearch -exact $sl_ccflood 0] == -1 && [validchan $chan] && ![isop $nick $chan]} {
240 if {$nick == $botnick} {return 0}
241 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 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 } elseif {[lindex $sl_bcflood 0] && $dest == $botnick} {
253 if {$sl_bflooded} {
254 sl_ignore [string tolower $uhost] $hand "CTCP flooder" ; return 1
255 }
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 if {$arg == "" || [validchan $chan]} {return 1}
336 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 if {$arg == "" || [validchan $chan]} {return 1}
354 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 if {$arg == "" || [validchan $chan]} {return 1}
359 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 if {[matchattr $hand b] && [string tolower [lindex [split $text] 0]] == "go"} {return 0}
373 if {$sl_bflooded} {
374 sl_ignore [string tolower $uhost] $hand "MSG flooder" ; return 0
375 }
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 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 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 if {[sl_checkaval $text] && [lsearch -exact $sl_avflood 0] == -1} {
409 set uhost [string trimleft [getchanhost $nick $chan] "~+-^="]
410 set hand [nick2hand $nick $chan]
411 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 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 sl_lock $chan "AVALANCHE/TSUNAMI flood" ${botnet-nick}
420 }
421 }
422 return 0
423 }
424
425 proc sl_checkaval {text} {
426 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 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 if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
437 lappend sl_nkbanhost($chan) [string tolower $uhost]
438 utimer [lindex $sl_nkflood 1] [split "sl_nkbanqueue $chan"]
439 }
440 if {!$sl_nickkick && $sl_flooded($chan) && $sl_locked($chan)} {
441 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 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban *!$bhost]} {
447 newban $bhost sentinel "NICK flooder" $sl_ban
448 }
449 } else {
450 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban *!$bhost $chan]} {
451 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 if {[lsearch -exact $sl_boflood 0] == -1 && [sl_checkbogus [lindex [split $uhost @] 0]]} {
478 if {!$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
479 set bhost *!*[string tolower [string range $uhost [string first @ $uhost] end]]
480 if {$sl_boban && [botisop $chan] && !$sl_flooded($chan)} {
481 putserv "KICK $chan $nick :BOGUS username"
482 if {$sl_globalban} {
483 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban *!$bhost]} {
484 newban $bhost sentinel "BOGUS username" $sl_boban
485 }
486 } else {
487 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban *!$bhost $chan]} {
488 newchanban $chan $bhost sentinel "BOGUS username" $sl_boban
489 }
490 }
491 }
492 if {$sl_ban} {
493 lappend sl_bobannick($chan) $nick ; lappend sl_bobanhost($chan) [string tolower $uhost]
494 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 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 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 if {$sl_jqueue($chan) >= [lindex $sl_jflood 0] && $sl_pqueue($chan) >= [lindex $sl_jflood 0]} {
514 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 if {$nick == $botnick} {
530 if {![validchan $chan]} {
531 timer 5 [split "sl_unsetarray $chan"]
532 }
533 return 0
534 }
535 set chan [string tolower $chan]
536 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 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 sl_quicklock $chan
563 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 if {[string match *i* $umode] && [string match *i* [lindex [split [getchanmode $chan]] 0]]} {
613 if {$sl_bfmaxbans && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
614 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 if {[string match *m* $umode] && [string match *m* [lindex [split [getchanmode $chan]] 0]]} {
621 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 if {$mode == "+b" && $sl_bfmaxbans && !$sl_bfull($chan) && ![string match *i* [lindex [split [getchanmode $chan]] 0]] && [botisop $chan] && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
632 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 } elseif {$mode == "+i" && $sl_flooded($chan)} {
647 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 } elseif {$mode == "-i" || $mode == "-m"} {
653 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 if {![botisop $chan]} {return 0}
674 set sl_kflooders 0
675 sl_kick $chan $sl_ccbannick($chan) "CTCP flooder" ; set sl_ccbannick($chan) ""
676 sl_kick $chan $sl_avbannick($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbannick($chan) ""
677 sl_kick $chan $sl_bobannick($chan) "BOGUS username" ; set sl_bobannick($chan) ""
678 set jklist $sl_jbannick($chan) ; set pklist $sl_pbannick($chan)
679 if {$jklist != "" && $pklist != ""} {
680 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 if {[onchan $nick $chan] && ![onchansplit $nick $chan]} {
705 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 global sl_avbanhost sl_bobanhost sl_ccbanhost sl_kflooders sl_jbanhost sl_nkbanhost sl_pbanhost sl_shortlock sl_unlocked
721 if {![botonchan $chan]} {return 0}
722 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 sl_ban $chan $sl_ccbanhost($chan) "CTCP flooder" ; set sl_ccbanhost($chan) ""
731 sl_ban $chan $sl_avbanhost($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbanhost($chan) ""
732 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 if {$sl_jbanhost($chan) != "" && $sl_pbanhost($chan) != ""} {
735 set blist ""
736 foreach bhost $sl_jbanhost($chan) {
737 if {[lsearch -exact $sl_pbanhost($chan) $bhost] != -1} {
738 lappend blist $bhost
739 }
740 }
741 sl_ban $chan $blist "JOIN-PART flooder"
742 }
743 set sl_jbanhost($chan) "" ; set sl_pbanhost($chan) ""
744 if {$sl_shortlock && $sl_kflooders <= 2 && [llength $allbans] <= 2 && [expr [unixtime] - $sl_unlocked($chan)] > 120} {
745 sl_killutimer "sl_unlock $chan *"
746 utimer 10 [split "sl_unlock $chan mi"]
747 }
748 return 0
749 }
750
751 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 proc sl_ban {chan blist reason} {
791 global sl_ban sl_banmax sl_globalban
792 if {$blist != ""} {
793 if {$sl_globalban} {
794 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 newban $bhost sentinel $reason $sl_ban
809 putlog "sentinel: banned $bhost ($reason)"
810 sl_ignore $bhost * $reason
811 }
812 } else {
813 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 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 proc sl_ignore {ihost hand flood} {
837 global sl_igtime
838 if {$hand != "*"} {
839 foreach chan [channels] {
840 if {[matchattr $hand f|f $chan]} {return 0}
841 }
842 }
843 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 newignore $ihost sentinel $flood $sl_igtime
860 putlog "sentinel: added $ihost to ignore list ($flood)"
861 return 1
862 }
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 if {[validchan $chan] && $sl_flooded($chan)} {return 1}
963 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 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
971 sl_quicklock $chan
972 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 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
981 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 if {[botisop $chan]} {
997 sl_quicklock $chan
998 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 sl_quicklock $chan
1016 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 if {[botisop $chan]} {
1032 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 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 proc sl_dcc {hand idx arg} {
1066 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 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 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 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 if {$sl_shortlock && $sl_ban} {
1126 putidx $idx "- Small flood short lock: Active"
1127 } else {
1128 putidx $idx "- Small flood short lock: Inactive"
1129 }
1130 if {$sl_ban && $sl_ban < 120} {
1131 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 if {!$sl_boban || [lsearch -exact $sl_boflood 0] != -1} {
1138 putidx $idx "- Bogus username bans: Disabled"
1139 } elseif {$sl_boban > 0 && $sl_boban < 120} {
1140 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 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1145 if {$sl_globalban} {
1146 putidx $idx "- Ban type: Global"
1147 } else {
1148 putidx $idx "- Ban type: Channel-specific"
1149 }
1150 }
1151 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1152 putidx $idx "- Maximum bans: $sl_banmax"
1153 }
1154 if {$sl_igtime > 0 && $sl_igtime < 120} {
1155 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 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 set chan [string tolower $chan]
1232 sl_killutimer "incr sl_*queue($chan) -1"
1233 sl_killutimer "sl_*banqueue $chan"
1234 sl_killutimer "sl_*queuereset $chan"
1235 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 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 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 if {![info exists sl_unlocked] && ![string match *sl_settimer* [utimers]]} {
1286 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 if {$sl_ilocktime > 0 && $sl_ilocktime < 30} {
1309 set sl_ilocktime 30
1310 }
1311 if {$sl_mlocktime > 0 && $sl_mlocktime < 30} {
1312 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 if {$numversion <= 1040400} {
1323 if {$numversion >= 1032100} {
1324 set kick-bogus 0
1325 }
1326 if {$numversion >= 1032400} {
1327 set ban-bogus 0
1328 }
1329 }
1330 if {$numversion >= 1032400} {
1331 set kick-fun 0 ; set ban-fun 0
1332 }
1333 if {$numversion >= 1032500} {
1334 set ctcp-mode 0
1335 }
1336
1337 if {![string match *sl_txqueuereset* [utimers]] && [lsearch -exact $sl_txflood 0] == -1} {
1338 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 if {[lsearch -exact $sl_avflood 0] != -1 && [lsearch -exact $sl_txflood 0] != -1} {
1353 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 putlog "Loaded sentinel.tcl v2.50 by slennox"
1380
1381 return

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23