Use a hash as internal username
This commit is contained in:
parent
43aa08fca8
commit
922f649a08
6 changed files with 34 additions and 29 deletions
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
const USERNAME_REGEX = '^[\p{L}\p{N}_-]{1,64}$';
|
const USERNAME_REGEX = '^.{1,1024}$';
|
||||||
const PASSWORD_REGEX = '^(?=.*[\p{Ll}])(?=.*[\p{Lu}])(?=.*[\p{N}]).{8,1024}|.{10,1024}$';
|
const PASSWORD_REGEX = '^(?=.*[\p{Ll}])(?=.*[\p{Lu}])(?=.*[\p{N}]).{8,1024}|.{10,1024}$';
|
||||||
|
|
||||||
const PLACEHOLDER_USERNAME = 'lain';
|
const PLACEHOLDER_USERNAME = 'lain';
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<dd>
|
<dd>
|
||||||
C'est le type de compte par défaut, avec des fonctionnalités limitées pour éviter les abus :
|
C'est le type de compte par défaut, avec des fonctionnalités limitées pour éviter les abus :
|
||||||
<ul>
|
<ul>
|
||||||
<li>Peut être supprimé n'importe quand</li>
|
<li>Risque d'être supprimé n'importe quand</li>
|
||||||
<li><?= ((CONF['ht']['user_quota_testing'] >> 30) >= 1) ? CONF['ht']['user_quota_testing'] >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : CONF['ht']['user_quota_testing'] >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>') ?> de SFTP</li>
|
<li><?= ((CONF['ht']['user_quota_testing'] >> 30) >= 1) ? CONF['ht']['user_quota_testing'] >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : CONF['ht']['user_quota_testing'] >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>') ?> de SFTP</li>
|
||||||
<li>Certificat Let's Encrypt de test</li>
|
<li>Certificat Let's Encrypt de test</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -5,17 +5,20 @@ if (processForm(false)) {
|
||||||
|
|
||||||
checkUsernameFormat($_POST['username']);
|
checkUsernameFormat($_POST['username']);
|
||||||
|
|
||||||
if (userExist($_POST['username']) !== true)
|
$internal_username = hash('sha256', $_POST['username']);
|
||||||
|
|
||||||
|
if (userExist($internal_username) !== true)
|
||||||
output(403, 'Connexion impossible : ce compte n\'existe pas.');
|
output(403, 'Connexion impossible : ce compte n\'existe pas.');
|
||||||
|
|
||||||
if (checkPassword($_POST['username'], $_POST['password']) !== true)
|
if (checkPassword($internal_username, $_POST['password']) !== true)
|
||||||
output(403, 'Connexion impossible : clé de passe invalide.');
|
output(403, 'Connexion impossible : clé de passe invalide.');
|
||||||
|
|
||||||
$_SESSION['username'] = $_POST['username'];
|
$_SESSION['username'] = $internal_username;
|
||||||
$_SESSION['type'] = query('select', 'users', ['username' => $_POST['username']], 'type')[0];
|
$_SESSION['display-username'] = htmlspecialchars($_POST['username']);
|
||||||
|
$_SESSION['type'] = query('select', 'users', ['username' => $internal_username], 'type')[0];
|
||||||
|
|
||||||
if (outdatedPasswordHash($_SESSION['username']))
|
if (outdatedPasswordHash($internal_username))
|
||||||
changePassword($_SESSION['username'], $_POST['password']);
|
changePassword($internal_username, $_POST['password']);
|
||||||
|
|
||||||
redir();
|
redir();
|
||||||
}
|
}
|
||||||
|
@ -26,7 +29,7 @@ if (processForm(false)) {
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<label for="username">Identifiant</label><br>
|
<label for="username">Identifiant</label><br>
|
||||||
<input required="" minlength="1" maxlength="64" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>">
|
<input required="" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>">
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<label for="password">Clé de passe</label><br>
|
<label for="password">Clé de passe</label><br>
|
||||||
|
|
|
@ -5,13 +5,15 @@ if (processForm(false)) {
|
||||||
|
|
||||||
checkUsernameFormat($_POST['username']);
|
checkUsernameFormat($_POST['username']);
|
||||||
|
|
||||||
if (userExist($_POST['username']) !== false)
|
$internal_username = hash('sha256', $_POST['username']);
|
||||||
|
|
||||||
|
if (userExist($internal_username) !== false)
|
||||||
output(403, 'Ce nom de compte est déjà utilisé.');
|
output(403, 'Ce nom de compte est déjà utilisé.');
|
||||||
|
|
||||||
rateLimit();
|
rateLimit();
|
||||||
|
|
||||||
insert('users', [
|
insert('users', [
|
||||||
'username' => $_POST['username'],
|
'username' => $internal_username,
|
||||||
'password' => hashPassword($_POST['password']),
|
'password' => hashPassword($_POST['password']),
|
||||||
'registration_date' => date('Y-m-d H:i:s'),
|
'registration_date' => date('Y-m-d H:i:s'),
|
||||||
'bucket_tokens' => 0,
|
'bucket_tokens' => 0,
|
||||||
|
@ -21,22 +23,23 @@ if (processForm(false)) {
|
||||||
|
|
||||||
// Setup SFTP directory
|
// Setup SFTP directory
|
||||||
umask(0002);
|
umask(0002);
|
||||||
if (mkdir(CONF['ht']['ht_path'] . '/' . $_POST['username'], 0775) !== true)
|
if (mkdir(CONF['ht']['ht_path'] . '/' . $internal_username, 0775) !== true)
|
||||||
output(500, 'Can\'t create user directory.');
|
output(500, 'Can\'t create user directory.');
|
||||||
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['chgrp_path'] . ' ' . CONF['ht']['sftpgo_group'] . ' ' . CONF['ht']['ht_path'] . '/' . $_POST['username'] . ' --no-dereference', result_code: $code);
|
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['chgrp_path'] . ' ' . CONF['ht']['sftpgo_group'] . ' ' . CONF['ht']['ht_path'] . '/' . $internal_username . ' --no-dereference', result_code: $code);
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
output(500, 'Can\'t change user directory group.');
|
output(500, 'Can\'t change user directory group.');
|
||||||
|
|
||||||
// Setup Tor config directory
|
// Setup Tor config directory
|
||||||
if (mkdir(CONF['ht']['tor_config_path'] . '/' . $_POST['username'], 0755) !== true)
|
if (mkdir(CONF['ht']['tor_config_path'] . '/' . $internal_username, 0755) !== true)
|
||||||
output(500, 'Can\'t create Tor config directory.');
|
output(500, 'Can\'t create Tor config directory.');
|
||||||
|
|
||||||
// Setup Tor keys directory
|
// Setup Tor keys directory
|
||||||
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['mkdir_path'] . ' --mode=0700 ' . CONF['ht']['tor_keys_path'] . '/' . $_POST['username'], result_code: $code);
|
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['mkdir_path'] . ' --mode=0700 ' . CONF['ht']['tor_keys_path'] . '/' . $internal_username, result_code: $code);
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
output(500, 'Can\'t create Tor keys directory.');
|
output(500, 'Can\'t create Tor keys directory.');
|
||||||
|
|
||||||
$_SESSION['username'] = $_POST['username'];
|
$_SESSION['username'] = $internal_username;
|
||||||
|
$_SESSION['display-username'] = htmlspecialchars($_POST['username']);
|
||||||
$_SESSION['type'] = 'testing';
|
$_SESSION['type'] = 'testing';
|
||||||
|
|
||||||
redir();
|
redir();
|
||||||
|
@ -48,18 +51,15 @@ if (processForm(false)) {
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
|
||||||
<details>
|
<label for="username">Identifiant</label>
|
||||||
<summary><label for="username">Identifiant</label></summary>
|
<br>
|
||||||
Uniquement composé de lettres minuscules.
|
<input id="username" minlength="1" maxlength="1024" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
|
||||||
</details>
|
|
||||||
<input id="username" minlength="1" maxlength="64" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><label for="password">Clé de passe</label></summary>
|
<summary><label for="password">Clé de passe</label></summary>
|
||||||
<p>Une clé de passe sécurisée est trop compliquée à deviner pour une attaque qui testerais automatiquement plein de clés de passe tout en connaissant d'autres informations et secrets sur vous.</p>
|
<p>Une clé de passe sécurisée est trop compliquée à deviner pour une attaque qui testerait automatiquement plein de clés de passe tout en connaissant d'autres informations et secrets sur vous.</p>
|
||||||
<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
|
<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
|
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
|
||||||
|
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
|
|
|
@ -92,7 +92,7 @@ foreach (glob('css/*.css') as $cssPath)
|
||||||
<header>
|
<header>
|
||||||
<p>
|
<p>
|
||||||
<?php if (isset($_SESSION['username'])) { ?>
|
<?php if (isset($_SESSION['username'])) { ?>
|
||||||
<?= ($_SESSION['type'] === 'trusted') ? '<span title="Compte confiancé">👤</span>' : '<span title="Compte de test">⏳</span>' ?> <strong><?= $_SESSION['username'] ?></strong> <a class="auth" href="<?= CONF['common']['prefix'] ?>/auth/logout">Se déconnecter</a>
|
<?= ($_SESSION['type'] === 'trusted') ? '<span title="Compte confiancé">👤</span>' : '<span title="Compte de test">⏳</span>' ?> <strong><?= $_SESSION['display-username'] ?></strong> <a class="auth" href="<?= CONF['common']['prefix'] ?>/auth/logout">Se déconnecter</a>
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<span aria-hidden="true">👻 </span><em>Anonyme</em> <a class="auth" href="<?= redirUrl('auth/login') ?>">Se connecter</a>
|
<span aria-hidden="true">👻 </span><em>Anonyme</em> <a class="auth" href="<?= redirUrl('auth/login') ?>">Se connecter</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
require 'router.php';
|
require 'router.php';
|
||||||
|
|
||||||
$authData = json_decode(file_get_contents('php://input'), true);
|
$auth_data = json_decode(file_get_contents('php://input'), true);
|
||||||
|
|
||||||
if (userExist($authData['username']) === true AND checkPassword($authData['username'], $authData['password']) === true) {
|
$internal_username = hash('sha256', $auth_data['username']);
|
||||||
$quotaSize = (query('select', 'users', ['username' => $authData['username']], 'type')[0] === 'trusted') ? CONF['ht']['user_quota_trusted'] : CONF['ht']['user_quota_testing'];
|
|
||||||
|
if (userExist($internal_username) === true AND checkPassword($internal_username, $auth_data['password']) === true) {
|
||||||
echo '
|
echo '
|
||||||
{
|
{
|
||||||
"status": 1,
|
"status": 1,
|
||||||
"username": "' . $authData['username'] . '",
|
"username": ' . json_encode($auth_data['username']) . ',
|
||||||
"quota_size": ' . $quotaSize . ',
|
"home_dir": "' . CONF['ht']['ht_path'] . '/' . $internal_username . '",
|
||||||
|
"quota_size": ' . ((query('select', 'users', ['username' => $internal_username], 'type')[0] === 'trusted') ? CONF['ht']['user_quota_trusted'] : CONF['ht']['user_quota_testing']) . ',
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"/": [
|
"/": [
|
||||||
"*"
|
"*"
|
||||||
|
|
Loading…
Reference in a new issue