diff options
| author | 2007-06-28 21:13:35 +0000 | |
|---|---|---|
| committer | 2007-06-28 21:13:35 +0000 | |
| commit | 7ea23cad4c72904b02ad5c359f5edfab8328268d (patch) | |
| tree | a0973bfe2aaa8d4d7c0e35c09f2466ed9410e56a | |
| parent | d944892a0c4d04c056a8697fc0aee54b5b01ff88 (diff) | |
memleak fix, better nick tracking, new commands, major security exploit fix
| -rw-r--r-- | config-default/commands.xml | 31 | ||||
| -rw-r--r-- | config-default/users.xml | 19 | ||||
| -rwxr-xr-x | meta.pl | 1 | ||||
| -rw-r--r-- | modules/command.pl | 5 | ||||
| -rw-r--r-- | modules/event.pl | 67 | ||||
| -rw-r--r-- | modules/xml.pl | 31 |
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> @@ -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 { |
