Improve handling of nick-change flood

This commit is contained in:
Pragmatic Software 2015-03-11 02:00:10 -07:00
parent 9ec50d8f5d
commit 7970018777
2 changed files with 161 additions and 170 deletions

View File

@ -196,7 +196,6 @@ sub check_flood {
$mask = "$newnick!$user\@$host"; $mask = "$newnick!$user\@$host";
$account = $self->{pbot}->{messagehistory}->get_message_account($newnick, $user, $host); $account = $self->{pbot}->{messagehistory}->get_message_account($newnick, $user, $host);
$nick = $newnick; $nick = $newnick;
$self->{nickflood}->{$account}->{changes}++; $self->{nickflood}->{$account}->{changes}++;
} }
} else { } else {
@ -218,29 +217,26 @@ sub check_flood {
return; return;
} }
my $channels;
if($mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}) { if($mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}) {
my @channels = $self->{pbot}->{messagehistory}->{database}->get_channels($account); $channels = $self->{pbot}->{nicklist}->get_channels($nick);
return if not @channels;
$channel = undef;
foreach my $chan (@channels) {
if($chan =~ m/^#/) {
$channel = $chan;
last;
}
}
return if not defined $channel;
} else { } else {
$self->check_join_watch($account, $channel, $text, $mode); $self->check_join_watch($account, $channel, $text, $mode);
push @$channels, $channel;
} }
# do not do flood processing for bot messages # do not do flood processing for bot messages
if($nick eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) { if($nick eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) {
foreach my $channel (@$channels) {
$self->{channels}->{$channel}->{last_spoken_nick} = $nick; $self->{channels}->{$channel}->{last_spoken_nick} = $nick;
}
return; return;
} }
foreach my $channel (@$channels) {
# do not do flood processing if channel is not in bot's channel list or bot is not set as chanop for the channel # do not do flood processing if channel is not in bot's channel list or bot is not set as chanop for the channel
return if ($channel =~ /^#/) and (not exists $self->{pbot}->{channels}->{channels}->hash->{$channel} or $self->{pbot}->{channels}->{channels}->hash->{$channel}{chanop} == 0); next if ($channel =~ /^#/) and (not exists $self->{pbot}->{channels}->{channels}->hash->{$channel} or $self->{pbot}->{channels}->{channels}->hash->{$channel}{chanop} == 0);
if($channel =~ /^#/ and $mode == $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}) { if($channel =~ /^#/ and $mode == $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}) {
# remove validation on PART or KICK so we check for ban-evasion when user returns at a later time # remove validation on PART or KICK so we check for ban-evasion when user returns at a later time
@ -249,6 +245,7 @@ sub check_flood {
$channel_data->{validated} &= ~$self->{NICKSERV_VALIDATED}; $channel_data->{validated} &= ~$self->{NICKSERV_VALIDATED};
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data); $self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
} }
next;
} }
if($max_messages > $self->{pbot}->{registry}->get_value('messagehistory', 'max_messages')) { if($max_messages > $self->{pbot}->{registry}->get_value('messagehistory', 'max_messages')) {
@ -275,7 +272,7 @@ sub check_flood {
} }
# do not do flood enforcement for logged in bot admins # do not do flood enforcement for logged in bot admins
return if $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host"); next if $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host");
# check for enter abuse # check for enter abuse
if($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT} and $channel =~ m/^#/) { if($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT} and $channel =~ m/^#/) {
@ -342,7 +339,7 @@ sub check_flood {
} }
elsif($mode == $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}) { elsif($mode == $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}) {
# no flood checks to be done for departure events # no flood checks to be done for departure events
return; next;
} }
else { else {
$self->{pbot}->{logger}->log("Unknown flood mode [$mode] ... aborting flood enforcement.\n"); $self->{pbot}->{logger}->log("Unknown flood mode [$mode] ... aborting flood enforcement.\n");
@ -378,7 +375,7 @@ sub check_flood {
} elsif($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT}) { } elsif($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT}) {
if($channel =~ /^#/) { #channel flood (opposed to private message or otherwise) if($channel =~ /^#/) { #channel flood (opposed to private message or otherwise)
# don't increment offenses again if already banned # don't increment offenses again if already banned
return if $self->{pbot}->{chanops}->{unban_timeout}->find_index($channel, "*!$user\@$host"); next if $self->{pbot}->{chanops}->{unban_timeout}->find_index($channel, "*!$user\@$host");
my $channel_data = $self->{pbot}->{messagehistory}->{database}->get_channel_data($account, $channel, 'offenses', 'last_offense'); my $channel_data = $self->{pbot}->{messagehistory}->{database}->get_channel_data($account, $channel, 'offenses', 'last_offense');
$channel_data->{offenses}++; $channel_data->{offenses}++;
@ -396,7 +393,7 @@ sub check_flood {
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data); $self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
} }
else { # private message flood else { # private message flood
return if exists ${ $self->{pbot}->{ignorelist}->{ignore_list} }{"$nick!$user\@$host"}{$channel}; next if exists ${ $self->{pbot}->{ignorelist}->{ignore_list} }{"$nick!$user\@$host"}{$channel};
my $channel_data = $self->{pbot}->{messagehistory}->{database}->get_channel_data($account, $channel, 'offenses', 'last_offense'); my $channel_data = $self->{pbot}->{messagehistory}->{database}->get_channel_data($account, $channel, 'offenses', 'last_offense');
$channel_data->{offenses}++; $channel_data->{offenses}++;
@ -419,14 +416,7 @@ sub check_flood {
if($self->{pbot}->{registry}->get_value('antiflood', 'enforce')) { if($self->{pbot}->{registry}->get_value('antiflood', 'enforce')) {
my $length = $self->{pbot}->{registry}->get_array_value('antiflood', 'nick_flood_punishment', $self->{nickflood}->{$account}->{offenses} - 1); my $length = $self->{pbot}->{registry}->get_array_value('antiflood', 'nick_flood_punishment', $self->{nickflood}->{$account}->{offenses} - 1);
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$host", $channel, $length);
my $channels = $self->{pbot}->{nicklist}->get_channels($oldnick);
foreach my $chan (@$channels) {
next if $chan !~ /^#/;
next if not exists $self->{pbot}->{channels}->{channels}->hash->{$chan} or $self->{pbot}->{channels}->{channels}->hash->{$chan}{chanop} == 0;
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$host", $chan, $length);
}
$length = duration($length); $length = duration($length);
$self->{pbot}->{logger}->log("$nick nickchange flood offense " . $self->{nickflood}->{$account}->{offenses} . " earned $length ban\n"); $self->{pbot}->{logger}->log("$nick nickchange flood offense " . $self->{nickflood}->{$account}->{offenses} . " earned $length ban\n");
$self->{pbot}->{conn}->privmsg($nick, "You have been temporarily banned due to nick-change flooding. You will be unbanned in $length."); $self->{pbot}->{conn}->privmsg($nick, "You have been temporarily banned due to nick-change flooding. You will be unbanned in $length.");
@ -434,6 +424,7 @@ sub check_flood {
} }
} }
} }
}
} }
sub unbanme { sub unbanme {
@ -762,13 +753,13 @@ sub adjust_offenses {
my $last_offense = delete $channel_data->{last_offense}; my $last_offense = delete $channel_data->{last_offense};
if(gettimeofday - $last_offense >= 60 * 60 * 24) { if(gettimeofday - $last_offense >= 60 * 60 * 24) {
$channel_data->{enter_abuses}--; $channel_data->{enter_abuses}--;
$self->{pbot}->{logger}->log("[adjust-offenses] [$id][$channel] decreasing enter abuse offenses to $channel_data->{enter_abuses}\n"); #$self->{pbot}->{logger}->log("[adjust-offenses] [$id][$channel] decreasing enter abuse offenses to $channel_data->{enter_abuses}\n");
$self->{pbot}->{messagehistory}->{database}->update_channel_data($id, $channel, $channel_data); $self->{pbot}->{messagehistory}->{database}->update_channel_data($id, $channel, $channel_data);
} }
} }
foreach my $account (keys %{ $self->{nickflood} }) { foreach my $account (keys %{ $self->{nickflood} }) {
if($self->{nickflood}->{$account}->{offenses} and gettimeofday - $self->{nickflood}->{$account}->{timestamp} >= 60 * 60 * 48) { if($self->{nickflood}->{$account}->{offenses} and gettimeofday - $self->{nickflood}->{$account}->{timestamp} >= 60 * 60 * 24) {
$self->{nickflood}->{$account}->{offenses}--; $self->{nickflood}->{$account}->{offenses}--;
if($self->{nickflood}->{$account}->{offenses} == 0) { if($self->{nickflood}->{$account}->{offenses} == 0) {

View File

@ -308,7 +308,7 @@ sub on_nickchange {
my $message_account = $self->{pbot}->{messagehistory}->{database}->get_message_account($nick, $user, $host); my $message_account = $self->{pbot}->{messagehistory}->{database}->get_message_account($nick, $user, $host);
$self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($message_account, $self->{pbot}->{antiflood}->{NEEDS_CHECKBAN}); $self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($message_account, $self->{pbot}->{antiflood}->{NEEDS_CHECKBAN});
my $channels = $self->{pbot}->{nicklist}->get_channels($nick); my $channels = $self->{pbot}->{nicklist}->get_channels($newnick);
foreach my $channel (@$channels) { foreach my $channel (@$channels) {
next if $channel !~ m/^#/; next if $channel !~ m/^#/;
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, "NICKCHANGE $newnick", $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}); $self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, "NICKCHANGE $newnick", $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});