Commit Diff
Diff:
6e28212dc089e20351348d8b951bb4b097a3605c
fcbdb0ca312eb9df292aef3f230f5fd92e0888a6
Commit:
fcbdb0ca312eb9df292aef3f230f5fd92e0888a6
Tree:
a27b1553f99fbe0b107ba210cd2cf2430b3901b4
Author:
jrmu <jrmu@ircnow.org>
Committer:
jrmu <jrmu@ircnow.org>
Date:
Thu Oct 15 11:54:49 2020 UTC
Message:
Refactored Hash and SQLite to specify table
blob - bd4d94867c76b74b91cbffe73779b7a61cfe53d6
blob + 1887104f1e0d878e22e7e62eb276563b5e627819
--- BNC.pm
+++ BNC.pm
@@ -10,6 +10,7 @@ use Data::Dumper;
use MIME::Base64;
use lib './';
use SQLite;
+use Hash;
my $chans;
my $teamchans;
@@ -43,7 +44,6 @@ sub init {
main::cbind("pub", "-", "bnc", \&mbnc);
main::cbind("msg", "-", "bnc", \&mbnc);
main::cbind("msg", "-", "delete", \&mdelete);
- main::cbind("msg", "-", "captcha", \&mcaptcha);
main::cbind("msg", "-", "regex", \&mregex);
main::cbind("msg", "-", "foreach", \&mforeach);
}
@@ -70,38 +70,6 @@ EOF
main::putserv($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
}
}
-sub mcaptcha {
- my ($bot, $nick, $host, $hand, @args) = @_;
- my ($chan, $text);
- if (@args == 2) {
- ($chan, $text) = ($args[0], $args[1]);
- } else { $text = $args[0]; }
- my $hostmask = "$nick!$host";
- my $captcha = SQLite::userget($hostmask, "captcha");
- if ($text =~ /^$captcha$/i) {
- my $pass = main::newpass();
- chomp(my $encrypted = `encrypt $pass`);
- my $username = SQLite::userget($hostmask, "username");
- my $email = SQLite::userget($hostmask, "email");
- my $version = SQLite::userget($hostmask, "version");
- my $bindhost = "$username.$hostname";
- SQLite::userset($hostmask, "password", $encrypted);
- if (DNS::nextdns($username)) {
- sleep(2);
- createbnc($bot, $username, $pass, $bindhost);
- main::putserv($bot, "PRIVMSG $nick :Check your email!");
- Mail::mailverify($username, $email, $pass, "bouncer", $version);
- SQLite::userset($hostmask, "date", main::date());
- #www($newnick, $reply, $password, "bouncer");
- } else {
- foreach my $chan (@teamchans) {
- main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
- }
- }
- } else {
- main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
- }
-}
sub mbnc {
my ($bot, $nick, $host, $hand, @args) = @_;
@@ -113,7 +81,7 @@ sub mbnc {
if (defined($chan) && $chans =~ /$chan/) {
main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
}
- if (defined(SQLite::userget($hostmask, "date"))) {
+ if (defined(SQLite::userget("bnc", $hostmask, "date"))) {
main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
### TODO: Check duplicate emails ###
} elsif ($text =~ /^$/) {
@@ -121,18 +89,51 @@ sub mbnc {
foreach my $chan (@teamchans) {
main::putserv($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
}
+ } elsif ($text =~ /^captcha\s+([[:alnum:]]+)/) {
+ my ($text) = ($1);
+ my $captcha = SQLite::userget("bnc", $hostmask, "captcha");
+ if ($text =~ /^$captcha$/i) {
+ my $pass = Hash::newpass();
+ chomp(my $encrypted = `encrypt $pass`);
+ my $username = SQLite::userget("bnc", $hostmask, "username");
+ my $email = SQLite::userget("bnc", $hostmask, "email");
+ my $version = SQLite::userget("bnc", $hostmask, "version");
+ my $bindhost = "$username.$hostname";
+ SQLite::userset("bnc", $hostmask, "password", $encrypted);
+ if (DNS::nextdns($username)) {
+ sleep(2);
+ createbnc($bot, $username, $pass, $bindhost);
+ main::putserv($bot, "PRIVMSG $nick :Check your email!");
+ Mail::mailverify($username, $email, $pass, "bouncer", $version);
+ SQLite::userset("bnc", $hostmask, "date", main::date());
+ #www($newnick, $reply, $password, "bouncer");
+ } else {
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
+ }
+ }
+ } else {
+ main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
+ }
+ } elsif ($staff =~ /$nick/ && $text =~ /^delete\s+([[:ascii:]]+)/) {
+ if (SQLite::userdel("bnc", $text)) {
+ main::putserv($bot, "PRIVMSG *controlpanel :deluser $text");
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :$text deleted");
+ }
+ }
} elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
my ($username, $email) = ($1, $2);
my $captcha = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..4;
- SQLite::userset($hostmask, "oldnick", $nick);
- SQLite::userset($hostmask, "username", $username);
- SQLite::userset($hostmask, "realname", $username);
- SQLite::userset($hostmask, "email", $email);
- SQLite::userset($hostmask, "captcha", $captcha);
+ SQLite::userset("bnc", $hostmask, "oldnick", $nick);
+ SQLite::userset("bnc", $hostmask, "username", $username);
+ SQLite::userset("bnc", $hostmask, "realname", $username);
+ SQLite::userset("bnc", $hostmask, "email", $email);
+ SQLite::userset("bnc", $hostmask, "captcha", $captcha);
main::whois($bot->{sock}, $nick);
main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
main::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
- main::putserv($bot, "PRIVMSG $nick :Type !captcha <text>");
+ main::putserv($bot, "PRIVMSG $nick :Type !bnc captcha <text>");
foreach my $chan (@teamchans) {
main::putserv($bot, "PRIVMSG $chan :$nick\'s captcha is $captcha");
}
@@ -160,7 +161,7 @@ sub mregex {
}
sub mforeach {
my ($bot, $nick, $host, $hand, $text) = @_;
- if ($main::conf{staff} !~ /$nick/) { return; }
+ if ($staff !~ /$nick/) { return; }
if ($text =~ /^network\s+del\s+([[:graph:]]+)\s+(#[[:graph:]]+)$/) {
my ($user, $chan) = ($1, $2);
foreach my $n (@main::networks) {
@@ -177,8 +178,8 @@ sub mdelete {
} else {
$text = $args[0];
}
- if ($main::conf{staff} !~ /$nick/) { return; }
- if (SQLite::userdel($text)) {
+ if ($staff !~ /$nick/) { return; }
+ if (SQLite::userdel("bnc", $text)) {
main::putserv($bot, "PRIVMSG *controlpanel :deluser $text");
foreach my $chan (@teamchans) {
main::putserv($bot, "PRIVMSG $chan :$text deleted");
@@ -226,7 +227,7 @@ sub regexlist {
sub createclone {
my ($bot) = @_;
my $socket = $bot->{sock};
- my $password = main::newpass();
+ my $password = Hash::newpass();
my $msg = <<"EOF";
adduser cloneuser $password
set Nick cloneuser cloneuser
blob - 382dcc8c8b561c26d01c711eac135623638aa955
blob + 6cf6cf8288f88210e488e059b06d4aa65444b752
--- SQLite.pm
+++ SQLite.pm
@@ -32,6 +32,7 @@ sub init {
main::cbind("msg", "-", "select", \&mselect);
}
+# !connectdb
sub mconnectdb {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
@@ -42,120 +43,120 @@ sub mconnectdb {
}
}
-# !insert <keys> <vals>
+# !insert <table> <keys> <vals>
# Comma-separated keys, values
sub minsert {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([[:ascii:]]+)/) {
- my ($keys, $vals) = ($1, $2);
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+([[:ascii:]]+)/) {
+ my ($table, $keys, $vals) = ($1, $2, $3);
# strings in the values must be quoted
if ($vals =~ s{,}{","}g) { $vals = '"'.$vals.'"'; }
- if (insertrow($keys, $vals)) {
- main::putserv($bot, "PRIVMSG $nick :($keys) => ($vals)");
+ if (insertrow($table, $keys, $vals)) {
+ main::putserv($bot, "PRIVMSG $nick :$table ($keys) => ($vals)");
} else {
- main::putserv($bot, "PRIVMSG $nick :insert failed");
+ main::putserv($bot, "PRIVMSG $nick :$table insert failed");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid insert");
}
}
-# !update <vhost> <key> <val>
+# !update <table> <vhost> <key> <val>
sub mupdate {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
- my ($vhost, $key, $val) = ($1, $2, $3);
- if (updaterow($vhost, $key, $val)) {
- main::putserv($bot, "PRIVMSG $nick :updated $vhost: $key => $val");
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
+ my ($table, $vhost, $key, $val) = ($1, $2, $3, $4);
+ if (updaterow($table, $vhost, $key, $val)) {
+ main::putserv($bot, "PRIVMSG $nick :$table updated $vhost: $key => $val");
} else {
- main::putserv($bot, "PRIVMSG $nick :update failed");
+ main::putserv($bot, "PRIVMSG $nick :$table update failed");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid update");
}
}
-# !delete <key> <val>
+# !delete <table> <key> <val>
sub mdelete {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_[:alnum:]]+)\s+(\S+)/) {
- my ($key, $val) = ($1, $2);
- if (deleterow($key, $val)) {
- main::putserv($bot, "PRIVMSG $nick :$key $val deleted");
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
+ my ($table, $key, $val) = ($1, $2, $3);
+ if (deleterow($table, $key, $val)) {
+ main::putserv($bot, "PRIVMSG $nick :$table $key $val deleted");
} else {
- main::putserv($bot, "PRIVMSG $nick :delete failed");
+ main::putserv($bot, "PRIVMSG $nick :$table delete failed");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid delete");
}
}
-# !select <key> <val>
+# !select <table> <key> <val>
sub mselect {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_[:alnum:]]+)\s+(\S+)/) {
- my ($key, $val) = ($1, $2);
- my @rows = selectrow($key, $val);
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
+ my ($table, $key, $val) = ($1, $2, $3);
+ my @rows = selectrow($table, $key, $val);
if (@rows) {
foreach my $row (@rows) {
foreach $key (keys %$row) {
my $val = $row->{$key} || "";
- print "$key => $val\n";
+ print "$table $key => $val\n";
}
}
} else {
- main::putserv($bot, "PRIVMSG $nick :no results");
+ main::putserv($bot, "PRIVMSG $nick :$table $key => $val: no results");
}
} else {
main::putserv($bot, "PRIVMSG $nick :select invalid");
}
}
-# !userget <vhost> <key>
+# !userget <table> <vhost> <key>
sub muserget {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)/) {
- my ($vhost, $key) = ($1, $2);
- my $val = userget($vhost, $key);
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)/) {
+ my ($table, $vhost, $key) = ($1, $2, $3);
+ my $val = userget($table, $vhost, $key);
if (defined($val)) {
- main::putserv($bot, "PRIVMSG $nick :$vhost $key => $val");
+ main::putserv($bot, "PRIVMSG $nick :$table $vhost $key => $val");
} else {
- main::putserv($bot, "PRIVMSG $nick :$vhost $key => undefined");
+ main::putserv($bot, "PRIVMSG $nick :$table $vhost $key => undefined");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid userget");
}
}
-# !userset <vhost> <key> <val>
+# !userset <table> <vhost> <key> <val>
sub muserset {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
- my ($vhost, $key, $val) = ($1, $2, $3);
- if (userset($vhost, $key, $val)) {
- main::putserv($bot, "PRIVMSG $nick :$vhost $key => $val");
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
+ my ($table, $vhost, $key, $val) = ($1, $2, $3, $4);
+ if (userset($table, $vhost, $key, $val)) {
+ main::putserv($bot, "PRIVMSG $nick :$table $vhost $key => $val");
} else {
- main::putserv($bot, "PRIVMSG $nick :failed userset");
+ main::putserv($bot, "PRIVMSG $nick :$table $vhost $key => failed userset");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid userset");
}
}
-# !userdel <vhost>
+# !userdel <table> <vhost>
sub muserdel {
my ($bot, $nick, $host, $hand, $text) = @_;
if ($staff !~ /$nick/) { return; }
- if ($text =~ /^([-_~@!,\.[:alnum:]]+)/) {
- my $vhost = $1;
- if (userdel($vhost)) {
- main::putserv($bot, "PRIVMSG $nick :$vhost deleted");
+ if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)/) {
+ my ($table, $vhost) = ($1, $2);
+ if (userdel($table, $vhost)) {
+ main::putserv($bot, "PRIVMSG $nick :$table $vhost deleted");
} else {
- main::putserv($bot, "PRIVMSG $nick :failed userdel");
+ main::putserv($bot, "PRIVMSG $nick :$table failed userdel");
}
} else {
main::putserv($bot, "PRIVMSG $nick :invalid userdel");
@@ -185,35 +186,36 @@ sub connectdb {
# Inserts comma-separated keys and values into table
sub insertrow {
- my ($keys, $vals) = @_;
+ my ($table, $keys, $vals) = @_;
if (!defined($dbh)) { connectdb(); }
- if ($verbose >= 3) { print "INSERT INTO bnc ($keys) values ($vals)"; }
- my $rows = $dbh->do("INSERT INTO bnc ($keys) values ($vals)");
+ if ($verbose >= 3) { print "INSERT INTO $table ($keys) values ($vals)"; }
+ my $rows = $dbh->do("INSERT INTO $table ($keys) values ($vals)");
return $rows;
}
-# Update key, value pair for record with vhost
+# Update key, value pair for record with vhost in table
# Returns number of rows successfully updated
sub updaterow {
- my ($vhost, $key, $val) = @_;
+ my ($table, $vhost, $key, $val) = @_;
if (!defined($dbh)) { connectdb(); }
- my $rows = $dbh->do("UPDATE bnc SET $key = ? where vhost = ?", undef, $val, $vhost);
+ my $rows = $dbh->do("UPDATE $table SET $key = ? where vhost = ?", undef, $val, $vhost);
return $rows;
}
-# Delete records where $key = $val
+# Delete records from $table where $key = $val
# Returns number of rows deleted
sub deleterow {
- my ($key, $val) = @_;
+ my ($table, $key, $val) = @_;
if (!defined($dbh)) { connectdb(); }
- my $rows = $dbh->do("DELETE FROM bnc WHERE $key = ?", undef, $val);
+ my $rows = $dbh->do("DELETE FROM $table WHERE $key = ?", undef, $val);
return $rows;
}
# Returns all records in the database
sub selectall {
+ my ($table) = @_;
if (!defined($dbh)) { connectdb(); }
- my $sth = $dbh->prepare("SELECT * FROM bnc");
+ my $sth = $dbh->prepare("SELECT * FROM $table");
$sth->execute();
my @results;
while (my $row = $sth->fetchrow_hashref) {
@@ -222,11 +224,11 @@ sub selectall {
return @results;
}
-# Returns all records in the database where key equals value
+# Returns all records from table where key equals value
sub selectrow {
- my ($key, $val) = @_;
+ my ($table, $key, $val) = @_;
if (!defined($dbh)) { connectdb(); }
- my $sth = $dbh->prepare("SELECT * FROM bnc WHERE $key = ?");
+ my $sth = $dbh->prepare("SELECT * FROM $table WHERE $key = ?");
$sth->execute($val);
my @results;
while (my $row = $sth->fetchrow_hashref) {
@@ -235,49 +237,64 @@ sub selectrow {
return @results;
}
+# Returns list of tables
+sub tables {
+ # if (!defined($dbh)) { connectdb(); }
+ # my $sth = $dbh->prepare(".tables");
+ # $sth->execute($val);
+ # my @results;
+ # while (my $row = $sth->fetchrow_hashref) {
+ # push(@results, $row);
+ # }
+ # return @results;
+ return qw(bnc shell www irc smtp);
+}
+
sub getrecords {
if (!defined($records)) {
- my @rows = selectall();
- if (@rows) {
+ my @tables = tables();
+ foreach my $table (@tables) {
+ my @rows = selectall($table);
+ if (@rows == 0) {
+ print "no records";
+ }
foreach my $row (@rows) {
my $vhost = $row->{vhost};
- $records->{$vhost} = ();
+ $records->{$table}->{$vhost} = ();
foreach my $key (keys %$row) {
my $val = $row->{$key} || "";
- $records->{$vhost}->{$key} = $val;
+ $records->{$table}->{$vhost}->{$key} = $val;
}
}
- } else {
- print "Error getting records\n";
}
}
}
sub userget {
- my ($vhost, $key) = @_;
+ my ($table, $vhost, $key) = @_;
if (!defined($records)) { getrecords(); }
- my $val = $records->{$vhost}->{$key};
- if ($verbose >= 3) { print "$vhost $key => ".($val or "undefined"); }
+ my $val = $records->{$table}->{$vhost}->{$key};
+ if ($verbose >= 3) { print "$table $vhost $key => ".($val or "undefined"); }
return $val;
}
sub userset {
- my ($vhost, $key, $val) = @_;
+ my ($table, $vhost, $key, $val) = @_;
if (!defined($records)) { getrecords(); }
my $ret;
- if (defined($records->{$vhost}) && keys %{$records->{$vhost}}) {
- $ret = updaterow($vhost, $key, $val) > 0;
+ if (defined($records->{$table}->{$vhost}) && keys %{$records->{$table}->{$vhost}}) {
+ $ret = updaterow($table, $vhost, $key, $val) > 0;
} else {
- $ret = insertrow("vhost,$key", "\"$vhost\",\"$val\"") > 0;
+ $ret = insertrow($table, "vhost,$key", "\"$vhost\",\"$val\"") > 0;
}
- $records->{$vhost}->{$key} = $val; # autovivifies
+ $records->{$table}->{$vhost}->{$key} = $val; # autovivifies
return $ret;
}
sub userdel {
- my ($vhost) = @_;
+ my ($table, $vhost) = @_;
if (!defined($records)) { getrecords(); }
- delete($records->{$vhost});
- if ($verbose >= 3) { print "$vhost deleted"; }
- return deleterow("vhost", $vhost);
+ delete($records->{$table}->{$vhost});
+ if ($verbose >= 3) { print "$table $vhost deleted"; }
+ return deleterow($table, "vhost", $vhost);
}
## !delkey <vhost> <key>
@@ -303,10 +320,10 @@ sub userdel {
# if ($verbose >= 3) { print "$vhost delkey $key "; }
#}
sub firstval {
- my ($key, $val) = @_;
+ my ($table, $key, $val) = @_;
if (!defined($records)) { getrecords(); }
- foreach my $vhost (keys %$records) {
- if (exists($records->{$vhost}->{$key}) && $records->{$vhost}->{$key} eq $val) {
+ foreach my $vhost (keys %{$records->{$table}}) {
+ if (exists($records->{$table}->{$vhost}->{$key}) && $records->{$table}->{$vhost}->{$key} eq $val) {
return $vhost;
}
}
blob - e807ff62803c5ea144e68e70ea7bcb2b76a8d631
blob + b3b8f00238fd785bf33480f7c7e87903a20b54b8
--- Shell.pm
+++ Shell.pm
@@ -6,10 +6,109 @@ use strict;
use warnings;
use OpenBSD::Pledge;
use OpenBSD::Unveil;
+use MIME::Base64;
+my $chans;
+my $teamchans;
+my @teamchans;
+my $staff;
+my $captchaURL = "https://guava.ircnow.org/captcha.php?vhost=";
+my $hostname;
+my $terms;
+
sub init {
+ $chans = $main::conf{chans};
+ $teamchans = $main::conf{teamchans};
+ @teamchans = split /[,\s]+/m, $teamchans;
+ $staff = $main::conf{staff};
+ $hostname = $main::conf{hostname};
+ $terms = $main::conf{terms};
+ #dependencies for figlet
+ unveil("/usr/local/bin/figlet", "rx") or die "Unable to unveil $!";
+ unveil("/usr/lib/libc.so.95.1", "r") or die "Unable to unveil $!";
+ unveil("/usr/libexec/ld.so", "r") or die "Unable to unveil $!";
+ main::cbind("pub", "-", "shell", \&mshell);
+ main::cbind("msg", "-", "shell", \&mshell);
+ main::cbind("msg", "-", "confirm", \&mconfirm);
}
-#sub createshell {
+sub mshell {
+ my ($bot, $nick, $host, $hand, @args) = @_;
+ my ($chan, $text);
+ if (@args == 2) {
+ ($chan, $text) = ($args[0], $args[1]);
+ } else { $text = $args[0]; }
+ my $hostmask = "$nick!$host";
+ if (defined($chan) && $chans =~ /$chan/) {
+ main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
+ }
+ if (defined(SQLite::userget("shell", $hostmask, "date"))) {
+ main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+ ### TODO: Check duplicate emails ###
+ } elsif ($text =~ /^$/) {
+ main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
+ }
+ } elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
+ my ($username, $email) = ($1, $2);
+ my $captcha = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..4;
+ SQLite::userset("shell", $hostmask, "oldnick", $nick);
+ SQLite::userset("shell", $hostmask, "username", $username);
+ SQLite::userset("shell", $hostmask, "realname", $username);
+ SQLite::userset("shell", $hostmask, "email", $email);
+ SQLite::userset("shell", $hostmask, "captcha", $captcha);
+ main::whois($bot->{sock}, $nick);
+ main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
+ main::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
+ main::putserv($bot, "PRIVMSG $nick :Type !captcha <text>");
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :$nick\'s captcha is $captcha");
+ }
+ } else {
+ main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !shell <username> <email> to try again.");
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
+ }
+ }
+}
+
+sub mconfirm {
+ my ($bot, $nick, $host, $hand, @args) = @_;
+ my ($chan, $text);
+ if (@args == 2) {
+ ($chan, $text) = ($args[0], $args[1]);
+ } else { $text = $args[0]; }
+ my $hostmask = "$nick!$host";
+ my $captcha = SQLite::userget("shell", $hostmask, "captcha");
+ if ($text =~ /^$captcha$/i) {
+ my $pass = Hash::newpass();
+ chomp(my $encrypted = `encrypt $pass`);
+ my $username = SQLite::userget("shell", $hostmask, "username");
+ my $email = SQLite::userget("shell", $hostmask, "email");
+ my $version = SQLite::userget("shell", $hostmask, "version");
+ my $bindhost = "$username.$hostname";
+ SQLite::userset("shell", $hostmask, "password", $encrypted);
+ if (DNS::nextdns($username)) {
+ sleep(2);
+ createshell($bot, $username, $pass, $bindhost);
+ main::putserv($bot, "PRIVMSG $nick :Check your email!");
+ Mail::mailverify($username, $email, $pass, "bouncer", $version);
+ SQLite::userset("shell", $hostmask, "date", main::date());
+ #www($newnick, $reply, $password, "bouncer");
+ } else {
+ foreach my $chan (@teamchans) {
+ main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
+ }
+ }
+ } else {
+ main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !shell <username> <email>");
+ }
+}
+sub createshell {
+ print "HOORAY";
+}
+
+#sub mcreateshell {
#my $msg = <<"EOF";
#Your shell account username is $newnick and password is $password . The server is $hostname , port 22. Our official support channel is on #shell. Instructions: https://ircnow.org/kb/doku.php?id=shell:shell .
#EOF
blob - 8e68514c70d93aac50c5a6fbe3b2084c68bc9100
blob + 35d24416ff86d2f966132f5ee5086ef1c8e1647f
--- botnow.pl
+++ botnow.pl
@@ -6,7 +6,6 @@ use IO::Socket;
use IO::Select;
use OpenBSD::Pledge;
use OpenBSD::Unveil;
-use Digest::SHA qw(sha256_hex);
use lib './';
use BNC;
use DNS;
@@ -99,6 +98,7 @@ Mail::init();
Shell::init();
VPN::init();
Login::init();
+WWW::init();
unveil("./", "r") or die "Unable to unveil $!";
unveil("$confpath", "r") or die "Unable to unveil $!";
@@ -113,20 +113,25 @@ pledge( qw(stdio rpath wpath cpath inet dns proc exec
our @networks;
my @bots;
-my @words;
my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
my @chans = split /[,\s]+/m, $conf{chans};
my @teamchans;
my $call;
if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; }
+my $botnick = $conf{nick};
+my $host = $conf{host};
+my $port = $conf{port};
+my $pass = $conf{pass};
+my $localnet = $conf{localnet};
+my $staff = $conf{staff};
+my $verbose = $conf{verbose};
# Read from filename and return array of lines without trailing newlines
sub readarray {
my ($filename) = @_;
- my (@lines, $fh);
- open($fh, '<', "$filename") or die "Could not read file '$filename' $!";
- chomp(@lines = <$fh>);
+ open(my $fh, '<', "$filename") or die "Could not read file '$filename' $!";
+ chomp(my @lines = <$fh>);
close $fh;
return @lines;
}
@@ -136,14 +141,14 @@ sub readstr {
my ($filename) = @_;
open my $fh, '<', $filename or die "Could not read file '$filename' $!";
my $str = do { local $/; <$fh> };
+ close $fh;
return $str;
}
# Write str to filename
sub writefile {
my ($filename, $str) = @_;
- my (@lines, $fh);
- open($fh, '>', "$filename") or die "Could not write to $filename";
+ open(my $fh, '>', "$filename") or die "Could not write to $filename";
print $fh $str;
close $fh;
}
@@ -183,9 +188,6 @@ sub readnetworks {
# networks must be sorted to avoid multiple connections
@networks = sort @networks;
-# dictionary words for passwords
-@words = readarray("words");
-
# create sockets
my $sel = IO::Select->new( );
my $lastnet = "";
@@ -193,12 +195,12 @@ foreach my $network (@networks) {
# avoid duplicate connections
if ($lastnet eq $network->{name}) { next; }
$lastnet = $network->{name};
- my $socket = IO::Socket::INET->new(PeerAddr=>$conf{host}, PeerPort=>$conf{port}, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n";
+ my $socket = IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n";
$sel->add($socket);
my $bot = {("sock" => $socket), %$network};
push(@bots, $bot);
- putserv($bot, "NICK $conf{nick}");
- putserv($bot, "USER $conf{nick} * * :$conf{nick}");
+ putserv($bot, "NICK $botnick");
+ putserv($bot, "USER $botnick * * :$botnick");
}
while(my @ready = $sel->can_read) {
@@ -219,36 +221,35 @@ while(my @ready = $sel->can_read) {
putserv($bot, "PONG :$1");
} elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) {
my ($type, $target, $text) = ($1, $2, $3);
- if ($type eq "001" && $target =~ /^$conf{nick}.?$/ && $text eq "Welcome to ZNC") {
- } elsif ($type eq "NOTICE" && $target =~ /^$conf{nick}.?$/ && $text eq "*** To connect now, you can use /quote PASS <username>:<password>, or /quote PASS <username>/<network>:<password> to connect to a specific network.") {
- } elsif ($type eq "NOTICE" && $target =~ /^$conf{nick}.?$/ && $text eq "*** You need to send your password. Configure your client to send a server password.") {
- } elsif ($type eq "464" && $target =~ /^$conf{nick}.?$/ && $text eq "Password required") {
- putserv($bot, "PASS $conf{nick}/$bot->{name}:$conf{pass}");
+ if ($type eq "001" && $target =~ /^$botnick.?$/ && $text eq "Welcome to ZNC") {
+ } elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** To connect now, you can use /quote PASS <username>:<password>, or /quote PASS <username>/<network>:<password> to connect to a specific network.") {
+ } elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** You need to send your password. Configure your client to send a server password.") {
+ } elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Password required") {
+ putserv($bot, "PASS $botnick/$bot->{name}:$pass");
foreach my $chan (@chans) {
putserv($bot, "JOIN $chan");
}
- if ($bot->{name} =~ /$conf{localnet}/i) {
- putserv($bot, "OPER $conf{nick} $conf{pass}");
+ if ($bot->{name} =~ /^$localnet$/i) {
+ putserv($bot, "OPER $botnick $pass");
putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel");
- putserv($bot, "PRIVMSG *controlpanel :get Admin $conf{nick}");
+ putserv($bot, "PRIVMSG *controlpanel :get Admin $botnick");
putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
foreach my $chan (@teamchans) {
putserv($bot, "JOIN $chan");
}
}
- } elsif ($type eq "464" && $target =~ /^$conf{nick}.?$/ && $text eq "Invalid Password") {
+ } elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Invalid Password") {
die "ERROR: Wrong Username/Password: $bot->{name}";
} else {
debug(ERRORS, "Unexpected: type: $type, target: $target, text: $text");
}
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) {
my ($hostmask, $nick, $host, $target, $text) = ($1, $2, $3, $4, $5);
- if ($hostmask eq '*status!znc@znc.in' && $target =~ /$conf{nick}.?/ && $text =~ /Network ([[:ascii:]]+) doesn't exist./) {
+ if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$botnick.?$/ && $text =~ /Network ([[:ascii:]]+) doesn't exist./) {
debug(ERRORS, "$1 is not connected");
} elsif ($text =~ /!([[:graph:]]+)\s*(.*)/) {
my ($cmd, $text) = ($1, $2);
- my $hand = $conf{staff}; # TODO fix later
-
+ my $hand = $staff; # TODO fix later
if ($target =~ /^#/) {
foreach my $c (@{$call->{pub}}) {
if ($cmd eq $c->{cmd}) {
@@ -268,7 +269,7 @@ while(my @ready = $sel->can_read) {
debug(ALL, "$hostmask $target $text");
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NOTICE ([^ ]+) :(.*)\r\n$/i) {
my ($hostmask, $nick, $host, $target, $text) = ($1, $2, $3, $4, $5);
- my $hand = $conf{staff}; # TODO fix later
+ my $hand = $staff; # TODO fix later
foreach my $c (@{$call->{notc}}) {
# if ($text eq $c->{mask}) { # TODO fix later
my $proc = $c->{proc};
@@ -280,14 +281,14 @@ while(my @ready = $sel->can_read) {
if ($hostmask ne '*status!znc@znc.in') {
if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) {
my ($key, $val) = ($1, $2);
- SQLite::userset($hostmask, lc($key), $val);
- SQLite::userset($hostmask, "localtime", gettime());
+ SQLite::userset("bnc", $hostmask, lc($key), $val);
+ SQLite::userset("bnc", $hostmask, "localtime", gettime());
}
}
debug(ALL, "$nick!$host NOTICE $target $text");
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) MODE ([^ ]+) ([^ ]+)\s*([^ ]*)\r\n$/i) {
my ($hostmask, $nick, $host, $chan, $change, $target) = ($1, $2, $3, $4, $5, $6);
- my $hand = $conf{staff}; # TODO fix later
+ my $hand = $staff; # TODO fix later
foreach my $c (@{$call->{mode}}) {
# TODO filter by mask
my $proc = $c->{proc};
@@ -299,7 +300,7 @@ while(my @ready = $sel->can_read) {
#:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) {
my ($hostmask, $nick, $host, $chan) = ($1, $2, $3, $4);
- my $hand = $conf{staff}; # TODO fix later
+ my $hand = $staff; # TODO fix later
foreach my $c (@{$call->{join}}) {
my $proc = $c->{proc};
$proc->($bot, $nick, $host, $hand, $chan);
@@ -308,7 +309,7 @@ while(my @ready = $sel->can_read) {
#:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) {
my ($hostmask, $nick, $host, $chan, $text) = ($1, $2, $3, $4, $5);
- my $hand = $conf{staff}; # TODO fix later
+ my $hand = $staff; # TODO fix later
foreach my $c (@{$call->{part}}) {
# if ($text eq $c->{mask}) { # TODO fix later
my $proc = $c->{proc};
@@ -321,7 +322,7 @@ while(my @ready = $sel->can_read) {
my ($hostmask, $nick, $host, $text) = ($1, $2, $3, $4);
debug(ALL, "$hostmask NICK $text");
#:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal
- } elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $conf{nick}.? :?(.*)\r?\n?\r$/i) {
+ } elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $botnick.? :?(.*)\r?\n?\r$/i) {
my ($server, $code, $text) = ($1, $2, $3);
if ($code =~ /^001$/) { # Server Info
debug(ERRORS, "botnow successfully connected to $bot->{name}");
@@ -334,59 +335,59 @@ while(my @ready = $sel->can_read) {
} elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) {
my ($sender, $key) = ($1, "registered");
$val = $2 eq ":is a registered nick" ? "True" : "$2";
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, "identified", $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, "identified", $val);
debug(ALL, "$key: $val");
} elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) {
my ($sender, $key, $val) = ($1, "vhost", "$1\!$2\@$3");
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) {
my ($sender, $key, $val) = ($1, "server", $2);
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) {
my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2"));
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) {
debug(ALL, "End of WHOIS");
} elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) {
($sender, my $idle, my $epochtime) = ($1, $2, $3);
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, "idle", $idle);
- SQLite::userset($hostmask, "epochtime", $epochtime);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, "idle", $idle);
+ SQLite::userset("bnc", $hostmask, "epochtime", $epochtime);
debug(ALL, "idle: $idle, epochtime: $epochtime");
} elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) {
debug(ALL, "End of WHOIS");
} elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) {
my ($sender, $key, $val) = ($1, "chans", $2);
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) {
my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2));
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) {
my ($sender, $key, $val) = ($1, "ip", $2);
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
#Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host
} elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) {
my ($sender, $key, $val) = ($1, "ip", $3);
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) {
my ($sender, $key, $val) = ($1, "ssl", "True");
- my $hostmask = SQLite::firstval("oldnick", $sender);
- SQLite::userset($hostmask, $key, $val);
+ my $hostmask = SQLite::firstval("bnc", "oldnick", $sender);
+ SQLite::userset("bnc", $hostmask, $key, $val);
debug(ALL, "$key: $val");
} elsif ($code =~ /^332$/) { # Topic
# print "$text\r\n";
@@ -407,18 +408,18 @@ while(my @ready = $sel->can_read) {
# print "$server $code $text\r\n";
} elsif ($code =~ /^464$/) { # Invalid password for oper
foreach my $chan (@teamchans) {
- putserv($bot, "PRIVMSG $chan :$conf{nick} oper password failed; the bot will be unable to view uncloaked IP addresses");
+ putserv($bot, "PRIVMSG $chan :$botnick oper password failed; the bot will be unable to view uncloaked IP addresses");
}
} elsif ($code =~ /^477$/) { # Can't join channel
foreach my $chan (@teamchans) {
- putserv($bot, "PRIVMSG $chan :ERROR: $conf{nick} on $server: $text");
+ putserv($bot, "PRIVMSG $chan :ERROR: $botnick on $server: $text");
}
} elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) {
debug(ALL, "$text");
} else {
debug(ERRORS, "Unexpected: $server $code $text");
}
- # } elsif($response =~ /^:\*status!znc\@znc\.in $conf{nick} (.*)/i) {
+ # } elsif($response =~ /^:\*status!znc\@znc\.in $nick (.*)/i) {
#my ($text) = ($1);
#debug(ERRORS, "$text");
} else {
@@ -458,17 +459,6 @@ sub gettime {
return $localtime;
}
-sub newpass {
- my $len = scalar @words;
- my $pass;
- for (my $i=0; $i < $conf{passlength}; $i++) {
- my $word = $words[int(rand($len))];
- $word =~ s/(\w+)/\u$1/g;
- $pass .= $word;
- }
- return $pass;
-}
-
sub whois {
my( $socket, $target )=@_;
print $socket "WHOIS $target $target\r\n";
@@ -504,5 +494,7 @@ sub cbind {
sub debug {
my ($level, $msg) = @_;
- if ($conf{verbose} >= $level) { print "$msg\n"; }
+ if ($verbose >= $level) { print "$msg\n"; }
}
+
+
blob - f8107bedd638dc3f948dd74dc1a14d53ceb9ddbb
blob + c0e549a5f2ed0bd3fb91223b91e5f5ebe2ff52fe
--- makefile
+++ makefile
@@ -22,7 +22,7 @@ botnow:
chmod ug+rw ${ZONES}/*
echo "permit nopass ${USERNAME} as _nsd cmd nsd-control" >> /etc/doas.conf
cp register.php ${HTDOCS}/
- cp LICENSE README botnow.pl botnow.conf botnow.conf.full BNC.pm DNS.pm Mail.pm SQLite.pm Shell.pm VPN.pm Login.pm WWW.pm table.sql makefile networks register.php words ${HOMEDIR}/
+ cp LICENSE README botnow.pl botnow.conf botnow.conf.full BNC.pm DNS.pm Mail.pm SQLite.pm Shell.pm VPN.pm Login.pm WWW.pm table.sql Hash.pm makefile networks register.php words ${HOMEDIR}/
chown -R ${USERNAME}:${USERNAME} ${HOMEDIR}
chmod u+x ${HOMEDIR}/botnow.pl
chown -R ${ZNCUSER}:daemon ${ZNCDIR}
blob - d0691a05cad4870dd6793f36bae7a097d5266876
blob + a8af2958b80a3ebf6c2a1666ea5788c2e29861ea
--- networks
+++ networks
@@ -127,7 +127,6 @@ globalirc irc.global-irc.org 6667
globalirc-it irc.globalirc.it ~6697
greekirc irc.greekirc.net 6667
hybridirc irc.hybridirc.com ~6697
-icq-chat irc.icq-chat.com +6697
icqchat irc.icq-chat.com +6697
insomnia irc.insomnia247.nl 6667
irc4fun irc.irc4fun.net 6667