diff --git a/PBot/AntiFlood.pm b/PBot/AntiFlood.pm index ff6df298..fbca4ea3 100644 --- a/PBot/AntiFlood.pm +++ b/PBot/AntiFlood.pm @@ -397,7 +397,7 @@ sub check_flood { } elsif ($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT}) { if ($chan =~ /^#/) { #channel flood (opposed to private message or otherwise) # don't increment offenses again if already banned - if ($self->{pbot}->{chanops}->has_ban_timeout($chan, "*!$user\@" . $self->address_to_mask($host))) { + if ($self->{pbot}->{banlist}->has_ban_timeout($chan, "*!$user\@" . $self->address_to_mask($host))) { $self->{pbot}->{logger}->log("$nick $chan flood offense disregarded due to existing ban\n"); next; } @@ -496,7 +496,7 @@ sub check_flood { $chan_data->{enter_abuses}++; if ($chan_data->{enter_abuses} >= $enter_abuse_max_offenses) { if ($self->{pbot}->{registry}->get_value('antiflood', 'enforce')) { - if ($self->{pbot}->{chanops}->has_ban_timeout($chan, "*!$user\@" . $self->address_to_mask($host))) { + if ($self->{pbot}->{banlist}->has_ban_timeout($chan, "*!$user\@" . $self->address_to_mask($host))) { $self->{pbot}->{logger}->log("$nick $chan enter abuse offense disregarded due to existing ban\n"); next; } @@ -594,13 +594,13 @@ sub unbanme { foreach my $baninfo (@$baninfos) { my $u = $self->{pbot}->{users}->loggedin($baninfo->{channel}, "$nick!$user\@$host"); my $whitelisted = $self->{pbot}->{capabilities}->userhas($u, 'is-whitelisted'); - if ($self->ban_exempted($baninfo->{channel}, $baninfo->{banmask}) || $whitelisted) { - $self->{pbot}->{logger}->log("anti-flood: [unbanme] $anick!$auser\@$ahost banned as $baninfo->{banmask} in $baninfo->{channel}, but allowed through whitelist\n"); + if ($self->ban_exempted($baninfo->{channel}, $baninfo->{mask}) || $whitelisted) { + $self->{pbot}->{logger}->log("anti-flood: [unbanme] $anick!$auser\@$ahost banned as $baninfo->{mask} in $baninfo->{channel}, but allowed through whitelist\n"); } else { if ($channel eq lc $baninfo->{channel}) { my $mode = $baninfo->{type} eq "+b" ? "banned" : "quieted"; - $self->{pbot}->{logger}->log("anti-flood: [unbanme] $anick!$auser\@$ahost $mode as $baninfo->{banmask} in $baninfo->{channel} by $baninfo->{owner}, unbanme rejected\n"); - return "/msg $nick You have been $mode as $baninfo->{banmask} by $baninfo->{owner}, unbanme will not work until it is removed."; + $self->{pbot}->{logger}->log("anti-flood: [unbanme] $anick!$auser\@$ahost $mode as $baninfo->{mask} in $baninfo->{channel} by $baninfo->{owner}, unbanme rejected\n"); + return "/msg $nick You have been $mode as $baninfo->{mask} by $baninfo->{owner}, unbanme will not work until it is removed."; } } } @@ -803,7 +803,7 @@ sub check_bans { } my $baninfo = {}; - $baninfo->{banmask} = $alias; + $baninfo->{mask} = $alias; $baninfo->{channel} = $channel; $baninfo->{owner} = 'blacklist'; $baninfo->{when} = 0; @@ -821,7 +821,7 @@ sub check_bans { foreach my $baninfo (@$baninfos) { if (time - $baninfo->{when} < 5) { $self->{pbot}->{logger} - ->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{banmask} in $baninfo->{channel}, but within 5 seconds of establishing ban; giving another chance\n"); + ->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{mask} in $baninfo->{channel}, but within 5 seconds of establishing ban; giving another chance\n"); my $channel_data = $self->{pbot}->{messagehistory}->{database}->get_channel_data($message_account, $channel, 'validated'); if ($channel_data->{validated} & $self->{NICKSERV_VALIDATED}) { $channel_data->{validated} &= ~$self->{NICKSERV_VALIDATED}; @@ -833,18 +833,18 @@ sub check_bans { my $u = $self->{pbot}->{users}->loggedin($baninfo->{channel}, $mask); my $whitelisted = $self->{pbot}->{capabilities}->userhas($u, 'is-whitelisted'); - if ($self->ban_exempted($baninfo->{channel}, $baninfo->{banmask}) || $whitelisted) { - #$self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{banmask} in $baninfo->{channel}, but allowed through whitelist\n"); + if ($self->ban_exempted($baninfo->{channel}, $baninfo->{mask}) || $whitelisted) { + #$self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{mask} in $baninfo->{channel}, but allowed through whitelist\n"); next; } # special case for twkm clone bans - if ($baninfo->{banmask} =~ m/\?\*!\*@\*$/) { - $self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{banmask} in $baninfo->{channel}, but disregarded due to clone ban\n"); + if ($baninfo->{mask} =~ m/\?\*!\*@\*$/) { + $self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask [$alias] evaded $baninfo->{mask} in $baninfo->{channel}, but disregarded due to clone ban\n"); next; } - my $banmask_regex = quotemeta $baninfo->{banmask}; + my $banmask_regex = quotemeta $baninfo->{mask}; $banmask_regex =~ s/\\\*/.*/g; $banmask_regex =~ s/\\\?/./g; @@ -853,7 +853,7 @@ sub check_bans { next; } - if (defined $nickserv and $baninfo->{type} eq '+q' and $baninfo->{banmask} =~ /^\$a:(.*)/ and lc $1 eq $nickserv and $nickserv eq $current_nickserv_account) { + if (defined $nickserv and $baninfo->{type} eq '+q' and $baninfo->{mask} =~ /^\$a:(.*)/ and lc $1 eq $nickserv and $nickserv eq $current_nickserv_account) { $self->{pbot}->{logger}->log("anti-flood: [check-bans] Hostmask ($mask) matches quiet on account ($nickserv), disregarding\n"); next; } @@ -861,7 +861,7 @@ sub check_bans { if (not defined $bans) { $bans = []; } $self->{pbot}->{logger} - ->log("anti-flood: [check-bans] Hostmask ($mask [$alias" . (defined $nickserv ? "/$nickserv" : "") . "]) matches $baninfo->{type} $baninfo->{banmask}, adding ban\n"); + ->log("anti-flood: [check-bans] Hostmask ($mask [$alias" . (defined $nickserv ? "/$nickserv" : "") . "]) matches $baninfo->{type} $baninfo->{mask}, adding ban\n"); push @$bans, $baninfo; goto GOT_BAN; } @@ -877,7 +877,7 @@ sub check_bans { my ($user, $host) = $mask =~ m/[^!]+!([^@]+)@(.*)/; if ($host =~ m{^([^/]+)/.+} and $1 ne 'gateway' and $1 ne 'nat') { $banmask = "*!*\@$host"; } elsif ( $current_nickserv_account - and $baninfo->{banmask} !~ m/^\$a:/i + and $baninfo->{mask} !~ m/^\$a:/i and not $self->{pbot}->{banlist}->{banlist}->exists($baninfo->{channel}, "\$a:$current_nickserv_account")) { $banmask = "\$a:$current_nickserv_account"; @@ -890,10 +890,10 @@ sub check_bans { } } - $self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask evaded $baninfo->{banmask} banned in $baninfo->{channel} by $baninfo->{owner}, banning $banmask\n"); + $self->{pbot}->{logger}->log("anti-flood: [check-bans] $mask evaded $baninfo->{mask} banned in $baninfo->{channel} by $baninfo->{owner}, banning $banmask\n"); my ($bannick) = $mask =~ m/^([^!]+)/; if ($self->{pbot}->{registry}->get_value('antiflood', 'enforce')) { - if ($self->{pbot}->{chanops}->has_ban_timeout($baninfo->{channel}, $banmask)) { + if ($self->{pbot}->{banlist}->has_ban_timeout($baninfo->{channel}, $banmask)) { $self->{pbot}->{logger}->log("anti-flood: [check-bans] $banmask already banned in $channel, disregarding\n"); return; } @@ -915,7 +915,7 @@ sub check_bans { else { my $owner = $baninfo->{owner}; $owner =~ s/!.*$//; - $self->{pbot}->{chanops}->add_op_command($baninfo->{channel}, "kick $baninfo->{channel} $bannick Evaded $baninfo->{banmask} set by $owner"); + $self->{pbot}->{chanops}->add_op_command($baninfo->{channel}, "kick $baninfo->{channel} $bannick Evaded $baninfo->{mask} set by $owner"); } $self->{pbot}->{banlist}->ban_user_timed( $banmask, $baninfo->{channel}, diff --git a/PBot/BanList.pm b/PBot/BanList.pm index b63bba7a..9a91d3da 100644 --- a/PBot/BanList.pm +++ b/PBot/BanList.pm @@ -75,7 +75,7 @@ sub banlist_cmd { if ($self->{banlist}->exists($arguments)) { my $count = $self->{banlist}->get_keys($arguments); - $result .= "$count bans:\n"; + $result .= "$count ban" . ($count == 1 ? '' : 's') . ":\n"; foreach my $mask ($self->{banlist}->get_keys($arguments)) { my $data = $self->{banlist}->get_data($arguments, $mask); $result .= " $mask banned "; @@ -100,7 +100,7 @@ sub banlist_cmd { if ($self->{quietlist}->exists($arguments)) { my $count = $self->{quietlist}->get_keys($arguments); - $result .= "$count mutes:\n"; + $result .= "$count mute" . ($count == 1 ? '' : 's') . ":\n"; foreach my $mask ($self->{quietlist}->get_keys($arguments)) { my $data = $self->{quietlist}->get_data($arguments, $mask); $result .= " $mask muted "; @@ -120,9 +120,10 @@ sub banlist_cmd { $result .= ";\n"; } } else { - $result .= "quiets: none;\n"; + $result .= "quiets: none\n"; } + $result =~ s/ ;/;/g; return $result; } @@ -166,7 +167,7 @@ sub on_banlist_entry { my $timestamp = $event->{event}->{args}[4]; my $ago = concise ago(gettimeofday - $timestamp); - $self->{pbot}->{logger}->log("banlist: [banlist entry] $channel: $target banned by $source $ago.\n"); + $self->{pbot}->{logger}->log("Ban List: [banlist entry] $channel: $target banned by $source $ago.\n"); $self->{temp_banlist}->{$channel}->{'+b'}->{$target} = [$source, $timestamp]; return 0; } @@ -180,7 +181,7 @@ sub on_quietlist_entry { my $timestamp = $event->{event}->{args}[5]; my $ago = concise ago(gettimeofday - $timestamp); - $self->{pbot}->{logger}->log("banlist: [quietlist entry] $channel: $target quieted by $source $ago.\n"); + $self->{pbot}->{logger}->log("Ban List: [quietlist entry] $channel: $target quieted by $source $ago.\n"); $self->{temp_banlist}->{$channel}->{'+q'}->{$target} = [$source, $timestamp]; return 0; } @@ -189,7 +190,7 @@ sub compare_banlist { my ($self, $event_type, $event) = @_; my $channel = lc $event->{event}->{args}[1]; - $self->{pbot}->{logger}->log("Finalizing ban list for $channel\n"); + $self->{pbot}->{logger}->log("Finalizing Ban List for $channel\n"); # first check for saved bans no longer in channel foreach my $mask ($self->{banlist}->get_keys($channel)) { @@ -226,7 +227,8 @@ sub compare_banlist { $self->{banlist}->add($channel, $mask, $data, 1); } - $self->{banlist}->save; + $self->{banlist}->save if keys %{$self->{temp_banlist}->{$channel}->{'+b'}}; + delete $self->{temp_banlist}->{$channel}->{'+b'}; } sub compare_quietlist { @@ -253,7 +255,8 @@ sub compare_quietlist { $self->{quietlist}->add($channel, $mask, $data, 1); } - $self->{quietlist}->save; + $self->{quietlist}->save if keys %{$self->{temp_banlist}->{$channel}->{'+q'}}; + delete $self->{temp_banlist}->{$channel}->{'+q'}; } sub track_mode { @@ -265,7 +268,7 @@ sub track_mode { $mask = lc $mask; if ($mode eq "+b" or $mode eq "+q") { - $self->{pbot}->{logger}->log("banlist: $mask " . ($mode eq '+b' ? 'banned' : 'quieted') . " by $source in $channel.\n"); + $self->{pbot}->{logger}->log("Ban List: $mask " . ($mode eq '+b' ? 'banned' : 'quieted') . " by $source in $channel.\n"); my $data = { owner => $source, @@ -280,7 +283,7 @@ sub track_mode { $self->{pbot}->{antiflood}->devalidate_accounts($mask, $channel); } elsif ($mode eq "-b" or $mode eq "-q") { - $self->{pbot}->{logger}->log("banlist: $mask " . ($mode eq '-b' ? 'unbanned' : 'unquieted') . " by $source in $channel.\n"); + $self->{pbot}->{logger}->log("Ban List: $mask " . ($mode eq '-b' ? 'unbanned' : 'unquieted') . " by $source in $channel.\n"); if ($mode eq "-b") { $self->{banlist}->remove($channel, $mask); @@ -323,7 +326,7 @@ sub track_mode { if (not $self->{banlist}->exists($channel, $mask)) { $self->{pbot}->{logger}->log("Temp ban for $mask in $channel.\n"); my $data = { - reason => 'Temp ban for *!*@... banmask', + reason => 'Temp ban for *!*@host', timeout => gettimeofday + $timeout, owner => $self->{pbot}->{registry}->get_value('irc', 'botnick'), timestamp => gettimeofday, @@ -383,14 +386,14 @@ sub unmode_user { my %unbanned; if (not defined $bans) { - push @$bans, { banmask => $mask, type => "+$mode" }; + push @$bans, { mask => $mask, type => "+$mode" }; } foreach my $ban (@$bans) { next if $ban->{type} ne "+$mode"; - next if exists $unbanned{$ban->{banmask}}; - $unbanned{$ban->{banmask}} = 1; - $self->add_to_unban_queue($channel, $mode, $ban->{banmask}); + next if exists $unbanned{$ban->{mask}}; + $unbanned{$ban->{mask}} = 1; + $self->add_to_unban_queue($channel, $mode, $ban->{mask}); } $self->flush_unban_queue if $immediately; @@ -695,7 +698,8 @@ sub enqueue_timeouts { foreach my $channel ($list->get_keys) { foreach my $mask ($list->get_keys($channel)) { my $timeout = $list->get_data($channel, $mask, 'timeout'); - next if $timeout <= 0; + next if defined $timeout and $timeout <= 0; + next if not defined $timeout; my $interval = $timeout - $now; $interval = 10 if $interval < 10; $self->enqueue_unban($channel, $mode, $mask, $interval); diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index 5cd780e3..5d700482 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -19,8 +19,8 @@ use LWP::UserAgent; # These are set automatically by the misc/update_version script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 3522, - BUILD_DATE => "2020-04-24", + BUILD_REVISION => 3536, + BUILD_DATE => "2020-04-28", }; sub initialize { diff --git a/Plugins/RelayUnreg.pm b/Plugins/RelayUnreg.pm index 110bd0d0..af8e7a7b 100644 --- a/Plugins/RelayUnreg.pm +++ b/Plugins/RelayUnreg.pm @@ -103,7 +103,7 @@ sub check_queue { # ensure they're not banned (+z allows us to see +q/+b messages as normal ones) my $banned = $self->{pbot}->{banlist}->is_banned($nick, $user, $host, $channel); $self->{pbot}->{logger} - ->log("[RelayUnreg] $nick!$user\@$host $banned->{mode} as $banned->{banmask} in $banned->{channel} by $banned->{owner}, not relaying unregistered message\n") + ->log("[RelayUnreg] $nick!$user\@$host $banned->{mode} as $banned->{mask} in $banned->{channel} by $banned->{owner}, not relaying unregistered message\n") if $banned; $self->{pbot}->{conn}->privmsg($channel, "(unreg) <$nick> $msg") unless $banned; } diff --git a/Plugins/RestrictedMod.pm b/Plugins/RestrictedMod.pm index 25cefc9c..7ca9ae89 100644 --- a/Plugins/RestrictedMod.pm +++ b/Plugins/RestrictedMod.pm @@ -90,7 +90,7 @@ sub generic_command { if ($command eq 'unban') { my $reason = $self->{pbot}->{banlist}->checkban($channel, 'b', $target); if ($reason =~ m/moderator ban/) { - $self->{pbot}->{chanops}->unban_user($channel, 'b', $target, 1); + $self->{pbot}->{banlist}->unban_user($channel, 'b', $target, 1); return ""; } else { return "I don't think so. That ban was not set by a moderator."; diff --git a/data/banlist b/data/banlist index 51bd9de1..31401aff 100644 --- a/data/banlist +++ b/data/banlist @@ -1,8 +1,8 @@ { "$metadata$" : { "$metadata$" : { - "update_version" : 3503, - "name" : "Ban List" + "name" : "Ban List", + "update_version" : "3536" } } } diff --git a/data/last_update b/data/last_update index 7ae5f23f..48a72702 100644 --- a/data/last_update +++ b/data/last_update @@ -1 +1 @@ -3512 +3536 diff --git a/data/quietlist b/data/quietlist index ef0fd699..2818ca26 100644 --- a/data/quietlist +++ b/data/quietlist @@ -1,8 +1,8 @@ { "$metadata$" : { "$metadata$" : { - "update_version" : 3503, - "name" : "Quiet List" + "name" : "Quiet List", + "update_version" : "3536" } } } diff --git a/data/registry b/data/registry index 41896e92..1f962454 100644 --- a/data/registry +++ b/data/registry @@ -1,8 +1,8 @@ { "$metadata$" : { "$metadata$" : { - "update_version" : 3503, - "name" : "Registry" + "name" : "Registry", + "update_version" : "3536" } }, "antiaway" : { @@ -123,7 +123,7 @@ "value" : "900,1800,3600" } }, - "bantracker" : { + "banlist" : { "chanserv_ban_timeout" : { "type" : "text", "value" : "604800" diff --git a/updates/3536_update_banlist.pl b/updates/3536_update_banlist.pl new file mode 100755 index 00000000..ee6dd8d0 --- /dev/null +++ b/updates/3536_update_banlist.pl @@ -0,0 +1,51 @@ +#!/usr/bin/env perl + +# Convert unmute_timeouts and unban_timeouts to quietlist and banlist +# Rename bantracker to banlist in registry + +use warnings; use strict; + +BEGIN { + use File::Basename; + my $location = -l __FILE__ ? dirname readlink __FILE__ : dirname __FILE__; + unshift @INC, $location; +} + +use lib3512::DualIndexHashObject; +use lib3503::PBot; + +my ($data_dir, $version, $last_update) = @ARGV; + +print "Updating ban list data... version: $version, last_update: $last_update, data_dir: $data_dir\n"; + +my $pbot = lib3503::PBot->new(); + +my $unmutes = lib3512::DualIndexHashObject->new(name => 'old unmute timeouts', filename => "$data_dir/unmute_timeouts", pbot => $pbot); +$unmutes->load; + +$unmutes->set('$metadata$', '$metadata$', 'name', 'Quiet List', 1); +$unmutes->set('$metadata$', '$metadata$', 'update_version', '3536'); + +my $unbans = lib3512::DualIndexHashObject->new(name => 'old unban timeouts', filename => "$data_dir/unban_timeouts", pbot => $pbot); +$unbans->load; + +$unbans->set('$metadata$', '$metadata$', 'name', 'Ban List', 1); +$unbans->set('$metadata$', '$metadata$', 'update_version', '3536'); + +use File::Copy; +move("$data_dir/unmute_timeouts", "$data_dir/quietlist") or die "Failed to move unmute_timeouts -> quietlist: $!"; +move("$data_dir/unban_timeouts", "$data_dir/banlist") or die "Failed to move unban_timeouts -> banlist: $!"; + +my $registry = lib3512::DualIndexHashObject->new(name => 'Registry', filename => "$data_dir/registry", pbot => $pbot); +$registry->load; + +my $data = $registry->get_data('bantracker'); +$registry->remove('bantracker', undef, undef, 1); + +foreach my $key (keys %{$data}) { + $registry->add('banlist', $key, $data->{$key}, 1); +} + +$registry->set('$metadata$', '$metadata$', 'update_version', '3536'); + +exit 0;