diff options
| author | 2012-08-16 06:58:14 +0000 | |
|---|---|---|
| committer | 2012-08-16 06:58:14 +0000 | |
| commit | 6cf8963cfc8dc562f7ec8f3c5d538f05a0e7a0be (patch) | |
| tree | 2f54ae3d0f4a21ae6026e401832fffd053b79da6 | |
| parent | 5154f3cac3c3537d94b748c365dce88f3805b4a7 (diff) | |
Disabled message-sending-throttling
Added a command to view uptime/cpu/ram usage statistics
The hilight/dehilight commands can accept a comma-separated list of nicks
The exempt command is now deprecated
A restriction-system has been added to replace the old exemption system, and also includes additional restrictions that can be added, such as "don't let this account use !ops"
Added a plugin command, so other bots can have ASM generate alerts
Updated users and flags
Updated channel hilights
Replaced code that shows up in several places to split a long privmsg into two parts with a utility function
Added a detection class for fuzzy-matching against a nick blacklist
Fixed some major memory leaks, the bot stays stable around 30MB rather than shooting up to 65MB after a couple of days
The bot now uses nickserv REGAIN instead of ghost/release/nick
Added channel modes, ban lists, and quiet lists to state tracking
Ignore chanserv in netsplit detections
Track time/setter when a topic is changed in a channel
Monitor if a channel is set +r and is still +r 45 minutes later, if so generate an alert
Print status and how long it took to sync once the bot has started and synced, and warn about failed syncings.
| -rw-r--r-- | config-default/channels.xml | 61 | ||||
| -rw-r--r-- | config-default/commands.xml | 88 | ||||
| -rw-r--r-- | config-default/restrictions.xml | 13 | ||||
| -rw-r--r-- | config-default/users.xml | 13 | ||||
| -rwxr-xr-x | meta.pl | 7 | ||||
| -rw-r--r-- | modules/classes.pl | 49 | ||||
| -rw-r--r-- | modules/event.pl | 145 | ||||
| -rw-r--r-- | modules/inspect.pl | 18 | ||||
| -rw-r--r-- | modules/services.pl | 8 | ||||
| -rw-r--r-- | modules/util.pl | 41 | ||||
| -rw-r--r-- | modules/xml.pl | 40 |
11 files changed, 377 insertions, 106 deletions
diff --git a/config-default/channels.xml b/config-default/channels.xml index c9312b7..ecefc7a 100644 --- a/config-default/channels.xml +++ b/config-default/channels.xml @@ -2,6 +2,11 @@ <channel id="##English"> <hilights></hilights> </channel> + <channel id="##Linux"> + <hilights> + <low>DLange</low> + </hilights> + </channel> <channel id="##asb-debug" monitor="no"> <hilights></hilights> </channel> @@ -42,15 +47,13 @@ </channel> <channel id="##linux" silence="yes"> <hilights> - <disable>ST47</disable> + <info>Dominian</info> <low>denny</low> - <low>numist</low> <low>tomaw</low> <low>WildPikachu</low> <low>Gary</low> <medium>vorian</medium> <medium>DLange</medium> - <medium>pinPoint</medium> <medium>njan</medium> </hilights> <msgs> @@ -61,13 +64,21 @@ <hilights> <opalert>WildPikachu</opalert> <opalert>denny</opalert> - <opalert>numist</opalert> - <opalert>PhilKC</opalert> + <opalert>tomaw</opalert> + <opalert>Gary</opalert> + <opalert>vorian</opalert> + <opalert>DLange</opalert> + <opalert>njan</opalert> + <opalert>Dominian</opalert> </hilights> <msgs> <opalert>##linux-ops</opalert> </msgs> </channel> + <channel id="##olympics"> + <hilights></hilights> + <msgs></msgs> + </channel> <channel id="##philosophy" silence="yes"> <hilights></hilights> <msgs></msgs> @@ -80,6 +91,12 @@ <hilights></hilights> <msgs></msgs> </channel> + <channel id="##trans" silence="yes"> + <hilights> + <info>Kelsie</info> + </hilights> + <msgs></msgs> + </channel> <channel id="##transgender"> <hilights> <info>ttuttle</info> @@ -121,6 +138,7 @@ <hilights></hilights> <msgs></msgs> </channel> + <channel id="#antispammeta-debug" /> <channel id="#cisco"> <hilights></hilights> <msgs></msgs> @@ -152,21 +170,18 @@ <debug>Dave2</debug> <debug>Martinp23</debug> <debug>SeJo</debug> - <debug>pctony</debug> <debug>Corey</debug> - <debug>theacolyte-</debug> <debug>nhandler</debug> - <debug>Plazma</debug> - <debug>Plazma-Rooolz</debug> <high>mquin</high> <high>ttuttle</high> <info>njan</info> <info>ttuttle</info> + <info>gry</info> + <info>Adran</info> <low>denny</low> <low>Gary</low> <low>JonathanD</low> <low>ZoFreX</low> - <low>DLange</low> <low>PriceChild</low> <low>werdan7</low> <low>dax</low> @@ -179,6 +194,10 @@ <channel id="#freenode-newyears" link="#freenode" silence="yes"> <hilights></hilights> </channel> + <channel id="#frikipedia"> + <hilights></hilights> + <msgs></msgs> + </channel> <channel id="#gentoo" silence="yes"> <hilights> <debug>NeddySeagoon</debug> @@ -207,7 +226,6 @@ <hilights> <disable>Thehelpfulone</disable> <high>tomaw</high> - <high>DLange</high> <high>RichiH</high> </hilights> <msgs></msgs> @@ -317,7 +335,6 @@ <debug>Martinp23</debug> <debug>PeterSymonds</debug> <debug>vvv</debug> - <debug>Barras</debug> <debug>AfterDeath</debug> <debug>DeltaQuad</debug> <debug>Snowolf</debug> @@ -371,13 +388,13 @@ <debug>Not_the_NSA</debug> <debug>Kanonkas</debug> <debug>PeterSymonds</debug> - <debug>Barras</debug> <debug>AfterDeath</debug> <debug>Logan_</debug> <debug>jeremyb</debug> <debug>AfterDeath</debug> <info>charitwo</info> <info>TBloemink</info> + <info>Mh7kJ</info> <low>slakr</low> </hilights> <msgs> @@ -403,7 +420,6 @@ <debug>Thehelpfulone</debug> <debug>Tempodivalse</debug> <debug>Tanvir</debug> - <debug>Barras</debug> <debug>peteforsyth</debug> <debug>Az1568</debug> <debug>Cbrown1023</debug> @@ -425,7 +441,6 @@ </channel> <channel id="#wikimedia-stewards"> <hilights> - <debug>Barras</debug> <debug>PeterSymonds</debug> <debug>Snowolf</debug> <debug>Thehelpfulone</debug> @@ -436,8 +451,8 @@ <info>Fluffernutter</info> <info>Pmlineditor</info> <info>juancarlos</info> - <info>omtsh</info> <info>MBisanz</info> + <info>Mh7kJ</info> </hilights> <msgs> <debug>#wikimedia-ops</debug> @@ -488,7 +503,6 @@ <debug>jeremyb</debug> <debug>Maximillion</debug> <debug>stwalkerster</debug> - <debug>Barras</debug> <debug>DeltaQuad</debug> <debug>Gfoley4</debug> <debug>Logan_</debug> @@ -497,6 +511,7 @@ <debug>Tanvir</debug> <debug>TBloemink</debug> <debug>Rjd0060</debug> + <debug>Shirik</debug> <low>bumm13_</low> <low>Cyrius</low> <low>DanielB</low> @@ -538,7 +553,6 @@ <debug>stwalkerster</debug> <debug>Jamesofur</debug> <debug>SpitfireWP</debug> - <debug>Barras</debug> <debug>jeremyb</debug> <debug>DeltaQuad</debug> <debug>Theo10011</debug> @@ -548,7 +562,6 @@ <debug>Steven_Zhang</debug> <debug>Shirik</debug> <debug>TBloemink</debug> - <debug>foxj</debug> <debug>Rjd0060</debug> <low>Cobi</low> <low>Golbez</low> @@ -634,8 +647,6 @@ <debug>Snowolf</debug> <debug>Tanvir</debug> <debug>TBloemink</debug> - <debug>Barras</debug> - <debug>Barras</debug> <debug>Ocaasi</debug> <info>mabdul</info> <low>KFP</low> @@ -690,13 +701,6 @@ <debug>#wikimedia-ops</debug> </msgs> </channel> - <channel id="+#wikimedia-ops"> - <hilights></hilights> - </channel> - <channel id="antispammeta"> - <hilights></hilights> - <msgs></msgs> - </channel> <channel id="default"> <hilights></hilights> </channel> @@ -706,7 +710,6 @@ <low>marienz</low> <low>mrmist</low> <medium>dave2</medium> - <medium>RichiH</medium> </hilights> <msgs> <debug>##asb-nexus</debug> diff --git a/config-default/commands.xml b/config-default/commands.xml index 56db997..19e91ac 100644 --- a/config-default/commands.xml +++ b/config-default/commands.xml @@ -1,4 +1,16 @@ <commands> + <command cmd="^;status$" flag="o"> + <![CDATA[ + my $size = `ps -p $$ h -o size`; + my $cputime = `ps -p $$ h -o time`; + chomp $size; chomp $cputime; + $conn->privmsg($event->{to}->[0], "This bot has been running for " . (time - $::starttime) . " seconds" . + ", is tracking " . (scalar (keys %::sn)) . " nicks" . + " across " . (scalar (keys %::sc)) . " tracked channels." . + " It is using " . $size . "KB of RAM" . + " and has used " . $cputime . " of CPU time."); + ]]> + </command> <command cmd="^;mship (\S+)$" flag="c"> <![CDATA[ $conn->privmsg($event->{to}->[0], $1 . " is on: " . ASM::Util->commaAndify(@{$::sn{lc $1}->{mship}})); @@ -164,7 +176,7 @@ <command cmd="^;hilight (\S+) (\S+) ?(\S*)$" flag="h"> <![CDATA[ my $chan = $1; - my $nick = $2; + my @nicks = split(/,/,$2); my $level= $3; if ($level eq '') { $level = 'info'; } $level = lc $level; @@ -183,17 +195,19 @@ unless (defined($::channels->{channel}->{$chan}->{hilights}->{$level})) { $::channels->{channel}->{$chan}->{hilights}->{$level} = []; } - my @tmphl = @{$::channels->{channel}->{$chan}->{hilights}->{$level}}; - push(@tmphl, $nick); - $::channels->{channel}->{$chan}->{hilights}->{$level} = \@tmphl; + foreach my $nick (@nicks) { + my @tmphl = @{$::channels->{channel}->{$chan}->{hilights}->{$level}}; + push(@tmphl, $nick); + $::channels->{channel}->{$chan}->{hilights}->{$level} = \@tmphl; + } ASM::XML->writeChannels(); - $conn->privmsg($event->{to}->[0], "$nick added to $level risk hilights for $chan"); + $conn->privmsg($event->{to}->[0], ASM::Util->commaAndify(@nicks) . " added to $level risk hilights for $chan"); ]]> </command> <command cmd="^;dehilight (\S+) (\S+)" flag="h"> <![CDATA[ my $chan = $1; - my $nick = $2; + my @nicks = split(/,/, $2); my $link = ASM::Util->getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->{to}->[0], "Error: $chan is linked to $link - use $link instead."); @@ -202,11 +216,13 @@ foreach my $risk ( keys %::RISKS ) { next unless defined($::channels->{channel}->{$chan}->{hilights}->{$risk}); my @ppl = @{$::channels->{channel}->{$chan}->{hilights}->{$risk}}; - @ppl = grep { lc $_ ne lc $nick } @ppl; + foreach my $nick (@nicks) { + @ppl = grep { lc $_ ne lc $nick } @ppl; + } $::channels->{channel}->{$chan}->{hilights}->{$risk} = \@ppl; } ASM::XML->writeChannels(); - $conn->privmsg($event->{to}->[0], "Removing hilights for $nick in $chan"); + $conn->privmsg($event->{to}->[0], "Removing hilights for " . ASM::Util->commaAndify(@nicks) . " in $chan"); ]]> </command> <command cmd="^;join (\S+)" flag="a"> @@ -275,15 +291,29 @@ </command> <command cmd="^;exempt (.*)" flag="o"> <![CDATA[ - my $x = lc $1; - $::eline{$x} = 1; - $x . "\n" >> io 'exempt.txt'; - $conn->privmsg($event->{to}->[0], $x . " exempted"); + $conn->privmsg($event->{to}->[0], "This command is now deprecated. Use ;restrict nick/account/host lineToRestrict +notrigger instead, i.e. ;restrict account eir +notrigger"); + ]]> + </command> + <command cmd="^;restrict (nick|account|host) (\S+) (\+|-)([a-z]+)$" flag="o"> + <![CDATA[ + my ($type, $who, $mode, $restriction) = ($1, lc $2, $3, $4); + if ($mode eq '-') { + delete $::restrictions->{$type . 's'}->{$type}->{$who}->{$restriction}; + $conn->privmsg($event->{to}->[0], "Removed $restriction restriction for $type $who"); + } + if ($mode eq '+') { + if (! defined($::restrictions->{$type . 's'}->{$type}->{$who})) { + $::restrictions->{$type . 's'}->{$type}->{$who} = {}; + } + $::restrictions->{$type . 's'}->{$type}->{$who}->{$restriction} = $restriction; + $conn->privmsg($event->{to}->[0], "Added $restriction restriction for $type $who"); + } + ASM::XML->writeRestrictions(); ]]> </command> <command cmd="^\!ops ?(#\S+)? ?(.*)" nohush="nohush"> <![CDATA[ -# if ($::sn{lc $event->{nick}}->{dnsbl} == 0) { + if (ASM::Util->notRestricted(lc $event->{nick}, "noops")) { my $tgt = $event->{to}->[0]; $tgt = $1 if (defined($1)); my $msg = $1; @@ -293,17 +323,10 @@ $conn->schedule(30, sub { delete($::ignored{$tgt})}); my $hilite=ASM::Util->commaAndify(ASM::Util->getAlert($tgt, 'opalert', 'hilights')); my $txtz = "[\x02$tgt\x02] - $event->{nick} wants op attention ($msg) $hilite"; - foreach my $tgt2 (ASM::Util->getAlert($tgt, 'opalert', 'msgs')) { #unfortunately wikipedia has way too many ops, and it breaks things - if (length($txtz) <= 380) { - $conn->privmsg($tgt2, $txtz); - } else { - my $splitpart = rindex($txtz, " ", 380); - $conn->privmsg($tgt2, substr($txtz, 0, $splitpart)); - $conn->privmsg($tgt2, substr($txtz, $splitpart)); - } - } + my @tgts = ASM::Util->getAlert($tgt, 'opalert', 'msgs'); + ASM::Util->sendLongMsg($conn, \@tgts, $txtz); } -# } + } ]]> </command> <command cmd="^;blacklist (.*)" flag="o"> @@ -314,4 +337,23 @@ $conn->privmsg($event->{to}->[0], "$str blacklisted"); ]]> </command> + <command cmd="^;plugin (\S+) (\S+) (.*)" flag="p"> + <![CDATA[ + my $chan = $1; + my $risk = $2; + my $reason = $3; + my $txtz = "\x03" . $::RCOLOR{$::RISKS{$risk}} . "\u$risk\x03 risk threat [\x02$chan\x02] - ". + "\x02($event->{nick} plugin)\x02 - ${reason}; ping "; + $txtz = $txtz . ASM::Util->commaAndify(ASM::Util->getAlert(lc $chan, $risk, 'hilights')) if (ASM::Util->getAlert(lc $chan, $risk, 'hilights')); + $txtz = $txtz . ' !att-' . $chan . '-' . $risk; + my @tgts = ASM::Util->getAlert($chan, $risk, 'msgs'); + if (length($txtz) <= 380) { + $conn->privmsg(\@tgts, $txtz); + } else { + my $splitpart = rindex($txtz, " ", 380); + $conn->privmsg(\@tgts, substr($txtz, 0, $splitpart)); + $conn->privmsg(\@tgts, substr($txtz, $splitpart)); + } + ]]> + </command> </commands> diff --git a/config-default/restrictions.xml b/config-default/restrictions.xml new file mode 100644 index 0000000..c022a7c --- /dev/null +++ b/config-default/restrictions.xml @@ -0,0 +1,13 @@ +<restrictions> + <hosts> + <host id="services." notrigger="notrigger" noops="noops" nocommands="nocommands" /> + <host id="freenode/utility-bot/ex-server/idoru" noops="noops" /> + </hosts> + <nicks> + <nick id="eir" nocommands="nocommands" /> + </nicks> + <accounts> + <account id="toracat" notrigger="notrigger" /> + <account id="/>" notrigger="notrigger" /> + </accounts> +</restrictions> diff --git a/config-default/users.xml b/config-default/users.xml index d083b8e..c01a206 100644 --- a/config-default/users.xml +++ b/config-default/users.xml @@ -1,27 +1,29 @@ <people> - <person id="afterdeath" flags="hocdat" /> + <person id="afterdeath" flags="hocdatp" /> <person id="cbrown1023" flags="oath" /> - <person id="charitwo" flags="oath" /> <person id="dave2" flags="oath" /> <person id="denny" flags="ha" /> - <person id="dlange" flags="oathd" /> + <person id="dlange" flags="coathd" /> <person id="dmcdevit" flags="oath" /> + <person id="dominian" flags="oath" /> <person id="dungodung" flags="oath" /> <person id="errantego" flags="doath" /> <person id="gary" flags="oath" /> <person id="idleone" flags="o" /> <person id="jeremyb" flags="th" /> <person id="jonathand" flags="oath" /> + <person id="kelsie" flags="a" /> <person id="kindone" flags="t" /> <person id="ljl" flags="o" /> <person id="logan_" flags="oath" /> <person id="lstarnes" flags="oath" /> - <person id="marienz" flags="oath" /> + <person id="marienz" flags="doath" /> <person id="martinp23" flags="oath" /> <person id="mquin" flags="hota" /> <person id="myrtti" flags="htoa" /> <person id="nhandler" flags="oath" /> <person id="njan" flags="oath" /> + <person id="o_o" flags="oath" /> <person id="paradox" flags="h" /> <person id="petersymonds" flags="oath" /> <person id="pricechild" flags="oath" /> @@ -29,6 +31,7 @@ <person id="rjd0060" flags="th" /> <person id="sauvin" flags="oath" /> <person id="seanw" flags="oath" /> + <person id="shiibot" flags="p" /> <person id="snowolf" flags="oath" /> <person id="th1" flags="th" /> <person id="thehelpfulone" flags="oath" /> @@ -36,6 +39,6 @@ <person id="troubled" flags="oath" /> <person id="ttuttle" flags="oath" /> <person id="werdan7" flags="oath" /> - <person id="wildpikachu" flags="oath" /> + <person id="wildpikachu" flags="doath" /> <person id="windowshasyou" flags="oath" /> </people> @@ -22,12 +22,15 @@ $::cset = ''; "dnsbl" => 0, "pingpong" => 0, "services" => 1, - "sync" => 1 + "sync" => 1, + "chanstate" => 1, + "restrictions" => 1 ); %::dsock = (); %::spy = (); $::starttime = time; @::syncqueue = (); +%::watchRegged = (); BEGIN { my @modules = qw/Util Xml Inspect Event Services Log Command Classes Mysql/; @@ -60,7 +63,7 @@ sub init { Ircname => $::settings->{realname}, Username => $::settings->{username}, Password => $::settings->{pass}, - Pacing => 1 ); + Pacing => 0 ); $conn->debug($::debug); $::inspector = ASM::Inspect->new(); $::services = ASM::Services->new(); diff --git a/modules/classes.pl b/modules/classes.pl index fc80da1..c8dcc54 100644 --- a/modules/classes.pl +++ b/modules/classes.pl @@ -25,7 +25,8 @@ sub new "gecos" => \&gecos, "nuhg" => \&nuhg, "levenflood" => \&levenflood, - "proxy" => \&proxy + "proxy" => \&proxy, + "nickbl" => \&nickbl }; $self->{ftbl} = $tbl; bless($self); @@ -84,6 +85,21 @@ sub levenflood return $ret; } +sub nickbl +{ + my ($chk, $id, $event, $chan) = @_; + my $nick = $event->{nick}; + $nick = $event->{args}->[0] if ($event->{type} eq 'nick'); + my ($fuzzy, $match) = split(/:/, $chk->{content}); + my @nicks = split(/,/, $match); + foreach my $item (@nicks) { + if (distance(lc $nick, lc $item) <= $fuzzy) { + return 1; + } + } + return 0; +} + sub dnsbl { my ($chk, $id, $event, $chan, $rev) = @_; @@ -147,8 +163,13 @@ sub process_cf foreach my $host ( keys %{$cf{$nid}{$xchan}} ) { next unless defined $cf{$nid}{$xchan}{$host}[0]; while ( time >= $cf{$nid}{$xchan}{$host}[0] + $cf{$nid}{'timeout'} ) { - last if ( $#{ $cf{$nid}{$xchan}{$host} } == 0 ); shift ( @{$cf{$nid}{$xchan}{$host}} ); + if ( (scalar @{$cf{$nid}{$xchan}{$host}}) == 0 ) { + delete $cf{$nid}{$xchan}{$host}; + last; + } +# last if ( $#{ $cf{$nid}{$xchan}{$host} } == 0 ); +# shift ( @{$cf{$nid}{$xchan}{$host}} ); } } } @@ -305,12 +326,34 @@ sub flood_process for my $host ( keys %{$sf{$id}{$chan}} ) { next unless defined $sf{$id}{$chan}{$host}[0]; while ( time >= $sf{$id}{$chan}{$host}[0] + $sf{$id}{'timeout'} ) { - last if ( $#{ $sf{$id}{$chan}{$host} } == 0 ); shift ( @{$sf{$id}{$chan}{$host}} ); + if ( (scalar @{$sf{$id}{$chan}{$host}}) == 0 ) { + delete $sf{$id}{$chan}{$host}; + last; + } +# last if ( $#{ $sf{$id}{$chan}{$host} } == 0 ); +# shift ( @{$sf{$id}{$chan}{$host}} ); } } } } } +sub dump +{ + #%sf, %ls, %cf, %bs + open(FH, ">", "sf.txt"); + print FH Dumper(\%sf); + close(FH); + open(FH, ">", "ls.txt"); + print FH Dumper(\%ls); + close(FH); + open(FH, ">", "cf.txt"); + print FH Dumper(\%cf); + close(FH); + open(FH, ">", "bs.txt"); + print FH Dumper(\%bs); + close(FH); +} + 1; diff --git a/modules/event.pl b/modules/event.pl index f9888e5..a0b3385 100644 --- a/modules/event.pl +++ b/modules/event.pl @@ -70,6 +70,8 @@ sub new $conn->add_handler('banlist', \&on_banlist); $conn->add_handler('dcc_open', \&dcc_open); $conn->add_handler('chat', \&on_dchat); + $conn->add_handler('channelmodeis', \&on_channelmodeis); + $conn->add_handler('quietlist', \&on_quietlist); $conn->add_handler('pong', \&on_pong); bless($self); return $self; @@ -132,8 +134,9 @@ sub on_connect { my ($conn, $event) = @_; # need to check for no services $conn->sl('MODE AntiSpamMeta +Q'); if (lc $event->{args}->[0] ne lc $::settings->{nick}) { - $conn->privmsg( 'NickServ', "ghost $::settings->{nick} $::settings->{pass}" ); - $conn->privmsg( 'NickServ', "release $::settings->{nick} $::settings->{pass}" ); + $conn->privmsg( 'NickServ', "regain $::settings->{nick} $::settings->{pass}" ); +# $conn->privmsg( 'NickServ', "ghost $::settings->{nick} $::settings->{pass}" ); +# $conn->privmsg( 'NickServ', "release $::settings->{nick} $::settings->{pass}" ); } $conn->sl('CAP REQ :extended-join multi-prefix account-notify'); #god help you if you try to use this bot off freenode } @@ -150,6 +153,8 @@ sub on_join { $::synced{$chan} = 0; unless ( @::syncqueue ) { $conn->sl('who ' . $chan . ' %tcnuhra,314'); + $conn->sl('mode ' . $chan); + $conn->sl('mode ' . $chan . ' bq'); } push @::syncqueue, $chan; } @@ -211,7 +216,9 @@ sub on_msg my ($conn, $event) = @_; $::commander->command($conn, $event); print strftime("%F %T ", gmtime) . "(msg) " . $event->{from} . " - " . $event->{args}->[0] . "\n"; - $conn->privmsg('#antispammeta', $event->{from} . ' told me: ' . $event->{args}->[0]); + if (ASM::Util->notRestricted($event->{nick}, "nomsgs")) { + $conn->privmsg('#antispammeta', $event->{from} . ' told me: ' . $event->{args}->[0]); + } } sub on_public @@ -259,7 +266,7 @@ sub on_quit } $event->{to} = \@channels; $::db->logg( $event ); - if (($::netsplit == 0) && ($event->{args}->[0] eq "*.net *.split")) { #special, netsplit situation + if (($::netsplit == 0) && ($event->{args}->[0] eq "*.net *.split") && (lc $event->{nick} ne 'chanserv')) { #special, netsplit situation $conn->privmsg("#antispammeta", "Entering netsplit mode - JOIN and QUIT inspection will be disabled for 60 minutes"); $::netsplit = 1; $conn->schedule(60*60, sub { $::netsplit = 0; $conn->privmsg('#antispammeta', 'Returning to regular operation'); }); @@ -301,21 +308,25 @@ sub irc_topic { $::inspector->inspect($conn, $event) if ($event->{format} ne 'server'); if ($event->{format} eq 'server') { + my $chan = lc $event->{args}->[1]; if ($event->{type} eq 'topic') { - $::sc{lc $event->{args}->[1]}{topic}{text} = $event->{args}->[2]; + $::sc{$chan}{topic}{text} = $event->{args}->[2]; } elsif ($event->{type} eq 'topicinfo') { - $::sc{lc $event->{args}->[1]}{topic}{time} = $event->{args}->[3]; - $::sc{lc $event->{args}->[1]}{topic}{by} = $event->{args}->[2]; + $::sc{$chan}{topic}{time} = $event->{args}->[3]; + $::sc{$chan}{topic}{by} = $event->{args}->[2]; } } else { if ($event->{type} eq 'topic') { - $::sc{lc $event->{to}->[0]}{topic}{text} = $event->{args}->[0]; + my $chan = lc $event->{args}->[1]; + $::sc{$chan}{topic}{text} = $event->{args}->[0]; + $::sc{$chan}{topic}{time} = time; + $::sc{$chan}{topic}{by} = $event->{from}; } $::log->logg($event); $::db->logg( $event ); @@ -381,11 +392,11 @@ sub parse_modes if (($c eq '-') || ($c eq '+')) { $t=$c; } - else { - if ( defined( grep( /[abdefhIJkloqv]/,($c) ) ) ) { #modes that take args + else { #eIbq,k,flj,CFLMPQcgimnprstz + if ( grep( /[eIbqkfljov]/,($c) ) ) { #modes that take args push (@new_modes, [$t.$c, shift @args]); } - elsif ( defined( grep( /[cgijLmnpPQrRstz]/, ($c) ) ) ) { + elsif ( grep( /[CFLMPQcgimnprstz]/, ($c) ) ) { push (@new_modes, [$t.$c]); } else { @@ -396,6 +407,29 @@ sub parse_modes return \@new_modes; } +sub on_channelmodeis +{ + my ($conn, $event) = @_; + my $chan = lc $event->{args}->[1]; + my @temp = @{$event->{args}}; + shift @temp; shift @temp; + my @modes = @{parse_modes(\@temp)}; + foreach my $line ( @modes ) { + my @ex = @{$line}; + my ($what, $mode) = split (//, $ex[0]); + if ($what eq '+') { + if (defined($ex[1])) { + push @{$::sc{$chan}{modes}}, $mode . ' ' . $ex[1]; + } else { + push @{$::sc{$chan}{modes}}, $mode; + } + } else { + my @modes = grep {!/^$mode/} @{$::sc{$chan}{modes}}; + $::sc{$chan}{modes} = \@modes; + } + } +} + sub on_mode { my ($conn, $event) = @_; @@ -416,11 +450,79 @@ sub on_mode elsif ( $ex[0] eq '-v' ) { $::sc{$chan}{users}{lc $ex[1]}{voice}=0; } + elsif ( $ex[0] eq '+b') { + $::sc{$chan}{bans}{$ex[1]} = { bannedBy => $event->{from}, bannedOn => time }; + } + elsif ( $ex[0] eq '-b') { + delete $::sc{$chan}{bans}{$ex[1]}; + } + elsif ( $ex[0] eq '+q') { + $::sc{$chan}{quiets}{$ex[1]} = { bannedBy => $event->{from}, bannedOn => time }; + } + elsif ( $ex[0] eq '-q') { + delete $::sc{$chan}{quiets}{$ex[1]}; + } + else { + my ($what, $mode) = split (//, $ex[0]); + if ($what eq '+') { + push @{$::sc{$chan}{modes}}, $mode . ' ' . $ex[1]; + } else { + my @modes = grep {!/^$mode/} @{$::sc{$chan}{modes}}; + $::sc{$chan}{modes} = \@modes; + } + if ( ($ex[0] eq '+r') && (! defined($::watchRegged{$chan})) ) { + $::watchRegged{$chan} = 1; + $conn->schedule(60*45, sub { checkRegged($conn, $chan); }); + } + } } $::log->logg($event); } } +sub checkRegged +{ + my ($conn, $chan) = @_; + if (grep {/r/} @{$::sc{$chan}{modes}}) { + my $tgt = $chan; + my $risk = "debug"; + my $hilite=ASM::Util->commaAndify(ASM::Util->getAlert($tgt, $risk, 'hilights')); + my $txtz ="\x03" . $::RCOLOR{$::RISKS{$risk}} . "\u$risk\x03 risk threat [\x02$chan\x02] - channel appears to still be +r after 45 minutes; $hilite"; + my @tgts = ASM::Util->getAlert($tgt, $risk, 'msgs'); + ASM::Util->sendLongMsg($conn, \@tgts, $txtz) + } + delete $::watchRegged{$chan}; +} + +sub on_banlist +{ + my ($conn, $event) = @_; +# 'args' => [ +# 'AntiSpamMetaBeta', +# '#antispammeta', +# 'test!*@*', +# 'fn-troll!icxcnika@freenode/weird-exception/network-troll/afterdeath', +# '1344235684' +# ], + my ($me, $chan, $ban, $banner, $bantime) = @{$event->{args}}; + $::sc{lc $chan}{bans}{$ban} = { bannedBy => $banner, bannedOn => $bantime }; +} + +sub on_quietlist +{ + my ($conn, $event) = @_; +# 'args' => [ +# 'AntiSpamMetaBeta', +# '#antispammeta', +# 'q', +# 'loltest!*@*', +# 'fn-troll!icxcnika@freenode/weird-exception/network-troll/afterdeath', +# '1344755722' +# ], + my ($me, $chan, $mode, $ban, $banner, $bantime) = @{$event->{args}}; + $::sc{lc $chan}{quiets}{$ban} = { bannedBy => $banner, bannedOn => $bantime }; +} + sub on_ctcp { my ($conn, $event) = @_; @@ -481,6 +583,23 @@ sub on_whoxover $::synced{$event->{args}->[1]} = 1; if (defined($chan) ){ $conn->sl('who ' . $chan . ' %tcnuhra,314'); + $conn->sl('mode ' . $chan); + $conn->sl('mode ' . $chan . ' bq'); + } else { + my $size = `ps -p $$ h -o size`; + my $cputime = `ps -p $$ h -o time`; + chomp $size; chomp $cputime; + $conn->privmsg("#antispammeta", "Finished syncing after " . (time - $::starttime) . " seconds. " . + "I'm tracking " . (scalar (keys %::sn)) . " nicks" . + " across " . (scalar (keys %::sc)) . " tracked channels." . + " I'm using " . $size . "KB of RAM" . + " and have used " . $cputime . " of CPU time."); + my %x = (); + foreach my $c (@{$::settings->{autojoins}}) { $x{$c} = 1; } + foreach my $cx (keys %::sc) { delete $x{$cx}; } + if (scalar (keys %x)) { + $conn->privmsg("#antispammeta", "Syncing appears to have failed for " . ASM::Util->commaAndify(keys %x)); + } } } @@ -491,10 +610,6 @@ sub on_whofuckedup print "on_whofuckedup called!\n"; } } -sub on_banlist -{ - my ($conn, $event) = @_; -} sub on_bannedfromchan { my ($conn, $event) = @_; diff --git a/modules/inspect.pl b/modules/inspect.pl index 6a4afec..02a6b35 100644 --- a/modules/inspect.pl +++ b/modules/inspect.pl @@ -25,7 +25,11 @@ sub inspect { my $nick = lc $event->{nick}; my $xresult; return if (index($nick, ".") != -1); - return if (defined($::eline{$nick}) || defined($::eline{lc $event->{user}}) || defined($::eline{lc $event->{host}})); + return unless (ASM::Util->notRestricted($nick, "notrigger")); + if (defined($::eline{$nick}) || defined($::eline{lc $event->{user}}) || defined($::eline{lc $event->{host}})) { + print "Deprecated eline found for $nick / $event->{user} / $event->{host} !\n"; + return; + } if ( $event->{host} =~ /gateway\/web\// ) { if ( $event->{user} =~ /([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/ ) { $rev = sprintf("%d.%d.%d.%d.", hex($4), hex($3), hex($2), hex($1)); @@ -63,7 +67,7 @@ sub inspect { $xresult = $dct{$id}{xresult}; my $nicereason = interpolate($dct{$id}{reason}); $::db->record($chan, $event->{nick}, $event->{user}, $event->{host}, $::sn{lc $event->{nick}}->{gecos}, $dct{$id}{risk}, $id, $nicereason); - $txtz = "\x03" . $::RCOLOR{$::RISKS{$dct{$id}{risk}}} . "\u$dct{$id}{risk}\x03 risk threat [\x02$chan\x02]: ". + $txtz = "\x03" . $::RCOLOR{$::RISKS{$dct{$id}{risk}}} . "\u$dct{$id}{risk}\x03 risk threat [\x02$chan\x02] - ". "\x02$event->{nick}\x02 - ${nicereason}; ping "; $txtz = $txtz . ASM::Util->commaAndify(ASM::Util->getAlert(lc $chan, $dct{$id}{risk}, 'hilights')) if (ASM::Util->getAlert(lc $chan, $dct{$id}{risk}, 'hilights')); $txtz = $txtz . ' !att-' . $chan . '-' . $dct{$id}{risk}; @@ -72,15 +76,7 @@ sub inspect { } unless (defined($::ignored{$chan}) && ($::ignored{$chan} >= $::RISKS{$dct{$id}{risk}})) { my @tgts = ASM::Util->getAlert($chan, $dct{$id}{risk}, 'msgs'); -# foreach my $tgt (@tgts) { #unfortunately wikipedia has way too many ops, and it breaks things - if (length($txtz) <= 380) { - $conn->privmsg(\@tgts, $txtz); - } else { - my $splitpart = rindex($txtz, " ", 380); - $conn->privmsg(\@tgts, substr($txtz, 0, $splitpart)); - $conn->privmsg(\@tgts, substr($txtz, $splitpart)); - } -# } + ASM::Util->sendLongMsg($conn, \@tgts, $txtz); $::ignored{$chan} = $::RISKS{$dct{$id}{risk}}; $conn->schedule(45, sub { delete($::ignored{$chan})}); } diff --git a/modules/services.pl b/modules/services.pl index aafe68e..d2b3d31 100644 --- a/modules/services.pl +++ b/modules/services.pl @@ -15,9 +15,9 @@ sub doServices { if ($event->{from} eq 'NickServ!NickServ@services.') { print "NickServ: $event->{args}->[0]\n"; - if ( $event->{args}->[0] eq 'This nickname is registered' ) + if ( $event->{args}->[0] =~ /^This nickname is registered/ ) { - $conn->privmsg( 'NickServ', "identify $::settings->{pass}" ); + $conn->privmsg( 'NickServ', "identify $::settings->{nick} $::settings->{pass}" ); } elsif ( $event->{args}->[0] =~ /^You are now identified/ ) { @@ -37,6 +37,10 @@ sub doServices { print "Got kill/release successful from nickserv!\n" if $::debugx{services}; $conn->nick( $::settings->{nick} ); } + elsif ($event->{args}->[0] =~ /has been regained/ ) + { + print "Got regain successful from nickserv!\n" if $::debugx{services}; + } elsif ($event->{args}->[0] =~ /Password Incorrect/ ) { die("NickServ password invalid.") diff --git a/modules/util.pl b/modules/util.pl index 109882b..7a111b5 100644 --- a/modules/util.pl +++ b/modules/util.pl @@ -137,6 +137,18 @@ sub flood_process { } } +# If $tgts="#antispammeta" that's fine, and if $tgts = ["#antispammeta", "##linux-ops"] that's cool too +sub sendLongMsg { + my ($module, $conn, $tgts, $txtz) = @_; + if (length($txtz) <= 380) { + $conn->privmsg($tgts, $txtz); + } else { + my $splitpart = rindex($txtz, " ", 380); + $conn->privmsg($tgts, substr($txtz, 0, $splitpart)); + $conn->privmsg($tgts, substr($txtz, $splitpart)); + } +} + sub getAlert { my ($module, $c, $risk, $t) = @_; my @disable = (); @@ -183,4 +195,33 @@ sub dprint { print $text if $::debug; } +sub notRestricted { + my ($module, $nick, $restriction) = @_; + $nick = lc $nick; + my $host = $::sn{$nick}{host}; + my $account = lc $::sn{$nick}{account}; + my $ret = 1; + if (defined($::restrictions->{nicks}->{nick}->{$nick})) { + if (defined($::restrictions->{nicks}->{nick}->{$nick}->{$restriction})) { + $ret= 0; + } + } + if ((defined($host)) && (defined($account))) { + if (defined($::restrictions->{accounts}->{account}->{$account})) { + if (defined($::restrictions->{accounts}->{account}->{$account}->{$restriction})) { + $ret= 0; + } + } + if (defined($::restrictions->{hosts}->{host}->{$host})) { + if (defined($::restrictions->{hosts}->{host}->{$host}->{$restriction})) { + $ret= 0; + } + } + } + if (($ret == 0) && ($::debugx{restrictions})) { + print "Restriction $restriction found for $nick\n"; + } + return $ret; +} + return 1; diff --git a/modules/xml.pl b/modules/xml.pl index 14f5826..a23df77 100644 --- a/modules/xml.pl +++ b/modules/xml.pl @@ -10,24 +10,26 @@ $::xs1 = XML::Simple->new( KeyAttr => ['id'], Cache => [ qw/storable memcopy/ ]) sub readXML { my ( $p ) = $::cset; my @fchan = ( 'event', keys %::RISKS ); - $::settings = $::xs1->XMLin( "$p/settings.xml", ForceArray => ['host'], 'GroupTags' => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }); - $::channels = $::xs1->XMLin( "$p/channels.xml", ForceArray => \@fchan ); - $::users = $::xs1->XMLin( "$p/users.xml", ForceArray => 'person'); - $::commands = $::xs1->XMLin( "$p/commands.xml", ForceArray => [qw/command/]); - $::mysql = $::xs1->XMLin( "$p/mysql.xml", ForceArray => []); - $::dnsbl = $::xs1->XMLin( "$p/dnsbl.xml", ForceArray => []); - $::rules = $::xs1->XMLin( "$p/rules.xml", ForceArray => []); + $::settings = $::xs1->XMLin( "$p/settings.xml", ForceArray => ['host'], 'GroupTags' => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }); + $::channels = $::xs1->XMLin( "$p/channels.xml", ForceArray => \@fchan ); + $::users = $::xs1->XMLin( "$p/users.xml", ForceArray => 'person'); + $::commands = $::xs1->XMLin( "$p/commands.xml", ForceArray => [qw/command/]); + $::mysql = $::xs1->XMLin( "$p/mysql.xml", ForceArray => []); + $::dnsbl = $::xs1->XMLin( "$p/dnsbl.xml", ForceArray => []); + $::rules = $::xs1->XMLin( "$p/rules.xml", ForceArray => []); + $::restrictions = $::xs1->XMLin( "$p/restrictions.xml", ForceArray => ['host', 'nick', 'account']); } sub writeXML { - $::xs1->XMLout($::settings, RootName => 'settings', KeyAttr => ['id'], - GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }, - ValueAttr => { debug => 'content', nick => 'content', port => 'content', - realname => 'content', username => 'content', dir => 'content', - zone => 'content', filefmt => 'content', timefmt => 'content'}) > io("$::cset/settings.xml"); - $::xs1->XMLout($::channels, RootName => 'channels', KeyAttr => ['id'], NumericEscape => 2) > io("$::cset/channels.xml"); - $::xs1->XMLout($::users, RootName => 'people', KeyAttr => ['id']) > io("$::cset/users.xml"); - $::xs1->XMLout($::commands, RootName => 'commands', KeyAttr => ['id']) > io("$::cset/commands.xml"); + $::xs1->XMLout($::settings, RootName => 'settings', KeyAttr => ['id'], + GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }, + ValueAttr => { debug => 'content', nick => 'content', port => 'content', + realname => 'content', username => 'content', dir => 'content', + zone => 'content', filefmt => 'content', timefmt => 'content'}) > io("$::cset/settings.xml"); + writeChannels(); + writeUsers(); + writeRestrictions(); + $::xs1->XMLout($::commands, RootName => 'commands', KeyAttr => ['id']) > io("$::cset/commands.xml"); } sub writeChannels { @@ -39,7 +41,13 @@ sub writeUsers { } sub writeSettings { - $::xs1->XMLout($::settings, RootName => 'settings', GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }, NoAttr => 1) > io("$::cset/settings.xml"); + $::xs1->XMLout($::settings, RootName => 'settings', + GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }, NoAttr => 1) > io("$::cset/settings.xml"); +} + +sub writeRestrictions { + $::xs1->XMLout($::restrictions, RootName => 'restrictions', KeyAttr => ['id'], + GroupTags => { hosts => "host", nicks => "nick", accounts => "account"}) > io("$::cset/restrictions.xml"); } return 1; |
