($msg === '') ? '' : '

' . _('Success: ') . '' . $msg . '

' . LF, 4 => '

' . _('User error: ') . '' . $msg . '

' . LF, 5 => '

' . _('Server error: ') . '' . $msg . '

' . LF, }; displayPage(['final_message' => $final_message]); } function insert($table, $values) { $query = 'INSERT INTO "' . $table . '"('; foreach ($values as $key => $val) { if ($key === array_key_last($values)) $query .= "$key"; else $query .= "$key, "; } $query .= ') VALUES('; foreach ($values as $key => $val) { if ($key === array_key_last($values)) $query .= ":$key"; else $query .= ":$key, "; } $query .= ')'; DB->prepare($query) ->execute($values); } function query($action, $table, $conditions = [], $column = NULL) { $query = match ($action) { 'select' => 'SELECT *', 'delete' => 'DELETE', }; $query .= ' FROM "' . $table . '"'; foreach ($conditions as $key => $val) { if ($key === array_key_first($conditions)) $query .= " WHERE $key = :$key"; else $query .= " AND $key = :$key"; } $stmt = DB->prepare($query); $stmt->execute($conditions); return array_column($stmt->fetchAll(PDO::FETCH_ASSOC), $column); } function displayIndex() { ?> redir.'); header('Location: ' . CONF['common']['prefix'] . '/' . $redir_to); exit(); } // PHP rmdir() only works on empty directories function removeDirectory($dir) { $dirObj = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($dirObj, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) $file->isDir() && !$file->isLink() ? rmdir($file->getPathname()) : unlink($file->getPathname()); if (rmdir($dir) !== true) output(500, 'Unable to remove directory.'); } function equalArrays($a, $b) { return array_diff($a, $b) === [] AND array_diff($b, $a) === []; } /* This token authenticates the user to the server through a public communication (the DNS). It is therefore also designed to keep private: - the user's id - that a same user used a token multiple times (by using a unique salt for each token) */ 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', 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); return $salt . '-' . substr($hash, 0, 32); } function checkAuthToken($salt, $hash) { $correctProof = substr(hash_hmac('sha256', $salt . $_SESSION['id'], SECRET_KEY), 0, 32); if (hash_equals($correctProof, $hash) !== true) output(403, _('Wrong proof.')); }