diff --git a/src/init.php b/src/init.php
index 3c6ba9d..806adf8 100644
--- a/src/init.php
+++ b/src/init.php
@@ -63,7 +63,7 @@ Lang::loadLang( Config::get('lang') );
$_mttinfo = array();
-if (need_auth() && !isset($dontStartSession)) {
+if (need_auth() && !isset($dontStartSession) && !Config::$noDatabase) {
setup_and_start_session();
}
set_nocache_headers();
diff --git a/src/setup.php b/src/setup.php
index 333533d..9019ab0 100644
--- a/src/setup.php
+++ b/src/setup.php
@@ -20,6 +20,7 @@ if (getenv('MTT_ENABLE_DEBUG') == 'YES') {
else {
set_exception_handler('myExceptionHandler');
define('MTT_DEBUG', false);
+ #ini_set('zend.exception_ignore_args', 1); // php 7.4+
}
if (!defined('MTTPATH')) define('MTTPATH', dirname(__FILE__) .'/');
@@ -32,6 +33,7 @@ require_once(MTTINC. 'version.php');
$db = null;
$ver = '';
$error = '';
+$passwordAskedV14 = false;
$setupToken = stoken();
if ($setupToken == '' || strlen($setupToken) != 36) {
@@ -49,16 +51,10 @@ echo "myTinyTodo $mttVersion Setup
";
if (!$configExists && $oldConfigExists)
{
- // First we need to migrate database config
+ // First we need to migrate database config of db v1.4
require_once(MTTPATH. 'db/config.php');
- if (isset($config['password']) && $config['password'] != '') {
- if (isset($_POST['configpassword'])) {
- check_post_stoken();
- }
- if ( !isset($_POST['configpassword']) || $_POST['configpassword'] != $config['password'] ) {
- exitMessage("Enter current password to continue.
");
- }
- }
+ askPasswordV14($config, $setupToken);
+ $passwordAskedV14 = true;
Config::loadConfigV14($config);
tryToSaveDBConfig();
$configExists = true;
@@ -95,13 +91,17 @@ if ($configExists)
// Need to upgrade. Do not ask for old password
Config::$noDatabase = true; //don't load settings from db
require_once(MTTPATH. 'db/config.php');
+ if ( !$passwordAskedV14 ) {
+ askPasswordV14($config, $setupToken);
+ $passwordAskedV14 = true;
+ }
Config::loadConfigV14($config);
unset($config);
DBConnection::init($db);
}
require_once('./init.php');
- if ( !is_logged() ) {
+ if ( !Config::$noDatabase && !is_logged() ) {
die("Access denied!
Disable password protection or Log in.");
}
@@ -239,6 +239,7 @@ function update_stoken()
$_COOKIE['mtt-s-token'] = $token;
return $token;
}
+
function check_post_stoken()
{
$token = $_POST['stoken'] ?? '';
@@ -247,6 +248,81 @@ function check_post_stoken()
}
}
+function askPasswordV14(
+ #[\SensitiveParameter]
+ array $config,
+ string $setupToken)
+{
+ if (!isset($config['password']) || $config['password'] == '') {
+ return;
+ }
+ if (isset($_POST['configpassword'])) {
+ check_post_stoken();
+ }
+ if (isset($_COOKIE['mtt-v14token'])) {
+ if (validateTokenV14($config, $_COOKIE['mtt-v14token'])) {
+ return; //authorized
+ }
+ if (MTT_DEBUG) error_log("Failed validation of v14token");
+ }
+ if ( !isset($_POST['configpassword']) || $_POST['configpassword'] != $config['password'] ) {
+ exitMessage("Enter current password to continue.
+ ");
+ }
+ $token = generateTokenV14($config);
+ if (PHP_VERSION_ID < 70300) {
+ setcookie('mtt-v14token', $token, 0, url_dir(getRequestUri()). '; samesite=lax', '', false, true ) ;
+ }
+ else {
+ /** @disregard P1006 available in php 7.3 */
+ setcookie('mtt-v14token', $token, [
+ 'path' => url_dir(getRequestUri()),
+ 'httponly' => true,
+ 'samesite' => 'lax'
+ ]);
+ }
+}
+
+function generateTokenV14(
+ #[\SensitiveParameter]
+ array $config) : ?string
+{
+ if (!isset($config['password']) || $config['password'] == '') {
+ return null;
+ }
+ $payload = base64_encode(json_encode([
+ 'exp' => time() + 300 # 5 min lifetime
+ ]));
+ return $payload. '.'. base64_encode(hash_hmac('sha256', $payload, $config['password'], true));
+}
+
+function validateTokenV14(
+ #[\SensitiveParameter]
+ array $config,
+ string $token) : bool
+{
+ if (!isset($config['password']) || $config['password'] == '') {
+ return true;
+ }
+ $parts = explode('.', $token);
+ if (count($parts) != 2) {
+ return false;
+ }
+ $signature = base64_decode($parts[1]); //binary
+ if ($signature === false) {
+ return false;
+ }
+ if ( !hash_equals($signature, hash_hmac('sha256', $parts[0], $config['password'], true)) ) {
+ return false;
+ }
+ $payload = json_decode(base64_decode($parts[0]), true);
+ if (!isset($payload['exp']) || time() > $payload['exp']) {
+ return false;
+ }
+ return true;
+}
+
function createAllTables($db, $dbtype)
{