{to}->[0] =~ /^#/) { $conn->privmsg($event->replyto, "This command must be used in PM. Try again WITH A DIFFERENT PASSWORD!"); return; } use Apache::Htpasswd; use Apache::Htgroup; my $o_Htpasswd = new Apache::Htpasswd({passwdFile => $::settings->{web}->{userfile}, UseMD5 => 1}); my $o_Htgroup = new Apache::Htgroup($::settings->{web}->{groupfile}); my $user = lc $::sn{lc $event->{nick}}->{account}; $o_Htpasswd->htDelete($user); $o_Htpasswd->htpasswd($user, $pass); $o_Htpasswd->writeInfo($user, strftime("%F %T", gmtime)); $o_Htgroup->adduser($user, 'actionlogs'); $o_Htgroup->save(); $conn->privmsg($event->replyto, "Added $user to the list of authorized web users.") ]]> privmsg($event->replyto, "This is not a teredo-tunnelled IP."); return; } my $server = join('.', unpack('C4', pack('N', hex($splitip[2] . $splitip[3])))); my $host = join('.', unpack('C4', pack('N', (hex($splitip[6] . $splitip[7])^hex('ffffffff'))))); my $port = hex($splitip[5]) ^ hex('ffff'); $conn->privmsg($event->replyto, "Source is $host:$port; teredo server in use is $server."); ]]> {_tx}/1024 > 1024) { $tx = sprintf("%.2fMB", $conn->{_tx}/(1024*1024)); } else { $tx = sprintf("%.2fKB", $conn->{_tx}/1024); } if ($conn->{_rx}/1024 > 1024) { $rx = sprintf("%.2fMB", $conn->{_rx}/(1024*1024)); } else { $rx = sprintf("%.2fKB", $conn->{_rx}/1024); } $conn->privmsg($event->replyto, "This bot has been running for " . $upstr . ", is tracking " . (scalar (keys %::sn)) . " nicks" . " across " . (scalar (keys %::sc)) . " tracked channels." . " It is using " . $size . "KB of RAM" . ", has used $cputime of CPU time" . ", has sent $tx of data, and received $rx of data."); ]]> {mship})) { $conn->privmsg($event->replyto, $1 . " is on: " . ASM::Util->commaAndify(sort @{$::sn{lc $1}->{mship}})); } else { $conn->privmsg($event->replyto, "I don't see $1."); } ]]> privmsg($event->replyto, "source is at https://gitlab.devlabs.linuxassist.net/asm/antispammeta/"); ]]> {DBH}; if ($1 eq 'log') { $dbh = $::db->{DBH_LOG}; } $::db->raw($conn, $event->{to}->[0], $dbh, $2); ]]> getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->replyto, "Error: $chan is linked to $link - use $link instead."); return; } $::channels->{channel}->{$chan}->{monitor} = $switch; ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "Monitor flag for $chan set to $switch"); ]]> privmsg($event->replyto, "Please refer to http://antispammeta.net and irc.freenode.net #antispammeta"); ]]> privmsg($event->replyto, "db is at http://antispammeta.net/query.html"); ]]> query($channel, $nuh[0], $nuh[2], $nuh[4]); $conn->privmsg($event->replyto, "$result results found."); ]]> privmsg($event->replyto, "I don't see $nick in my state tracking database, so I can't run any queries on their info, sorry :(" . " You can try https://antispammeta.net/cgi-bin/secret/investigate.pl?nick=$nick instead!"); return; } my $person = $::sn{$nick}; my $dbh = $::db->{DBH}; my $mnicks = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE nick like " . $dbh->quote($nick) . ';'); my $musers = (lc $person->{user} ~~ $::mysql->{ignoredidents}) ? "didn't check" : $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE user like " . $dbh->quote($person->{user}) . ';'); my $mhosts = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE host like " . $dbh->quote($person->{host}) . ';'); my $maccts = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE account like " . $dbh->quote($person->{account}) . ';'); my $mgecos = (lc $person->{gecos} ~~ $::mysql->{ignoredgecos}) ? "didn't check" : $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE gecos like " . $dbh->quote($person->{gecos}) . ';'); my $ip = ASM::Util->getNickIP($nick); my $matchedip = 0; $matchedip = $dbh->do("SELECT * from $::db->{ACTIONTABLE} WHERE ip = " . $dbh->quote($ip) . ';') if defined($ip); $mnicks =~ s/0E0/0/; $musers =~ s/0E0/0/; $mhosts =~ s/0E0/0/; $maccts =~ s/0E0/0/; $mgecos =~ s/0E0/0/; $matchedip =~ s/0E0/0/; my $dq = ''; if (defined($ip)) { $dq = '&realip=' . join '.', unpack 'C4', pack 'N', $ip; } $conn->privmsg($event->replyto, "I found $mnicks matches by nick, $musers user matches, $mhosts by hostname, " . "$maccts by NickServ account, $mgecos by gecos field, and $matchedip by real IP." . ' Web results are at https://antispammeta.net/cgi-bin/secret/investigate.pl?nick=' . uri_escape($nick) . ((lc $person->{user} ~~ $::mysql->{ignoredidents}) ? '' : '&user=' . uri_escape($person->{user})) . '&host=' . uri_escape($person->{host}) . '&account=' . uri_escape($person->{account}) . ((lc $person->{gecos} ~~ $::mysql->{ignoredgecos}) ? '' : '&gecos=' . uri_escape($person->{gecos})) . $dq . ' )'); ]]> {command}} ) { next unless $xcommand->{cmd} eq '^;investigate (\S+) *$'; if (";investigate $nick" =~ /$xcommand->{cmd}/) { eval $xcommand->{content}; warn $@ if $@; last; } } unless (defined($::sn{$nick})) { return; } my $person = $::sn{$nick}; my $dbh = $::db->{DBH}; my $query = "SELECT * from $::db->{ACTIONTABLE} WHERE nick like " . $dbh->quote($nick) . ((lc $person->{user} ~~ $::mysql->{ignoredidents}) ? '' : ' or user like ' . $dbh->quote($person->{user})) . ' or host like ' . $dbh->quote($person->{host}) . ' or account like ' . $dbh->quote($person->{account}) . ((lc $person->{gecos} ~~ $::mysql->{ignoredgecos}) ? '' : ' or gecos like ' . $dbh->quote($person->{gecos})); my $ip = ASM::Util->getNickIP($nick); if (defined($ip)) { $query = $query . ' or ip = ' . $dbh->quote($ip); } $query = $query . " order by time desc limit $skip,10;"; ASM::Util->dprint($query, 'mysql'); my $query_handle = $dbh->prepare($query); $query_handle->execute(); my $dq = ''; if (defined($ip)) { $dq = '&realip=' . join '.', unpack 'C4', pack 'N', $ip; } my @data = @{$query_handle->fetchall_arrayref()}; if (@data) { $conn->privmsg($event->replyto, 'Sending you the results...'); } else { $conn->privmsg($event->replyto, 'No results to send!'); } # reverse @data; #$data will be an array of arrays, my ($xindex, $xtime, $xaction, $xreason, $xchannel, $xnick, $xuser, $xhost, $xip, $xgecos, $xaccount, $xbynick, $xbyuser, $xbyhost, $xbygecos, $xbyaccount ) = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); foreach my $line (@data) { my $reason = ''; my $channel = ''; $reason = ' (' . $line->[$xreason] . ')' if defined($line->[$xreason]); $channel = ' on ' . $line->[$xchannel] if defined($line->[$xchannel]); $conn->privmsg($event->nick, '#' . $line->[$xindex] . ': ' . $line->[$xtime] . ' ' . $line->[$xnick] . '!' . $line->[$xuser] . '@' . $line->[$xhost] . ' (' . $line->[$xgecos] . ') ' . $line->[$xaction] . $reason . $channel . ' by ' . $line->[$xbynick]); # . "\n"; } if (@data) { $conn->privmsg($event->nick, "Only 10 results are shown at a time. For more, do ;investigate2 $nick " . ($skip+10) . '.'); } ]]> {person}->{lc $::sn{lc $event->{nick}}->{account}}->{flags})) { $hasflagshash{$item} = 1; } foreach my $flag (split(//, $flags)) { if (!defined($hasflagshash{$flag})) { $conn->privmsg($event->replyto, "You can't give a flag you don't already have."); return; } } if ($flags =~ /d/i) { $conn->privmsg($event->replyto, "The d flag may not be assigned over IRC. Edit the configuration manually."); return; } if ( (defined($::sn{$nick}->{account})) && ( lc $::sn{$nick}->{account} ne $nick ) ) { $conn->privmsg($event->replyto, "I'm assuming you mean " . $nick . "'s nickserv account, " . lc $::sn{$nick}->{account} . '.'); $nick = lc $::sn{$nick}->{account}; } $::users->{person}->{$nick} = { 'flags' => $flags }; ASM::XML->writeUsers(); $conn->privmsg($event->replyto, "Flags for NickServ account $nick set to $flags"); ]]> {account})) && ( lc $::sn{$nick}->{account} ne $nick ) ) { $conn->privmsg($event->replyto, "I'm assuming you mean " . $nick . "'s nickserv account, " . lc $::sn{$nick}->{account} . '.'); $nick = lc $::sn{$nick}->{account}; } if (defined($::users->{person}->{$nick}->{flags})) { $conn->privmsg($event->replyto, "Flags for $nick: $::users->{person}->{$nick}->{flags}"); } else { $conn->privmsg($event->replyto, "$nick has no flags"); } ]]> {person}->{lc $::sn{lc $event->{nick}}->{account}}->{flags})) { $hasflagshash{$item} = 1; } foreach my $flag (split(//, $flags)) { if (!defined($hasflagshash{$flag})) { $conn->privmsg($event->replyto, "You can't give a flag you don't already have."); return; } } if ($flags =~ /d/i) { $conn->privmsg($event->replyto, "The d flag may not be assigned over IRC. Edit the configuration manually."); return; } if ( (defined($::sn{$nick}->{account})) && ( lc $::sn{$nick}->{account} ne $nick ) ) { $conn->privmsg($event->replyto, "I'm assuming you mean " . $nick . "'s nickserv account, " . lc $::sn{$nick}->{account} . '.'); $nick = lc $::sn{$nick}->{account}; } $::users->{person}->{$nick}->{flags} = $flags; ASM::XML->writeUsers(); $conn->privmsg($event->replyto, "Flags for $nick set to $flags"); ]]> {person}->{$nick}); ASM::XML->writeUsers(); $conn->privmsg($event->replyto, "Removed $nick from authorized users." . "MAKE SURE YOU PROVIDED a nickserv account to this command, rather than the nick the accountholder"); ]]> getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->replyto, "Error: $chan is linked to $link - use $link instead."); return; } if ($level eq '') { $level = 'debug'; } unless (defined($::channels->{channel}->{$chan}->{msgs})) { $::channels->{channel}->{$chan}->{msgs} = {}; } unless (defined($::channels->{channel}->{$chan}->{msgs}->{$level})) { $::channels->{channel}->{$chan}->{msgs}->{$level} = []; } my @tmphl = @{$::channels->{channel}->{$chan}->{msgs}->{$level}}; push(@tmphl, $nick); $::channels->{channel}->{$chan}->{msgs}->{$level} = \@tmphl; ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "$nick added to $level risk messages for $chan"); ]]> getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->replyto, "Error: $chan is linked to $link - use $link instead."); return; } foreach my $risk ( keys %::RISKS ) { next unless defined($::channels->{channel}->{$chan}->{msgs}->{$risk}); my @ppl = @{$::channels->{channel}->{$chan}->{msgs}->{$risk}}; @ppl = grep { lc $_ ne lc $nick } @ppl; $::channels->{channel}->{$chan}->{msgs}->{$risk} = \@ppl; } ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "$nick removed from targets for $chan"); ]]> {channel}})) { foreach my $level (keys(%{$::channels->{channel}->{$chan}->{hilights}})) { if (grep(/^${nick}$/i, @{$::channels->{channel}->{$chan}->{hilights}->{$level}})) { push @channels, $chan . " ($level)"; } } } if (! @channels) { $conn->privmsg($event->replyto, "$nick isn't on any hilights"); } else { $conn->privmsg($event->replyto, "$nick is hilighted for " . join(', ', @channels)); } ]]> privmsg($event->replyto, "Error: I don't recognize $level as a valid level."); return; } my $link = ASM::Util->getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->replyto, "Error: $chan is linked to $link - use $link instead."); return; } unless (defined($::channels->{channel}->{$chan}->{hilights})) { $::channels->{channel}->{$chan}->{hilights} = {}; } unless (defined($::channels->{channel}->{$chan}->{hilights}->{$level})) { $::channels->{channel}->{$chan}->{hilights}->{$level} = []; } 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->replyto, ASM::Util->commaAndify(@nicks) . " added to $level risk hilights for $chan"); ]]> getLink(lc $chan); if ( lc $link ne lc $chan ) { $conn->privmsg($event->replyto, "Error: $chan is linked to $link - use $link instead."); return; } foreach my $risk ( keys %::RISKS ) { next unless defined($::channels->{channel}->{$chan}->{hilights}->{$risk}); my @ppl = @{$::channels->{channel}->{$chan}->{hilights}->{$risk}}; foreach my $nick (@nicks) { @ppl = grep { lc $_ ne lc $nick } @ppl; } $::channels->{channel}->{$chan}->{hilights}->{$risk} = \@ppl; } ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "Removing hilights for " . ASM::Util->commaAndify(@nicks) . " in $chan"); ]]> {channel}->{$chan})) { $::channels->{channel}->{$chan} = { }; ASM::XML->writeChannels(); } $conn->join($chan); my @autojoins = @{$::settings->{autojoins}}; @autojoins = (@autojoins, $chan); $::settings->{autojoins} = \@autojoins; ASM::XML->writeSettings(); ]]> part($chan); my @autojoins = @{$::settings->{autojoins}}; @autojoins = grep { lc $_ ne lc $chan } @autojoins; $::settings->{autojoins} = \@autojoins; ASM::XML->writeSettings(); ]]> sl($1); ]]> quit($1); ]]> readXML(); my @strbl = io('string_blacklist.txt')->getlines; chomp @strbl; @::string_blacklist = @strbl; my @eline=io('exempt.txt')->getlines; chomp @eline; %::eline = (); foreach my $item (@eline) { $::eline{lc $item} = 1; } $conn->privmsg($event->replyto, 'config files were re-read'); ]]> {$type . 's'}->{$type}->{$who}->{$restriction}; $conn->privmsg($event->replyto, "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->replyto, "Added $restriction restriction for $type $who"); } ASM::XML->writeRestrictions(); ]]> {to}->[0]; $tgt = lc $1 if (defined($1)); my $msg = $1; $msg = $2 if defined($2); if (ASM::Util->notRestricted(lc $event->{nick}, "noops")) { my $tgt = lc $event->{to}->[0]; $tgt = lc $1 if (defined($1)); my $msg = $1; $msg = $2 if defined($2); unless (lc $tgt ~~ $::sn{lc $event->{nick}}->{mship}) { return; #they're not on the channel they're calling !ops for } unless (defined($::ignored{$tgt}) && ($::ignored{$tgt} >= $::RISKS{'opalert'})) { if (lc $event->{to}->[0] eq '##linux') { $conn->privmsg($event->{nick}, "I've summoned op attention. In the future, please use /msg " . "$conn->{_nick} !ops $event->{to}->[0] reasonGoesHere - this allows ops to " . "be notified while minimizing channel hostility."); } elsif ((lc $event->{to}->[0] eq '#wikipedia-en-help') && (!defined($msg))) { $conn->privmsg($event->{nick}, "I've summoned op attention, but in the future, please specify " . "a reason, e.g. !ops reasongoeshere - so ops know what is going on. Thanks! :)"); } elsif (lc $event->{to}->[0] eq lc $conn->{_nick}) { if (lc $tgt eq lc $conn->{_nick}) { # they privmsged the bot without providing a target $conn->privmsg($event->{nick}, "Sorry, it looks like you've tried to use the !ops command " . "via PM but haven't specified a target. Try again with /msg $conn->{_nick} " . "!ops #channelGoesHere ReasonGoesHere"); return; } else { $conn->privmsg($event->{nick}, "Thanks, I'm notifying $tgt ops."); } } $::ignored{$tgt} = $::RISKS{'opalert'}; $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"; if ((time-$::sc{$tgt}{users}{lc $event->{nick}}{jointime}) > 90) { # return; #they've been on the channel for less than 90 seconds, probably nuisance botspam $txtz = "$txtz ($msg) $hilite !att-$tgt-opalert"; } my @tgts = ASM::Util->getAlert($tgt, 'opalert', 'msgs'); ASM::Util->sendLongMsg($conn, \@tgts, $txtz); $::log->incident($tgt, "$tgt: $event->{nick} requested op attention\n"); } else { # ops has recently been called if (lc $event->{to}->[0] eq '##linux') { $conn->privmsg($event->{nick}, "I've already been recently asked to summon op attention. " . "In the future, please use /msg $conn->{_nick} !ops $event->{to}->[0] reasonGoesHere" . " - this allows ops to be notified while minimizing channel hostility."); } elsif (lc $event->{to}->[0] eq lc $conn->{_nick}) { if (lc $tgt eq lc $conn->{_nick}) { # they privmsged the bot without providing a target $conn->privmsg($event->{nick}, "Sorry, it looks like you've tried to use the !ops command " . "via PM but haven't specified a target. Try again with /msg $conn->{_nick} " . "!ops #channelGoesHere ReasonGoesHere"); return; } else { $conn->privmsg($event->{nick}, "I've already recently notified $tgt ops."); } } } } else { my @tgts = ASM::Util->getAlert($tgt, 'opalert', 'msgs'); foreach my $chan (@tgts) { $conn->privmsg($chan, $event->{nick} . " tried to use the ops trigger for $tgt but is restricted from doing so."); } } ]]> {string}->{$id} = { "content" => $str, "setby" => $event->nick }; ASM::XML->writeBlacklist(); $conn->privmsg($event->replyto, "$str blacklisted with id $id, please use ;blreason $id reasonGoesHere to set a reason"); ]]> {string}->{$id})) { delete $::blacklist->{string}->{$id}; $conn->privmsg($event->replyto, "blacklist id $id removed"); ASM::XML->writeBlacklist(); } else { $conn->privmsg($event->replyto, "invalid id"); } ]]> {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'); ASM::Util->sendLongMsg(\@tgts, $txtz); ]]> sl("MODE $chan bq"); $conn->sl("MODE $chan"); $conn->sl("WHO $chan %tcnuhra,314"); ]]> privmsg($event->replyto, "pong"); ]]> {string}->{$id})) { $::blacklist->{string}->{$id}->{reason} = $reason; $conn->privmsg($event->replyto, "Reason set"); ASM::XML->writeBlacklist(); } else { $conn->privmsg($event->replyto, "ID is invalid"); } ]]>