website/en/register.php

242 lines
12 KiB
PHP

<!DOCTYPE html>
<!--
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<html lang="en">
<head>
<meta name="viewport" content="width=device-width">
<meta charset="UTF-8">
<meta name="description" content="Register for ~vern">
<link rel="stylesheet" href="//gcdn.vern.cc/vernsite/style.css">
<title>Registration | ~vern</title>
</head>
<body>
<!--#include file="nav.php" -->
<p><b>If you can/do not want to share your email for ~vern registration, please contact an <a href=/en/admins>admin</a> so we can create one for you without one</b></p>
<?php
function sanitize($str) {
$str = trim($str);
$str = stripslashes($str);
$str = htmlspecialchars($str);
$str = str_replace("\r", '', $str);
return $str;
}
$success = false;
$username = $email = $ssh = $reason =
$username_err = $email_err = $ssh_err = $reason_err = '';
$username_re = '/^[a-z_][a-z0-9_]{0,30}$/';
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!empty($_POST['username'])) {
if (preg_match($username_re, $_POST['username']) === 1) {
if (!file_exists('/vm/' . $_POST['username'])) {
if (!file_exists("/var/tmp/register/" . sanitize($_POST['username'])))
$username = sanitize($_POST['username']);
else $username_err = "A request for the username " . $_POST['username'] . " exists already. Try again later or choose a different username.";
}
else $username_err = "Username is already in use";
} else {
$username_err = "Invalid username. Username must be a valid GNU/Linux username (match $username_re)";
}
} else {
$username_err = "Username is required";
}
if (!empty($_POST['email'])) {
if (filter_var(sanitize($_POST['email']), FILTER_VALIDATE_EMAIL)) {
$email = sanitize($_POST['email']);
} else {
$email_err = "Invalid E-mail";
}
} else {
$email_err = "E-mail is required";
}
if (!empty($_POST['ssh'])) {
$ret = shell_exec('bash -c "ssh-keygen -lf - <<< ' . escapeshellarg($_POST['ssh']) . ' 2>&1"');
if (trim($ret) != "(stdin) is not a public key file.") {
$ssh = $_POST['ssh'];
} else {
$ssh_err = "Not a valid SSH public key";
}
unset($ret);
} else {
$ssh_err = "Public key is required";
}
if (!empty($_POST['joinreason'])) {
$reason = $_POST['joinreason'];
} else {
$reason_err = "Join reason is required";
}
if (empty($username_err . $email_err . $ssh_err . $reason_err) && isset($_POST['tos']))
$success = true;
}
if (!$success) {
?>
<div class=h><h1 id=signup>Sign Up</h1> <a aria-hidden=true href=#signup>#signup</a></div>
<p>See the <a href="//wiki.vern.cc/en/guides/register/">wiki page</a> on how to register.</p>
<span class="red">* Required field</span>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<p>Username:
<input type="text" name="username">
<span class="red">* <?php echo $username_err; ?></span></p>
<p>E-mail (We need one so we can contact you) <span class="red">* <?php echo $email_err; ?></span>
<input type="text" name="email"></p>
<p>SSH public keys (one key per line) <span class="red">* <?php echo $ssh_err; ?></span><br>
<textarea name="ssh" rows="3" cols="50"></textarea></p>
<p>Why do you want to join? <span class="red">* <?php echo $reason_err; ?></span><br>
<textarea name="joinreason" rows="8" cols="50"></textarea></p>
<p>What services do you want? (You can always request an account on one later)</p>
<input type="checkbox" id="pubnix" name="pubnix" value="Pubnix" disabled checked>
<label for="pubnix">Pubnix (Includes E-Mail)</label><br>
<input type="checkbox" id="matrix" name="matrix" value="Matrix" checked>
<label for="matrix">Matrix</label><br>
<input type="checkbox" id="fedi" name="fedi" value="Mastodon" checked>
<label for="fedi">Mastodon</label><br>
<input type="checkbox" id="akkoma" name="akkoma" value="Akkoma" checked>
<label for="akkoma">Akkoma (Pleroma Fork)</label><br>
<input type="checkbox" id="soju" name="soju" value="Soju" checked>
<label for="soju">Soju</label><br>
<input type="checkbox" id="git" name="git" value="Forgejo" checked>
<label for="git">Forgejo</label><br>
<input type="checkbox" id="freshrss" name="freshrss" value="FreshRSS" checked>
<label for="freshrss">FreshRSS</label><br>
<input type="checkbox" id="miniflux" name="miniflux" value="Miniflux" checked>
<label for="miniflux">Miniflux</label><br>
<input type="checkbox" id="penpot" name="penpot" value="Penpot" checked>
<label for="penpot">Penpot</label><br>
<input type="checkbox" id="nextcloud" name="nextcloud" value="Nextcloud" checked>
<label for="nextcloud">Nextcloud</label><br>
<input type="checkbox" id="peertube" name="peertube" value="PeerTube" checked>
<label for="peertube">PeerTube</label><br>
<input type="checkbox" id="xmpp" name="xmpp" value="XMPP" checked>
<label for="xmpp">XMPP/Jabber</label><br>
<input type="checkbox" id="xmppo" name="xmppo" value="XMPP Onion">
<label for="xmppo">XMPP/Jabber Onion (Don't check if you don't know what it is)</label><br>
<input type="checkbox" id="xmppi" name="xmppi" value="XMPP I2P">
<label for="xmppi">XMPP/Jabber I2P (Don't check if you don't know what it is)</label><br>
<br>
<input type="checkbox" id="tos" name="tos" value="I agree to the ToS and Privacy Policy">
<label for="tos">I agree to the <a href=/en/tos>Terms of Service</a> and <a href=/en/privpol>Privacy Policy</a></label><br>
<br>
<span><input type="submit" value="Submit" style="width:100px;height:40px;font-size:20px"></span>
</form><br>
<p>THE SERVICE IS PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, AND WE DO NOT GUARANTEE THAT THE SERVICE WILL BE AVAILABLE AT ALL TIMES, NOR THE ACCURACY OF THE SERVICE OR ANY MATERIAL PROVIDED BY THE SERVICE OR ON THE ~VERN WEBSITE. IN NO EVENT SHALL THE ADMINISTRATORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE SERVICE OR THE USE OF OTHER DEALINGS IN THE SERVICE. YOU ARE SOLELY RESPONSIBLE FOR YOUR USE OF THE SERVICE.</p>
<?php
} else {
?>
<meta http-equiv="refresh" content="5;url=http://<?php echo htmlspecialchars($_SERVER['HTTP_HOST']); ?>" />
<div class=h><h1 id=thanks>Thank you for signing up.</h1> <a aria-hidden=true href=#thanks>#thanks</a></div>
<p>An admin will review your request, and an e-mail will be sent if your registration is successful.</p>
<p>You will be redirected back <a href=/en/>home</a> in 5 seconds.</p>
<?php
if (isset($_POST['matrix'])) $use_matrix = true;
if (isset($_POST['fedi'])) $use_fedi = true;
if (isset($_POST['akkoma'])) $use_akkoma = true;
if (isset($_POST['soju'])) $use_soju = true;
if (isset($_POST['git'])) $use_git = true;
if (isset($_POST['nextcloud'])) $use_nc = true;
if (isset($_POST['freshrss'])) $use_freshrss = true;
if (isset($_POST['miniflux'])) $use_miniflux = true;
if (isset($_POST['penpot'])) $use_penpot = true;
if (isset($_POST['peertube'])) $use_peertube = true;
if (isset($_POST['xmpp'])) $use_xmpp = true;
if (isset($_POST['xmppo'])) $use_xmppo = true;
if (isset($_POST['xmppi'])) $use_xmppi = true;
$to = "root@vern.cc";
$subject = "New registration request from $username <$email>";
$message = "Hello Administrators,\nSomeone has requested a membership. Please view the details below and decide if it is worth approving.\n\nSSH keys:\n$ssh\n\nRequested username: $username\nRequested services: Tilde";
if ($use_matrix) $message .= ", Matrix";
if ($use_fedi) $message .= ", Mastodon";
if ($use_akkoma) $message .= ", Akkoma";
if ($use_soju) $message .= ", Soju";
if ($use_git) $message .= ", Forgejo";
if ($use_nc) $message .= ", Nextcloud";
if ($use_freshrss) $message .= ", FreshRSS";
if ($use_miniflux) $message .= ", Miniflux";
if ($use_penpot) $message .= ", Penpot";
if ($use_peertube) $message .= ", PeerTube";
if ($use_xmpp) $message .= ", XMPP";
if ($use_xmppo) $message .= ", XMPP Onion";
if ($use_xmppi) $message .= ", XMPP I2P";
$message .= ".\nJoin reason:\n$reason\n\n\nTo accept this request, run this command as root:\n/root/bin/accept $username\nTo deny this request, run this command as root:\n/root/bin/deny $username\n";
$contents = "#!/usr/bin/env -S bash -e\n\n# This is the registration script for $username \n# This script was automatically generated by http://" . $_SERVER['HTTP_HOST'] . htmlspecialchars($_SERVER['PHP_SELF']). "\n\n";
$contents .= 'password="$(tr -dc A-Za-z0-9 </dev/urandom | head -c 64)"' . "\n";
$contents .= '~/bin/mktuser ' . escapeshellarg($username) . ' "$password"' . " <<< " . escapeshellarg($_POST['ssh']) . "\n";
$contents .= 'echo "$password" > /sshfs/home/' . $username . '/pass && chmod 600 /sshfs/home/' . $username . '/pass && ssh 192.168.122.30 chown ' . escapeshellarg($username . ':' . $username) . ' /sshfs/home/' . $username . '/pass' . "\n\n";
if ($use_matrix) $contents .= '~/bin/mkmuser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_fedi) {
$pass_file = '/home/' . $username . '/mastodon-pass';
$contents .= 'touch /sshfs' . $pass_file . "\n";
$contents .= 'chmod 600 /sshfs' . $pass_file . "\n";
$contents .= 'ssh 192.168.122.30 chown ' . escapeshellarg($username . ':' . $username) . ' ' . escapeshellarg($pass_file) . "\n";
$contents .= '~/bin/mkfuser ' . escapeshellarg($username) . ' | tee /sshfs' . escapeshellarg($pass_file) . "\n";
unset($pass_file);
}
if ($use_akkoma) $contents .= '~/bin/mkauser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_soju) $contents .= '~/bin/mksuser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_git) $contents .= '~/bin/mkguser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_nc) $contents .= '~/bin/mknuser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_freshrss) $contents .= '~/bin/mkfruser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_freshrss) $contents .= '~/bin/mkmfuser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_penpot) $contents .= '~/bin/mkppuser ' . escapeshellarg($username) . ' "$password"' . "\n";
if ($use_peertube) $contents .= '~/bin/mkpuser ' . escapeshellarg($username) . ' "$password"' . ' ' . escapeshellarg($email) . "\n";
if ($use_xmpp) $contents .= '~/bin/mkxuser ' . escapeshellarg($username) . ' "$password"' . " vern.cc\n";
if ($use_xmppo) $contents .= '~/bin/mkxuser ' . escapeshellarg($username) . ' "$password"' . " vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion\n";
if ($use_xmppi) $contents .= '~/bin/mkxuser ' . escapeshellarg($username) . ' "$password"' . " verncceu2kgz54wi7r5jatgmx2mqtsh3knxhiy4m5shescuqtqfa.b32.i2p\n";
$contents .= "s-nail -vr 'register@vern.cc' -s 'Your ~vern account has been created' -M text/plain " . escapeshellarg($email) . " < <(printf 'Hello %s,\\nYour membership request on ~vern has been accepted.\\nYou can now SSH into vern.cc using the public key(s) that you supplied to ~vern.\\nA global password for all the services you signed up to can be found at ~/pass. If you signed up for Mastodon, password for the account can be found at ~/mastodon-pass\\n\\nThank you for being a part of ~vern!' " . escapeshellarg($username) . ")\n";
$contents .= "rm -f $0\n";
$contents .= "exit\n\n\n";
$contents .= $reason . "\n";
$filename = "/var/tmp/register/" . $username;
$handle = fopen($filename, "w+");
chmod($filename, 0600);
unset($filename);
fwrite($handle, $contents);
fclose($handle);
$from = "register@vern.cc";
$headers = "From: " . $from . "\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-type: text/plain\n";
mail($to, $subject, $message, $headers);
}
?>
<!--#include file="footer.cgi" -->
</body>
</html>