Blob


1 #!/usr/bin/perl
3 package VPN;
5 use strict;
6 use warnings;
7 use OpenBSD::Pledge;
8 use OpenBSD::Unveil;
9 require "DNS.pm";
10 require "SQLite.pm";
12 my %conf = %main::conf;
13 my $chans = $conf{chans};
14 my $teamchans = $conf{teamchans};
15 my @teamchans = split /[,\s]+/m, $teamchans;
16 my $staff = $conf{staff};
17 my $expires = $conf{expires};
18 my $ikedconf = $conf{ikedconf} || "/etc/iked.conf";
19 # File containing IRC networks
20 my $netpath = "networks";
21 my @networks;
23 main::cbind("pub", "-", "vpn", \&vpn);
24 main::cbind("msg", "-", "vpn", \&vpn);
26 sub init {
27 # unveil("/usr/bin/rcctl", "rx") or die "Unable to unveil $!";
28 unveil($ikedconf, "crx") or die "Unable to unveil $!";
29 }
31 sub vpn {
32 my ($bot, $nick, $host, $hand, @args) = @_;
33 my ($chan, $text);
34 if (@args == 2) {
35 ($chan, $text) = ($args[0], $args[1]);
36 } else { $text = $args[0]; }
37 my $hostmask = "$nick!$host";
38 if (defined($chan) && $chans =~ /$chan/) {
39 main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
40 }
41 if ($text =~ /^$/) {
42 main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
43 foreach my $chan (@teamchans) {
44 main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network".$bot->{name});
45 }
46 return;
47 }
48 my @rows = SQLite::selectrows("irc", "nick", $nick);
49 foreach my $row (@rows) {
50 my $password = SQLite::get("vpn", "ircid", $row->{id}, "password");
51 if (defined($password)) {
52 main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
53 return;
54 }
55 }
56 if ($text =~ /^captcha\s+([[:alnum:]]+)/) {
57 my $text = $1;
58 my $ircid = SQLite::id("irc", "nick", $nick, $expires);
59 if (!defined($ircid)) { die "undefined ircid"; }
60 my $captcha = SQLite::get("vpn", "ircid", $ircid, "captcha");
61 if ($text ne $captcha) {
62 main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !vpn <username> <email>");
63 return;
64 }
65 my $pass = Hash::newpass();
66 chomp(my $encrypted = `encrypt $pass`);
67 my $username = SQLite::get("vpn", "ircid", $ircid, "username");
68 my $email = SQLite::get("vpn", "ircid", $ircid, "email");
69 my $version = SQLite::get("vpn", "ircid", $ircid, "version");
70 SQLite::set("vpn", "ircid", $ircid, "password", $encrypted);
72 createvpn($username, $pass);
73 foreach my $chan (@teamchans) {
74 main::putservlocalnet($bot, "PRIVMSG $chan :$staff: vpn created for $username");
75 }
76 my $msg = <<"EOF";
77 Your vpn account has been created! Username: $username with password: $pass
78 Our official support channel is #vpn. To connect, please follow these instructions:
79 https://wiki.ircnow.org/Vpn/Vpn
80 EOF
81 main::putserv($bot, "PRIVMSG $nick :$msg");
82 } elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
83 my ($username, $email) = ($1, $2);
84 if ($staff !~ /$nick/) {
85 return;
86 }
87 my @users = col($ikedconf);
88 my @matches = grep(/^$username$/i, @users);
89 if (scalar(@matches) > 0) {
90 main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help.");
91 return;
92 }
94 my $captcha = int(rand(999));
95 my $ircid = int(rand(2147483647));
96 SQLite::set("irc", "id", $ircid, "localtime", time());
97 SQLite::set("irc", "id", $ircid, "date", main::date());
98 SQLite::set("irc", "id", $ircid, "hostmask", $hostmask);
99 SQLite::set("irc", "id", $ircid, "nick", $nick);
100 SQLite::set("vpn", "ircid", $ircid, "username", $username);
101 SQLite::set("vpn", "ircid", $ircid, "email", $email);
102 SQLite::set("vpn", "ircid", $ircid, "captcha", $captcha);
103 main::whois($bot, $nick);
104 main::ctcp($bot, $nick);
105 main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
106 # main::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
107 main::putserv($bot, "PRIVMSG $nick :Type !vpn captcha <text>");
108 foreach my $chan (@teamchans) {
109 main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha");
113 sub createvpn {
114 my ($username, $password) = @_;
115 `doas sh -c 'echo "user $username $password" >> /etc/iked.conf'`;
116 `doas rcctl reload iked`;
118 sub col {
119 my ($filename) = @_;
120 my @rows = main::readarray($filename);
121 my @results;
122 foreach my $row (@rows) {
123 if ($row =~ /^user (.*?) /) {
124 push(@results, $1);
127 return @results;
130 #sub init {
131 #}
132 # if ($reply =~ /^!vpn (.*) ([-_0-9a-zA-Z]+)$/i) {
133 # my $ircnick = $1;
134 # my $newnick = $2;
135 # if ($staff !~ /$sender/) {
136 # return;
137 # }
138 # my $password = newpass();
139 # createvpn($password, $newnick);
140 # sendmsg($bot, $sender, "vpn created for $newnick");
141 #my $msg = <<"EOF";
142 #Your vpn account has been created! Username: $newnick with password: $password
143 #Our official support channel is #vpn. To connect, please follow these instructions: https://ircnow.org/kb/doku.php?id=vpn:vpn .
144 #EOF
145 # sendmsg($bot, $ircnick, $msg);
146 # }
147 #sub createvpn {
148 # my ($password, $username) = @_;
149 # `doas sh -c 'echo "user '$username' '$password'" >> /etc/iked.conf'`;
150 # `doas rcctl reload iked`;
151 #}
153 1; # MUST BE LAST STATEMENT IN FILE