=================================================================== RCS file: /cvs/botnow/Shell.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- botnow/Shell.pm 2021/05/15 15:12:32 1.1 +++ botnow/Shell.pm 2021/07/21 22:04:30 1.2 @@ -27,6 +27,10 @@ my $mailname = $conf{mailname}; my $passpath = "/etc/passwd"; my $httpdconfpath = "/etc/httpd.conf"; my $acmeconfpath = "/etc/acme-client.conf"; +my $pfconfpath = "/etc/pf.conf"; +my $relaydconfpath = "/etc/relayd.conf"; +my $startPort; +my $endPort; main::cbind("pub", "-", "shell", \&mshell); main::cbind("msg", "-", "shell", \&mshell); @@ -39,6 +43,8 @@ sub init { unveil($passpath, "r") or die "Unable to unveil $!"; unveil($httpdconfpath, "rwxc") or die "Unable to unveil $!"; unveil($acmeconfpath, "rwxc") or die "Unable to unveil $!"; + unveil($pfconfpath, "rwxc") or die "Unable to unveil $!"; + unveil($relaydconfpath, "rwxc") or die "Unable to unveil $!"; unveil("/usr/sbin/chown", "rx") or die "Unable to unveil $!"; unveil("/bin/chmod", "rx") or die "Unable to unveil $!"; unveil("/usr/sbin/groupadd", "rx") or die "Unable to unveil $!"; @@ -75,7 +81,7 @@ sub mshell { my $username = $1; if (SQLite::deleterows("shell", "username", $username)) { # TODO delete shell - deleteshell($bot, $username); + deleteshell($username); foreach my $chan (@teamchans) { main::putserv($bot, "PRIVMSG $chan :$username deleted"); } @@ -111,7 +117,7 @@ sub mshell { SQLite::set("shell", "ircid", $ircid, "password", $encrypted); if (DNS::nextdns($username)) { sleep(2); - createshell($bot, $username, $pass, $bindhost); + createshell($username, $pass, $bindhost); mailshell($username, $email, $pass, "shell", $version); main::putserv($bot, "PRIVMSG $nick :Check your email!"); @@ -159,7 +165,6 @@ sub mailshell { my( $username, $email, $password, $service, $version )=@_; my $passhash = sha256_hex("$username"); my $versionhash = encode_base64($version); - my $ports; my $body = <<"EOF"; You created a shell account! @@ -167,13 +172,15 @@ Username: $username Password: $password Server: $hostname SSH Port: 22 -Your Ports: $ports for plaintext +Your Ports: $startPort to $endPort +To customize your vhost, connect to ask in #ircnow + *IMPORTANT*: Verify your email address: https://www.$hostname/register.php?id=$passhash&version=$versionhash -You *MUST* click on the link or your account will be deleted. +You *MUST* click on the link within 24 hours or your account will be deleted. IRCNow EOF @@ -244,8 +251,7 @@ EOF #} sub createshell { - my ($bot, $username, $password, $bindhost) = @_; - my $netname = $bot->{name}; + my ($username, $password, $bindhost) = @_; system "doas groupadd $username"; system "doas adduser -batch $username $username $username `encrypt $password`"; system "doas chmod 700 /home/$username /home/$username/.ssh"; @@ -259,7 +265,6 @@ sub createshell { my $block = <<"EOF"; server "$lusername.$hostname" { listen on * port 80 - listen on * port 8001 location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 @@ -274,24 +279,27 @@ EOF $block = <<"EOF"; domain "$lusername.$hostname" { domain key "/etc/ssl/private/$lusername.$hostname.key" - domain full chain certificate "/etc/ssl/$lusername.$hostname.fullchain.pem" + domain full chain certificate "/etc/ssl/$lusername.$hostname.crt" sign with letsencrypt } EOF main::appendfile($acmeconfpath, $block); - + configurepf($username); system "doas rcctl reload httpd"; - system "doas mv /etc/ssl/private/$hostname.key /etc/ssl/private/l.k"; system "doas acme-client -F $lusername.$hostname"; - system "doas ln -s /etc/ssl/crt/$lusername.$hostname.fullchain.pem /etc/ssl/$lusername.$hostname.crt"; - system "doas mv /etc/ssl/private/l.k /etc/ssl/private/$hostname.key"; + system "doas ln -s /etc/ssl/$lusername.$hostname.crt /etc/ssl/$lusername.$hostname.fullchain.pem"; + system "doas pfctl -f /etc/pf.conf"; + configurerelayd($username); + $block = <<"EOF"; +~ * * * * acme-client $lusername.$hostname && rcctl reload relayd +EOF + system "echo $block | doas crontab -"; #edquota $username return 1; } sub deleteshell { - my ($bot, $username, $bindhost) = @_; - my $netname = $bot->{name}; + my ($username, $bindhost) = @_; my $lusername = lc $username; system "doas groupdel $username"; system "doas userdel $username"; @@ -348,5 +356,44 @@ sub col { } return @results; } + +sub configurepf { + my $username = shift; + my @read = split('\n', main::readstr($pfconfpath) ); + + my $previousline = ""; + my @pfcontent; + foreach my $line(@read) + { + my $currline = $line; + if( $currline ne "# end user ports") { + $previousline = $currline; + } else { + #pass in proto {tcp udp} to port {31361:31370} user {JL} + if( $previousline =~ /(\d*):(\d*)/ ) { + my $startport = ( $1 + 10 ); + my $endport = ( $2 + 10 ); + my $insert = "pass in proto {tcp udp} to port {$startport:$endport} user {$username}"; + push(@pfcontent, $insert); + $startPort = $startport; + $endPort = $endport; + } + } + push(@pfcontent, $currline) + } + main::writefile("$pfconfpath", join("\n",@pfcontent)) +} + +sub configurerelayd { + my ($username) = @_; + my $block = "tls { keypair $username.$hostname }"; + my $relaydconf = main::readstr($relaydconfpath); + my $newconf; + if ($relaydconf =~ /^.*tls\s+{\s+keypair\s+[.0-9a-zA-Z]+\s*}/m) { + $newconf = "$`$&\n\t$block$'"; + } + main::writefile($relaydconfpath, $newconf); +} + #unveil("./newacct", "rx") or die "Unable to unveil $!"; 1; # MUST BE LAST STATEMENT IN FILE