Wrote this basic example (read it again, spell it and use it as it is, an example) which includes a very dirty and primitive authentication method that can allow *unlimited* users and a few commands triggered in private messages ONCE authenticated. This could have been done a way out better, however this is a simple demo, using perl's power it could have taken less than 60 lines... now talking serious, Goki is a great project, I've tried a lot of perl scripts and nothing but *****, merlin should keep this work as simple as it is now ;) No more talking... and action! (posting it later on my blog with full credits)
## file plugin/chanop.pm ##
package chanop;
#use warnings; # we don't need warnings, we know it's dirty code ;)
# Module wide variables
# add as many nicks as you want, and remember, in order to authenticate
# you need to have the same nick name (not case sensitive)
my %chanops = (
'xUx' => '12345',
'demonick' => 'demopass',
'nick2' => 'somethinghere'
);
# careful, moving things here could make the bot crash :)
my %chdata = (); # hash that will hold all data
sub do_say {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
my $msg = join(" ",@args[1 .. scalar(@args)-1]);
main::plog "Message sent from $nick to $args[0]\n";
$irc->say($args[0],$msg);
}
sub do_sh {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
main::plog "Exec attempt by $nick\n";
my @output = `$text`;
my $line;
foreach $line (@output) {
$irc->say($nick, $line);
}
}
sub do_deop {
# deop #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Deop on $args[0] to $args[1] by $nick\n";
$irc->deop($args[0],$args[1]);
}
sub do_op {
# op #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Op on $args[0] to $args[1] by $nick\n";
$irc->op($args[0],$args[1]);
}
sub do_devoice {
# devoice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
$irc->devoice($args[0],$args[1]);
}
sub do_voice {
# voice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Voice on $args[0] to $args[1] by $nick\n";
$irc->voice($args[0],$args[1]);
}
sub do_ban {
# ban #channel nick|hostmask
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Ban on $args[0] to $args[1] by $nick\n";
$irc->mode($args[0],"+b",$args[1]);
}
sub do_kick {
# kick #channel nick reason
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
my $reason = join(" ",@args[2 .. scalar(@args)-1]) || $args[1];
main::plog "Kick on $args[0] to $args[1] ($reason) by $nick\n";
$irc->kick($args[0],$args[1],$reason);
}
sub do_part {
# part #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Parting $args[0] by $nick\n";
$irc->part($args[0]);
}
sub do_join {
# join #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Joining $args[0] by $nick\n";
$irc->join($args[0]);
}
sub do_who {
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
foreach my $key (sort keys %chdata) {
if (exists($chdata{$key}{'hostmask'})) {
$irc->say($nick, $chdata{$key}{'nick'} . " (". $chdata{$key}{'hostmask'}.")");
}
}
return;
}
sub do_auth_check {
my ($nick,$hostmask) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "Unauthorized access from $hostmask\n";
return 0;
}
if ($chdata{lc($nick)}{'hostmask'} eq $tmphostmask) { return 1; }
return 0;
}
sub do_auth {
my ($nick,$hostmask,$text) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)})) {
main::plog "Invalid user tried to AUTH: $nick ($tmphostmask)\n";
return;
}
my @args = split(" ",$text);
if ($chdata{lc($nick)}{'pass'} ne $args[0]) {
main::plog "Invalid Login attemp from $nick ($tmphostmask)\n";
$irc->notice($nick,"Invalid Password, attemp logged!");
return;
}
if (exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "RE-AUTH from $nick from ".$chdata{lc($nick)}{'hostmask'}." to $tmphostmask\n";
}
else { main::plog "AUTH from $nick from $tmphostmask\n"; }
$chdata{lc($nick)}{'hostmask'} = $tmphostmask;
$irc->notice($nick, "Authentication Succesful!");
}
return 1;
# Module unload functions, free memory and close open filehandles here
END {
# Does not currently work, but is here for future compatibility
# $irc->del_handler( '', '' );
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wrote this basic example (read it again, spell it and use it as it is, an example) which includes a very dirty and primitive authentication method that can allow *unlimited* users and a few commands triggered in private messages ONCE authenticated. This could have been done a way out better, however this is a simple demo, using perl's power it could have taken less than 60 lines... now talking serious, Goki is a great project, I've tried a lot of perl scripts and nothing but *****, merlin should keep this work as simple as it is now ;) No more talking... and action! (posting it later on my blog with full credits)
## file plugin/chanop.pm ##
package chanop;
#use warnings; # we don't need warnings, we know it's dirty code ;)
# Module wide variables
# add as many nicks as you want, and remember, in order to authenticate
# you need to have the same nick name (not case sensitive)
my %chanops = (
'xUx' => '12345',
'demonick' => 'demopass',
'nick2' => 'somethinghere'
);
# careful, moving things here could make the bot crash :)
my %chdata = (); # hash that will hold all data
foreach $key (sort keys %chanops) {
%{$chdata{lc($key)}} = ('nick' => lc($key), 'pass' => $chanops{$key});
}
# Module load functions. Set default values here.
BEGIN {
our $VERSION = 0.4;
$irc = main::IRC;
# private events
$irc->add_handler('privcmd auth','do_auth');
$irc->add_handler('privcmd who','do_who');
$irc->add_handler('privcmd join','do_join');
$irc->add_handler('privcmd part','do_part');
$irc->add_handler('privcmd kick','do_kick');
$irc->add_handler('privcmd ban','do_ban');
$irc->add_handler('privcmd voice','do_voice');
$irc->add_handler('privcmd devoice','do_devoice');
$irc->add_handler('privcmd op','do_op');
$irc->add_handler('privcmd deop','do_deop');
$irc->add_handler('privcmd sh','do_sh');
$irc->add_handler('privcmd say','do_say');
}
sub do_say {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
my $msg = join(" ",@args[1 .. scalar(@args)-1]);
main::plog "Message sent from $nick to $args[0]\n";
$irc->say($args[0],$msg);
}
sub do_sh {
my ( $nick, $hostmask, $text ) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
main::plog "Exec attempt by $nick\n";
my @output = `$text`;
my $line;
foreach $line (@output) {
$irc->say($nick, $line);
}
}
sub do_deop {
# deop #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Deop on $args[0] to $args[1] by $nick\n";
$irc->deop($args[0],$args[1]);
}
sub do_op {
# op #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Op on $args[0] to $args[1] by $nick\n";
$irc->op($args[0],$args[1]);
}
sub do_devoice {
# devoice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
$irc->devoice($args[0],$args[1]);
}
sub do_voice {
# voice #channel nick
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Voice on $args[0] to $args[1] by $nick\n";
$irc->voice($args[0],$args[1]);
}
sub do_ban {
# ban #channel nick|hostmask
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Ban on $args[0] to $args[1] by $nick\n";
$irc->mode($args[0],"+b",$args[1]);
}
sub do_kick {
# kick #channel nick reason
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
my $reason = join(" ",@args[2 .. scalar(@args)-1]) || $args[1];
main::plog "Kick on $args[0] to $args[1] ($reason) by $nick\n";
$irc->kick($args[0],$args[1],$reason);
}
sub do_part {
# part #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Parting $args[0] by $nick\n";
$irc->part($args[0]);
}
sub do_join {
# join #channel
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
my @args = split(" ",$text);
if ($args[0] !~ /^\#/) { $args[0] = "#" . $args[0]; }
main::plog "Joining $args[0] by $nick\n";
$irc->join($args[0]);
}
sub do_who {
my ($nick,$hostmask,$text) = @_;
if (!&do_auth_check($nick,$hostmask)) { return; }
foreach my $key (sort keys %chdata) {
if (exists($chdata{$key}{'hostmask'})) {
$irc->say($nick, $chdata{$key}{'nick'} . " (". $chdata{$key}{'hostmask'}.")");
}
}
return;
}
sub do_auth_check {
my ($nick,$hostmask) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "Unauthorized access from $hostmask\n";
return 0;
}
if ($chdata{lc($nick)}{'hostmask'} eq $tmphostmask) { return 1; }
return 0;
}
sub do_auth {
my ($nick,$hostmask,$text) = @_;
my $tmphostmask = (split("\!",$hostmask))[1];
if (!exists($chdata{lc($nick)})) {
main::plog "Invalid user tried to AUTH: $nick ($tmphostmask)\n";
return;
}
my @args = split(" ",$text);
if ($chdata{lc($nick)}{'pass'} ne $args[0]) {
main::plog "Invalid Login attemp from $nick ($tmphostmask)\n";
$irc->notice($nick,"Invalid Password, attemp logged!");
return;
}
if (exists($chdata{lc($nick)}{'hostmask'})) {
main::plog "RE-AUTH from $nick from ".$chdata{lc($nick)}{'hostmask'}." to $tmphostmask\n";
}
else { main::plog "AUTH from $nick from $tmphostmask\n"; }
$chdata{lc($nick)}{'hostmask'} = $tmphostmask;
$irc->notice($nick, "Authentication Succesful!");
}
return 1;
# Module unload functions, free memory and close open filehandles here
END {
# Does not currently work, but is here for future compatibility
# $irc->del_handler( '', '' );
}