/[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.4 - (show annotations) (download) (as text)
Tue Apr 30 16:20:36 2002 UTC (17 years, 4 months ago) by wcc
Branch: MAIN
CVS Tags: r1, eggdrop_1_6_15, eggdrop_1_6_13, blah, test, v2_0, eggdrop1_6_11, HEAD
Changes since 1.3: +107 -73 lines
File MIME type: application/x-tcl
updated slennox's sentinel.tcl to the latest version

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23