Blame
Date:
Sun Oct 8 22:28:02 2023 UTC
Message:
Now prevents creating accounts that exist in database with a password
001
2021-12-17
jrmu
#!/usr/bin/perl
002
2021-12-17
jrmu
003
2021-12-17
jrmu
package BNC;
004
2021-12-17
jrmu
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
2023-02-26
jrmu
use Digest::SHA qw(sha256_hex);
010
2021-12-17
jrmu
use lib './';
011
2021-12-17
jrmu
require "SQLite.pm";
012
2021-12-17
jrmu
require "Hash.pm";
013
2021-12-17
jrmu
require "DNS.pm";
014
2021-12-17
jrmu
require "Mail.pm";
015
2021-12-17
jrmu
016
2021-12-17
jrmu
my %conf = %main::conf;
017
2021-12-17
jrmu
my $chans = $conf{chans};
018
2021-12-17
jrmu
my $teamchans = $conf{teamchans};
019
2021-12-17
jrmu
my @teamchans = split /[,\s]+/m, $teamchans;
020
2021-12-17
jrmu
my $staff = $conf{staff};
021
2021-12-17
jrmu
my $zncdir = $conf{zncdir};
022
2021-12-17
jrmu
my $znclog = $conf{znclog} || "$zncdir/.znc/moddata/adminlog/znc.log";
023
2021-12-17
jrmu
my $hostname = $conf{hostname};
024
2023-06-11
jrmu
my $bnchostname = $conf{bnchostname};
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
2023-03-05
jrmu
my $approval = $conf{approval};
033
2023-03-06
jrmu
my $webpanel = $conf{webpanel};
034
2023-02-17
jrmu
# File containing IRC networks
035
2023-02-17
jrmu
my $netpath = "networks";
036
2023-02-17
jrmu
my @networks;
037
2021-12-17
jrmu
038
2021-12-17
jrmu
use constant {
039
2021-12-17
jrmu
NONE => 0,
040
2021-12-17
jrmu
ERRORS => 1,
041
2021-12-17
jrmu
WARNINGS => 2,
042
2021-12-17
jrmu
ALL => 3,
043
2021-12-17
jrmu
};
044
2021-12-17
jrmu
045
2021-12-17
jrmu
`doas chmod g+r /home/znc/home/znc/.znc/`;
046
2021-12-17
jrmu
my @users;
047
2021-12-17
jrmu
main::cbind("pub", "-", "bnc", \&mbnc);
048
2021-12-17
jrmu
main::cbind("msg", "-", "bnc", \&mbnc);
049
2021-12-17
jrmu
main::cbind("msg", "-", "regex", \&mregex);
050
2021-12-17
jrmu
main::cbind("msg", "-", "foreach", \&mforeach);
051
2021-12-17
jrmu
main::cbind("msgm", "-", "*", \&mcontrolpanel);
052
2021-12-17
jrmu
main::cbind("msg", "-", "taillog", \&mtaillog);
053
2021-12-17
jrmu
main::cbind("msg", "-", "lastseen", \&mlastseen);
054
2021-12-17
jrmu
055
2023-02-23
jrmu
sub init {
056
2023-02-23
jrmu
unveil("/usr/local/bin/figlet", "rx") or die "Unable to unveil $!";
057
2023-02-23
jrmu
unveil("/usr/lib/libc.so.95.1", "r") or die "Unable to unveil $!";
058
2023-02-23
jrmu
unveil("/usr/libexec/ld.so", "r") or die "Unable to unveil $!";
059
2023-02-23
jrmu
unveil("/usr/bin/tail", "rx") or die "Unable to unveil $!";
060
2023-02-23
jrmu
unveil("$netpath", "r") or die "Unable to unveil $!";
061
2023-02-23
jrmu
062
2023-02-23
jrmu
@networks = readnetworks($netpath);
063
2023-02-23
jrmu
064
2023-02-23
jrmu
# networks must be sorted to avoid multiple connections
065
2023-02-23
jrmu
@networks = sort @networks;
066
2023-02-23
jrmu
}
067
2023-02-23
jrmu
068
2023-02-17
jrmu
# Return list of networks from filename
069
2023-02-17
jrmu
# To add multiple servers for a single network, simply create a new entry with
070
2023-02-17
jrmu
# the same net name; znc ignores addnetwork commands when a network already exists
071
2023-02-17
jrmu
sub readnetworks {
072
2023-02-17
jrmu
my ($filename) = @_;
073
2023-02-17
jrmu
my @lines = main::readarray($filename);
074
2023-02-17
jrmu
my @networks;
075
2023-02-17
jrmu
foreach my $line (@lines) {
076
2023-02-17
jrmu
if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace
077
2023-02-17
jrmu
next;
078
2023-02-17
jrmu
} elsif ($line =~ /^\s*([-a-zA-Z0-9]+)\s*([-_.:a-zA-Z0-9]+)\s*(~|\+)?([0-9]+)\s*$/) {
079
2023-02-17
jrmu
my ($name, $server, $port) = ($1, $2, $4);
080
2023-02-17
jrmu
my $trustcerts;
081
2023-02-17
jrmu
if (!defined($3)) {
082
2023-02-17
jrmu
$trustcerts = 0;
083
2023-02-17
jrmu
} elsif ($3 eq "~") { # Use SSL but trust all certs
084
2023-02-17
jrmu
$port = "+".$port;
085
2023-02-17
jrmu
$trustcerts = 1;
086
2023-02-17
jrmu
} else { # Use SSL and verify certs
087
2023-02-17
jrmu
$port = "+".$port;
088
2023-02-17
jrmu
$trustcerts = 0;
089
2023-02-17
jrmu
}
090
2023-02-17
jrmu
push(@networks, {"name" => $name, "server" => $server, "port" => $port, "trustcerts" => $trustcerts });
091
2023-02-17
jrmu
} else {
092
2023-02-17
jrmu
die "network format invalid: $line\n";
093
2023-02-17
jrmu
}
094
2023-02-17
jrmu
}
095
2023-02-17
jrmu
return @networks;
096
2023-02-17
jrmu
}
097
2023-02-17
jrmu
098
2021-12-17
jrmu
sub mbnc {
099
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
100
2021-12-17
jrmu
my ($chan, $text);
101
2021-12-17
jrmu
if (@args == 2) {
102
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
103
2021-12-17
jrmu
} else { $text = $args[0]; }
104
2021-12-17
jrmu
my $hostmask = "$nick!$host";
105
2021-12-17
jrmu
if (defined($chan) && $chans =~ /$chan/) {
106
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
107
2021-12-17
jrmu
}
108
2021-12-17
jrmu
if ($text =~ /^$/) {
109
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
110
2021-12-17
jrmu
foreach my $chan (@teamchans) {
111
2023-03-01
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
112
2021-12-17
jrmu
}
113
2021-12-17
jrmu
return;
114
2021-12-17
jrmu
} elsif (main::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
115
2021-12-17
jrmu
my $username = $1;
116
2021-12-17
jrmu
if (SQLite::deleterows("bnc", "username", $username)) {
117
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :deluser $username");
118
2021-12-17
jrmu
foreach my $chan (@teamchans) {
119
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$username deleted");
120
2021-12-17
jrmu
}
121
2021-12-17
jrmu
}
122
2021-12-17
jrmu
return;
123
2023-03-05
jrmu
} elsif (main::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
124
2023-03-05
jrmu
my $username = $1;
125
2023-05-06
jrmu
if (SQLite::selectrows("bnc", "username", $username)) {
126
2023-06-30
jrmu
my $email = SQLite::get("bnc", "username", $username, "email");
127
2023-06-30
jrmu
my $password = Hash::newpass();
128
2023-06-30
jrmu
main::putserv($bot,"privmsg *controlpanel :set Password $username $password");
129
2023-06-30
jrmu
main::putserv($bot, "PRIVMSG *blockuser :unblock $username");
130
2023-06-30
jrmu
mailbncApproved($username,$email,$password);
131
2023-05-06
jrmu
foreach my $chan (@teamchans) {
132
2023-03-05
jrmu
main::putserv($bot, "PRIVMSG $chan :$username bnc approved");
133
2023-05-06
jrmu
}
134
2023-05-06
jrmu
} else {
135
2023-05-06
jrmu
main::putserv($bot, "PRIVMSG $chan :$username hasn't requested a bnc account");
136
2023-03-05
jrmu
}
137
2023-03-05
jrmu
return;
138
2021-12-17
jrmu
} elsif ($staff =~ /$nick/ && $text =~ /^cloneuser$/i) {
139
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :deluser cloneuser");
140
2021-12-17
jrmu
sleep 3;
141
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
142
2021-12-17
jrmu
}
143
2023-02-23
jrmu
### Check duplicate hostmasks ###
144
2021-12-17
jrmu
my @rows = SQLite::selectrows("irc", "hostmask", $hostmask);
145
2021-12-17
jrmu
foreach my $row (@rows) {
146
2021-12-17
jrmu
my $password = SQLite::get("bnc", "ircid", $row->{id}, "password");
147
2021-12-17
jrmu
if (defined($password)) {
148
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
149
2021-12-17
jrmu
return;
150
2021-12-17
jrmu
}
151
2021-12-17
jrmu
}
152
2023-02-23
jrmu
153
2021-12-17
jrmu
if ($text =~ /^captcha\s+([[:alnum:]]+)/) {
154
2021-12-17
jrmu
my $text = $1;
155
2021-12-17
jrmu
# TODO avoid using host mask because cloaking can cause problems
156
2021-12-17
jrmu
my $ircid = SQLite::id("irc", "nick", $nick, $expires);
157
2021-12-17
jrmu
my $captcha = SQLite::get("bnc", "ircid", $ircid, "captcha");
158
2021-12-17
jrmu
if ($text ne $captcha) {
159
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
160
2021-12-17
jrmu
return;
161
2021-12-17
jrmu
}
162
2021-12-17
jrmu
my $pass = Hash::newpass();
163
2021-12-17
jrmu
chomp(my $encrypted = `encrypt $pass`);
164
2021-12-17
jrmu
my $username = SQLite::get("bnc", "ircid", $ircid, "username");
165
2021-12-17
jrmu
my $email = SQLite::get("bnc", "ircid", $ircid, "email");
166
2021-12-17
jrmu
my $hashirc = SQLite::get("irc", "id", $ircid, "hashid");
167
2021-12-17
jrmu
my $bindhost = "$username.$hostname";
168
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "password", $encrypted);
169
2021-12-17
jrmu
if (DNS::nextdns($username)) {
170
2021-12-17
jrmu
sleep(2);
171
2021-12-17
jrmu
createbnc($bot, $username, $pass, $bindhost);
172
2023-03-05
jrmu
if ($approval eq "true") {
173
2023-03-05
jrmu
main::putserv($bot, "PRIVMSG *blockuser :block $username");
174
2023-06-30
jrmu
main::putserv($bot, "PRIVMSG $nick :Your account has been created but must be approved by your admins ($staff) before it can be used. Please reply to the email and contact staff over IRC.");
175
2023-06-30
jrmu
mailbncPending($username, $email);
176
2023-03-05
jrmu
foreach my $chan (@teamchans) {
177
2023-06-30
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$staff: To approve $nick, you must type !bnc approve $username");
178
2023-03-05
jrmu
}
179
2023-06-30
jrmu
} else {
180
2023-06-30
jrmu
main::putserv($bot, "PRIVMSG $nick :Check your email! Please reply to the email and contact staff over IRC.");
181
2023-06-30
jrmu
mailbncApproved($username,$email,$pass);
182
2023-03-05
jrmu
}
183
2023-03-01
jrmu
foreach my $chan (@teamchans) {
184
2023-03-06
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s bnc registration of $username on $bot->{name} was successful, *but* you *must* help him connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Bouncer.Bouncer and give him connection instructions");
185
2023-03-01
jrmu
}
186
2021-12-17
jrmu
#www($newnick, $reply, $password, "bouncer");
187
2021-12-17
jrmu
} else {
188
2021-12-17
jrmu
foreach my $chan (@teamchans) {
189
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
190
2021-12-17
jrmu
}
191
2021-12-17
jrmu
}
192
2021-12-17
jrmu
return;
193
2021-12-17
jrmu
} elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
194
2021-12-17
jrmu
my ($username, $email) = ($1, $2);
195
2023-10-08
izzyb
#XXX Check if this user is staff - hotfix for bug
196
2023-10-08
izzyb
if (bncExists($bot,$username)) {
197
2023-10-08
izzyb
main::putserv($bot, "PRIVMSG $nick :Sorry, that account already exists");
198
2023-10-08
izzyb
return;
199
2023-10-08
izzyb
}
200
2023-02-23
jrmu
my @userrows = SQLite::selectrows("bnc", "username", $username);
201
2023-02-26
jrmu
foreach my $row (@userrows) {
202
2023-02-26
jrmu
my $password = SQLite::get("bnc", "ircid", $row->{id}, "password");
203
2023-02-26
jrmu
if (defined($password)) {
204
2023-02-26
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
205
2023-02-26
jrmu
return;
206
2023-02-26
jrmu
}
207
2023-02-26
jrmu
}
208
2023-02-23
jrmu
my @emailrows = SQLite::selectrows("bnc", "email", $email);
209
2023-02-26
jrmu
foreach my $row (@userrows) {
210
2023-02-25
jrmu
my $password = SQLite::get("bnc", "ircid", $row->{id}, "password");
211
2023-02-23
jrmu
if (defined($password)) {
212
2023-02-23
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
213
2023-02-23
jrmu
return;
214
2023-02-23
jrmu
}
215
2023-02-23
jrmu
}
216
2023-02-23
jrmu
217
2021-12-17
jrmu
# my @users = treeget($znctree, "User", "Node");
218
2021-12-17
jrmu
foreach my $user (@users) {
219
2021-12-17
jrmu
if ($user eq $username) {
220
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
221
2021-12-17
jrmu
return;
222
2021-12-17
jrmu
}
223
2021-12-17
jrmu
}
224
2023-02-23
jrmu
225
2021-12-17
jrmu
#my $captcha = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..4;
226
2021-12-17
jrmu
my $captcha = int(rand(999));
227
2021-12-17
jrmu
my $ircid = int(rand(9223372036854775807));
228
2021-12-17
jrmu
my $hashid = sha256_hex("$ircid");
229
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "localtime", time());
230
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "hashid", sha256_hex($ircid));
231
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "date", main::date());
232
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "hostmask", $hostmask);
233
2021-12-17
jrmu
SQLite::set("irc", "id", $ircid, "nick", $nick);
234
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "username", $username);
235
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "email", $email);
236
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "captcha", $captcha);
237
2021-12-17
jrmu
SQLite::set("bnc", "ircid", $ircid, "hashid", $hashid);
238
2023-08-01
jrmu
main::whois($bot, $nick);
239
2023-08-01
jrmu
main::ctcp($bot, $nick);
240
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
241
2023-02-23
jrmu
#main::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
242
2023-02-23
jrmu
#main::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
243
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Type !bnc captcha <text>");
244
2021-12-17
jrmu
foreach my $chan (@teamchans) {
245
2021-12-17
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} bnc captcha is $captcha");
246
2021-12-17
jrmu
}
247
2021-12-17
jrmu
} else {
248
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !bnc <username> <email> to try again.");
249
2021-12-17
jrmu
foreach my $chan (@teamchans) {
250
2023-03-06
jrmu
main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
251
2021-12-17
jrmu
}
252
2021-12-17
jrmu
}
253
2021-12-17
jrmu
}
254
2021-12-17
jrmu
255
2021-12-17
jrmu
sub mregex {
256
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
257
2021-12-17
jrmu
if (!main::isstaff($bot, $nick)) { return; }
258
2021-12-17
jrmu
if ($text =~ /^ips?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
259
2021-12-17
jrmu
my $ips = $1; # space-separated list of IPs
260
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
261
2021-12-17
jrmu
} elsif ($text =~ /^users?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
262
2021-12-17
jrmu
my $users = $1; # space-separated list of usernames
263
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $nick :".regexlist($users));
264
2021-12-17
jrmu
} elsif ($text =~ /^[-_()|0-9A-Za-z:,\.?*\s]{3,}$/) {
265
2021-12-17
jrmu
my @lines = regex($text);
266
2021-12-17
jrmu
foreach my $l (@lines) { print "$l\n"; }
267
2021-12-17
jrmu
}
268
2021-12-17
jrmu
}
269
2021-12-17
jrmu
sub mforeach {
270
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
271
2021-12-17
jrmu
if ($staff !~ /$nick/) { return; }
272
2021-12-17
jrmu
if ($text =~ /^network\s+del\s+([[:graph:]]+)\s+(#[[:graph:]]+)$/) {
273
2021-12-17
jrmu
my ($user, $chan) = ($1, $2);
274
2023-02-17
jrmu
foreach my $n (@networks) {
275
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
276
2021-12-17
jrmu
}
277
2021-12-17
jrmu
}
278
2021-12-17
jrmu
}
279
2021-12-17
jrmu
280
2021-12-17
jrmu
sub mcontrolpanel {
281
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
282
2021-12-17
jrmu
my ($chan, $text);
283
2021-12-17
jrmu
if (@args == 2) {
284
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
285
2021-12-17
jrmu
} else { $text = $args[0]; }
286
2021-12-17
jrmu
my $hostmask = "$nick!$host";
287
2021-12-17
jrmu
if($hostmask eq '*controlpanel!znc@znc.in') {
288
2021-12-17
jrmu
if ($text =~ /^Error: User \[cloneuser\] does not exist/) {
289
2021-12-17
jrmu
createclone($bot);
290
2023-03-06
jrmu
main::putserv($bot, "PRIVMSG *status :loadmod blockuser");
291
2021-12-17
jrmu
foreach my $chan (@teamchans) {
292
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :Cloneuser created");
293
2021-12-17
jrmu
}
294
2021-12-17
jrmu
} elsif ($text =~ /^User (.*) added!$/) {
295
2021-12-17
jrmu
main::debug(ALL, "User $1 created");
296
2021-12-17
jrmu
} elsif ($text =~ /^Password has been changed!$/) {
297
2021-12-17
jrmu
main::debug(ALL, "Password changed");
298
2021-12-17
jrmu
} elsif ($text =~ /^Queued network (.*) of user (.*) for a reconnect.$/) {
299
2021-12-17
jrmu
main::debug(ALL, "$2 now connecting to $1...");
300
2021-12-17
jrmu
} elsif ($text =~ /^Admin = false/) {
301
2021-12-17
jrmu
foreach my $chan (@teamchans) {
302
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :ERROR: $nick is not admin");
303
2021-12-17
jrmu
}
304
2021-12-17
jrmu
die "ERROR: $nick is not admin";
305
2021-12-17
jrmu
} elsif ($text =~ /^Admin = true/) {
306
2021-12-17
jrmu
main::debug(ALL, "$nick is ZNC admin");
307
2021-12-17
jrmu
} elsif ($text =~ /(.*) = (.*)/) {
308
2021-12-17
jrmu
my ($key, $val) = ($1, $2);
309
2021-12-17
jrmu
main::debug(ALL, "ZNC: $key => $val");
310
2021-12-17
jrmu
} else {
311
2021-12-17
jrmu
main::debug(ERRORS, "Unexpected 290 BNC.pm: $hostmask $text");
312
2021-12-17
jrmu
}
313
2021-12-17
jrmu
}
314
2021-12-17
jrmu
}
315
2021-12-17
jrmu
sub loadlog {
316
2021-12-17
jrmu
open(my $fh, '<', "$znclog") or die "Could not read file 'znc.log' $!";
317
2021-12-17
jrmu
chomp(@logs = <$fh>);
318
2021-12-17
jrmu
close $fh;
319
2021-12-17
jrmu
}
320
2021-12-17
jrmu
321
2021-12-17
jrmu
# return all lines matching a pattern
322
2021-12-17
jrmu
sub regex {
323
2021-12-17
jrmu
my ($pattern) = @_;
324
2021-12-17
jrmu
if (!@logs) { loadlog(); }
325
2021-12-17
jrmu
return grep(/$pattern/, @logs);
326
2021-12-17
jrmu
}
327
2021-12-17
jrmu
328
2021-12-17
jrmu
# given a list of IPs, return matching users
329
2021-12-17
jrmu
# or given a list of users, return matching IPs
330
2021-12-17
jrmu
sub regexlist {
331
2021-12-17
jrmu
my ($items) = @_;
332
2021-12-17
jrmu
my @items = split /[,\s]+/m, $items;
333
2021-12-17
jrmu
my $pattern = "(".join('|', @items).")";
334
2021-12-17
jrmu
if (!@logs) { loadlog(); }
335
2021-12-17
jrmu
my @matches = grep(/$pattern/, @logs);
336
2021-12-17
jrmu
my @results;
337
2021-12-17
jrmu
foreach my $match (@matches) {
338
2021-12-17
jrmu
if ($match =~ /^\[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\] \[([^]\/]+)(\/[^]]+)?\] connected to ZNC from (.*)/) {
339
2021-12-17
jrmu
my ($user, $ip) = ($1, $3);
340
2021-12-17
jrmu
if ($items =~ /[.:]/) { # items are IP addresses
341
2021-12-17
jrmu
push(@results, $user);
342
2021-12-17
jrmu
} else { # items are users
343
2021-12-17
jrmu
push(@results, $ip);
344
2021-12-17
jrmu
}
345
2021-12-17
jrmu
}
346
2021-12-17
jrmu
}
347
2021-12-17
jrmu
my @sorted = sort @results;
348
2021-12-17
jrmu
@results = do { my %seen; grep { !$seen{$_}++ } @sorted }; # uniq
349
2021-12-17
jrmu
return join(' ', @results);
350
2021-12-17
jrmu
}
351
2021-12-17
jrmu
352
2021-12-17
jrmu
sub createclone {
353
2021-12-17
jrmu
my ($bot) = @_;
354
2021-12-17
jrmu
my $socket = $bot->{sock};
355
2021-12-17
jrmu
my $password = Hash::newpass();
356
2021-12-17
jrmu
my $msg = <<"EOF";
357
2021-12-17
jrmu
adduser cloneuser $password
358
2021-12-17
jrmu
set Nick cloneuser cloneuser
359
2021-12-17
jrmu
set Altnick cloneuser cloneuser_
360
2021-12-17
jrmu
set Ident cloneuser cloneuser
361
2021-12-17
jrmu
set RealName cloneuser cloneuser
362
2021-12-17
jrmu
set MaxNetworks cloneuser 1000
363
2021-12-17
jrmu
set ChanBufferSize cloneuser 1000
364
2021-12-17
jrmu
set MaxQueryBuffers cloneuser 1000
365
2021-12-17
jrmu
set QueryBufferSize cloneuser 1000
366
2021-12-17
jrmu
set NoTrafficTimeout cloneuser 600
367
2021-12-17
jrmu
set QuitMsg cloneuser IRCNow and Forever!
368
2021-12-17
jrmu
set RealName cloneuser cloneuser
369
2021-12-17
jrmu
set DenySetBindHost cloneuser true
370
2021-12-17
jrmu
set Timezone cloneuser US/Pacific
371
2021-12-17
jrmu
LoadModule cloneuser controlpanel
372
2021-12-17
jrmu
LoadModule cloneuser chansaver
373
2021-12-17
jrmu
EOF
374
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
375
2023-02-17
jrmu
foreach my $n (@networks) {
376
2021-12-17
jrmu
my $net = $n->{name};
377
2021-12-17
jrmu
my $server = $n->{server};
378
2021-12-17
jrmu
my $port = $n->{port};
379
2021-12-17
jrmu
my $trustcerts = $n->{trustcerts};
380
2021-12-17
jrmu
$msg = <<"EOF";
381
2021-12-17
jrmu
addnetwork cloneuser $net
382
2021-12-17
jrmu
addserver cloneuser $net $server $port
383
2021-12-17
jrmu
disconnect cloneuser $net
384
2021-12-17
jrmu
EOF
385
2021-12-17
jrmu
if ($trustcerts) {
386
2021-12-17
jrmu
$msg .= "SetNetwork TrustAllCerts cloneuser $net True\r\n";
387
2021-12-17
jrmu
}
388
2021-12-17
jrmu
my @chans = split /[,\s]+/m, $chans;
389
2021-12-17
jrmu
foreach my $chan (@chans) {
390
2021-12-17
jrmu
$msg .= "addchan cloneuser $net $chan\r\n";
391
2021-12-17
jrmu
}
392
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
393
2021-12-17
jrmu
}
394
2021-12-17
jrmu
}
395
2021-12-17
jrmu
396
2023-10-08
izzyb
sub bncExists {
397
2023-10-08
izzyb
my ($bot, $username) = @_;
398
2023-10-08
izzyb
return 1 if (main::isstaff($bot, $username));
399
2023-10-08
izzyb
if (!defined($SQLite::dbh)) { SQLite::connectdb() || die "Can't open database"; }
400
2023-10-08
izzyb
my $dbh = $SQLite::dbh;
401
2023-10-08
izzyb
my $exists = $dbh->selectrow_array(
402
2023-10-08
izzyb
"SELECT count(*) FROM BNC WHERE username = ? and password is not null",
403
2023-10-08
izzyb
undef,$username
404
2023-10-08
izzyb
); #count will be only element in array
405
2023-10-08
izzyb
return $exists; #should be 0 if it doesnt exist
406
2023-10-08
izzyb
#XXX Need to add signaling to query znc directly.
407
2023-10-08
izzyb
}
408
2023-10-08
izzyb
409
2023-10-08
izzyb
410
2023-10-08
izzyb
411
2021-12-17
jrmu
sub createbnc {
412
2021-12-17
jrmu
my ($bot, $username, $password, $bindhost) = @_;
413
2021-12-17
jrmu
my $netname = $bot->{name};
414
2021-12-17
jrmu
my $msg = <<"EOF";
415
2021-12-17
jrmu
cloneuser cloneuser $username
416
2021-12-17
jrmu
set Nick $username $username
417
2021-12-17
jrmu
set Altnick $username ${username}_
418
2021-12-17
jrmu
set Ident $username $username
419
2021-12-17
jrmu
set RealName $username $username
420
2021-12-17
jrmu
set Password $username $password
421
2021-12-17
jrmu
set MaxNetworks $username 1000
422
2021-12-17
jrmu
set ChanBufferSize $username 1000
423
2021-12-17
jrmu
set MaxQueryBuffers $username 1000
424
2021-12-17
jrmu
set QueryBufferSize $username 1000
425
2021-12-17
jrmu
set NoTrafficTimeout $username 600
426
2021-12-17
jrmu
set QuitMsg $username IRCNow and Forever!
427
2021-12-17
jrmu
set BindHost $username $bindhost
428
2021-12-17
jrmu
set DCCBindHost $username $bindhost
429
2021-12-17
jrmu
set DenySetBindHost $username true
430
2021-12-17
jrmu
reconnect $username $netname
431
2021-12-17
jrmu
EOF
432
2021-12-17
jrmu
#set Language $username en-US
433
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG *controlpanel :$msg");
434
2021-12-17
jrmu
return 1;
435
2021-12-17
jrmu
}
436
2023-06-30
jrmu
sub mailbncApproved {
437
2023-06-30
jrmu
my( $username, $email, $password)=@_;
438
2023-06-30
jrmu
my $body = <<"EOF";
439
2023-06-30
jrmu
Welcome to $conf{localnet}!
440
2021-12-17
jrmu
441
2023-03-05
jrmu
You created a bouncer:
442
2023-03-05
jrmu
443
2021-12-17
jrmu
Username: $username
444
2021-12-17
jrmu
Password: $password
445
2023-05-06
jrmu
Server: $bnchostname
446
2021-12-17
jrmu
Port: $sslport for SSL (secure connection)
447
2021-12-17
jrmu
Port: $plainport for plaintext
448
2023-03-05
jrmu
Webpanel: $webpanel
449
2021-12-17
jrmu
450
2023-06-30
jrmu
Connection Instructions: https://wiki.ircnow.org/?n=Bouncer.Bouncer
451
2021-12-17
jrmu
452
2023-06-30
jrmu
Enjoy!
453
2023-06-30
jrmu
454
2023-06-30
jrmu
$conf{localnet}
455
2023-06-30
jrmu
IRCNow Federation
456
2021-12-17
jrmu
EOF
457
2023-06-30
jrmu
main::mail($mailfrom, $email, $mailname, "Your $conf{localnet} Bouncer", $body);
458
2021-12-17
jrmu
}
459
2021-12-17
jrmu
460
2023-06-30
jrmu
sub mailbncPending {
461
2023-06-30
jrmu
my( $username, $email)=@_;
462
2023-06-30
jrmu
my $body = <<"EOF";
463
2023-06-30
jrmu
Welcome to $conf{localnet}!
464
2023-06-30
jrmu
465
2023-06-30
jrmu
Your bouncer needs to be approved by staff ($staff).
466
2023-06-30
jrmu
Please reply to this email and contact them over IRC.
467
2023-06-30
jrmu
468
2023-06-30
jrmu
Once $staff have been contacted, they will send you login
469
2023-06-30
jrmu
instructions. This may take up to 48 hours.
470
2023-06-30
jrmu
471
2023-06-30
jrmu
$conf{localnet}
472
2023-06-30
jrmu
IRCNow Federation
473
2023-06-30
jrmu
EOF
474
2023-06-30
jrmu
main::mail($mailfrom, $email, $mailname, "Confirm $conf{localnet} Bouncer", $body);
475
2023-06-30
jrmu
}
476
2023-06-30
jrmu
477
2021-12-17
jrmu
sub mtaillog {
478
2023-06-30
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
479
2021-12-17
jrmu
my ($chan, $text);
480
2021-12-17
jrmu
if (@args == 2) {
481
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
482
2021-12-17
jrmu
} else { $text = $args[0]; }
483
2021-12-17
jrmu
my $hostmask = "$nick!$host";
484
2021-12-17
jrmu
open(my $fh, "-|", "/usr/bin/tail", "-f", $znclog) or die "could not start tail: $!";
485
2021-12-17
jrmu
while (my $line = <$fh>) {
486
2021-12-17
jrmu
foreach my $chan (@teamchans) {
487
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$line");
488
2021-12-17
jrmu
}
489
2021-12-17
jrmu
}
490
2021-12-17
jrmu
}
491
2021-12-17
jrmu
492
2021-12-17
jrmu
sub mlastseen {
493
2021-12-17
jrmu
my ($bot, $nick, $host, $hand, @args) = @_;
494
2021-12-17
jrmu
my ($chan, $text);
495
2021-12-17
jrmu
if (@args == 2) {
496
2021-12-17
jrmu
($chan, $text) = ($args[0], $args[1]);
497
2021-12-17
jrmu
} else { $text = $args[0]; }
498
2021-12-17
jrmu
my $hostmask = "$nick!$host";
499
2021-12-17
jrmu
if (!@logs) { loadlog(); }
500
2023-02-10
jrmu
#my @users = treeget($znctree, "User", "Node");
501
2021-12-17
jrmu
foreach my $user (@users) {
502
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);
503
2021-12-17
jrmu
if (scalar(@lines) == 0) {
504
2021-12-17
jrmu
foreach my $chan (@teamchans) {
505
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$user never logged in");
506
2021-12-17
jrmu
}
507
2021-12-17
jrmu
next;
508
2021-12-17
jrmu
}
509
2021-12-17
jrmu
my $recent = pop(@lines);
510
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:]+/) {
511
2021-12-17
jrmu
my $date = $1;
512
2021-12-17
jrmu
foreach my $chan (@teamchans) {
513
2021-12-17
jrmu
main::putserv($bot, "PRIVMSG $chan :$user $date");
514
2021-12-17
jrmu
}
515
2021-12-17
jrmu
}
516
2021-12-17
jrmu
}
517
2021-12-17
jrmu
}
518
2021-12-17
jrmu
#sub resend {
519
2021-12-17
jrmu
# my ($bot, $newnick, $email) = @_;
520
2021-12-17
jrmu
# my $password = newpass();
521
2021-12-17
jrmu
# sendmsg($bot, "*controlpanel", "set Password $newnick $password");
522
2021-12-17
jrmu
# mailverify($newnick, $email, $password, "bouncer");
523
2021-12-17
jrmu
# sendmsg($bot, "$newnick", "Email sent");
524
2021-12-17
jrmu
#}
525
2021-12-17
jrmu
526
2023-02-22
jrmu
#`doas chown znc:daemon /home/znc/home/znc/.znc/configs/znc.conf`;
527
2023-02-22
jrmu
528
2021-12-17
jrmu
# if ($reply =~ /^!resend ([-_0-9a-zA-Z]+) ([-_0-9a-zA-Z]+@[-_0-9a-zA-Z]+\.[-_0-9a-zA-Z]+)$/i) {
529
2021-12-17
jrmu
# my ($newnick, $email) = ($1, $2);
530
2021-12-17
jrmu
# my $password = newpass();
531
2021-12-17
jrmu
# resend($bot, $newnick, $email);
532
2021-12-17
jrmu
# }
533
2021-12-17
jrmu
534
2021-12-17
jrmu
#sub resetznc {
535
2021-12-17
jrmu
#
536
2021-12-17
jrmu
#AnonIPLimit 10000
537
2021-12-17
jrmu
#AuthOnlyViaModule false
538
2021-12-17
jrmu
#ConnectDelay 0
539
2021-12-17
jrmu
#HideVersion true
540
2021-12-17
jrmu
#LoadModule
541
2021-12-17
jrmu
#ServerThrottle
542
2021-12-17
jrmu
#1337 209.141.38.137
543
2021-12-17
jrmu
#31337 209.141.38.137
544
2021-12-17
jrmu
#1337 2605:6400:20:5cc::
545
2021-12-17
jrmu
#31337 2605:6400:20:5cc::
546
2021-12-17
jrmu
#1337 127.0.0.1
547
2021-12-17
jrmu
#1338 127.0.0.1
548
2021-12-17
jrmu
#}
549
2021-12-17
jrmu
#
550
2021-12-17
jrmu
#alias Provides bouncer-side command alias support.
551
2021-12-17
jrmu
#autoreply Reply to queries when you are away
552
2021-12-17
jrmu
#block_motd Block the MOTD from IRC so it's not sent to your client(s).
553
2021-12-17
jrmu
#bouncedcc Bounces DCC transfers through ZNC instead of sending them directly to the user.
554
2021-12-17
jrmu
#clientnotify Notifies you when another IRC client logs into or out of your account. Configurable.
555
2021-12-17
jrmu
#ctcpflood Don't forward CTCP floods to clients
556
2021-12-17
jrmu
#dcc This module allows you to transfer files to and from ZNC
557
2021-12-17
jrmu
#perform Keeps a list of commands to be executed when ZNC connects to IRC.
558
2021-12-17
jrmu
#webadmin Web based administration module.
559
2021-12-17
jrmu
560
2023-02-22
jrmu
#my $zncconfpath = $conf{zncconfpath} || "$zncdir/.znc/configs/znc.conf";
561
2023-02-22
jrmu
#my $znctree = { Node => "root" };
562
2023-02-22
jrmu
#znc.conf file
563
2023-02-22
jrmu
#unveil("$zncconfpath", "r") or die "Unable to unveil $!";
564
2023-02-22
jrmu
#dependencies for figlet
565
2023-02-22
jrmu
#znc.log file
566
2023-02-22
jrmu
#unveil("$znclog", "r") or die "Unable to unveil $!";
567
2023-02-22
jrmu
#print treeget($znctree, "AnonIPLimit")."\n";
568
2023-02-22
jrmu
#print treeget($znctree, "ServerThrottle")."\n";
569
2023-02-22
jrmu
#print treeget($znctree, "ConnectDelay")."\n";
570
2023-02-22
jrmu
#print "treeget\n";
571
2023-02-22
jrmu
#print Dumper \treeget($znctree, "User", "Node");
572
2023-02-22
jrmu
#print Dumper \treeget($znctree, "User", "Network", "Node");
573
2023-02-22
jrmu
#my @zncconf = main::readarray($zncconfpath);
574
2023-02-22
jrmu
#$znctree;
575
2023-02-22
jrmu
#foreach my $line (@zncconf) {
576
2023-02-22
jrmu
# if ($line =~ /<User (.*)>/) {
577
2023-02-22
jrmu
# push(@users, $1);
578
2023-02-22
jrmu
# }
579
2023-02-22
jrmu
#}
580
2023-02-22
jrmu
#$znctree = parseml($znctree, @zncconf);
581
2021-12-17
jrmu
582
2023-02-22
jrmu
## parseml($tree, @lines)
583
2023-02-22
jrmu
## tree is a reference to a hash
584
2023-02-22
jrmu
## returns hash ref of tree
585
2023-02-22
jrmu
#sub parseml {
586
2023-02-22
jrmu
# my ($tree, @lines) = @_;
587
2023-02-22
jrmu
# #if (scalar(@lines) == 0) { return $tree; }
588
2023-02-22
jrmu
# while (scalar(@lines) > 0) {
589
2023-02-22
jrmu
# my $line = shift(@lines);
590
2023-02-22
jrmu
# if ($line =~ /^\s*([^=<>\s]+)\s*=\s*([^=<>]+)\s*$/) {
591
2023-02-22
jrmu
# my ($tag, $val) = ($1, $2);
592
2023-02-22
jrmu
# $tree->{$tag} = $val;
593
2023-02-22
jrmu
# } elsif ($line =~ /^\/\//) { # skip comments
594
2023-02-22
jrmu
# } elsif ($line =~ /^\s*$/) { # skip blank lines
595
2023-02-22
jrmu
# } elsif ($line =~ /^\s*<([^>\s\/]+)\s*([^>\/]*)>\s*$/) {
596
2023-02-22
jrmu
# my ($tag, $val) = ($1, $2);
597
2023-02-22
jrmu
# if (!defined($tree->{$tag})) { $tree->{$tag} = []; }
598
2023-02-22
jrmu
# my @newlines;
599
2023-02-22
jrmu
# while (scalar(@lines) > 0) {
600
2023-02-22
jrmu
# my $line = shift(@lines);
601
2023-02-22
jrmu
# if ($line =~ /^\s*<\/$tag>\s*$/) {
602
2023-02-22
jrmu
# my $subtree = parseml({ Node => $val }, @newlines);
603
2023-02-22
jrmu
# push(@{$tree->{$tag}}, $subtree);
604
2023-02-22
jrmu
# return parseml($tree, @lines);
605
2023-02-22
jrmu
# }
606
2023-02-22
jrmu
# push(@newlines, $line);
607
2023-02-22
jrmu
# }
608
2023-02-22
jrmu
# } else { print "ERROR: $line\n"; }
609
2023-02-22
jrmu
# #TODO ERRORS not defined??
610
2023-02-22
jrmu
## } else { main::debug(ERRORS, "ERROR: $line"); }
611
2023-02-22
jrmu
# }
612
2023-02-22
jrmu
# return $tree;
613
2023-02-22
jrmu
#}
614
2023-02-22
jrmu
#
615
2023-02-22
jrmu
##Returns array of all values
616
2023-02-22
jrmu
##treeget($tree, "User");
617
2023-02-22
jrmu
#sub treeget {
618
2023-02-22
jrmu
# my ($tree, @keys) = @_;
619
2023-02-22
jrmu
# my $subtree;
620
2023-02-22
jrmu
# my @rest = @keys;
621
2023-02-22
jrmu
# my $key = shift(@rest);
622
2023-02-22
jrmu
# $subtree = $tree->{$key};
623
2023-02-22
jrmu
# if (!defined($subtree)) {
624
2023-02-22
jrmu
# return ("Undefined");
625
2023-02-22
jrmu
# } elsif (ref($subtree) eq 'HASH') {
626
2023-02-22
jrmu
# return treeget($subtree, @rest);
627
2023-02-22
jrmu
# } elsif (ref($subtree) eq 'ARRAY') {
628
2023-02-22
jrmu
# my @array = @{$subtree};
629
2023-02-22
jrmu
# my @ret;
630
2023-02-22
jrmu
# foreach my $hashref (@array) {
631
2023-02-22
jrmu
# push(@ret, treeget($hashref, @rest));
632
2023-02-22
jrmu
# }
633
2023-02-22
jrmu
# return @ret;
634
2023-02-22
jrmu
# #my @array = @{$subtree};
635
2023-02-22
jrmu
# #print Dumper treeget($hashref, @rest);
636
2023-02-22
jrmu
# #print Dumper treeget({$key => $subtree}, @rest);
637
2023-02-22
jrmu
# #return (treeget($hashref, @rest), treeget({$key => $subtree}, @rest));
638
2023-02-22
jrmu
# } else {
639
2023-02-22
jrmu
# return ($subtree);
640
2023-02-22
jrmu
# }
641
2023-02-22
jrmu
#}
642
2023-02-22
jrmu
643
2023-02-22
jrmu
644
2021-12-17
jrmu
1; # MUST BE LAST STATEMENT IN FILE
IRCNow