summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2021-05-04 17:32:26 +0200
committerSimon Rettberg2021-05-11 14:50:11 +0200
commit1e8329986ef4d06a9bb7550e24f4dacc7715fb5b (patch)
tree67e13b41650992d2266d42c88b91489a65840eae
parent[systemstatus] Fix displaying VM store usage if using internal storage (diff)
downloadslx-admin-1e8329986ef4d06a9bb7550e24f4dacc7715fb5b.tar.gz
slx-admin-1e8329986ef4d06a9bb7550e24f4dacc7715fb5b.tar.xz
slx-admin-1e8329986ef4d06a9bb7550e24f4dacc7715fb5b.zip
[main+Session] Move session from /tmp/ to session table
-rw-r--r--inc/session.inc.php133
-rw-r--r--inc/user.inc.php10
-rw-r--r--inc/util.inc.php1
-rw-r--r--modules-available/main/install.inc.php11
-rw-r--r--modules-available/rebootcontrol/inc/rebootcontrol.inc.php1
-rw-r--r--modules-available/rebootcontrol/pages/exec.inc.php1
-rw-r--r--modules-available/session/hooks/cron.inc.php6
-rw-r--r--modules-available/sysconfig/addmodule_branding.inc.php2
-rw-r--r--modules-available/sysconfig/addmodule_custommodule.inc.php2
-rw-r--r--modules-available/sysconfig/addmodule_screensaver.inc.php2
-rw-r--r--modules-available/syslog/page.inc.php17
-rw-r--r--modules-available/vmstore/page.inc.php2
12 files changed, 115 insertions, 73 deletions
diff --git a/inc/session.inc.php b/inc/session.inc.php
index cb52cd38..f06cd580 100644
--- a/inc/session.inc.php
+++ b/inc/session.inc.php
@@ -2,18 +2,17 @@
require_once('config.php');
-@mkdir(CONFIG_SESSION_DIR, 0700, true);
-@chmod(CONFIG_SESSION_DIR, 0700);
-if (!is_writable(CONFIG_SESSION_DIR)) die('Config error: Session Path not writable!');
-
class Session
{
private static $sid = false;
private static $data = false;
+ private static $dataChanged = false;
+ private static $userId = 0;
- private static function generateSessionId($salt)
+ private static function generateSessionId(string $salt)
{
- if (self::$sid !== false) Util::traceError('Error: Asked to generate session id when already set.');
+ if (self::$sid !== false)
+ Util::traceError('Error: Asked to generate session id when already set.');
self::$sid = sha1($salt . ','
. mt_rand(0, 65535)
. $_SERVER['REMOTE_ADDR']
@@ -27,26 +26,40 @@ class Session
);
}
- public static function create($salt = '')
+ public static function create(string $salt, int $userId, bool $fixedAddress)
{
self::generateSessionId($salt);
- self::$data = array();
+ self::$data = [];
+ self::$userId = $userId;
+ Database::exec("INSERT INTO session (sid, userid, dateline, lastip, fixedip, data)
+ VALUES (:sid, :userid, 0, '', :fixedip, '')", [
+ 'sid' => self::$sid,
+ 'userid' => $userId,
+ 'fixedip' => $fixedAddress ? 1 : 0,
+ ]);
}
- public static function load()
+ public static function load(): bool
{
// Try to load session id from cookie
- if (!self::loadSessionId()) return false;
+ if (!self::loadSessionId())
+ return false;
// Succeeded, now try to load session data. If successful, job is done
- if (self::readSessionData()) return true;
+ if (self::readSessionData())
+ return true;
// Loading session data failed
- self::delete();
return false;
}
- public static function get($key)
+ public static function getUserId(): int
+ {
+ return self::$userId;
+ }
+
+ public static function get(string $key)
{
- if (!isset(self::$data[$key]) || !is_array(self::$data[$key])) return false;
+ if (!isset(self::$data[$key]) || !is_array(self::$data[$key]))
+ return false;
return self::$data[$key][0];
}
@@ -55,30 +68,37 @@ class Session
* @param mixed $value data to store for key, false = delete
* @param int|false $validMinutes validity in minutes, or false = forever
*/
- public static function set($key, $value, $validMinutes = false)
+ public static function set(string $key, $value, $validMinutes = 60)
{
- if (self::$data === false) Util::traceError('Tried to set session data with no active session');
+ if (self::$data === false)
+ Util::traceError('Tried to set session data with no active session');
if ($value === false) {
unset(self::$data[$key]);
} else {
self::$data[$key] = [$value, $validMinutes === false ? false : time() + $validMinutes * 60];
}
+ self::$dataChanged = true;
}
- private static function loadSessionId()
+ private static function loadSessionId(): bool
{
- if (self::$sid !== false) die('Error: Asked to load session id when already set.');
- if (empty($_COOKIE['sid'])) return false;
+ if (self::$sid !== false)
+ Util::traceError('Error: Asked to load session id when already set.');
+ if (empty($_COOKIE['sid']))
+ return false;
$id = preg_replace('/[^a-zA-Z0-9]/', '', $_COOKIE['sid']);
- if (empty($id)) return false;
+ if (empty($id))
+ return false;
self::$sid = $id;
return true;
}
public static function delete()
{
- if (self::$sid === false) return;
- @unlink(self::getSessionFile());
+ if (self::$sid === false)
+ return;
+ Database::exec("DELETE FROM session WHERE sid = :sid",
+ ['sid' => self::$sid]);
self::deleteCookie();
self::$sid = false;
self::$data = false;
@@ -88,47 +108,58 @@ class Session
{
Util::clearCookie('sid');
}
-
- private static function getSessionFile()
- {
- if (self::$sid === false) Util::traceError('Error: Tried to access session file when no session id was set.');
- return CONFIG_SESSION_DIR . '/' . self::$sid;
- }
- private static function readSessionData()
+ private static function readSessionData(): bool
{
- if (self::$data !== false) Util::traceError('Tried to call read session data twice');
- $sessionfile = self::getSessionFile();
- if (!is_readable($sessionfile) || filemtime($sessionfile) + CONFIG_SESSION_TIMEOUT < time()) {
- @unlink($sessionfile);
- return false;
- }
- self::$data = @unserialize(@file_get_contents($sessionfile));
- if (self::$data === false)
- return false;
+ if (self::$data !== false)
+ Util::traceError('Tried to call read session data twice');
+ $row = Database::queryFirst("SELECT userid, dateline, lastip, fixedip, data FROM session WHERE sid = :sid",
+ ['sid' => self::$sid]);
$now = time();
- $save = false;
+ if ($row === false || $row['dateline'] < $now) {
+ self::delete();
+ return false;
+ }
+ if ($row['fixedip'] && $row['lastip'] !== $_SERVER['REMOTE_ADDR']) {
+ return false; // Ignore but don't invalidate
+ }
+ self::$userId = $row['userid'];
+ self::$data = @json_decode($row['data'], true);
+ if (!is_array(self::$data)) {
+ self::$data = [];
+ }
foreach (array_keys(self::$data) as $key) {
if (self::$data[$key][1] !== false && self::$data[$key][1] < $now) {
unset(self::$data[$key]);
- $save = true;
+ self::$dataChanged = true;
}
}
- if ($save) {
- self::save();
- }
return true;
}
- public static function save()
+ public static function saveInternal()
{
- if (self::$sid === false || self::$data === false) return; //Util::traceError('Called saveSession with no active session');
- $sessionfile = self::getSessionFile();
- $ret = @file_put_contents($sessionfile, @serialize(self::$data));
- if (!$ret) Util::traceError('Storing session data in ' . $sessionfile . ' failed.');
- Util::clearCookie('sid');
- $ret = setcookie('sid', self::$sid, time() + CONFIG_SESSION_TIMEOUT, null, null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true);
- if (!$ret) Util::traceError('Error: Could not set Cookie for Client (headers already sent)');
+ $now = time();
+ $args = [
+ 'dateline' => $now + CONFIG_SESSION_TIMEOUT,
+ 'lastip' => $_SERVER['REMOTE_ADDR'],
+ ];
+ if (self::$dataChanged) {
+ $args['data'] = json_encode(self::$data);
+ }
+ $query = "UPDATE session SET " . implode(', ', array_map(function ($key) {
+ return "$key = :$key";
+ }, array_keys($args))) . " WHERE sid = :sid";
+ $args['sid'] = self::$sid;
+ Database::exec($query, $args);
+ $ret = setcookie('sid', self::$sid, $now + CONFIG_SESSION_TIMEOUT,
+ null, null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true);
+ if (!$ret)
+ Util::traceError('Error: Could not set Cookie for Client (headers already sent)');
}
+
}
+register_shutdown_function(function () {
+ Session::saveInternal();
+});
diff --git a/inc/user.inc.php b/inc/user.inc.php
index 2ad256af..46cc6012 100644
--- a/inc/user.inc.php
+++ b/inc/user.inc.php
@@ -113,8 +113,8 @@ class User
if (self::isLoggedIn())
return true;
if (Session::load()) {
- $uid = Session::get('uid');
- if ($uid === false || $uid < 1)
+ $uid = Session::getUserId();
+ if ($uid < 1)
self::logout();
self::$user = Database::queryFirst('SELECT * FROM user WHERE userid = :uid LIMIT 1', array(':uid' => $uid));
if (self::$user === false)
@@ -149,8 +149,7 @@ class User
return false;
if (!Crypto::verify($pass, $ret['passwd']))
return false;
- Session::create($ret['passwd']);
- Session::set('uid', $ret['userid']);
+ Session::create($ret['passwd'], $ret['userid'], false);
Session::set('token', md5($ret['passwd'] . ','
. rand() . ','
. time() . ','
@@ -159,8 +158,7 @@ class User
. rand() . ','
. $_SERVER['REMOTE_PORT'] . ','
. rand() . ','
- . $_SERVER['HTTP_USER_AGENT']));
- Session::save();
+ . $_SERVER['HTTP_USER_AGENT']), false);
return true;
}
diff --git a/inc/util.inc.php b/inc/util.inc.php
index fbc894df..81c7d807 100644
--- a/inc/util.inc.php
+++ b/inc/util.inc.php
@@ -158,7 +158,6 @@ SADFACE;
if ($location === false) {
$location = preg_replace('/([&?])message\[\]\=[^&]*/', '\1', $_SERVER['REQUEST_URI']);
}
- Session::save();
$messages = Message::toRequest();
if ($preferRedirectPost
&& ($redirect = Request::post('redirect', false, 'string')) !== false
diff --git a/modules-available/main/install.inc.php b/modules-available/main/install.inc.php
index 92ad4db1..fe572487 100644
--- a/modules-available/main/install.inc.php
+++ b/modules-available/main/install.inc.php
@@ -48,6 +48,17 @@ $res[] = tableCreate('user', "
UNIQUE KEY `login` (`login`)
");
+$res[] = tableCreate('session', "
+ `sid` char(50) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
+ `userid` int(10) unsigned NOT NULL,
+ `dateline` int(10) unsigned NOT NULL DEFAULT '0',
+ `lastip` varchar(45) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
+ `fixedip` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `data` blob NOT NULL,
+ PRIMARY KEY (`sid`),
+ KEY `dateline` (`dateline`)
+");
+
// Update path
// #######################
diff --git a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
index a8018004..da1dd69a 100644
--- a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
+++ b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
@@ -494,7 +494,6 @@ class RebootControl
return;
$id = mt_rand();
Session::set('exec-' . $id, $machines, 60);
- Session::save();
Util::redirect('?do=rebootcontrol&show=exec&what=prepare&id=' . $id);
}
diff --git a/modules-available/rebootcontrol/pages/exec.inc.php b/modules-available/rebootcontrol/pages/exec.inc.php
index e5fe3cd8..6b5ea407 100644
--- a/modules-available/rebootcontrol/pages/exec.inc.php
+++ b/modules-available/rebootcontrol/pages/exec.inc.php
@@ -46,7 +46,6 @@ class SubPage
return;
}
Session::set('exec-' . $id, false);
- Session::save();
Render::addTemplate('exec-enter-command', ['clients' => $machines, 'id' => $id]);
}
diff --git a/modules-available/session/hooks/cron.inc.php b/modules-available/session/hooks/cron.inc.php
new file mode 100644
index 00000000..e2cd46e6
--- /dev/null
+++ b/modules-available/session/hooks/cron.inc.php
@@ -0,0 +1,6 @@
+<?php
+
+// Clean up old sessions
+if (mt_rand(1, 10) === 4) {
+ Database::exec("DELETE FROM session WHERE dateline < UNIX_TIMESTAMP()");
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/addmodule_branding.inc.php b/modules-available/sysconfig/addmodule_branding.inc.php
index 22c42f54..e6da9edb 100644
--- a/modules-available/sysconfig/addmodule_branding.inc.php
+++ b/modules-available/sysconfig/addmodule_branding.inc.php
@@ -65,7 +65,6 @@ class Branding_ProcessFile extends AddModule_Base
Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start');
}
Session::set('logo_tgz', $this->tarFile);
- Session::save();
}
protected function renderInternal()
@@ -227,7 +226,6 @@ class Branding_Finish extends AddModule_Base
Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start');
Session::set('logo_tgz', false);
Session::set('logo_name', false);
- Session::save();
// Yay
if ($this->edit !== false)
Message::addSuccess('module-edited');
diff --git a/modules-available/sysconfig/addmodule_custommodule.inc.php b/modules-available/sysconfig/addmodule_custommodule.inc.php
index f7ab863e..13794e83 100644
--- a/modules-available/sysconfig/addmodule_custommodule.inc.php
+++ b/modules-available/sysconfig/addmodule_custommodule.inc.php
@@ -83,7 +83,6 @@ class CustomModule_ProcessUpload extends AddModule_Base
'title' => $title,
'userGroupWarn' => $userGroupWarn,
));
- Session::save();
}
}
@@ -135,7 +134,6 @@ class CustomModule_CompressModule extends AddModule_Base
elseif (!$module->generate($this->edit === false, NULL, 200))
Util::redirect('?do=SysConfig&action=addmodule&step=CustomModule_Start');
Session::set('mod_temp', false);
- Session::save();
// Yay
if ($this->edit !== false)
Message::addSuccess('module-edited');
diff --git a/modules-available/sysconfig/addmodule_screensaver.inc.php b/modules-available/sysconfig/addmodule_screensaver.inc.php
index 8e5c5d28..9641bab3 100644
--- a/modules-available/sysconfig/addmodule_screensaver.inc.php
+++ b/modules-available/sysconfig/addmodule_screensaver.inc.php
@@ -47,7 +47,6 @@ class Screensaver_Start extends AddModule_Base
}
$this->session_data['next'] = 'idle-kill';
Session::set('data', $this->session_data);
- Session::save();
}
protected function renderInternal()
@@ -85,7 +84,6 @@ class Screensaver_Text extends AddModule_Base
$next = Request::post('next', $this->session_data['next'], 'string');
$this->session_data['next'] = $next;
Session::set('data', $this->session_data);
- Session::save();
if ($next === 'finish')
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index 6868994e..410a1ed7 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -26,14 +26,19 @@ class Page_SysLog extends Page
Util::redirect('?do=syslog');
}
if (Request::isPost()) {
- $search = Request::any('search');
- $filter = Request::any('filter');
+ $search = Request::any('search', false, 'string');
+ $filter = Request::any('filter', false, 'string');
$not = Request::any('not', false, 'bool');
$machineuuid = Request::any('machineuuid');
- Session::set('log_search', $search);
- Session::set('log_filter', $filter);
- Session::set('log_not', $not);
- Session::save();
+ if (empty($search)) {
+ $search = false;
+ }
+ if (empty($filter)) {
+ $filter = false;
+ }
+ Session::set('log_search', $search, false);
+ Session::set('log_filter', $filter, false);
+ Session::set('log_not', $not, false);
Util::redirect('?do=syslog&' . http_build_query(compact('search', 'filter', 'not', 'machineuuid')));
}
User::assertPermission('*');
diff --git a/modules-available/vmstore/page.inc.php b/modules-available/vmstore/page.inc.php
index 39f6abdc..08d56d96 100644
--- a/modules-available/vmstore/page.inc.php
+++ b/modules-available/vmstore/page.inc.php
@@ -44,7 +44,7 @@ class Page_VmStore extends Page
// Remove rw setting
if ($key === 'cifsopts' || $key === 'nfsopts') {
$vmstore[$key] = preg_replace('/\s+,\s+/', ',', $vmstore[$key]);
- $vmstore[$key] = preg_replace('/^rw,|,rw$/', '', str_replace(',rw,', ',', $vmstore[$key]));
+ $vmstore[$key] = preg_replace('/^rw ,|,rw$/', '', str_replace(',rw,', ',', $vmstore[$key]));
}
}
$storetype = $vmstore['storetype'];