anti-flood: Improve linking of accounts

This commit is contained in:
Pragmatic Software 2014-03-10 06:28:56 +00:00
parent e808286f24
commit bd3fa4dee3
3 changed files with 45 additions and 25 deletions

View File

@ -136,17 +136,22 @@ sub get_flood_account {
return "$nick!$user\@$host" if exists $self->message_history->{"$nick!$user\@$host"}; return "$nick!$user\@$host" if exists $self->message_history->{"$nick!$user\@$host"};
my $found_link;
foreach my $mask (keys %{ $self->message_history }) { foreach my $mask (keys %{ $self->message_history }) {
# check if foo!bar@baz matches foo!*@*; e.g., same nick, but possibly different user@host # check if foo!bar@baz matches foo!*@*; e.g., same nick, but possibly different user@host
# (usually logging into nickserv or a dynamic ip address, but could possibly be attempted nick hijacking) # (usually logging into nickserv or a dynamic ip address, but could possibly be attempted nick hijacking)
if($mask =~ m/^\Q$nick\E!.*/i) { if($mask =~ m/^\Q$nick\E!.*/i) {
#$self->{pbot}->logger->log("anti-flood: [get-account] $nick!$user\@$host seen previously as $mask\n"); #$self->{pbot}->logger->log("anti-flood: [get-account] $nick!$user\@$host seen previously as $mask\n");
$found_link = 1;
} }
# check if foo!bar@baz matches *!bar@baz; e.g., same user@host, but different nick # check if foo!bar@baz matches *!bar@baz; e.g., same user@host, but different nick
# (usually alternate-nicks due to rejoining) # (usually alternate-nicks due to rejoining)
if($mask =~ m/!\Q$user\E@\Q$host\E$/i) { if($mask =~ m/!\Q$user\E@\Q$host\E$/i) {
$found_link = 1;
}
if($found_link) {
$self->{pbot}->logger->log("anti-flood: [get-account] $nick!$user\@$host linked to $mask\n"); $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->{message_history}->{"$nick!$user\@$host"} = $self->{message_history}->{$mask};
@ -156,7 +161,7 @@ sub get_flood_account {
if(exists $self->{message_history}->{$mask}->{nickserv_accounts}) { if(exists $self->{message_history}->{$mask}->{nickserv_accounts}) {
foreach my $nickserv_account (keys $self->{message_history}->{$mask}->{nickserv_accounts}) { foreach my $nickserv_account (keys $self->{message_history}->{$mask}->{nickserv_accounts}) {
$self->check_nickserv_accounts($nick, $nickserv_account); $self->check_nickserv_accounts($nick, $nickserv_account, "$nick!$user\@$host");
} }
} }
@ -444,7 +449,7 @@ sub unbanme {
if(exists $self->{message_history}->{"$nick!$user\@$host"}->{nickserv_accounts}) { if(exists $self->{message_history}->{"$nick!$user\@$host"}->{nickserv_accounts}) {
$nickserv_accounts = $self->{message_history}->{"$nick!$user\@$host"}->{nickserv_accounts}; $nickserv_accounts = $self->{message_history}->{"$nick!$user\@$host"}->{nickserv_accounts};
} else { } else {
$nickserv_accounts->{0} = 0; $nickserv_accounts->{-1} = undef;
} }
foreach my $nickserv_account (keys $nickserv_accounts) { foreach my $nickserv_account (keys $nickserv_accounts) {
@ -603,7 +608,7 @@ sub check_bans {
CHECKBAN: CHECKBAN:
if($check_ban) { if($check_ban) {
if(not defined $target_nickserv_accounts) { if(not defined $target_nickserv_accounts) {
$target_nickserv_accounts->{0} = 0; $target_nickserv_accounts->{-1} = undef;
} }
foreach my $target_nickserv_account (keys $target_nickserv_accounts) { foreach my $target_nickserv_account (keys $target_nickserv_accounts) {
@ -680,32 +685,46 @@ sub check_bans {
} }
sub check_nickserv_accounts { sub check_nickserv_accounts {
my ($self, $nick, $account) = @_; my ($self, $nick, $account, $hostmask) = @_;
my $force_validation = 0;
$account = lc $account; $account = lc $account;
foreach my $mask (keys %{ $self->{message_history} }) { if(not defined $hostmask) {
if(exists $self->{message_history}->{$mask}->{nickserv_accounts} and exists $self->{message_history}->{$mask}->{nickserv_accounts}->{$account}) { foreach my $mask (keys %{ $self->{message_history} }) {
# pre-existing mask found using this account previously if(exists $self->{message_history}->{$mask}->{nickserv_accounts} and exists $self->{message_history}->{$mask}->{nickserv_accounts}->{$account}) {
#$self->{pbot}->logger->log("anti-flood: [check-account] $nick [nickserv: $account] seen previously as $mask.\n"); # pre-existing mask found using this account previously
} #$self->{pbot}->logger->log("anti-flood: [check-account] $nick [nickserv: $account] seen previously as $mask.\n");
else { }
# no nickserv account set yet else {
if($mask =~ m/^\Q$nick\E!/i) { # no nickserv account set yet
# nick matches, must belong to account if($mask =~ m/^\Q$nick\E!/i) {
$self->{pbot}->logger->log("anti-flood: $mask: setting nickserv account to [$account]\n"); # nick matches, must belong to account
$self->message_history->{$mask}->{nickserv_accounts}->{$account} = gettimeofday; $hostmask = $mask;
$self->message_history->{$mask}->{nickserv_account} = $account; last;
# check to see if any channels need check-ban validation
foreach my $channel (keys %{ $self->message_history->{$mask}->{channels} }) {
if(exists $self->message_history->{$mask}->{channels}{$channel}->{needs_validation}) {
# $self->{pbot}->logger->log("anti-flood: [check-account] $nick [nickserv: $account] needs check-ban validation for $mask in $channel.\n");
$self->check_bans($mask, $channel);
}
} }
} }
} }
} else {
$force_validation = 1;
}
if(not defined $hostmask) {
# could not find mask for nick/account
$self->{pbot}->logger->log("anti-flood: [check-account] could not find mask for $nick [nickserv: $account]\n");
return;
}
$self->{pbot}->logger->log("anti-flood: $hostmask: setting nickserv account to [$account]\n");
$self->{message_history}->{$hostmask}->{nickserv_accounts}->{$account} = gettimeofday;
$self->{message_history}->{$hostmask}->{nickserv_account} = $account;
# check to see if any channels need check-ban validation
foreach my $channel (keys %{ $self->message_history->{$hostmask}->{channels} }) {
if($force_validation or exists $self->message_history->{$hostmask}->{channels}{$channel}->{needs_validation}) {
# $self->{pbot}->logger->log("anti-flood: [check-account] $nick [nickserv: $account] needs check-ban validation for $hostmask in $channel.\n");
$self->check_bans($hostmask, $channel);
}
} }
} }

View File

@ -64,6 +64,7 @@ sub get_baninfo {
my ($self, $mask, $channel, $account) = @_; my ($self, $mask, $channel, $account) = @_;
my ($bans, $ban_account); my ($bans, $ban_account);
$account = undef if $account == -1;
$account = lc $account if defined $account; $account = lc $account if defined $account;
$self->{pbot}->logger->log("[get-baninfo] Getting baninfo for $mask in $channel using account " . (defined $account ? $account : "[undefined]") . "\n"); $self->{pbot}->logger->log("[get-baninfo] Getting baninfo for $mask in $channel using account " . (defined $account ? $account : "[undefined]") . "\n");

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script # These are set automatically by the build/commit script
use constant { use constant {
BUILD_NAME => "PBot", BUILD_NAME => "PBot",
BUILD_REVISION => 517, BUILD_REVISION => 518,
BUILD_DATE => "2014-03-09", BUILD_DATE => "2014-03-09",
}; };