#!/usr/bin/perl package VPN; use strict; use warnings; use OpenBSD::Pledge; use OpenBSD::Unveil; require "DNS.pm"; require "SQLite.pm"; my %conf = %main::conf; my $chans = $conf{chans}; my $teamchans = $conf{teamchans}; my @teamchans = split /[,\s]+/m, $teamchans; my $staff = $conf{staff}; my $expires = $conf{expires}; my $ikedconf = $conf{ikedconf} || "/etc/iked.conf"; # File containing IRC networks my $netpath = "networks"; my @networks; main::cbind("pub", "-", "vpn", \&vpn); main::cbind("msg", "-", "vpn", \&vpn); sub init { # unveil("/usr/bin/rcctl", "rx") or die "Unable to unveil $!"; unveil($ikedconf, "crx") or die "Unable to unveil $!"; } sub vpn { 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 ($text =~ /^$/) { main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions"); foreach my $chan (@teamchans) { main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network".$bot->{name}); } return; } my @rows = SQLite::selectrows("irc", "nick", $nick); foreach my $row (@rows) { my $password = SQLite::get("vpn", "ircid", $row->{id}, "password"); if (defined($password)) { main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help."); return; } } if ($text =~ /^captcha\s+([[:alnum:]]+)/) { my $text = $1; my $ircid = SQLite::id("irc", "nick", $nick, $expires); if (!defined($ircid)) { die "undefined ircid"; } my $captcha = SQLite::get("vpn", "ircid", $ircid, "captcha"); if ($text ne $captcha) { main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !vpn "); return; } my $pass = Hash::newpass(); chomp(my $encrypted = `encrypt $pass`); my $username = SQLite::get("vpn", "ircid", $ircid, "username"); my $email = SQLite::get("vpn", "ircid", $ircid, "email"); my $version = SQLite::get("vpn", "ircid", $ircid, "version"); SQLite::set("vpn", "ircid", $ircid, "password", $encrypted); createvpn($username, $pass); foreach my $chan (@teamchans) { main::putservlocalnet($bot, "PRIVMSG $chan :$staff: vpn created for $username"); } my $msg = <<"EOF"; Your vpn account has been created! Username: $username with password: $pass Our official support channel is #vpn. To connect, please follow these instructions: https://wiki.ircnow.org/Vpn/Vpn EOF main::putserv($bot, "PRIVMSG $nick :$msg"); } elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) { my ($username, $email) = ($1, $2); if ($staff !~ /$nick/) { return; } my @users = col($ikedconf); my @matches = grep(/^$username$/i, @users); if (scalar(@matches) > 0) { main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help."); return; } my $captcha = int(rand(999)); my $ircid = int(rand(2147483647)); SQLite::set("irc", "id", $ircid, "localtime", time()); SQLite::set("irc", "id", $ircid, "date", main::date()); SQLite::set("irc", "id", $ircid, "hostmask", $hostmask); SQLite::set("irc", "id", $ircid, "nick", $nick); SQLite::set("vpn", "ircid", $ircid, "username", $username); SQLite::set("vpn", "ircid", $ircid, "email", $email); SQLite::set("vpn", "ircid", $ircid, "captcha", $captcha); main::whois($bot->{sock}, $nick); main::ctcp($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 !vpn captcha "); foreach my $chan (@teamchans) { main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha"); } } } sub createvpn { my ($username, $password) = @_; `doas sh -c 'echo "user $username $password" >> /etc/iked.conf'`; `doas rcctl reload iked`; } sub col { my ($filename) = @_; my @rows = main::readarray($filename); my @results; foreach my $row (@rows) { if ($row =~ /^user (.*?) /) { push(@results, $1); } } return @results; } #sub init { #} # if ($reply =~ /^!vpn (.*) ([-_0-9a-zA-Z]+)$/i) { # my $ircnick = $1; # my $newnick = $2; # if ($staff !~ /$sender/) { # return; # } # my $password = newpass(); # createvpn($password, $newnick); # sendmsg($bot, $sender, "vpn created for $newnick"); #my $msg = <<"EOF"; #Your vpn account has been created! Username: $newnick with password: $password #Our official support channel is #vpn. To connect, please follow these instructions: https://ircnow.org/kb/doku.php?id=vpn:vpn . #EOF # sendmsg($bot, $ircnick, $msg); # } #sub createvpn { # my ($password, $username) = @_; # `doas sh -c 'echo "user '$username' '$password'" >> /etc/iked.conf'`; # `doas rcctl reload iked`; #} 1; # MUST BE LAST STATEMENT IN FILE