Blame
Date:
Sun Oct 8 22:28:02 2023 UTC
Message:
Now prevents creating accounts that exist in database with a password
001
2023-02-10
jrmu
#!/usr/bin/perl
002
2023-02-10
jrmu
003
2023-02-10
jrmu
use strict;
004
2023-02-10
jrmu
use warnings;
005
2023-02-10
jrmu
no strict 'refs';
006
2023-02-10
jrmu
use IO::Socket;
007
2023-02-10
jrmu
use IO::Select;
008
2023-02-10
jrmu
use OpenBSD::Pledge;
009
2023-02-10
jrmu
use OpenBSD::Unveil;
010
2023-03-07
jrmu
use File::Copy qw(copy);
011
2023-03-07
jrmu
use File::Basename;
012
2023-02-10
jrmu
013
2023-03-07
jrmu
# Path to configuration file
014
2023-03-07
jrmu
my $confpath = "botnow.conf";
015
2023-03-07
jrmu
my $backupspath = "/home/botnow/backups/";
016
2023-03-07
jrmu
017
2023-03-07
jrmu
# Returns date in YYYYMMDD format
018
2023-03-07
jrmu
sub date {
019
2023-03-07
jrmu
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
020
2023-03-07
jrmu
my $localtime = sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday);
021
2023-03-07
jrmu
return $localtime;
022
2023-03-07
jrmu
}
023
2023-03-07
jrmu
024
2023-02-10
jrmu
# Read from filename and return array of lines without trailing newlines
025
2023-02-10
jrmu
sub readarray {
026
2023-02-10
jrmu
my ($filename) = @_;
027
2023-02-10
jrmu
open(my $fh, '<', $filename) or die "Could not read file '$filename' $!";
028
2023-02-10
jrmu
chomp(my @lines = <$fh>);
029
2023-02-10
jrmu
close $fh;
030
2023-02-10
jrmu
return @lines;
031
2023-02-10
jrmu
}
032
2023-02-10
jrmu
033
2023-02-10
jrmu
# Read from filename and return as string
034
2023-02-10
jrmu
sub readstr {
035
2023-02-10
jrmu
my ($filename) = @_;
036
2023-02-10
jrmu
open(my $fh, '<', $filename) or die "Could not read file '$filename' $!";
037
2023-02-10
jrmu
my $str = do { local $/; <$fh> };
038
2023-02-10
jrmu
close $fh;
039
2023-02-10
jrmu
return $str;
040
2023-02-10
jrmu
}
041
2023-02-10
jrmu
042
2023-02-10
jrmu
# Write str to filename
043
2023-02-10
jrmu
sub writefile {
044
2023-02-10
jrmu
my ($filename, $str) = @_;
045
2023-03-07
jrmu
my $date = date();
046
2023-03-07
jrmu
copy($filename, $backupspath.basename($filename).".".date()) or die "Could not make backup of $filename";
047
2023-02-10
jrmu
open(my $fh, '>', "$filename") or die "Could not write to $filename";
048
2023-02-10
jrmu
print $fh $str;
049
2023-02-10
jrmu
close $fh;
050
2023-02-10
jrmu
}
051
2023-02-10
jrmu
052
2023-02-10
jrmu
# Append str to filename
053
2023-02-10
jrmu
sub appendfile {
054
2023-02-10
jrmu
my ($filename, $str) = @_;
055
2023-02-10
jrmu
open(my $fh, '>>', "$filename") or die "Could not append to $filename";
056
2023-02-10
jrmu
print $fh $str;
057
2023-02-10
jrmu
close $fh;
058
2023-02-10
jrmu
}
059
2023-02-10
jrmu
060
2023-02-19
jrmu
# Returns timestamp in "Day MM DD HH:MM:SS" format
061
2023-02-19
jrmu
sub gettime {
062
2023-02-19
jrmu
my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
063
2023-02-19
jrmu
my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
064
2023-02-19
jrmu
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
065
2023-02-19
jrmu
my $localtime = sprintf("%s %s %d %02d:%02d:%02d", $days[$wday], $months[$mon], $mday, $hour, $min, $sec);
066
2023-02-19
jrmu
return $localtime;
067
2023-02-19
jrmu
}
068
2023-02-19
jrmu
069
2023-08-01
jrmu
# Send email using sendmail
070
2023-03-07
jrmu
sub mail {
071
2023-03-07
jrmu
my( $from, $to, $fromname, $subject, $body )=@_;
072
2023-03-07
jrmu
my $msg = <<"EOF";
073
2023-03-07
jrmu
From: $from
074
2023-03-07
jrmu
To: $to
075
2023-03-07
jrmu
Subject: $subject
076
2023-03-07
jrmu
MIME-Version: 1.0
077
2023-03-07
jrmu
Content-Type: text/plain; charset=us-ascii
078
2023-03-07
jrmu
Content-Disposition: inline
079
2023-03-07
jrmu
080
2023-03-07
jrmu
$body
081
2023-03-07
jrmu
EOF
082
2023-03-07
jrmu
open(my $fh, "| /usr/sbin/sendmail -tv -F '$fromname' -f $from") or die "Could not send mail $!";
083
2023-03-07
jrmu
print $fh $msg;
084
2023-03-07
jrmu
close $fh;
085
2023-03-07
jrmu
return "true";
086
2023-03-07
jrmu
}
087
2023-03-07
jrmu
088
2023-02-10
jrmu
# Configuration variables will be stored in key => value pairs
089
2023-02-10
jrmu
our %conf;
090
2023-02-10
jrmu
091
2023-02-10
jrmu
foreach my $line (readarray($confpath)) {
092
2023-02-10
jrmu
if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace
093
2023-02-10
jrmu
next;
094
2023-02-10
jrmu
} elsif ($line =~ /^([-_a-zA-Z0-9]+)\s*=\s*([[:print:]]+)$/) {
095
2023-02-10
jrmu
$conf{$1} = $2;
096
2023-02-10
jrmu
} else {
097
2023-02-10
jrmu
die "ERROR: botnow.conf format invalid: $line";
098
2023-02-10
jrmu
}
099
2023-02-10
jrmu
}
100
2023-02-10
jrmu
101
2023-02-10
jrmu
# Name of local network
102
2023-02-10
jrmu
$conf{localnet} = $conf{localnet} or die "ERROR: botnow.conf: localnet";
103
2023-02-10
jrmu
104
2023-02-10
jrmu
# Internal IPv4 address and plaintext port
105
2023-02-10
jrmu
$conf{host} = $conf{host} || "127.0.0.1";
106
2023-02-10
jrmu
$conf{port} = $conf{port} || 1337;
107
2023-02-10
jrmu
108
2023-02-10
jrmu
# Bouncer hostname
109
2023-02-10
jrmu
chomp($conf{hostname} = $conf{hostname} || `hostname`);
110
2023-02-10
jrmu
111
2023-03-07
jrmu
# Mail hostname
112
2023-03-07
jrmu
chomp($conf{mailhostname} = $conf{mailhostname} || `hostname`);
113
2023-03-07
jrmu
114
2023-03-05
jrmu
# Webpanel URL
115
2023-03-05
jrmu
chomp($conf{webpanel} = $conf{webpanel} || "https://bnc.$conf{hostname}");
116
2023-03-05
jrmu
117
2023-03-07
jrmu
# Webmail URL
118
2023-03-07
jrmu
chomp($conf{webmail} = $conf{webmail} || "https://mail.$conf{hostname}");
119
2023-03-07
jrmu
120
2023-02-10
jrmu
# External IPv4 address, plaintext and ssl port
121
2023-02-10
jrmu
$conf{ip4} = $conf{ip4} or die "ERROR: botnow.conf: ip4";
122
2023-02-10
jrmu
$conf{ip6} = $conf{ip6} or die "ERROR: botnow.conf: ip6";
123
2023-02-10
jrmu
$conf{ip6subnet} = $conf{ip6subnet} or die "ERROR: botnow.conf: ip6subnet";
124
2023-02-10
jrmu
$conf{ip6prefix} = $conf{ip6prefix} or die "ERROR: botnow.conf: ip6prefix";
125
2023-02-10
jrmu
$conf{plainport} = $conf{plainport} || 1337;
126
2023-02-10
jrmu
$conf{sslport} = $conf{sslport} || 31337;
127
2023-03-05
jrmu
$conf{imapport} = $conf{imapport} || 143;
128
2023-03-05
jrmu
$conf{smtpport} = $conf{smtpport} || 587;
129
2023-02-10
jrmu
130
2023-02-10
jrmu
# Nick and password of bot -- Make sure to add to oper block
131
2023-02-10
jrmu
$conf{nick} = $conf{nick} or die "ERROR: botnow.conf: nick";
132
2023-02-10
jrmu
$conf{pass} = $conf{pass} or die "ERROR: botnow.conf: pass";
133
2023-02-10
jrmu
134
2023-02-10
jrmu
# Comma-separated list of channels for requesting bouncers
135
2023-02-10
jrmu
$conf{chans} = $conf{chans} or die "ERROR: botnow.conf: chans";
136
2023-02-10
jrmu
137
2023-02-17
jrmu
my @networks;
138
2023-02-17
jrmu
if (defined($conf{networks})) {
139
2023-02-17
jrmu
@networks = split(/\s+/, $conf{networks});
140
2023-02-17
jrmu
}
141
2023-02-10
jrmu
142
2023-02-10
jrmu
# Mail from address
143
2023-02-10
jrmu
if (!defined($conf{mailname})) {
144
2023-02-10
jrmu
if ($conf{mailfrom} =~ /^([^@]+)@/) {
145
2023-02-10
jrmu
$conf{mailname} = $1 or die "ERROR: botnow.conf mailname";
146
2023-02-10
jrmu
}
147
2023-02-10
jrmu
}
148
2023-02-10
jrmu
149
2023-08-01
jrmu
# Terms of Service
150
2023-02-17
jrmu
$conf{terms} = $conf{terms} or die "ERROR: botnow.conf terms";
151
2023-02-17
jrmu
152
2023-02-17
jrmu
# Number of words in password
153
2023-02-17
jrmu
$conf{passlength} = $conf{passlength} || 3;
154
2023-02-17
jrmu
155
2023-02-17
jrmu
# Time before captcha expires
156
2023-02-17
jrmu
$conf{expires} = $conf{expires} || 1800;
157
2023-02-17
jrmu
158
2023-02-10
jrmu
# NSD zone dir
159
2023-02-10
jrmu
$conf{zonedir} = $conf{zonedir} || "/var/nsd/zones/master/";
160
2023-02-10
jrmu
161
2023-02-17
jrmu
# ZNC install directory
162
2023-02-17
jrmu
$conf{zncdir} = $conf{zncdir} || "/home/znc/home/znc";
163
2023-02-17
jrmu
164
2023-02-10
jrmu
# Network Interface Config File
165
2023-02-10
jrmu
$conf{hostnameif} = $conf{hostnameif} || "/etc/hostname.vio0";
166
2023-02-10
jrmu
167
2023-02-10
jrmu
# Verbosity: 0 (no errors), 1 (errors), 2 (warnings), 3 (diagnostic)
168
2023-02-10
jrmu
use constant {
169
2023-02-10
jrmu
NONE => 0,
170
2023-02-10
jrmu
ERRORS => 1,
171
2023-02-10
jrmu
WARNINGS => 2,
172
2023-02-10
jrmu
ALL => 3,
173
2023-02-10
jrmu
};
174
2023-08-01
jrmu
175
2023-02-10
jrmu
$conf{verbose} = $conf{verbose} || ERRORS;
176
2023-02-10
jrmu
177
2023-02-10
jrmu
if(defined($conf{die})) { die $conf{die}; }
178
2023-02-10
jrmu
179
2023-02-17
jrmu
my @modules;
180
2023-02-17
jrmu
if (defined($conf{modules})) {
181
2023-02-17
jrmu
@modules = split(/\s+/, $conf{modules});
182
2023-02-17
jrmu
}
183
2023-02-17
jrmu
use lib './';
184
2023-02-17
jrmu
foreach my $mod (@modules) {
185
2023-02-17
jrmu
require "$mod.pm";
186
2023-02-17
jrmu
}
187
2023-02-17
jrmu
foreach my $mod (@modules) {
188
2023-02-17
jrmu
my $init = "${mod}::init";
189
2023-02-17
jrmu
$init->();
190
2023-02-17
jrmu
}
191
2023-02-17
jrmu
192
2023-02-10
jrmu
my @bots;
193
2023-02-10
jrmu
my @chans = split /[,\s]+/m, $conf{chans};
194
2023-02-10
jrmu
my @teamchans;
195
2023-02-10
jrmu
if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; }
196
2023-02-10
jrmu
my $call;
197
2023-02-17
jrmu
my $nick = $conf{nick};
198
2023-02-10
jrmu
my $host = $conf{host};
199
2023-02-10
jrmu
my $port = $conf{port};
200
2023-02-10
jrmu
my $pass = $conf{pass};
201
2023-02-10
jrmu
my $localnet = $conf{localnet};
202
2023-02-10
jrmu
my $staff = $conf{staff};
203
2023-02-10
jrmu
my @stafflist = split(/ /,$staff);
204
2023-02-10
jrmu
my $verbose = $conf{verbose};
205
2023-02-10
jrmu
my $expires = $conf{expires};
206
2023-02-10
jrmu
207
2023-08-01
jrmu
# Unveil limits files and directories that botnow can access
208
2023-02-10
jrmu
unveil("./", "r") or die "Unable to unveil $!";
209
2023-02-10
jrmu
unveil("$confpath", "r") or die "Unable to unveil $!";
210
2023-03-07
jrmu
unveil("$backupspath", "rwc") or die "Unable to unveil $!";
211
2023-06-03
jrmu
unveil("/usr/sbin/sendmail", "rx") or die "Unable to unveil $!";
212
2023-06-03
jrmu
unveil("/bin/sh", "rx") or die "Unable to unveil $!";
213
2023-02-10
jrmu
unveil() or die "Unable to lock unveil $!";
214
2023-02-10
jrmu
215
2023-08-01
jrmu
# Pledge limits botnow's syscalls
216
2023-08-01
jrmu
# dns and inet for sockets, proc and exec for figlet
217
2023-08-01
jrmu
# rpath for reading file, wpath for writing file, cpath for creating path
218
2023-08-01
jrmu
# flock, fattr for sqlite
219
2023-02-10
jrmu
pledge( qw(stdio rpath wpath cpath inet dns proc exec flock fattr) ) or die "Unable to pledge: $!";
220
2023-02-17
jrmu
221
2023-08-01
jrmu
# Writes text to the network socket
222
2023-08-01
jrmu
sub putserv {
223
2023-08-01
jrmu
my( $bot, $text )=@_;
224
2023-08-01
jrmu
my $socket = $bot->{sock};
225
2023-08-01
jrmu
# If a multiline command, write multiple times; else write once
226
2023-08-01
jrmu
if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) {
227
2023-08-01
jrmu
my ($cmd, $line) = ($1, $2);
228
2023-08-01
jrmu
my @lines = split /\r?\n/m, $line;
229
2023-08-01
jrmu
foreach my $l (@lines) {
230
2023-08-01
jrmu
print $socket "$cmd:$l\r\n";
231
2023-08-01
jrmu
}
232
2023-08-01
jrmu
} else {
233
2023-08-01
jrmu
print $socket "$text\r\n";
234
2023-08-01
jrmu
}
235
2023-08-01
jrmu
}
236
2023-08-01
jrmu
237
2023-08-01
jrmu
# Writes text to the local network socket
238
2023-08-01
jrmu
sub putservlocalnet {
239
2023-08-01
jrmu
my( $bot, $text )=@_;
240
2023-08-01
jrmu
foreach my $b (@bots) {
241
2023-08-01
jrmu
if($b->{name} =~ /^$localnet$/i) {
242
2023-08-01
jrmu
putserv($b, $text);
243
2023-08-01
jrmu
return;
244
2023-08-01
jrmu
}
245
2023-08-01
jrmu
}
246
2023-08-01
jrmu
}
247
2023-08-01
jrmu
248
2023-08-01
jrmu
sub whois {
249
2023-08-01
jrmu
my( $bot, $target )=@_;
250
2023-08-01
jrmu
putserv($bot, "WHOIS $target $target\r\n");
251
2023-08-01
jrmu
}
252
2023-08-01
jrmu
253
2023-08-01
jrmu
sub ctcp {
254
2023-08-01
jrmu
my( $bot, $target )=@_;
255
2023-08-01
jrmu
#putserv($bot, "PRIVMSG $target :".chr(01)."CLIENTINFO".chr(01)."\r\n");
256
2023-08-01
jrmu
#putserv($bot, "PRIVMSG $target :".chr(01)."FINGER".chr(01)."\r\n");
257
2023-08-01
jrmu
#putserv($bot, "PRIVMSG $target :".chr(01)."SOURCE".chr(01)."\r\n");
258
2023-08-01
jrmu
putserv($bot, "PRIVMSG $target :".chr(01)."TIME".chr(01)."\r\n");
259
2023-08-01
jrmu
#putserv($bot, "PRIVMSG $target :".chr(01)."USERINFO".chr(01)."\r\n");
260
2023-08-01
jrmu
putserv($bot, "PRIVMSG $target :".chr(01)."VERSION".chr(01)."\r\n");
261
2023-08-01
jrmu
#putserv($bot, "PRIVMSG $target :".chr(01)."PING".chr(01)."\r\n");
262
2023-08-01
jrmu
}
263
2023-08-01
jrmu
264
2023-08-01
jrmu
sub debug {
265
2023-08-01
jrmu
my ($level, $msg) = @_;
266
2023-08-01
jrmu
if ($verbose >= $level) { print "$msg\n"; }
267
2023-08-01
jrmu
}
268
2023-08-01
jrmu
269
2023-08-01
jrmu
sub isstaff {
270
2023-08-01
jrmu
my( $bot, $nick ) = @_;
271
2023-08-01
jrmu
if( !( $bot->{name} =~ /^$localnet$/i ) ) {
272
2023-08-01
jrmu
return 0;
273
2023-08-01
jrmu
}
274
2023-08-01
jrmu
foreach( @stafflist ) {
275
2023-08-01
jrmu
if( $nick eq $_ ) {
276
2023-08-01
jrmu
return 1;
277
2023-08-01
jrmu
}
278
2023-08-01
jrmu
}
279
2023-08-01
jrmu
return 0;
280
2023-08-01
jrmu
}
281
2023-08-01
jrmu
282
2023-08-01
jrmu
283
2023-08-01
jrmu
# Create sockets
284
2023-02-10
jrmu
my $sel = IO::Select->new( );
285
2023-02-17
jrmu
foreach my $network (@networks) {
286
2023-02-10
jrmu
my $socket = IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n";
287
2023-02-10
jrmu
$sel->add($socket);
288
2023-02-10
jrmu
my $bot = {("sock" => $socket), ("name" => $network)};
289
2023-02-10
jrmu
push(@bots, $bot);
290
2023-02-17
jrmu
putserv($bot, "NICK $nick");
291
2023-02-17
jrmu
putserv($bot, "USER $nick * * :$nick");
292
2023-02-10
jrmu
}
293
2023-02-10
jrmu
294
2023-02-10
jrmu
while(my @ready = $sel->can_read) {
295
2023-08-01
jrmu
my ($bot, $response, $sender, $val);
296
2023-02-10
jrmu
foreach my $socket (@ready) {
297
2023-02-10
jrmu
foreach my $b (@bots) {
298
2023-02-10
jrmu
if($socket == $b->{sock}) {
299
2023-02-10
jrmu
$bot = $b;
300
2023-02-10
jrmu
last;
301
2023-02-10
jrmu
}
302
2023-02-10
jrmu
}
303
2023-08-01
jrmu
### TODO: Reconnect if znc crashes
304
2023-02-10
jrmu
if (!defined($response = <$socket>)) {
305
2023-02-10
jrmu
debug(ERRORS, "ERROR ".$bot->{name}." has no response:");
306
2023-02-10
jrmu
next;
307
2023-02-10
jrmu
}
308
2023-02-10
jrmu
if ($response =~ /^PING :(.*)\r\n$/i) {
309
2023-02-10
jrmu
putserv($bot, "PONG :$1");
310
2023-02-10
jrmu
} elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) {
311
2023-02-10
jrmu
my ($type, $target, $text) = ($1, $2, $3);
312
2023-02-19
jrmu
if ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Password required") {
313
2023-02-17
jrmu
putserv($bot, "PASS $nick/$bot->{name}:$pass");
314
2023-02-10
jrmu
if ($bot->{name} =~ /^$localnet$/i) {
315
2023-02-17
jrmu
putserv($bot, "OPER $nick $pass");
316
2023-02-10
jrmu
putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel");
317
2023-02-17
jrmu
putserv($bot, "PRIVMSG *controlpanel :get Admin $nick");
318
2023-02-10
jrmu
putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
319
2023-02-10
jrmu
foreach my $chan (@teamchans) {
320
2023-02-10
jrmu
putserv($bot, "JOIN $chan");
321
2023-02-10
jrmu
}
322
2023-02-10
jrmu
}
323
2023-02-10
jrmu
if ($bot->{name} !~ /^$localnet$/i) {
324
2023-02-10
jrmu
foreach my $chan (@chans) {
325
2023-02-10
jrmu
putserv($bot, "JOIN $chan");
326
2023-02-10
jrmu
}
327
2023-02-10
jrmu
}
328
2023-02-17
jrmu
} elsif ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Invalid Password") {
329
2023-02-10
jrmu
die "ERROR: Wrong Username/Password: $bot->{name}";
330
2023-02-10
jrmu
} else {
331
2023-02-19
jrmu
debug(ALL, "Debug type: $type, target: $target, text: $text");
332
2023-02-10
jrmu
}
333
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) {
334
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $target, $text) = ($1, $2, $3, $4, $5);
335
2023-02-17
jrmu
if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$nick.?$/) {
336
2023-02-10
jrmu
if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) {
337
2023-02-17
jrmu
debug(ERRORS, "ERROR: nonexistent: $1");
338
2023-02-10
jrmu
} elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") {
339
2023-02-17
jrmu
debug(ERRORS, "ERROR: disconnected: $bot->{name}");
340
2023-02-10
jrmu
} elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) {
341
2023-02-10
jrmu
debug(ALL, "Module $1 already loaded\n");
342
2023-02-10
jrmu
} elsif ($text =~ /^Disconnected from IRC.*$/) {
343
2023-02-17
jrmu
debug(ERRORS, "ERROR: $bot->{name}: $text");
344
2023-02-10
jrmu
} elsif ($text =~ /^|/) {
345
2023-02-17
jrmu
debug(ERRORS, "ERROR: $bot->{name}: $text");
346
2023-02-10
jrmu
} else {
347
2023-02-17
jrmu
debug(ERRORS, "ERROR: Unexpected: $response");
348
2023-02-10
jrmu
}
349
2023-02-10
jrmu
} elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) {
350
2023-02-10
jrmu
my ($cmd, $text) = ($1, $2);
351
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
352
2023-02-10
jrmu
if ($target =~ /^#/) {
353
2023-02-10
jrmu
foreach my $c (@{$call->{pub}}) {
354
2023-02-10
jrmu
if ($cmd eq $c->{cmd}) {
355
2023-02-10
jrmu
my $proc = $c->{proc};
356
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $target, $text);
357
2023-02-10
jrmu
}
358
2023-02-10
jrmu
}
359
2023-02-10
jrmu
} else {
360
2023-02-10
jrmu
foreach my $c (@{$call->{msg}}) {
361
2023-02-10
jrmu
if ($cmd eq $c->{cmd}) {
362
2023-02-10
jrmu
my $proc = $c->{proc};
363
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $text);
364
2023-02-10
jrmu
}
365
2023-02-10
jrmu
}
366
2023-02-10
jrmu
}
367
2023-02-10
jrmu
} else {
368
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
369
2023-02-10
jrmu
if ($target =~ /^#/) {
370
2023-02-10
jrmu
foreach my $c (@{$call->{pubm}}) {
371
2023-02-10
jrmu
my $proc = $c->{proc};
372
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $target, $text);
373
2023-02-10
jrmu
}
374
2023-02-10
jrmu
} else {
375
2023-02-10
jrmu
foreach my $c (@{$call->{msgm}}) {
376
2023-02-10
jrmu
my $proc = $c->{proc};
377
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $text);
378
2023-02-10
jrmu
}
379
2023-02-10
jrmu
}
380
2023-02-10
jrmu
}
381
2023-02-10
jrmu
debug(ALL, "$hostmask $target $text");
382
2023-02-10
jrmu
} elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) {
383
2023-02-10
jrmu
my ($hostmask, $target, $text) = ($1, $2, $3);
384
2023-02-10
jrmu
if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
385
2023-02-17
jrmu
my ($sendnick, $host) = ($1, $2);
386
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
387
2023-02-10
jrmu
foreach my $c (@{$call->{notc}}) {
388
2023-02-10
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
389
2023-02-10
jrmu
my $proc = $c->{proc};
390
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $text, $target);
391
2023-02-10
jrmu
# }
392
2023-02-10
jrmu
}
393
2023-02-17
jrmu
394
2023-02-10
jrmu
# CTCP replies
395
2023-02-10
jrmu
if ($hostmask ne '*status!znc@znc.in') {
396
2023-02-10
jrmu
if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) {
397
2023-02-10
jrmu
my ($key, $val) = ($1, $2);
398
2023-02-17
jrmu
my $id = SQLite::id("irc", "nick", $sendnick, $expires);
399
2023-02-10
jrmu
SQLite::set("irc", "id", $id, "ctcp".lc($key), $val);
400
2023-02-10
jrmu
SQLite::set("irc", "id", $id, "localtime", time());
401
2023-02-10
jrmu
}
402
2023-02-10
jrmu
}
403
2023-02-10
jrmu
}
404
2023-02-10
jrmu
debug(ALL, "$hostmask NOTICE $target $text");
405
2023-02-10
jrmu
#:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients)
406
2023-02-10
jrmu
#:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr
407
2023-02-10
jrmu
} elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) {
408
2023-02-10
jrmu
my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4);
409
2023-02-10
jrmu
if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
410
2023-02-17
jrmu
my ($sendnick, $host) = ($1, $2);
411
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
412
2023-02-10
jrmu
foreach my $c (@{$call->{mode}}) {
413
2023-02-10
jrmu
# TODO filter by mask
414
2023-02-10
jrmu
my $proc = $c->{proc};
415
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $chan, $change, $targets);
416
2023-02-10
jrmu
}
417
2023-02-10
jrmu
}
418
2023-02-10
jrmu
debug(ALL, "$hostmask MODE $chan $change $targets");
419
2023-02-10
jrmu
#:guava!guava@guava.guava.ircnow.org MODE guava :+Ci
420
2023-02-10
jrmu
#:ChanServ!services@services.irc.ircnow.org MODE #testing +q jrmu
421
2023-02-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu
422
2023-02-10
jrmu
#Unexpected bncnow.pl 460: :irc.guava.ircnow.org MODE guava :+o
423
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) {
424
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $chan) = ($1, $2, $3, $4);
425
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
426
2023-02-10
jrmu
foreach my $c (@{$call->{join}}) {
427
2023-02-10
jrmu
my $proc = $c->{proc};
428
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $chan);
429
2023-02-10
jrmu
}
430
2023-02-10
jrmu
debug(ALL, "$hostmask JOIN $chan");
431
2023-02-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing
432
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) {
433
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $chan, $text) = ($1, $2, $3, $4, $5);
434
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
435
2023-02-10
jrmu
foreach my $c (@{$call->{part}}) {
436
2023-02-10
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
437
2023-02-10
jrmu
my $proc = $c->{proc};
438
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $chan, $text);
439
2023-02-10
jrmu
# }
440
2023-02-10
jrmu
}
441
2023-02-10
jrmu
debug(ALL, "$hostmask PART $chan :$text");
442
2023-02-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org PART #testing :
443
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) KICK (#[^ ]+) ([^ ]+) :(.*)\r\n$/i) {
444
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $chan, $kicked, $text) = ($1, $2, $3, $4, $5, $6);
445
2023-02-10
jrmu
my $hand = $staff; # TODO fix later
446
2023-02-10
jrmu
foreach my $c (@{$call->{kick}}) {
447
2023-02-10
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
448
2023-02-10
jrmu
my $proc = $c->{proc};
449
2023-02-17
jrmu
$proc->($bot, $sendnick, $host, $hand, $chan, $text);
450
2023-02-10
jrmu
# }
451
2023-02-10
jrmu
}
452
2023-02-10
jrmu
debug(ALL, "$hostmask KICK $chan $kicked :$text");
453
2023-02-10
jrmu
#jrmu!jrmu@jrmu.users.undernet.org KICK #ircnow guava :this is a test
454
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NICK :?(.*)\r\n$/i) {
455
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4);
456
2023-02-10
jrmu
debug(ALL, "$hostmask NICK $text");
457
2023-02-10
jrmu
#:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal
458
2023-02-10
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) QUIT :(.*)\r\n$/i) {
459
2023-02-17
jrmu
my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4);
460
2023-02-10
jrmu
debug(ALL, "$hostmask QUIT :$text");
461
2023-02-10
jrmu
#:Testah!~sid268081@aa38a510 QUIT :Client closed connection
462
2023-02-10
jrmu
} elsif($response =~ /^NOTICE AUTH :(.*)\r\n$/i) {
463
2023-02-10
jrmu
my ($text) = ($1);
464
2023-02-10
jrmu
debug(ALL, "NOTICE AUTH: $text");
465
2023-02-10
jrmu
#NOTICE AUTH :*** Looking up your hostname
466
2023-02-10
jrmu
#NOTICE AUTH: *** Looking up your hostname
467
2023-02-10
jrmu
#NOTICE AUTH: *** Checking Ident
468
2023-02-10
jrmu
#NOTICE AUTH: *** Got ident response
469
2023-02-10
jrmu
#NOTICE AUTH: *** Found your hostname
470
2023-02-17
jrmu
} elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $nick.? :?(.*)\r?\n?\r$/i) {
471
2023-02-10
jrmu
my ($server, $code, $text) = ($1, $2, $3);
472
2023-02-10
jrmu
if ($code =~ /^001$/) { # Server Info
473
2023-02-10
jrmu
debug(ERRORS, "connected: $bot->{name}");
474
2023-02-10
jrmu
} elsif ($code =~ /^0\d\d$/) { # Server Info
475
2023-02-10
jrmu
debug(ALL, "$server $code $text");
476
2023-02-10
jrmu
} elsif ($code =~ /^2\d\d$/) { # Server Stats
477
2023-02-10
jrmu
debug(ALL, "$server $code $text");
478
2023-02-10
jrmu
} elsif ($code == 301 && $text =~ /^([-_\|`a-zA-Z0-9]+) :([[:graph:]]+)/) {
479
2023-02-10
jrmu
debug(ALL, "$text");
480
2023-02-10
jrmu
} elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) {
481
2023-02-10
jrmu
my ($sender, $key) = ($1, "registered");
482
2023-02-10
jrmu
$val = $2 eq ":is a registered nick" ? "True" : "$2";
483
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
484
2023-02-10
jrmu
SQLite::set("irc", "id", $id, "identified", $val);
485
2023-02-10
jrmu
debug(ALL, "$key: $val");
486
2023-02-10
jrmu
} elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) {
487
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "hostmask", "$1\!$2\@$3");
488
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
489
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
490
2023-02-10
jrmu
debug(ALL, "$key: $val");
491
2023-02-10
jrmu
} elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) {
492
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "server", $2);
493
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
494
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
495
2023-02-10
jrmu
debug(ALL, "$key: $val");
496
2023-02-10
jrmu
} elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) {
497
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2"));
498
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
499
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
500
2023-02-10
jrmu
debug(ALL, "$key: $val");
501
2023-02-10
jrmu
} elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHO(IS)? list/) {
502
2023-02-10
jrmu
debug(ALL, "End of WHOIS");
503
2023-02-10
jrmu
} elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) {
504
2023-02-10
jrmu
($sender, my $idle, my $epochtime) = ($1, $2, $3);
505
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
506
2023-02-10
jrmu
SQLite::set("irc", "id", $id, "idle", $idle);
507
2023-02-10
jrmu
# SQLite::set("irc", "id", $id, "epochtime", time());
508
2023-02-10
jrmu
debug(ALL, "idle: $idle, epochtime: $epochtime");
509
2023-02-10
jrmu
} elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) {
510
2023-02-10
jrmu
debug(ALL, "End of WHOIS");
511
2023-02-10
jrmu
} elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) {
512
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "chans", $2);
513
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
514
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
515
2023-02-10
jrmu
debug(ALL, "$key: $val");
516
2023-02-10
jrmu
} elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) {
517
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2));
518
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
519
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
520
2023-02-10
jrmu
debug(ALL, "$key: $val");
521
2023-02-10
jrmu
} elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) {
522
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "ip", $2);
523
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
524
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
525
2023-02-10
jrmu
debug(ALL, "$key: $val");
526
2023-02-10
jrmu
#Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host
527
2023-02-10
jrmu
} elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) {
528
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "ip", $3);
529
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
530
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
531
2023-02-10
jrmu
debug(ALL, "$key: $val");
532
2023-02-10
jrmu
} elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) {
533
2023-02-10
jrmu
my ($sender, $key, $val) = ($1, "ssl", "True");
534
2023-02-10
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
535
2023-02-10
jrmu
SQLite::set("irc", "id", $id, $key, $val);
536
2023-02-10
jrmu
debug(ALL, "$key: $val");
537
2023-02-10
jrmu
} elsif ($code =~ /^332$/) { # Topic
538
2023-02-10
jrmu
# print "$text\r\n";
539
2023-02-10
jrmu
} elsif ($code =~ /^333$/) { #
540
2023-02-10
jrmu
# print "$server $text\r\n";
541
2023-02-10
jrmu
#karatkievich.freenode.net 333 #ircnow jrmu!znc@206.253.167.44 1579277253
542
2023-02-10
jrmu
} elsif ($code =~ /^352$/) { # Hostmask
543
2023-02-10
jrmu
#:datapacket.hk.quakenet.org 352 * znc guava.guava.ircnow.org *.quakenet.org guava H :0 guava
544
2023-02-10
jrmu
# print "$server $code $text\r\n";
545
2023-02-10
jrmu
} elsif ($code =~ /^353$/) { # Names
546
2023-02-10
jrmu
# print "$server $code $text\r\n";
547
2023-02-10
jrmu
} elsif ($code =~ /^366$/) { # End of names
548
2023-02-10
jrmu
# print "$server $code $text\r\n";
549
2023-02-10
jrmu
} elsif ($code =~ /^37\d$/) { # MOTD
550
2023-02-10
jrmu
# print "$server $code $text\r\n";
551
2023-02-10
jrmu
} elsif ($code =~ /^381$/) { # IRC Operator Verified
552
2023-02-10
jrmu
# print "IRC Oper Verified\r\n";
553
2023-02-10
jrmu
} elsif ($code =~ /^401$/) { # IRC Operator Verified
554
2023-02-10
jrmu
# print "IRC Oper Verified\r\n";
555
2023-02-10
jrmu
} elsif ($code =~ /^403$/) { # No such channel
556
2023-02-10
jrmu
# debug(ERRORS, "$text");
557
2023-02-10
jrmu
} elsif ($code =~ /^422$/) { # MOTD missing
558
2023-02-10
jrmu
# print "$server $code $text\r\n";
559
2023-02-10
jrmu
} elsif ($code =~ /^396$/) { # Display hostname
560
2023-02-10
jrmu
# print "$server $code $text\r\n";
561
2023-02-10
jrmu
#Unexpected bncnow.pl 454: irc.guava.ircnow.org 396 guava.guava.ircnow.org :is your displayed hostname now
562
2023-02-10
jrmu
} elsif ($code =~ /^464$/) { # Invalid password for oper
563
2023-02-10
jrmu
foreach my $chan (@teamchans) {
564
2023-02-17
jrmu
putserv($bot, "PRIVMSG $chan :$nick oper password failed; the bot will be unable to view uncloaked IP addresses");
565
2023-02-10
jrmu
}
566
2023-02-10
jrmu
} elsif ($code =~ /^477$/) { # Can't join channel
567
2023-02-10
jrmu
foreach my $chan (@teamchans) {
568
2023-02-17
jrmu
putserv($bot, "PRIVMSG $chan :ERROR: $nick on $server: $text");
569
2023-02-10
jrmu
}
570
2023-02-10
jrmu
} elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) {
571
2023-02-10
jrmu
debug(ALL, "$text");
572
2023-02-10
jrmu
} else {
573
2023-02-10
jrmu
debug(ERRORS, "Unexpected bncnow.pl 454: $server $code $text");
574
2023-02-10
jrmu
}
575
2023-02-10
jrmu
} else {
576
2023-02-10
jrmu
debug(ERRORS, "Unexpected bncnow.pl 460: $response");
577
2023-02-10
jrmu
}
578
2023-02-10
jrmu
}
579
2023-02-10
jrmu
}
580
2023-02-10
jrmu
581
2023-02-10
jrmu
sub cbind {
582
2023-02-10
jrmu
my ($type, $flags, $cmd, $proc) = @_;
583
2023-02-10
jrmu
if ($type eq "pub") {
584
2023-02-10
jrmu
push(@{$call->{pub}}, {cmd => $cmd, proc => $proc});
585
2023-02-10
jrmu
} elsif ($type eq "msg") {
586
2023-02-10
jrmu
push(@{$call->{msg}}, {cmd => $cmd, proc => $proc});
587
2023-02-10
jrmu
} elsif ($type eq "notc") {
588
2023-02-10
jrmu
push(@{$call->{notc}}, {mask => $cmd, proc => $proc});
589
2023-02-10
jrmu
} elsif ($type eq "mode") {
590
2023-02-10
jrmu
push(@{$call->{mode}}, {mask => $cmd, proc => $proc});
591
2023-02-10
jrmu
} elsif ($type eq "join") {
592
2023-02-10
jrmu
push(@{$call->{join}}, {mask => $cmd, proc => $proc});
593
2023-02-10
jrmu
} elsif ($type eq "partcall") {
594
2023-02-10
jrmu
push(@{$call->{part}}, {mask => $cmd, proc => $proc});
595
2023-02-10
jrmu
} elsif ($type eq "pubm") {
596
2023-02-10
jrmu
push(@{$call->{pubm}}, {mask => $cmd, proc => $proc});
597
2023-02-10
jrmu
} elsif ($type eq "msgm") {
598
2023-02-10
jrmu
push(@{$call->{msgm}}, {mask => $cmd, proc => $proc});
599
2023-02-10
jrmu
}
600
2023-02-10
jrmu
}
IRCNow