diff options
-rw-r--r-- | Zotlabs/Web/Session.php | 40 | ||||
-rw-r--r-- | Zotlabs/Web/SessionHandler.php | 80 | ||||
-rw-r--r-- | version.inc | 3 |
3 files changed, 65 insertions, 58 deletions
diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index 0cd83c15e..55536fdc7 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -14,6 +14,7 @@ namespace Zotlabs\Web; class Session { private static $handler = null; + private static $session_started = false; function init() { @@ -37,20 +38,19 @@ class Session { // Force cookies to be secure (https only) if this site is SSL enabled. // Must be done before session_start(). - if(intval(\App::$config['system']['ssl_cookie_protection'])) { - $arr = session_get_cookie_params(); - session_set_cookie_params( - ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0), - ((isset($arr['path'])) ? $arr['path'] : '/'), - ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()), - ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false), - ((isset($arr['httponly'])) ? $arr['httponly'] : true) - ); - } + $arr = session_get_cookie_params(); + session_set_cookie_params( + ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0), + ((isset($arr['path'])) ? $arr['path'] : '/'), + ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()), + ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false), + ((isset($arr['httponly'])) ? $arr['httponly'] : true) + ); } function start() { session_start(); + self::$session_started = true; } /** @@ -74,10 +74,13 @@ class Session { $old_sid = session_id(); - session_regenerate_id(false); + if(self::$handler && self::$session_started) { + session_regenerate_id(true); + + // force SessionHandler record creation with the new session_id + // which occurs as a side effect of read() - if(self::$handler) { - self::$handler->rename($old_sid,session_id()); + self::$handler->read(session_id()); } else logger('no session handler'); @@ -87,14 +90,21 @@ class Session { } setcookie(session_name(),session_id(),$newxtime); + $arr = array('expire' => $xtime); + call_hooks('new_cookie', $arr); + } function extend_cookie() { // if there's a long-term cookie, extend it - if(intval($_SESSION['remember_me'])) - setcookie(session_name(),session_id(),(time() + (60 * 60 * 24 * 365))); + $xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 ); + + if($xtime) + setcookie(session_name(),session_id(),(time() + $xtime)); + $arr = array('expire' => $xtime); + call_hooks('extend_cookie', $arr); } diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php index 359279384..6980a6408 100644 --- a/Zotlabs/Web/SessionHandler.php +++ b/Zotlabs/Web/SessionHandler.php @@ -5,24 +5,30 @@ namespace Zotlabs\Web; class SessionHandler implements \SessionHandlerInterface { - private $session_exists; - private $session_expire; - function open ($s, $n) { - $this->session_exists = 0; - $this->session_expire = 180000; return true; } + // IMPORTANT: if we read the session and it doesn't exist, create an empty record. + // We rely on this due to differing PHP implementation of session_regenerate_id() + // some which call read explicitly and some that do not. So we call it explicitly + // just after sid regeneration to force a record to exist. + function read ($id) { - if(x($id)) + if($id) { $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id)); - if($r) { - $this->session_exists = true; - return $r[0]['data']; + if($r) { + return $r[0]['data']; + } + else { + q("INSERT INTO `session` (sid, expire) values ('%s', '%s')", + dbesc($id), + dbesc(time() + 300) + ); + } } return ''; @@ -35,30 +41,30 @@ class SessionHandler implements \SessionHandlerInterface { return false; } - // Can't just use $data here because we can't be certain of the serialisation algorithm - - if($_SESSION && array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me'])) - $expire = time() + (60 * 60 * 24 * 365); - else - $expire = time() + $this->session_expire; - $default_expire = time() + 300; - - if($this->session_exists) { - q("UPDATE `session` - SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'", - dbesc($data), - dbesc($expire), - dbesc($id) - ); - } - else { - q("INSERT INTO `session` (sid, expire, data) values ('%s', '%s', '%s')", - dbesc($id), - dbesc($default_expire), - dbesc($data) - ); + // Unless we authenticate somehow, only keep a session for 5 minutes + // The viewer can extend this by performing any web action using the + // original cookie, but this allows us to cleanup the hundreds or + // thousands of empty sessions left around from web crawlers which are + // assigned cookies on each page that they never use. + + $expire = time() + 300; + + if($_SESSION) { + if(array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me'])) + $expire = time() + (60 * 60 * 24 * 365); + elseif(local_channel()) + $expire = time() + (60 * 60 * 24 * 3); + elseif(remote_channel()) + $expire = time() + (60 * 60 * 24 * 1); } + q("UPDATE `session` + SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'", + dbesc($data), + dbesc($expire), + dbesc($id) + ); + return true; } @@ -79,14 +85,4 @@ class SessionHandler implements \SessionHandlerInterface { return true; } - - // not part of the official interface, used when regenerating the session id - - function rename($old,$new) { - $v = q("UPDATE session SET sid = '%s' WHERE sid = '%s'", - dbesc($new), - dbesc($old) - ); - } - -}
\ No newline at end of file +} diff --git a/version.inc b/version.inc index 5f361e977..4c06763d5 100644 --- a/version.inc +++ b/version.inc @@ -1,2 +1,3 @@ -2016-04-11.1363H +2016-04-12.1364H + |