001
2021-12-17
jrmu
#!/usr/bin/perl
003
2021-12-17
jrmu
package BNC;
005
2021-12-17
jrmu
use strict;
006
2021-12-17
jrmu
use warnings;
007
2021-12-17
jrmu
use OpenBSD::Pledge;
008
2021-12-17
jrmu
use OpenBSD::Unveil;
009
2021-12-17
jrmu
use MIME::Base64;
010
2021-12-17
jrmu
use Digest::SHA qw(sha256_hex);
011
2021-12-17
jrmu
use lib './';
012
2021-12-17
jrmu
require "SQLite.pm";
013
2021-12-17
jrmu
require "Hash.pm";
014
2021-12-17
jrmu
require "DNS.pm";
015
2021-12-17
jrmu
require "Mail.pm";
017
2021-12-17
jrmu
my %conf = %main::conf;
018
2021-12-17
jrmu
my $chans = $conf{chans};
019
2021-12-17
jrmu
my $teamchans = $conf{teamchans};
020
2021-12-17
jrmu
my @teamchans = split /[,\s]+/m, $teamchans;
021
2021-12-17
jrmu
my $staff = $conf{staff};
022
2021-12-17
jrmu
my $zncdir = $conf{zncdir};
023
2021-12-17
jrmu
my $znclog = $conf{znclog} || "$zncdir/.znc/moddata/adminlog/znc.log";
024
2021-12-17
jrmu
my $hostname = $conf{hostname};
025
2021-12-17
jrmu
my $terms = $conf{terms};
026
2021-12-17
jrmu
my @logs;
027
2021-12-17
jrmu
my $expires = $conf{expires};
028
2021-12-17
jrmu
my $sslport = $conf{sslport};
029
2021-12-17
jrmu
my $plainport = $conf{plainport};
030
2021-12-17
jrmu
my $mailfrom = $conf{mailfrom};
031
2021-12-17
jrmu
my $mailname = $conf{mailname};
032
2021-12-17
jrmu
my $zncconfpath = $conf{zncconfpath} || "$zncdir/.znc/configs/znc.conf";
033
2021-12-17
jrmu
my $znctree = { Node => "root" };
035
2021-12-17
jrmu
use constant {
036
2021-12-17
jrmu
NONE => 0,
037
2021-12-17
jrmu
ERRORS => 1,
038
2021-12-17
jrmu
WARNINGS => 2,
039
2021-12-17
jrmu
ALL => 3,
042
2021-12-17
jrmu
`doas chown znc:daemon /home/znc/home/znc/.znc/configs/znc.conf`;
043
2021-12-17
jrmu
`doas chmod g+r /home/znc/home/znc/.znc/`;
044
2021-12-17
jrmu
my @zncconf = main::readarray($zncconfpath);
045
2021-12-17
jrmu
$znctree;
046
2021-12-17
jrmu
my @users;
047
2021-12-17
jrmu
foreach my $line (@zncconf) {
048
2021-12-17
jrmu
if ($line =~ /<User (.*)>/) {
049
2021-12-17
jrmu
push(@users, $1);
052
2021-12-17
jrmu
#$znctree = parseml($znctree, @zncconf);
053
2021-12-17
jrmu
main::cbind("pub", "-", "bnc", \&mbnc);
054
2021-12-17
jrmu
main::cbind("msg", "-", "bnc", \&mbnc);
055
2021-12-17
jrmu
main::cbind("msg", "-", "regex", \&mregex);
056
2021-12-17
jrmu
main::cbind("msg", "-", "foreach", \&mforeach);
057
2021-12-17
jrmu
main::cbind("msgm", "-", "*", \&mcontrolpanel);
058
2021-12-17
jrmu
main::cbind("msg", "-", "taillog", \&mtaillog);
059
2021-12-17
jrmu
main::cbind("msg", "-", "lastseen", \&mlastseen);
061
2021-12-17
jrmu
sub init {
062
2021-12-17
jrmu
#znc.conf file
063
2021-12-17
jrmu
unveil("$zncconfpath", "r") or die "Unable to unveil $!";
064
2021-12-17
jrmu
#dependencies for figlet
065
2021-12-17
jrmu
unveil("/usr/local/bin/figlet", "rx") or die "Unable to unveil $!";
066
2021-12-17
jrmu
unveil("/usr/lib/libc.so.95.1", "r") or die "Unable to unveil $!";
067
2021-12-17
jrmu
unveil("/usr/libexec/ld.so", "r") or die "Unable to unveil $!";
068
2021-12-17
jrmu
unveil("/usr/bin/tail", "rx") or die "Unable to unveil $!";
069
2021-12-17
jrmu
#znc.log file
070
2021-12-17
jrmu
unveil("$znclog", "r") or die "Unable to unveil $!";
071
2021-12-17
jrmu
#print treeget($znctree, "AnonIPLimit")."\n";
072
2021-12-17
jrmu
#print treeget($znctree, "ServerThrottle")."\n";
073
2021-12-17
jrmu
#print treeget($znctree, "ConnectDelay")."\n";
074
2021-12-17
jrmu
#print "treeget\n";
075
2021-12-17
jrmu
#print Dumper \treeget($znctree, "User", "Node");
076
2021-12-17
jrmu
#print Dumper \treeget($znctree, "User", "Network", "Node");
079
2021-12-17
jrmu
# parseml($tree, @lines)
080
2021-12-17
jrmu
# tree is a reference to a hash
081
2021-12-17
jrmu
# returns hash ref of tree
082
2021-12-17
jrmu
sub parseml {
083
2021-12-17
jrmu
my ($tree, @lines) = @_;
084
2021-12-17
jrmu
#if (scalar(@lines) == 0) { return $tree; }
085
2021-12-17
jrmu
while (scalar(@lines) > 0) {
086
2021-12-17
jrmu
my $line = shift(@lines);
087
2021-12-17
jrmu
if ($line =~ /^\s*([^=<>\s]+)\s*=\s*([^=<>]+)\s*$/) {
088
2021-12-17
jrmu
my ($tag, $val) = ($1, $2);
089
2021-12-17
jrmu
$tree->{$tag} = $val;
090
2021-12-17
jrmu
} elsif ($line =~ /^\/\//) { # skip comments
091
2021-12-17
jrmu
} elsif ($line =~ /^\s*$/) { # skip blank lines
092
2021-12-17
jrmu
} elsif ($line =~ /^\s*<([^>\s\/]+)\s*([^>\/]*)>\s*$/) {
093
2021-12-17
jrmu
my ($tag, $val) = ($1, $2);
094
2021-12-17
jrmu
if (!defined($tree->{$tag})) { $tree->{$tag} = []; }
095
2021-12-17
jrmu
my @newlines;
096
2021-12-17
jrmu
while (scalar(@lines) > 0) {
097
2021-12-17
jrmu
my $line = shift(@lines);
098
2021-12-17
jrmu
if ($line =~ /^\s*<\/$tag>\s*$/) {
099
2021-12-17
jrmu
my $subtree = parseml({ Node => $val }, @newlines);
100
2021-12-17
jrmu
push(@{$tree->{$tag}}, $subtree);
101
2021-12-17
jrmu
return parseml($tree, @lines);
103
2021-12-17
jrmu
push(@newlines, $line);
105
2021-12-17
jrmu
} else { print "ERROR: $line\n"; }
106
2021-12-17
jrmu
#TODO ERRORS not defined??
107
2021-12-17
jrmu
# } else { main::debug(ERRORS, "ERROR: $line"); }
109
2021-12-17
jrmu
return $tree;
112
2021-12-17
jrmu
#Returns array of all values
113
2021-12-17
jrmu
#treeget($tree, "User");
114
2021-12-17
jrmu
#treeget($tree, "MaFFia Network");
115
2021-12-17
jrmu
sub treeget {
116
2021-12-17
jrmu
my ($tree, @keys) = @_;
117
2021-12-17
jrmu
my $subtree;
118
2021-12-17
jrmu
my @rest = @keys;
119
2021-12-17
jrmu
my $key = shift(@rest);
120
2021-12-17
jrmu
$subtree = $tree->{$key};
121
2021-12-17
jrmu
if (!defined($subtree)) {
122
2021-12-17
jrmu
return ("Undefined");
123
2021-12-17
jrmu
} elsif (ref($subtree) eq 'HASH') {
124
2021-12-17
jrmu
return treeget($subtree, @rest);
125
2021-12-17
jrmu
} elsif (ref($subtree) eq 'ARRAY') {
126
2021-12-17
jrmu
my @array = @{$subtree};
127
2021-12-17
jrmu
my @ret;
128
2021-12-17
jrmu
foreach my $hashref (@array) {
129
2021-12-17
jrmu
push(@ret, treeget($hashref, @rest));
131
2021-12-17
jrmu
return @ret;
132
2021-12-17
jrmu
#my @array = @{$subtree};
133
2021-12-17
jrmu
#print Dumper treeget($hashref, @rest);
134
2021-12-17
jrmu
#print Dumper treeget({$key => $subtree}, @rest);
135
2021-12-17
jrmu
#return (treeget($hashref, @rest), treeget({$key => $subtree}, @rest));
136
2021-12-17
jrmu
} else {
137
2021-12-17
jrmu
return ($subtree);
141
2021-12-17
jrmu
sub mbnc {
142
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
143
2021-12-17
jrmu
my ($chan, $text);
144
2021-12-17
jrmu
if (@args == 2) {
145
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
146
2021-12-17
jrmu
} else { $text = $args[0]; }
147
2021-12-17
jrmu
my $hostmask = "$nick!$host";
148
2021-12-17
jrmu
if (defined($chan) && $chans =~ /$chan/) {
149
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
151
2021-12-17
jrmu
if ($text =~ /^$/) {
152
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
153
2021-12-17
jrmu
foreach my $chan (@teamchans) {
154
2021-12-17
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
156
2021-12-17
jrmu
return;
157
2021-12-17
jrmu
} elsif (main::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
158
2021-12-17
jrmu
my $username = $1;
159
2021-12-17
jrmu
if (SQLite::deleterows("bnc", "username", $username)) {
160
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :deluser $username");
161
2021-12-17
jrmu
foreach my $chan (@teamchans) {
162
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$username deleted");
165
2021-12-17
jrmu
return;
166
2021-12-17
jrmu
} elsif ($staff =~ /$nick/ && $text =~ /^cloneuser$/i) {
167
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :deluser cloneuser");
168
2021-12-17
jrmu
sleep 3;
169
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
171
2021-12-17
jrmu
### TODO: Check duplicate emails ###
172
2021-12-17
jrmu
my @rows = SQLite::selectrows("irc", "hostmask", $hostmask);
173
2021-12-17
jrmu
foreach my $row (@rows) {
174
2021-12-17
jrmu
my $password = SQLite::get("bnc", "ircid", $row->{id}, "password");
175
2021-12-17
jrmu
if (defined($password)) {
176
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
177
2021-12-17
jrmu
return;
180
2021-12-17
jrmu
if ($text =~ /^captcha\s+([[:alnum:]]+)/) {
181
2021-12-17
jrmu
my $text = $1;
182
2021-12-17
jrmu
# TODO avoid using host mask because cloaking can cause problems
183
2021-12-17
jrmu
my $ircid = SQLite::id("irc", "nick", $nick, $expires);
184
2021-12-17
jrmu
my $captcha = SQLite::get("bnc", "ircid", $ircid, "captcha");
185
2021-12-17
jrmu
if ($text ne $captcha) {
186
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
187
2021-12-17
jrmu
return;
189
2021-12-17
jrmu
my $pass = Hash::newpass();
190
2021-12-17
jrmu
chomp(my $encrypted = `encrypt $pass`);
191
2021-12-17
jrmu
my $username = SQLite::get("bnc", "ircid", $ircid, "username");
192
2021-12-17
jrmu
my $email = SQLite::get("bnc", "ircid", $ircid, "email");
193
2021-12-17
jrmu
my $hashirc = SQLite::get("irc", "id", $ircid, "hashid");
194
2021-12-17
jrmu
my $bindhost = "$username.$hostname";
195
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "password", $encrypted);
196
2021-12-17
jrmu
if (DNS::nextdns($username)) {
197
2021-12-17
jrmu
sleep(2);
198
2021-12-17
jrmu
createbnc($bot, $username, $pass, $bindhost);
199
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Check your email!");
200
2021-12-17
jrmu
mailbnc($username, $email, $pass, "bouncer", $hashirc);
201
2021-12-17
jrmu
#www($newnick, $reply, $password, "bouncer");
202
2021-12-17
jrmu
} else {
203
2021-12-17
jrmu
foreach my $chan (@teamchans) {
204
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
207
2021-12-17
jrmu
return;
208
2021-12-17
jrmu
} elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
209
2021-12-17
jrmu
my ($username, $email) = ($1, $2);
210
2021-12-17
jrmu
# my @users = treeget($znctree, "User", "Node");
211
2021-12-17
jrmu
foreach my $user (@users) {
212
2021-12-17
jrmu
if ($user eq $username) {
213
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
214
2021-12-17
jrmu
return;
217
2021-12-17
jrmu
#my $captcha = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..4;
218
2021-12-17
jrmu
my $captcha = int(rand(999));
219
2021-12-17
jrmu
my $ircid = int(rand(9223372036854775807));
220
2021-12-17
jrmu
my $hashid = sha256_hex("$ircid");
221
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "localtime", time());
222
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "hashid", sha256_hex($ircid));
223
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "date", main::date());
224
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "hostmask", $hostmask);
225
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "nick", $nick);
226
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "username", $username);
227
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "email", $email);
228
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "captcha", $captcha);
229
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "hashid", $hashid);
230
2021-12-17
jrmu
main::whois($bot->{sock}, $nick);
231
2021-12-17
jrmu
main::ctcp($bot->{sock}, $nick);
232
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
233
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
234
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
235
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Type !bnc captcha <text>");
236
2021-12-17
jrmu
foreach my $chan (@teamchans) {
237
2021-12-17
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} bnc captcha is $captcha");
239
2021-12-17
jrmu
} else {
240
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !bnc <username> <email> to try again.");
241
2021-12-17
jrmu
foreach my $chan (@teamchans) {
242
2021-12-17
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :Help *$nick* on ".$bot->{name});
247
2021-12-17
jrmu
sub mregex {
248
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
249
2021-12-17
jrmu
if (!main::isstaff($bot, $nick)) { return; }
250
2021-12-17
jrmu
if ($text =~ /^ips?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
251
2021-12-17
jrmu
my $ips = $1; # space-separated list of IPs
252
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
253
2021-12-17
jrmu
} elsif ($text =~ /^users?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
254
2021-12-17
jrmu
my $users = $1; # space-separated list of usernames
255
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".regexlist($users));
256
2021-12-17
jrmu
} elsif ($text =~ /^[-_()|0-9A-Za-z:,\.?*\s]{3,}$/) {
257
2021-12-17
jrmu
my @lines = regex($text);
258
2021-12-17
jrmu
foreach my $l (@lines) { print "$l\n"; }
261
2021-12-17
jrmu
sub mforeach {
262
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
263
2021-12-17
jrmu
if ($staff !~ /$nick/) { return; }
264
2021-12-17
jrmu
if ($text =~ /^network\s+del\s+([[:graph:]]+)\s+(#[[:graph:]]+)$/) {
265
2021-12-17
jrmu
my ($user, $chan) = ($1, $2);
266
2021-12-17
jrmu
foreach my $n (@main::networks) {
267
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
272
2021-12-17
jrmu
sub mcontrolpanel {
273
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
274
2021-12-17
jrmu
my ($chan, $text);
275
2021-12-17
jrmu
if (@args == 2) {
276
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
277
2021-12-17
jrmu
} else { $text = $args[0]; }
278
2021-12-17
jrmu
my $hostmask = "$nick!$host";
279
2021-12-17
jrmu
if($hostmask eq '*controlpanel!znc@znc.in') {
280
2021-12-17
jrmu
if ($text =~ /^Error: User \[cloneuser\] does not exist/) {
281
2021-12-17
jrmu
createclone($bot);
282
2021-12-17
jrmu
foreach my $chan (@teamchans) {
283
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :Cloneuser created");
285
2021-12-17
jrmu
} elsif ($text =~ /^User (.*) added!$/) {
286
2021-12-17
jrmu
main::debug(ALL, "User $1 created");
287
2021-12-17
jrmu
} elsif ($text =~ /^Password has been changed!$/) {
288
2021-12-17
jrmu
main::debug(ALL, "Password changed");
289
2021-12-17
jrmu
} elsif ($text =~ /^Queued network (.*) of user (.*) for a reconnect.$/) {
290
2021-12-17
jrmu
main::debug(ALL, "$2 now connecting to $1...");
291
2021-12-17
jrmu
} elsif ($text =~ /^Admin = false/) {
292
2021-12-17
jrmu
foreach my $chan (@teamchans) {
293
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :ERROR: $nick is not admin");
295
2021-12-17
jrmu
die "ERROR: $nick is not admin";
296
2021-12-17
jrmu
} elsif ($text =~ /^Admin = true/) {
297
2021-12-17
jrmu
main::debug(ALL, "$nick is ZNC admin");
298
2021-12-17
jrmu
} elsif ($text =~ /(.*) = (.*)/) {
299
2021-12-17
jrmu
my ($key, $val) = ($1, $2);
300
2021-12-17
jrmu
main::debug(ALL, "ZNC: $key => $val");
301
2021-12-17
jrmu
} else {
302
2021-12-17
jrmu
main::debug(ERRORS, "Unexpected 290 BNC.pm: $hostmask $text");
306
2021-12-17
jrmu
sub loadlog {
307
2021-12-17
jrmu
open(my $fh, '<', "$znclog") or die "Could not read file 'znc.log' $!";
308
2021-12-17
jrmu
chomp(@logs = <$fh>);
309
2021-12-17
jrmu
close $fh;
312
2021-12-17
jrmu
# return all lines matching a pattern
313
2021-12-17
jrmu
sub regex {
314
2021-12-17
jrmu
my ($pattern) = @_;
315
2021-12-17
jrmu
if (!@logs) { loadlog(); }
316
2021-12-17
jrmu
return grep(/$pattern/, @logs);
319
2021-12-17
jrmu
# given a list of IPs, return matching users
320
2021-12-17
jrmu
# or given a list of users, return matching IPs
321
2021-12-17
jrmu
sub regexlist {
322
2021-12-17
jrmu
my ($items) = @_;
323
2021-12-17
jrmu
my @items = split /[,\s]+/m, $items;
324
2021-12-17
jrmu
my $pattern = "(".join('|', @items).")";
325
2021-12-17
jrmu
if (!@logs) { loadlog(); }
326
2021-12-17
jrmu
my @matches = grep(/$pattern/, @logs);
327
2021-12-17
jrmu
my @results;
328
2021-12-17
jrmu
foreach my $match (@matches) {
329
2021-12-17
jrmu
if ($match =~ /^\[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\] \[([^]\/]+)(\/[^]]+)?\] connected to ZNC from (.*)/) {
330
2021-12-17
jrmu
my ($user, $ip) = ($1, $3);
331
2021-12-17
jrmu
if ($items =~ /[.:]/) { # items are IP addresses
332
2021-12-17
jrmu
push(@results, $user);
333
2021-12-17
jrmu
} else { # items are users
334
2021-12-17
jrmu
push(@results, $ip);
338
2021-12-17
jrmu
my @sorted = sort @results;
339
2021-12-17
jrmu
@results = do { my %seen; grep { !$seen{$_}++ } @sorted }; # uniq
340
2021-12-17
jrmu
return join(' ', @results);
343
2021-12-17
jrmu
sub createclone {
344
2021-12-17
jrmu
my ($bot) = @_;
345
2021-12-17
jrmu
my $socket = $bot->{sock};
346
2021-12-17
jrmu
my $password = Hash::newpass();
347
2021-12-17
jrmu
my $msg = <<"EOF";
348
2021-12-17
jrmu
adduser cloneuser $password
349
2021-12-17
jrmu
set Nick cloneuser cloneuser
350
2021-12-17
jrmu
set Altnick cloneuser cloneuser_
351
2021-12-17
jrmu
set Ident cloneuser cloneuser
352
2021-12-17
jrmu
set RealName cloneuser cloneuser
353
2021-12-17
jrmu
set MaxNetworks cloneuser 1000
354
2021-12-17
jrmu
set ChanBufferSize cloneuser 1000
355
2021-12-17
jrmu
set MaxQueryBuffers cloneuser 1000
356
2021-12-17
jrmu
set QueryBufferSize cloneuser 1000
357
2021-12-17
jrmu
set NoTrafficTimeout cloneuser 600
358
2021-12-17
jrmu
set QuitMsg cloneuser IRCNow and Forever!
359
2021-12-17
jrmu
set RealName cloneuser cloneuser
360
2021-12-17
jrmu
set DenySetBindHost cloneuser true
361
2021-12-17
jrmu
set Timezone cloneuser US/Pacific
362
2021-12-17
jrmu
LoadModule cloneuser controlpanel
363
2021-12-17
jrmu
LoadModule cloneuser chansaver
365
2021-12-17
jrmu
#LoadModule cloneuser buffextras
366
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
367
2021-12-17
jrmu
foreach my $n (@main::networks) {
368
2021-12-17
jrmu
my $net = $n->{name};
369
2021-12-17
jrmu
my $server = $n->{server};
370
2021-12-17
jrmu
my $port = $n->{port};
371
2021-12-17
jrmu
my $trustcerts = $n->{trustcerts};
372
2021-12-17
jrmu
$msg = <<"EOF";
373
2021-12-17
jrmu
addnetwork cloneuser $net
374
2021-12-17
jrmu
addserver cloneuser $net $server $port
375
2021-12-17
jrmu
disconnect cloneuser $net
377
2021-12-17
jrmu
if ($trustcerts) {
378
2021-12-17
jrmu
$msg .= "SetNetwork TrustAllCerts cloneuser $net True\r\n";
380
2021-12-17
jrmu
my @chans = split /[,\s]+/m, $chans;
381
2021-12-17
jrmu
foreach my $chan (@chans) {
382
2021-12-17
jrmu
$msg .= "addchan cloneuser $net $chan\r\n";
384
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
388
2021-12-17
jrmu
sub createbnc {
389
2021-12-17
jrmu
my ($bot, $username, $password, $bindhost) = @_;
390
2021-12-17
jrmu
my $netname = $bot->{name};
391
2021-12-17
jrmu
my $msg = <<"EOF";
392
2021-12-17
jrmu
cloneuser cloneuser $username
393
2021-12-17
jrmu
set Nick $username $username
394
2021-12-17
jrmu
set Altnick $username ${username}_
395
2021-12-17
jrmu
set Ident $username $username
396
2021-12-17
jrmu
set RealName $username $username
397
2021-12-17
jrmu
set Password $username $password
398
2021-12-17
jrmu
set MaxNetworks $username 1000
399
2021-12-17
jrmu
set ChanBufferSize $username 1000
400
2021-12-17
jrmu
set MaxQueryBuffers $username 1000
401
2021-12-17
jrmu
set QueryBufferSize $username 1000
402
2021-12-17
jrmu
set NoTrafficTimeout $username 600
403
2021-12-17
jrmu
set QuitMsg $username IRCNow and Forever!
404
2021-12-17
jrmu
set BindHost $username $bindhost
405
2021-12-17
jrmu
set DCCBindHost $username $bindhost
406
2021-12-17
jrmu
set DenySetBindHost $username true
407
2021-12-17
jrmu
reconnect $username $netname
409
2021-12-17
jrmu
#set Language $username en-US
410
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
411
2021-12-17
jrmu
return 1;
413
2021-12-17
jrmu
sub mailbnc {
414
2021-12-17
jrmu
my( $username, $email, $password, $service, $hashirc )=@_;
415
2021-12-17
jrmu
my $passhash = sha256_hex("$username");
417
2021-12-17
jrmu
my $body = <<"EOF";
418
2021-12-17
jrmu
You created a bouncer!
420
2021-12-17
jrmu
Username: $username
421
2021-12-17
jrmu
Password: $password
422
2021-12-17
jrmu
Server: $hostname
423
2021-12-17
jrmu
Port: $sslport for SSL (secure connection)
424
2021-12-17
jrmu
Port: $plainport for plaintext
426
2021-12-17
jrmu
*IMPORTANT*: Verify your email address:
428
2021-12-17
jrmu
https://$hostname/register.php?hashirc=$hashirc
430
2021-12-17
jrmu
You *MUST* click on the link or your account will be deleted.
434
2021-12-17
jrmu
Mail::mail($mailfrom, $email, $mailname, "Verify IRCNow Account", $body);
437
2021-12-17
jrmu
sub mtaillog {
438
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
439
2021-12-17
jrmu
my ($chan, $text);
440
2021-12-17
jrmu
if (@args == 2) {
441
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
442
2021-12-17
jrmu
} else { $text = $args[0]; }
443
2021-12-17
jrmu
my $hostmask = "$nick!$host";
444
2021-12-17
jrmu
open(my $fh, "-|", "/usr/bin/tail", "-f", $znclog) or die "could not start tail: $!";
445
2021-12-17
jrmu
while (my $line = <$fh>) {
446
2021-12-17
jrmu
foreach my $chan (@teamchans) {
447
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$line");
452
2021-12-17
jrmu
sub mlastseen {
453
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
454
2021-12-17
jrmu
my ($chan, $text);
455
2021-12-17
jrmu
if (@args == 2) {
456
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
457
2021-12-17
jrmu
} else { $text = $args[0]; }
458
2021-12-17
jrmu
my $hostmask = "$nick!$host";
459
2021-12-17
jrmu
if (!@logs) { loadlog(); }
460
2021-12-17
jrmu
my @users = treeget($znctree, "User", "Node");
461
2021-12-17
jrmu
foreach my $user (@users) {
462
2021-12-17
jrmu
my @lines = grep(/^\[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\] \[$user\] connected to ZNC from [.0-9a-fA-F:]+/, @logs);
463
2021-12-17
jrmu
if (scalar(@lines) == 0) {
464
2021-12-17
jrmu
foreach my $chan (@teamchans) {
465
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$user never logged in");
469
2021-12-17
jrmu
my $recent = pop(@lines);
470
2021-12-17
jrmu
if ($recent =~ /^\[(\d{4}-\d\d-\d\d) \d\d:\d\d:\d\d\] \[$user\] connected to ZNC from [.0-9a-fA-F:]+/) {
471
2021-12-17
jrmu
my $date = $1;
472
2021-12-17
jrmu
foreach my $chan (@teamchans) {
473
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$user $date");
478
2021-12-17
jrmu
#sub resend {
479
2021-12-17
jrmu
# my ($bot, $newnick, $email) = @_;
480
2021-12-17
jrmu
# my $password = newpass();
481
2021-12-17
jrmu
# sendmsg($bot, "*controlpanel", "set Password $newnick $password");
482
2021-12-17
jrmu
# mailverify($newnick, $email, $password, "bouncer");
483
2021-12-17
jrmu
# sendmsg($bot, "$newnick", "Email sent");
486
2021-12-17
jrmu
# if ($reply =~ /^!resend ([-_0-9a-zA-Z]+) ([-_0-9a-zA-Z]+@[-_0-9a-zA-Z]+\.[-_0-9a-zA-Z]+)$/i) {
487
2021-12-17
jrmu
# my ($newnick, $email) = ($1, $2);
488
2021-12-17
jrmu
# my $password = newpass();
489
2021-12-17
jrmu
# resend($bot, $newnick, $email);
492
2021-12-17
jrmu
#sub resetznc {
494
2021-12-17
jrmu
#AnonIPLimit 10000
495
2021-12-17
jrmu
#AuthOnlyViaModule false
496
2021-12-17
jrmu
#ConnectDelay 0
497
2021-12-17
jrmu
#HideVersion true
498
2021-12-17
jrmu
#LoadModule
499
2021-12-17
jrmu
#ServerThrottle
500
2021-12-17
jrmu
#1337 209.141.38.137
501
2021-12-17
jrmu
#31337 209.141.38.137
502
2021-12-17
jrmu
#1337 2605:6400:20:5cc::
503
2021-12-17
jrmu
#31337 2605:6400:20:5cc::
504
2021-12-17
jrmu
#1337 127.0.0.1
505
2021-12-17
jrmu
#1338 127.0.0.1
508
2021-12-17
jrmu
#alias Provides bouncer-side command alias support.
509
2021-12-17
jrmu
#autoreply Reply to queries when you are away
510
2021-12-17
jrmu
#block_motd Block the MOTD from IRC so it's not sent to your client(s).
511
2021-12-17
jrmu
#bouncedcc Bounces DCC transfers through ZNC instead of sending them directly to the user.
512
2021-12-17
jrmu
#clientnotify Notifies you when another IRC client logs into or out of your account. Configurable.
513
2021-12-17
jrmu
#ctcpflood Don't forward CTCP floods to clients
514
2021-12-17
jrmu
#dcc This module allows you to transfer files to and from ZNC
515
2021-12-17
jrmu
#perform Keeps a list of commands to be executed when ZNC connects to IRC.
516
2021-12-17
jrmu
#webadmin Web based administration module.
519
2021-12-17
jrmu
1; # MUST BE LAST STATEMENT IN FILE