Store secret key in DB + autorotate it
This commit is contained in:
parent
75e7caed88
commit
57dfb02a40
8 changed files with 16 additions and 40 deletions
|
@ -6,6 +6,8 @@ CREATE TABLE IF NOT EXISTS "params" (
|
|||
);
|
||||
INSERT INTO "params"("name", "value") VALUES("instance_bucket_tokens", "0");
|
||||
INSERT INTO "params"("name", "value") VALUES("instance_bucket_last_update", "0");
|
||||
INSERT INTO "params"("name", "value") VALUES("secret_key", "0");
|
||||
INSERT INTO "params"("name", "value") VALUES("secret_key_last_change", "0");
|
||||
INSERT INTO "params"("name", "value") VALUES("username_salt", "00000000000000000000000000000000"); -- Should be unique and secret ; generate one using `openssl rand -hex 16` ; can't be changed without breaking current accounts login
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" TEXT NOT NULL UNIQUE,
|
||||
|
|
|
@ -113,13 +113,13 @@ function linkToDocs($ref, $title) {
|
|||
- the user's id
|
||||
- that a same user used a token multiple times (by using a unique salt for each token)
|
||||
*/
|
||||
define('SECRET_KEY_FILE', sys_get_temp_dir() . '/Niver.key');
|
||||
if (!file_exists(SECRET_KEY_FILE)) {
|
||||
$original_umask = umask(0077);
|
||||
file_put_contents(SECRET_KEY_FILE, random_bytes(32));
|
||||
umask($original_umask);
|
||||
if (time() - query('select', 'params', ['name' => 'secret_key_last_change'], 'value')[0] >= 86400 * 20) {
|
||||
DB->prepare("UPDATE params SET value = :secret_key WHERE name = 'secret_key';")
|
||||
->execute([':secret_key' => bin2hex(random_bytes(32))]);
|
||||
DB->prepare("UPDATE params SET value = :last_change WHERE name = 'secret_key_last_change';")
|
||||
->execute([':last_change' => time()]);
|
||||
}
|
||||
define('SECRET_KEY', file_get_contents(SECRET_KEY_FILE));
|
||||
define('SECRET_KEY', hex2bin(query('select', 'params', ['name' => 'secret_key'], 'value')[0]));
|
||||
function getAuthToken() {
|
||||
$salt = bin2hex(random_bytes(4));
|
||||
$hash = hash_hmac('sha256', $salt . ($_SESSION['id'] ?? ''), SECRET_KEY);
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
<?php
|
||||
|
||||
$dirsStatuses = dirsStatuses('dns', 'http');
|
||||
|
||||
$proof = getAuthToken();
|
||||
|
||||
?>
|
||||
|
||||
<p>
|
||||
Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par <?= linkToDocs('dns', 'DNS') ?> et <?= linkToDocs('tls', 'TLS') ?> <?= linkToDocs('ca', 'authentifié par <em>Let\'s Encrypt</em>') ?>.
|
||||
</p>
|
||||
|
@ -25,7 +17,7 @@ $proof = getAuthToken();
|
|||
</dd>
|
||||
<dt><code>TXT</code></dt>
|
||||
<dd>
|
||||
<code><?= SERVER_NAME ?>_domain-verification=<?= $proof ?></code>
|
||||
<code><?= SERVER_NAME ?>_domain-verification=<?= getAuthToken() ?></code>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
@ -36,7 +28,7 @@ $proof = getAuthToken();
|
|||
<select required="" name="dir" id="dir">
|
||||
<option value="" disabled="" selected="">---</option>
|
||||
<?php
|
||||
foreach ($dirsStatuses as $dir => $alreadyEnabled)
|
||||
foreach (dirsStatuses('dns', 'http') as $dir => $alreadyEnabled)
|
||||
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||
?>
|
||||
</select>
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
<?php
|
||||
|
||||
$dirsStatuses = dirsStatuses('onion', 'http');
|
||||
|
||||
?>
|
||||
|
||||
<p>
|
||||
Ajouter un accès en .onion sur un dossier
|
||||
</p>
|
||||
|
@ -13,7 +7,7 @@ $dirsStatuses = dirsStatuses('onion', 'http');
|
|||
<select required="" name="dir" id="dir">
|
||||
<option value="" disabled="" selected="">---</option>
|
||||
<?php
|
||||
foreach ($dirsStatuses as $dir => $alreadyEnabled)
|
||||
foreach (dirsStatuses('onion', 'http') as $dir => $alreadyEnabled)
|
||||
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||
?>
|
||||
</select>
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
<?php
|
||||
|
||||
$dirsStatuses = dirsStatuses('dns', 'http');
|
||||
|
||||
?>
|
||||
|
||||
<p>
|
||||
Retirer un accès DNS et TLS d'un dossier
|
||||
</p>
|
||||
|
@ -13,7 +7,7 @@ $dirsStatuses = dirsStatuses('dns', 'http');
|
|||
<select required="" name="dir" id="dir">
|
||||
<option value="" disabled="" selected="">---</option>
|
||||
<?php
|
||||
foreach ($dirsStatuses as $dir => $alreadyEnabled)
|
||||
foreach (dirsStatuses('dns', 'http') as $dir => $alreadyEnabled)
|
||||
echo ' <option' . ($alreadyEnabled ? '' : ' disabled=""') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||
?>
|
||||
</select>
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
<?php
|
||||
|
||||
$dirsStatuses = dirsStatuses('onion', 'http');
|
||||
|
||||
?>
|
||||
|
||||
<p>
|
||||
Retirer un accès Onion d'un dossier
|
||||
</p>
|
||||
|
@ -13,7 +7,7 @@ $dirsStatuses = dirsStatuses('onion', 'http');
|
|||
<select required="" name="dir" id="dir">
|
||||
<option value="" disabled="" selected="">---</option>
|
||||
<?php
|
||||
foreach ($dirsStatuses as $dir => $alreadyEnabled)
|
||||
foreach (dirsStatuses('onion', 'http') as $dir => $alreadyEnabled)
|
||||
echo ' <option' . ($alreadyEnabled ? '' : ' disabled=""') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||
?>
|
||||
</select>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<p>
|
||||
Pour prouver que vous possédez bien ce domaine, il doit posséder un <?= linkToDocs('ns-record', 'enregistrement NS') ?> égal à <code><?= $proof ?>._domain-verification.<?= SERVER_NAME ?>.</code> lors du traitement de ce formulaire.
|
||||
Pour prouver que vous possédez bien ce domaine, il doit posséder un <?= linkToDocs('ns-record', 'enregistrement NS') ?> égal à <code><?= getAuthToken() ?>._domain-verification.<?= SERVER_NAME ?>.</code> lors du traitement de ce formulaire.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
define('TIME', hrtime(true));
|
||||
define('CONF', parse_ini_file(__DIR__ . '/config.ini', true, INI_SCANNER_TYPED));
|
||||
|
||||
define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
|
||||
|
||||
foreach (array_diff(scandir(CONF['common']['root_path'] . '/fn'), array('..', '.')) as $file)
|
||||
require CONF['common']['root_path'] . '/fn/' . $file;
|
||||
require 'pages.php';
|
||||
|
||||
define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
|
||||
|
||||
const LF = "\n";
|
||||
|
||||
const PLACEHOLDER_DOMAIN = 'example'; // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
|
||||
|
|
Loading…
Reference in a new issue