{channel}}) { if (defined($::channels->{channel}->{$chan}->{msgs})) { foreach my $risk (keys %{$::channels->{channel}->{$chan}->{msgs}}) { push @chans, @{$::channels->{channel}->{$chan}->{msgs}->{$risk}}; } } } my %uniq = (); foreach my $chan (@chans) { $uniq{$chan} = 1; } @chans = keys(%uniq); print Dumper(\@chans); ]]> {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.") ]]> $::settings->{web}->{userfile}, UseMD5 => 1}); my $o_Htgroup = new Apache::Htgroup($::settings->{web}->{groupfile}); $o_Htpasswd->htDelete($user); $o_Htgroup->deleteuser($user, 'actionlogs'); $o_Htgroup->save(); $conn->privmsg($event->replyto, "Removed $user from 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})) { if ($event->{to}->[0] =~ /^#/) { $conn->privmsg($event->replyto, $nick . " is on: " . ASM::Util->commaAndify(sort(grep { not grep { /^s$/ } @{$::sc{$_}{modes}} } @{$::sn{lc $nick}->{mship}}))); } else { $conn->privmsg($event->replyto, $nick . " is on: " . ASM::Util->commaAndify(sort @{$::sn{lc $nick}->{mship}})); } } else { $conn->privmsg($event->replyto, "I don't see $nick."); } ]]> privmsg($event->replyto, "source is at https://gitlab.devlabs.linuxassist.net/asm/antispammeta/"); ]]> privmsg($event->replyto, "I am set to run without a database, fool."); return; } my $dbh = $::db->{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; } if (defined($2)) { my $switch = lc $2; $::channels->{channel}->{$chan}->{monitor} = $switch; ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "Monitor flag for $chan set to $switch"); } else { my $switch = $::channels->{channel}->{$chan}->{monitor} // 'yes'; $conn->privmsg($event->replyto, "Monitor flag for $chan is currently set to $switch"); } ]]> {channel}->{$chan}->{silence} = $switch; ASM::XML->writeChannels(); $conn->privmsg($event->replyto, "Silence flag for $chan set to $switch"); } else { my $switch = $::channels->{channel}->{$chan}->{silence} // 'no'; $conn->privmsg($event->replyto, "Silence flag for $chan is currently 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 ($person->{user})" : $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 ($person->{gecos})" : $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}; } my $sayNick = substr($nick, 0, 1) . "\x02\x02" . substr($nick, 1); if (defined($::users->{person}->{$nick}->{flags})) { $conn->privmsg($event->replyto, "Flags for $sayNick: $::users->{person}->{$nick}->{flags}"); } else { $conn->privmsg($event->replyto, "$sayNick 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; } my $chan_regex = qr/^#|^default$|^master$/; if ( $chan !~ $chan_regex ) { my $msg = "Error: '$chan' doesn't look like a channel to me."; if ( $nick_str =~ $chan_regex ) { $msg .= ' (Maybe you just specified nick and channel in the wrong order?)'; } $conn->privmsg($event->replyto, $msg); 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}}; if (!grep { $chan eq lc $_ } @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; $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 ((defined($::channels->{channel}->{$tgt}->{monitor})) and ($::channels->{channel}->{$tgt}->{monitor} eq "no")) { return; } unless (lc $tgt ~~ $::sn{lc $event->{nick}}->{mship}) { return; #they're not on the channel they're calling !ops for } if (defined($::ignored{$tgt}) && ($::ignored{$tgt} >= $::RISKS{'opalert'})) { if (ASM::Util->notRestricted(lc $event->{nick}, "noops")) { 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"); } else { $conn->privmsg($event->{nick}, "I've already recently notified $tgt ops."); } } } return; } 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); 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."); } } 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 { unless (defined($::ignored{$tgt}) && ($::ignored{$tgt} >= $::RISKS{'opalert'})) { 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."); } } } $::ignored{$tgt} = $::RISKS{'opalert'}; $conn->schedule(45, sub { delete($::ignored{$tgt}) if $::ignored{$tgt} == $::RISKS{'opalert'} }); ]]> {string}->{$id} = { "content" => $str, "setby" => $event->nick, "settime" => strftime('%F', gmtime) }; 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(lc $chan, $risk, 'msgs'); ASM::Util->sendLongMsg($conn, \@tgts, $txtz); ]]> sl("MODE $chan bq"); $conn->sl("MODE $chan"); $conn->sl("WHO $chan %tcnuhra,314"); ]]> privmsg($event->replyto, "pong $1"); ]]> 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"); } ]]> {string}->{$id})) { my $content = $::blacklist->{string}->{$id}->{content}; my $setby = $::blacklist->{string}->{$id}->{setby}; my $settime = $::blacklist->{string}->{$id}->{settime}; my $reason = $::blacklist->{string}->{$id}->{reason}; $reason = 'none ever provided' unless defined($reason); $conn->privmsg($event->nick, "'$content' blacklisted by $setby on $settime with reason $reason"); if ($event->{to}->[0] =~ /^#/) { $conn->privmsg($event->replyto, "Info on blacklist ID $id sent via PM"); } } else { $conn->privmsg($event->replyto, "ID is invalid"); } ]]> privmsg($event->replyto, 'To whitelist false matches for the impersonation check, have someone with the a flag run ";restrict nick LegitimateNickGoesHere +nonickbl_impersonate". Contact ilbelkyr if this issue reoccurs.'); ]]>