mirror of
https://github.com/pragma-/pbot.git
synced 2024-12-23 11:12:42 +01:00
Add weak/strong also-known-as linking
PBot will now use weak links if the ip address portion of a hostmask hasn't been seen in the last 48 hours in order to prevent false-positive linking of dynamic ip addresses. Weak links are excluded from ban-evasion logic. Weak links can be manually upgraded to strong links with the `akalink` command if a human confirms they are the same person through the `aka -w` command. Individuals with matching nicks or matching nickserv accounts, etc, will automatically be strongly linked, as usual.
This commit is contained in:
parent
6a6eff1150
commit
850c8a0525
@ -601,6 +601,11 @@ sub check_bans {
|
||||
foreach my $alias (keys %aliases) {
|
||||
next if $alias =~ /^Guest\d+(?:!.*)?$/;
|
||||
|
||||
if ($aliases{$alias}->{type} == $self->{messagehistory}->{alias_type}->{WEAK}) {
|
||||
$self->{pbot}->{logger}->log("anti-flood: [check-bans] skipping WEAK alias $alias in channel $channel\n") if $debug_checkban >= 2;
|
||||
next;
|
||||
}
|
||||
|
||||
$self->{pbot}->{logger}->log("anti-flood: [check-bans] checking blacklist for $alias in channel $channel\n") if $debug_checkban >= 5;
|
||||
if ($self->{pbot}->{blacklist}->check_blacklist($alias, $channel)) {
|
||||
my $baninfo = {};
|
||||
|
@ -74,10 +74,12 @@ sub rebuild_aliases {
|
||||
sub aka_link {
|
||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||
|
||||
my ($id, $alias) = split /\s+/, $arguments;
|
||||
my ($id, $alias, $type) = split /\s+/, $arguments;
|
||||
|
||||
$type = $self->{messagehistory}->{alias_type}->{STRONG} if not defined $type;
|
||||
|
||||
if (not $id or not $alias) {
|
||||
return "Usage: link <target id> <alias id>";
|
||||
return "Usage: link <target id> <alias id> [type]";
|
||||
}
|
||||
|
||||
my $source = $self->{database}->find_most_recent_hostmask($id);
|
||||
@ -91,8 +93,8 @@ sub aka_link {
|
||||
return "No such id $alias found.";
|
||||
}
|
||||
|
||||
if ($self->{database}->link_alias($id, $alias)) {
|
||||
return "$source linked to $target.";
|
||||
if ($self->{database}->link_alias($id, $alias, $type)) {
|
||||
return "$source " . ($type == $self->{messagehistory}->{alias_type}->{WEAK} ? "weakly" : "strongly") . " linked to $target.";
|
||||
} else {
|
||||
return "Link failed.";
|
||||
}
|
||||
@ -128,7 +130,7 @@ sub aka_unlink {
|
||||
sub list_also_known_as {
|
||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||
|
||||
my $usage = "Usage: aka [-h] [-i] [-n] [-r] <nick>; -h show hostmasks; -i show ids; -n show nickserv accounts; -r show relationships";
|
||||
my $usage = "Usage: aka [-h] [-i] [-n] [-r] [-w] <nick>; -h show hostmasks; -i show ids; -n show nickserv accounts; -r show relationships; -w show weak links";
|
||||
|
||||
if(not length $arguments) {
|
||||
return $usage;
|
||||
@ -140,11 +142,12 @@ sub list_also_known_as {
|
||||
chomp $getopt_error;
|
||||
};
|
||||
|
||||
my ($show_hostmasks, $show_nickserv, $show_id, $show_relationship, $dont_use_aliases_table);
|
||||
my ($show_hostmasks, $show_nickserv, $show_id, $show_relationship, $show_weak, $dont_use_aliases_table);
|
||||
my ($ret, $args) = GetOptionsFromString($arguments,
|
||||
'h' => \$show_hostmasks,
|
||||
'n' => \$show_nickserv,
|
||||
'r' => \$show_relationship,
|
||||
'w' => \$show_weak,
|
||||
'nt' => \$dont_use_aliases_table,
|
||||
'i' => \$show_id);
|
||||
|
||||
@ -161,6 +164,7 @@ sub list_also_known_as {
|
||||
my $sep = "";
|
||||
foreach my $aka (sort keys %akas) {
|
||||
next if $aka =~ /^Guest\d+(?:!.*)?$/;
|
||||
next if $akas{$aka}->{type} == $self->{messagehistory}->{alias_type}->{WEAK} && not $show_weak;
|
||||
|
||||
if (not $show_hostmasks) {
|
||||
my ($nick) = $aka =~ m/([^!]+)/;
|
||||
@ -182,6 +186,8 @@ sub list_also_known_as {
|
||||
$result .= " [$akas{$aka}->{id}]";
|
||||
}
|
||||
|
||||
$result .= " [WEAK]" if $akas{$aka}->{type} == $self->{messagehistory}->{alias_type}->{WEAK};
|
||||
|
||||
if ($show_hostmasks or $show_nickserv or $show_id or $show_relationship) {
|
||||
$sep = ",\n";
|
||||
} else {
|
||||
|
@ -44,6 +44,9 @@ sub initialize {
|
||||
$self->{pbot}->{registry}->get_value('messagehistory', 'sqlite_commit_interval'),
|
||||
'messagehistory_sqlite_commit_interval'
|
||||
);
|
||||
|
||||
$self->{alias_type}->{WEAK} = 0;
|
||||
$self->{alias_type}->{STRONG} = 1;
|
||||
}
|
||||
|
||||
sub sqlite_commit_interval_trigger {
|
||||
@ -122,13 +125,14 @@ SQL
|
||||
$self->{dbh}->do(<<SQL);
|
||||
CREATE TABLE IF NOT EXISTS Aliases (
|
||||
id INTEGER,
|
||||
alias INTEGER
|
||||
alias INTEGER,
|
||||
type INTEGER
|
||||
)
|
||||
SQL
|
||||
|
||||
$self->{dbh}->do('CREATE INDEX IF NOT EXISTS MsgIdx1 ON Messages(id, channel, mode)');
|
||||
$self->{dbh}->do('CREATE INDEX IF NOT EXISTS AliasIdx1 ON Aliases(id, alias)');
|
||||
$self->{dbh}->do('CREATE INDEX IF NOT EXISTS AliasIdx2 ON Aliases(alias, id)');
|
||||
$self->{dbh}->do('CREATE INDEX IF NOT EXISTS AliasIdx1 ON Aliases(id, alias, type)');
|
||||
$self->{dbh}->do('CREATE INDEX IF NOT EXISTS AliasIdx2 ON Aliases(alias, id, type)');
|
||||
|
||||
$self->{dbh}->begin_work();
|
||||
};
|
||||
@ -826,6 +830,24 @@ sub link_aliases {
|
||||
my %ids;
|
||||
|
||||
if ($hostmask) {
|
||||
my ($host) = $hostmask =~ /(\@.*)$/;
|
||||
my $sth = $self->{dbh}->prepare('SELECT id, last_seen FROM Hostmasks WHERE hostmask LIKE ?');
|
||||
$sth->bind_param(1, "\%$host");
|
||||
$sth->execute();
|
||||
my $rows = $sth->fetchall_arrayref({});
|
||||
|
||||
my $now = gettimeofday;
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
if ($now - $row->{last_seen} <= 60 * 60 * 48) {
|
||||
$ids{$row->{id}} = { id => $row->{id}, type => $self->{alias_type}->{STRONG} };
|
||||
$self->{pbot}->{logger}->log("found STRONG matching id $row->{id} for host [$host]\n") if $debug_link;
|
||||
} else {
|
||||
$ids{$row->{id}} = { id => $row->{id}, type => $self->{alias_type}->{WEAK} };
|
||||
$self->{pbot}->{logger}->log("found WEAK matching id $row->{id} for host [$host]\n") if $debug_link;
|
||||
}
|
||||
}
|
||||
|
||||
my ($nick) = $hostmask =~ m/([^!]+)/;
|
||||
unless ($nick =~ m/^Guest\d+$/) {
|
||||
my $qnick = quotemeta $nick;
|
||||
@ -837,21 +859,10 @@ sub link_aliases {
|
||||
my $rows = $sth->fetchall_arrayref({});
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
$ids{$row->{id}} = $row->{id};
|
||||
$self->{pbot}->{logger}->log("found matching id $row->{id} for nick [$qnick]\n") if $debug_link;
|
||||
$ids{$row->{id}} = { id => $row->{id}, type => $self->{alias_type}->{STRONG} };
|
||||
$self->{pbot}->{logger}->log("found STRONG matching id $row->{id} for nick [$qnick]\n") if $debug_link;
|
||||
}
|
||||
}
|
||||
|
||||
my ($host) = $hostmask =~ /(\@.*)$/;
|
||||
my $sth = $self->{dbh}->prepare('SELECT id FROM Hostmasks WHERE hostmask LIKE ?');
|
||||
$sth->bind_param(1, "\%$host");
|
||||
$sth->execute();
|
||||
my $rows = $sth->fetchall_arrayref({});
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
$ids{$row->{id}} = $row->{id};
|
||||
$self->{pbot}->{logger}->log("found matching id $row->{id} for host [$host]\n") if $debug_link;
|
||||
}
|
||||
}
|
||||
|
||||
if ($nickserv) {
|
||||
@ -861,22 +872,30 @@ sub link_aliases {
|
||||
my $rows = $sth->fetchall_arrayref({});
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
$ids{$row->{id}} = $row->{id};
|
||||
$self->{pbot}->{logger}->log("found matching id $row->{id} for nickserv [$nickserv]\n") if $debug_link;
|
||||
$ids{$row->{id}} = { id => $row->{id}, type => $self->{alias_type}->{STRONG} };
|
||||
$self->{pbot}->{logger}->log("found STRONG matching id $row->{id} for nickserv [$nickserv]\n") if $debug_link;
|
||||
}
|
||||
}
|
||||
|
||||
my $sth = $self->{dbh}->prepare('INSERT INTO Aliases SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM Aliases WHERE id = ? AND alias = ?)');
|
||||
$sth->bind_param(1, $account);
|
||||
$sth->bind_param(3, $account);
|
||||
my $sth = $self->{dbh}->prepare('REPLACE INTO Aliases (id, alias, type) VALUES (?, ?, ?)');
|
||||
|
||||
foreach my $id (sort keys %ids) {
|
||||
next if $account == $id;
|
||||
$sth->bind_param(1, $account);
|
||||
$sth->bind_param(2, $id);
|
||||
$sth->bind_param(4, $id);
|
||||
$sth->bind_param(3, $ids{$id}->{type});
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{pbot}->{logger}->log("Linked $account to $id\n") if $debug_link;
|
||||
$self->{pbot}->{logger}->log("Linked $account to $id [$ids{$id}->{type}]\n") if $debug_link;
|
||||
$self->{new_entries}++;
|
||||
}
|
||||
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->bind_param(2, $account);
|
||||
$sth->bind_param(3, $ids{$id}->{type});
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{pbot}->{logger}->log("Linked $id to $account [$ids{$id}->{type}]\n") if $debug_link;
|
||||
$self->{new_entries}++;
|
||||
}
|
||||
}
|
||||
@ -885,31 +904,55 @@ sub link_aliases {
|
||||
}
|
||||
|
||||
sub link_alias {
|
||||
my ($self, $id, $alias) = @_;
|
||||
my ($self, $id, $alias, $type) = @_;
|
||||
|
||||
my $ret = eval {
|
||||
my $ret = 0;
|
||||
my $sth = $self->{dbh}->prepare('INSERT INTO Aliases SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM Aliases WHERE id = ? AND alias = ?)');
|
||||
|
||||
my $sth = $self->{dbh}->prepare('INSERT INTO Aliases SELECT ?, ?, ? WHERE NOT EXISTS (SELECT 1 FROM Aliases WHERE id = ? AND alias = ?)');
|
||||
$sth->bind_param(1, $alias);
|
||||
$sth->bind_param(2, $id);
|
||||
$sth->bind_param(3, $alias);
|
||||
$sth->bind_param(4, $id);
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{new_entries}++;
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->bind_param(2, $alias);
|
||||
$sth->bind_param(3, $id);
|
||||
$sth->bind_param(3, $type);
|
||||
$sth->bind_param(4, $alias);
|
||||
$sth->bind_param(5, $id);
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{new_entries}++;
|
||||
$ret = 1;
|
||||
} else {
|
||||
$ret = 0;
|
||||
$sth = $self->{dbh}->prepare('UPDATE Aliases SET type = ? WHERE id = ? AND alias = ?');
|
||||
$sth->bind_param(1, $type);
|
||||
$sth->bind_param(2, $id);
|
||||
$sth->bind_param(3, $alias);
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{new_entries}++;
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$sth = $self->{dbh}->prepare('INSERT INTO Aliases SELECT ?, ?, ? WHERE NOT EXISTS (SELECT 1 FROM Aliases WHERE id = ? AND alias = ?)');
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->bind_param(2, $alias);
|
||||
$sth->bind_param(3, $type);
|
||||
$sth->bind_param(4, $id);
|
||||
$sth->bind_param(5, $alias);
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{new_entries}++;
|
||||
$ret = 1;
|
||||
} else {
|
||||
$sth = $self->{dbh}->prepare('UPDATE Aliases SET type = ? WHERE id = ? AND alias = ?');
|
||||
$sth->bind_param(1, $type);
|
||||
$sth->bind_param(2, $alias);
|
||||
$sth->bind_param(3, $id);
|
||||
$sth->execute();
|
||||
if ($sth->rows) {
|
||||
$self->{new_entries}++;
|
||||
$ret = 1;
|
||||
} else {
|
||||
$ret = 0;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
};
|
||||
@ -1008,22 +1051,22 @@ sub get_also_known_as {
|
||||
return %akas;
|
||||
}
|
||||
|
||||
$ids{$id} = $id;
|
||||
$ids{$id} = { id => $id, type => $self->{alias_type}->{STRONG} };
|
||||
$self->{pbot}->{logger}->log("Adding $id -> $id\n") if $debug;
|
||||
|
||||
|
||||
my $sth = $self->{dbh}->prepare('SELECT alias FROM Aliases WHERE id = ?');
|
||||
my $sth = $self->{dbh}->prepare('SELECT alias, type FROM Aliases WHERE id = ?');
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->execute();
|
||||
my $rows = $sth->fetchall_arrayref({});
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
$ids{$row->{alias}} = $id;
|
||||
$self->{pbot}->{logger}->log("[$id] Adding $row->{alias} -> $id\n") if $debug;
|
||||
$ids{$row->{alias}} = { id => $id, type => $row->{type} };
|
||||
$self->{pbot}->{logger}->log("[$id] Adding $row->{alias} -> $id [type $row->{type}]\n") if $debug;
|
||||
}
|
||||
|
||||
my %seen_id;
|
||||
$sth = $self->{dbh}->prepare('SELECT id FROM Aliases WHERE alias = ?');
|
||||
$sth = $self->{dbh}->prepare('SELECT id, type FROM Aliases WHERE alias = ?');
|
||||
|
||||
while (1) {
|
||||
my $new_aliases = 0;
|
||||
@ -1037,9 +1080,9 @@ sub get_also_known_as {
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
next if exists $ids{$row->{id}};
|
||||
$ids{$row->{id}} = $id;
|
||||
$ids{$row->{id}} = { id => $id, type => $row->{type} };
|
||||
$new_aliases++;
|
||||
$self->{pbot}->{logger}->log("[$id] Adding $row->{id} -> $id\n") if $debug;
|
||||
$self->{pbot}->{logger}->log("[$id] Adding $row->{id} -> $id [type $row->{type}]\n") if $debug;
|
||||
}
|
||||
}
|
||||
last if not $new_aliases;
|
||||
@ -1054,8 +1097,8 @@ sub get_also_known_as {
|
||||
$rows = $hostmask_sth->fetchall_arrayref({});
|
||||
|
||||
foreach my $row (@$rows) {
|
||||
$akas{$row->{hostmask}} = { hostmask => $row->{hostmask}, id => $id, alias => $ids{$id} };
|
||||
$self->{pbot}->{logger}->log("[$id] Adding hostmask $row->{hostmask} -> $ids{$id}\n") if $debug;
|
||||
$akas{$row->{hostmask}} = { hostmask => $row->{hostmask}, id => $id, alias => $ids{$id}->{id}, type => $ids{$id}->{type} };
|
||||
$self->{pbot}->{logger}->log("[$id] Adding hostmask $row->{hostmask} -> $ids{$id}->{id} [type $ids{$id}->{type}]\n") if $debug;
|
||||
}
|
||||
|
||||
$nickserv_sth->bind_param(1, $id);
|
||||
|
Loading…
Reference in New Issue
Block a user