diff --git a/PBot/AntiFlood.pm b/PBot/AntiFlood.pm index 11d97320..79526c86 100644 --- a/PBot/AntiFlood.pm +++ b/PBot/AntiFlood.pm @@ -144,7 +144,11 @@ sub get_flood_account { if($mask =~ m/!\Q$user\E@\Q$host\E$/i) { $self->{pbot}->logger->log("anti-flood: [get-account] $nick!$user\@$host linked to $mask\n"); $self->{message_history}->{"$nick!$user\@$host"} = $self->{message_history}->{$mask}; - $self->check_nickserv_accounts($nick, $self->{message_history}->{$mask}->{nickserv_account}) if defined $self->{message_history}->{$mask}->{nickserv_account}; + + if(defined $self->{message_history}->{$mask}->{nickserv_account}) { + $self->check_nickserv_accounts($nick, $self->{message_history}->{$mask}->{nickserv_account}); + } + return "$nick!$user\@$host"; } } @@ -463,8 +467,7 @@ sub address_to_mask { sub check_nickserv_accounts { my ($self, $nick, $account) = @_; - my @banned_channels; - my @account_masks; + my ($account_mask, @bans); foreach my $mask (keys %{ $self->{message_history} }) { if(exists $self->{message_history}->{$mask}->{nickserv_account}) { @@ -480,13 +483,11 @@ sub check_nickserv_accounts { $self->{pbot}->logger->log("anti-flood: [check-bans] $mask evaded $baninfo->{banmask} in $baninfo->{channel}, but allowed through whitelist\n"); next; } else { - $self->{pbot}->logger->log("anti-flood: [check-bans] $mask evaded $baninfo->{banmask} banned in $baninfo->{channel} by $baninfo->{owner}\n"); - push @banned_channels, $baninfo->{channel}; - $self->{pbot}->conn->privmsg($nick, "You have been banned in $baninfo->{channel} for attempting to evade a ban on $baninfo->{banmask} set by $baninfo->{owner}"); + push @bans, $baninfo; } } } - } + } else { # no nickserv account set yet if($mask =~ m/^\Q$nick\E!/i) { @@ -494,19 +495,32 @@ sub check_nickserv_accounts { $self->{pbot}->logger->log("anti-flood: $mask: setting nickserv account to [$account]\n"); $self->message_history->{$mask}->{nickserv_account} = $account; - push @account_masks, $mask; + $account_mask = $mask; + + my $baninfo = $self->{pbot}->bantracker->get_baninfo($mask); + + if(defined $baninfo) { + if($self->ban_whitelisted($baninfo->{channel}, $baninfo->{banmask})) { + $self->{pbot}->logger->log("anti-flood: [check-bans] $mask evaded $baninfo->{banmask} in $baninfo->{channel}, but allowed through whitelist\n"); + next; + } else { + push @bans, $baninfo; + } + } } } } - foreach my $banned_channel (@banned_channels) { - foreach my $account_mask (@account_masks) { - $account_mask =~ m/[^@]+\@(.*)/; - my $banmask = "*!*\@$1"; + foreach my $baninfo (@bans) { + $self->{pbot}->logger->log("anti-flood: [check-bans] $account_mask evaded $baninfo->{banmask} banned in $baninfo->{channel} by $baninfo->{owner}\n"); + $self->{pbot}->conn->privmsg($nick, "You have been banned in $baninfo->{channel} for attempting to evade a ban on $baninfo->{banmask} set by $baninfo->{owner}"); - $self->{pbot}->logger->log("anti-flood: [check-bans] Ban detected on account $account in $banned_channel, banning $banmask.\n"); - $self->{pbot}->chanops->ban_user_timed($banmask, $banned_channel, 60 * 60 * 5); - } + $account_mask =~ m/[^!]+\!(.*)/; + my $banmask = "*!$1"; + + $self->{pbot}->logger->log("anti-flood: [check-bans] Ban detected on account $account in $baninfo->{channel}, banning $banmask.\n"); + + $self->{pbot}->chanops->ban_user_timed($banmask, $baninfo->{channel}, 60 * 60 * 5); } } diff --git a/PBot/BanTracker.pm b/PBot/BanTracker.pm index a83ad2a2..ab4856db 100644 --- a/PBot/BanTracker.pm +++ b/PBot/BanTracker.pm @@ -77,7 +77,14 @@ sub get_baninfo { $baninfo->{channel} = $channel; $baninfo->{owner} = $self->{banlist}{$channel}{$banmask_key}[0]; $baninfo->{when} = $self->{banlist}{$channel}{$banmask_key}[1]; + $baninfo->{type} = $self->{banlist}{$channel}{$banmask_key}[2]; $self->{pbot}->logger->log("get-baninfo: dump: " . Dumper($baninfo) . "\n"); + + if($baninfo->{type} eq '+b' and $banmask_key =~ m/!\*@\*$/) { + $self->{pbot}->logger->log("get-baninfo: Disregarding generic nick ban\n"); + return undef; + } + return $baninfo; } } @@ -96,7 +103,7 @@ sub on_quietlist_entry { my $ago = ago(gettimeofday - $timestamp); $self->{pbot}->logger->log("ban-tracker: [quietlist entry] $channel: $target quieted by $source $ago.\n"); - $self->{banlist}->{$channel}->{$target} = [ $source, $timestamp ]; + $self->{banlist}->{$channel}->{$target} = [ $source, $timestamp, '+q' ]; } sub on_banlist_entry { @@ -109,7 +116,7 @@ sub on_banlist_entry { my $ago = ago(gettimeofday - $timestamp); $self->{pbot}->logger->log("ban-tracker: [banlist entry] $channel: $target banned by $source $ago.\n"); - $self->{banlist}->{$channel}->{$target} = [ $source, $timestamp ]; + $self->{banlist}->{$channel}->{$target} = [ $source, $timestamp, '+b' ]; } sub track_mode { @@ -117,11 +124,11 @@ sub track_mode { my ($source, $mode, $target, $channel) = @_; if($mode eq "+b" or $mode eq "+q") { - $self->{pbot}->logger->log("ban-tracker: $target banned by $source in $channel.\n"); - $self->{banlist}->{$channel}->{$target} = [ $source, gettimeofday ]; + $self->{pbot}->logger->log("ban-tracker: $target " . ($mode eq '+b' ? 'banned' : 'quieted') . " by $source in $channel.\n"); + $self->{banlist}->{$channel}->{$target} = [ $source, gettimeofday, $mode ]; } elsif($mode eq "-b" or $mode eq "-q") { - $self->{pbot}->logger->log("ban-tracker: $target unbanned by $source in $channel.\n"); + $self->{pbot}->logger->log("ban-tracker: $target " . ($mode eq '-b' ? 'unbanned' : 'unquieted') . " by $source in $channel.\n"); delete $self->{banlist}->{$channel}->{$target}; } else { $self->{pbot}->logger->log("BanTracker: Unknown mode '$mode'\n"); diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index 60ed5984..573bdfee 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -13,7 +13,7 @@ use warnings; # These are set automatically by the build/commit script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 339, + BUILD_REVISION => 340, BUILD_DATE => "2011-12-14", };