Commit Diff


commit - 0b43d183bcae91d4cb5255c82b8c7cbc253373d8
commit + 177e2ac30d11b85641abf065dc23621b8e7d43e0
blob - 1d5af6d5879fc9494712adb399e02c47fe2dcd9c
blob + 922c5d3ab0fcb632c7562c93dca8fc2b9fd94563
--- VPN.pm
+++ VPN.pm
@@ -6,9 +6,129 @@ 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 <username> <email>");
+			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 <text>");
+		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;