summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarWilliam Heimbigner <william.heimbigner@gmail.com>2007-06-28 21:13:35 +0000
committerLibravatarWilliam Heimbigner <william.heimbigner@gmail.com>2007-06-28 21:13:35 +0000
commit7ea23cad4c72904b02ad5c359f5edfab8328268d (patch)
treea0973bfe2aaa8d4d7c0e35c09f2466ed9410e56a
parentd944892a0c4d04c056a8697fc0aee54b5b01ff88 (diff)
memleak fix, better nick tracking, new commands, major security exploit fix
-rw-r--r--config-default/commands.xml31
-rw-r--r--config-default/users.xml19
-rwxr-xr-xmeta.pl1
-rw-r--r--modules/command.pl5
-rw-r--r--modules/event.pl67
-rw-r--r--modules/xml.pl31
6 files changed, 126 insertions, 28 deletions
diff --git a/config-default/commands.xml b/config-default/commands.xml
index 77ee1c7..9aee415 100644
--- a/config-default/commands.xml
+++ b/config-default/commands.xml
@@ -7,6 +7,15 @@
$conn->privmsg($event->{to}->[0], "$result results found.");
]]>
</command>
+ <command cmd="^;autoban (\S+)$" flag="a">
+ <![CDATA[
+ my $chan = $1;
+ my $set = $::channels->{channel}->{$chan}->{op};
+ if ($set eq "no") { $set = "when"; } else { $set = "no"; }
+ $::channels->{channel}->{$chan}->{op} = $set;
+ $conn->privmsg($event->{to}->[0], "Operator action for $chan set to \"$set\".");
+ ]]>
+ </command>
<command cmd="^;hilight (\S+) (\S+) ?(\S*)$" flag="a">
<![CDATA[
my $chan = $1;
@@ -33,14 +42,28 @@
$conn->privmsg($event->{to}->[0], "kthxbai $nick");
]]>
</command>
- <command cmd="^;join (.*)" flag="a">
+ <command cmd="^;join (\S+)" flag="a">
<![CDATA[
- $conn->join($1);
+ my $chan = $1;
+ unless (defined($::channels->{channel}->{$chan})) {
+ $::channels->{channel}->{$chan} = { 'op' => 'no' };
+ writeChannels();
+ }
+ $conn->join($chan);
+ my @autojoins = @{$::settings->{autojoins}};
+ @autojoins = (@autojoins, $chan);
+ $::settings->{autojoins} = \@autojoins;
+ writeSettings();
]]>
</command>
- <command cmd="^;part (.*)" flag="a">
+ <command cmd="^;part (\S+)" flag="a">
<![CDATA[
- $conn->part($1);
+ my $chan = $1;
+ $conn->part($chan);
+ my @autojoins = @{$::settings->{autojoins}};
+ @autojoins = grep { lc $_ ne lc $chan } @autojoins;
+ $::settings->{autojoins} = \@autojoins;
+ writeSettings();
]]>
</command>
<command cmd="^;sl (.*)" flag="d">
diff --git a/config-default/users.xml b/config-default/users.xml
index 555ac73..9bdfed3 100644
--- a/config-default/users.xml
+++ b/config-default/users.xml
@@ -1,12 +1,11 @@
<people>
- <person id="afterdeath" flags="oda" host="IDENTIFY" />
- <person id="filiated" flags="oda" host="IDENTIFY" />
- <person id="ocee" host="unaffiliated/ocee" />
- <person id="wildpikachu" host="about/linux/staff/wildpikachu" />
- <person id="slowking_man" host="IDENTIFY" flags="o" />
- <person id="cchan" host="IDENTIFY" flags="oda" />
- <person id="mark_ryan" host="wikimedia/mark" flags="o" />
- <person id="dmcdevit" host="IDENTIFY" flags="oa" />
- <person id="seanw" host="freenode/staff/wikimedia.sean-whitton" flags="oa" />
- <person id="st47" host="IDENTIFY" flags="oa" />
+ <person id="afterdeath" flags="odat" host="IDENTIFY" />
+ <person id="filiated" flags="odat" host="IDENTIFY" />
+ <person id="wildpikachu" host="about/linux/staff/wildpikachu" flags="odat" />
+ <person id="slowking_man" host="IDENTIFY" flags="ot" />
+ <person id="cchan" host="IDENTIFY" flags="odat" />
+ <person id="mark_ryan" host="wikimedia/mark" flags="ot" />
+ <person id="dmcdevit" host="IDENTIFY" flags="oat" />
+ <person id="seanw" host="freenode/staff/wikimedia.sean-whitton" flags="oat" />
+ <person id="st47" host="IDENTIFY" flags="oat" />
</people>
diff --git a/meta.pl b/meta.pl
index cf994dd..f0e3593 100755
--- a/meta.pl
+++ b/meta.pl
@@ -93,6 +93,7 @@ sub registerHandlers {
$conn->add_handler('320', \&whois_identified);
$conn->add_handler('318', \&whois_end);
$conn->add_handler('311', \&whois_user);
+ $conn->add_handler('352', \&on_whoreply);
}
init();
diff --git a/modules/command.pl b/modules/command.pl
index 87c768f..41d65fb 100644
--- a/modules/command.pl
+++ b/modules/command.pl
@@ -14,7 +14,7 @@ sub do_command
if (defined($command->{flag})) {
next unless defined($::xusers->{$nick});
next unless defined($::xusers->{$nick}->{flags});
- next unless defined(grep {$_ eq $command->{flag}} split('', $::xusers->{$nick}->{flags}));
+ next unless (grep {$_ eq $command->{flag}} split('', $::xusers->{$nick}->{flags}));
if ($::xusers->{$nick}->{host} ne 'IDENTIFY') {
next unless leq($::xusers->{$nick}->{host}, $event->{host});
}
@@ -22,7 +22,7 @@ sub do_command
if ( $cmd =~ /$command->{cmd}/ ){
push (@{$::idqueue{$nick}}, [$cmd, $command, $event]);
$conn->sl("whois $nick $nick");
- next;
+ last;
}
}
}
@@ -30,6 +30,7 @@ sub do_command
print "$event->{from} told me: $cmd \n";
eval $command->{content};
warn $@ if $@;
+ last;
}
}
}
diff --git a/modules/event.pl b/modules/event.pl
index dd04512..3754190 100644
--- a/modules/event.pl
+++ b/modules/event.pl
@@ -18,6 +18,7 @@ sub on_join {
my $chan = lc $event->{to}->[0];
if ( leq($conn->{_nick}, $nick) ) {
$::sc{$chan} = {};
+ $conn->sl("who $chan");
$conn->privmsg('ChanServ', "op $chan" ) if (defined cs($chan)->{op}) && (cs($chan)->{op} eq 'yes');
}
$::sc{$chan}{users}{$nick} = {};
@@ -25,8 +26,16 @@ sub on_join {
$::sc{$chan}{users}{$nick}{op} = 0;
$::sc{$chan}{users}{$nick}{voice} = 0;
if (defined($::sn{$nick})) {
+ my @mship = ();
+ if (defined($::sn{$nick}->{mship})) {
+ @mship = @{$::sn{$nick}->{mship}};
+ }
+ @mship = (@mship, $chan);
+ $::sn{$nick}->{mship} = \@mship;
inspect( $conn, $event );
} else {
+ $::sn{$nick} = {};
+ $::sn{$nick}->{mship} = [ $chan ];
if (defined($::needgeco{$nick})) {
$::needgeco{$nick} = [ @{$::needgeco{$nick}}, $evcopy ];
} else {
@@ -58,6 +67,15 @@ sub on_part
inspect( $conn, $event );
my $nick = lc $event->{nick};
logg( $event );
+ if (defined($::sn{$nick}) && defined($::sn{$nick}->{mship})) {
+ my @mship = @{$::sn{$nick}->{mship}};
+ @mship = grep { lc $_ ne lc $event->{to}->[0] } @mship;
+ if ( @mship ) {
+ $::sn{$nick}->{mship} = \@mship;
+ } else {
+ delete($::sn{$nick});
+ }
+ }
if ( leq( $conn->{_nick}, $nick ) )
{
delete( $::sc{lc $event->{to}->[0]} );
@@ -106,6 +124,7 @@ sub on_quit
push ( @channels, $_ ) if delete $::sc{lc $_}{users}{lc $event->{nick}};
}
$event->{to} = \@channels;
+ delete($::sn{lc $event->{nick}});
inspect( $conn, $event );
logg ( $event );
}
@@ -185,7 +204,23 @@ sub on_kick {
if (lc $event->{to}->[0] eq lc $::settings->{nick}) {
$conn->join($event->{args}->[0]);
}
+ my $nick = lc $event->{to}->[0];
logg( $event );
+ my @mship = @{$::sn{$nick}->{mship}};
+ @mship = grep { lc $_ ne lc $event->{args}->[0] } @mship;
+ if ( @mship ) {
+ $::sn{$nick}->{mship} = \@mship;
+ } else {
+ delete($::sn{$nick});
+ }
+ if ( leq( $conn->{_nick}, $nick ) )
+ {
+ delete( $::sc{lc $event->{args}->[0]} );
+ }
+ else
+ {
+ delete( $::sc{lc $event->{args}->[0]}{users}{$nick} );
+ }
}
sub on_mode
@@ -263,6 +298,38 @@ sub whois_user {
delete $::needgeco{$lnick};
}
}
+
+sub on_whoreply
+{
+ my ($conn, $event) = @_;
+ my ($tgt, $chan, $user, $host, $server, $nick, $flags, $hops_and_gecos) = @{$event->{args}};
+ my ($voice, $op) = (0, 0);
+ my ($hops, $gecos);
+ $op = 1 if ( $flags =~ /\@/ );
+ $voice = 1 if ($flags =~ /\+/);
+ if ($hops_and_gecos =~ /^(\d+) (.*)$/) {
+ $hops = $1;
+ $gecos = $2;
+ } else {
+ $hops = "0";
+ $gecos = "";
+ }
+ $::sn{lc $nick} = {} unless defined $::sn{lc $nick};
+ my @mship=();
+ if (defined($::sn{lc $nick}->{mship})) {
+ @mship = @{$::sn{lc $nick}->{mship}};
+ }
+ @mship = grep { lc $_ ne lc $chan } @mship;
+ @mship = (@mship, $chan);
+ $::sn{lc $nick}->{mship} = \@mship;
+ $::sn{lc $nick}->{gecos} = $gecos;
+ $::sn{lc $nick}->{user} = $user;
+ $::sn{lc $nick}->{host} = $host;
+ $::sc{lc $chan}{users}{lc $nick} = {};
+ $::sc{lc $chan}{users}{lc $nick}{op} = $op;
+ $::sc{lc $chan}{users}{lc $nick}{voice} = $voice;
+}
+
#<<< :kubrick.freenode.net 311 AntiSpamMeta AfterDeath i=icxcnika atheme/troll/about.linux.afterdeath * :[[User:WHeimbigner]]
#Trying to handle event 'whoisuser'.
#Handler for 'whoisuser' called.
diff --git a/modules/xml.pl b/modules/xml.pl
index 9e7e526..10158d0 100644
--- a/modules/xml.pl
+++ b/modules/xml.pl
@@ -3,47 +3,54 @@ use strict;
use XML::Simple qw(:strict);
-my $xs1 = XML::Simple->new( KeyAttr => ['id'], Cache => [ qw/storable memcopy/ ]);
+$::xs1 = XML::Simple->new( KeyAttr => ['id'], Cache => [ qw/storable memcopy/ ]);
sub readXML {
my ( $p ) = $::cset; #@_;
$p = 'default' if $p eq '';
$p = "config-$p";
- $::settings = $xs1->XMLin( "$p/settings.xml", ForceArray => [qw/host/],
+ $::settings = $::xs1->XMLin( "$p/settings.xml", ForceArray => [qw/host/],
GroupTags => { altnicks => 'altnick', server => 'host', autojoins=> 'autojoin' });
- $::channels = $xs1->XMLin( "$p/channels.xml", ForceArray => [qw/event debug info low medium high/] );
- $::users = $xs1->XMLin( "$p/users.xml", ForceArray => 'person' );
+ $::channels = $::xs1->XMLin( "$p/channels.xml", ForceArray => [qw/event debug info low medium high/] );
+ $::users = $::xs1->XMLin( "$p/users.xml", ForceArray => 'person' );
$::xusers = $::users->{person};
- $::commands = $xs1->XMLin( "$p/commands.xml", ForceArray => [qw/command/]);
- $::mysql = $xs1->XMLin( "$p/mysql.xml", ForceArray => [] );
+ $::commands = $::xs1->XMLin( "$p/commands.xml", ForceArray => [qw/command/]);
+ $::mysql = $::xs1->XMLin( "$p/mysql.xml", ForceArray => [] );
}
sub writeXML {
my ( $p ) = $::cset; #@_;
$p = 'default' if $p eq '';
$p = "config-$p";
- $xs1->XMLout($::settings, RootName => 'settings', KeyAttr => ['id'],
+ $::xs1->XMLout($::settings, RootName => 'settings', KeyAttr => ['id'],
GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' },
ValueAttr => { debug => 'content', nick => 'content', port => 'content',
realname => 'content', username => 'content', dir => 'content',
zone => 'content', filefmt => 'content', timefmt => 'content'}) > io("$p/settings.xml");
- $xs1->XMLout($::channels, RootName => 'channels', KeyAttr => ['id']) > io("$p/channels.xml");
- $xs1->XMLout($::users, RootName => 'people', KeyAttr => ['id']) > io("$p/users.xml");
- $xs1->XMLout($::commands, RootName => 'commands', KeyAttr => ['id']) > io("$p/commands.xml");
+ $::xs1->XMLout($::channels, RootName => 'channels', KeyAttr => ['id']) > io("$p/channels.xml");
+ $::xs1->XMLout($::users, RootName => 'people', KeyAttr => ['id']) > io("$p/users.xml");
+ $::xs1->XMLout($::commands, RootName => 'commands', KeyAttr => ['id']) > io("$p/commands.xml");
}
sub writeChannels {
my ( $p ) = $::cset; #@_;
$p = 'default' if $p eq '';
$p = "config-$p";
- $xs1->XMLout($::channels, RootName => 'channels', KeyAttr => ['id']) > io("$p/channels.xml");
+ $::xs1->XMLout($::channels, RootName => 'channels', KeyAttr => ['id']) > io("$p/channels.xml");
}
sub writeUsers {
my ( $p ) = $::cset; #@_;
$p = 'default' if $p eq '';
$p = "config-$p";
- $xs1->XMLout($::users, RootName => 'people', KeyAttr => ['id']) > io("$p/users.xml");
+ $::xs1->XMLout($::users, RootName => 'people', KeyAttr => ['id']) > io("$p/users.xml");
+}
+
+sub writeSettings {
+ my ( $p ) = $::cset; #@_;
+ $p = 'default' if $p eq '';
+ $p = "config-$p";
+ $::xs1->XMLout($::settings, RootName => 'settings', GroupTags => { altnicks => 'altnick', server => 'host', autojoins => 'autojoin' }, NoAttr => 1) > io("$p/settings.xml");
}
sub Xml::killsub {