--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2008 Polytechnique.org *
+ * http://opensource.polytechnique.org/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ ***************************************************************************/
+
+
+/** The PlSession is a wrapper around the user session management.
+ */
+abstract class PlSession
+{
+ /** Build a new session object.
+ * If a session is already started, this just wraps the session... if no
+ * session is currently started, this set the base session variables.
+ * * auth contains the current authentication level. The level is
+ * an integer that grows with the security of the authentication
+ * method.
+ * * perms contains the current permission flags of the user. This flags
+ * depends on the category of the user.
+ * * challenge contains a random uniq id for authentication.
+ * * xsrf_token contains a random uniq id for xsrf prevention.
+ * * user contains a reference to the current user.
+ */
+ public function __construct()
+ {
+ session_start();
+ $this->fillSession();
+ }
+
+ /** Build the session structure with system fields.
+ */
+ private function fillSession()
+ {
+ S::bootstrap('user', null);
+ S::bootstrap('auth', AUTH_PUBLIC);
+ S::bootstrap('challenge', sha1(uniqid(rand(), true)));
+ S::bootstrap('xsrf_token', rand_url_id());
+ S::bootstrap('perms', new PlFlagSet());
+ }
+
+ /** Write current session and close it.
+ */
+ public function close()
+ {
+ session_write_close();
+ }
+
+ /** Kill the current session.
+ */
+ public function destroy()
+ {
+ session_destroy();
+ unset($_SESSION);
+ }
+
+ /** Check if the user has at least the given authentication level.
+ */
+ public function checkAuth($level)
+ {
+ return S::i('auth') >= $level;
+ }
+
+ /** Check if the user has the given permissions.
+ */
+ public function checkPerms($perms)
+ {
+ return S::v('perms')->hasFlagCombination($perms);
+ }
+
+ /** Run authentication procedure to reach at least the given level.
+ */
+ public function start($level)
+ {
+ if ($this->checkAuth($level)) {
+ return true;
+ }
+ $user = $this->doAuth($level);
+ if (is_null($user) || !$this->checkAuth($level)) {
+ return false;
+ }
+ if ($this->startSessionAs($user, $level)) {
+ if (is_null(S::v('user'))) {
+ S::set('user', $user);
+ }
+ return true;
+ } else {
+ $this->destroy();
+ }
+ return false;
+ }
+
+
+ /*** Abstract methods ***/
+
+ /** Run the effectively authentication procedure to reach the given user.
+ * This method must return a user object (that will be used to fill the
+ * $_SESSION['user'] field).
+ *
+ * If auth failed, the function MUST return null. If auth succeed, the
+ * field $_SESSION['auth'] MUST be filled to the current effective level.
+ */
+ abstract protected function doAuth($level);
+
+ /** Set the session environment to the given user and authentication level.
+ * This function MUST return false if a session is already started and the
+ * user mismatch.
+ *
+ * On succes, this function MUST return true.
+ * If $level is set to -1, this means you are building a new SUID session.
+ */
+ abstract protected function startSessionAs($user, $level);
+
+
+ /*** SUID management ***/
+
+ /** Start a new SUID session.
+ */
+ public function startSUID($user)
+ {
+ if (isset($_SESSION['suid'])) {
+ return false;
+ }
+ $newsession = array();
+ $backup =& $_SESSION;
+ $_SESSION =& $newsession;
+ $this->fillSession();
+ S::set('suid', $backup);
+ if (!$this->startSessionAs($user, -1)) {
+ $this->stopSUID();
+ return false;
+ }
+ return true;
+ }
+
+ /** Stop a SUID session
+ */
+ public function stopSUID()
+ {
+ if (!isset($_SESSION['suid'])) {
+ return false;
+ }
+ $_SESSION =& $_SESSION['suid'];
+ return true;
+ }
+
+
+ /*** Thresholds ***/
+
+ /** Minimum level of authentication that is considered as sure.
+ */
+ abstract public function sureLevel();
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
-class S extends Session {
+class S
+{
+ /** Set a constructor because this is called prior to S::s(), so we can
+ * define S::s() for other usages.
+ */
+ private function __construct()
+ {
+ assert(false);
+ }
+
+ public static function has($key)
+ {
+ return isset($_SESSION[$key]);
+ }
+
+ public static function kill($key)
+ {
+ unset($_SESSION[$key]);
+ }
+
+ public static function v($key, $default = null)
+ {
+ return isset($_SESSION[$key]) ? $_SESSION[$key] : $default;
+ }
+
+ public static function s($key, $default = '')
+ {
+ return (string)S::v($key, $default);
+ }
+
+ public static function i($key, $default = 0)
+ {
+ $i = S::v($key, $default);
+ return is_numeric($i) ? intval($i) : $default;
+ }
+
+ public static function l(array $keys)
+ {
+ return array_map(array('S', 'v'), $keys);
+ }
+
+ public static function set($key, &$value)
+ {
+ $_SESSION[$key] =& $value;
+ }
+
+ public static function bootstrap($key, &$value)
+ {
+ if (!S::has($key)) {
+ S::set($key, $value);
+ }
+ }
+
+ public static function has_perms()
+ {
+ global $session;
+ return $session->checkPerms(PERMS_ADMIN);
+ }
+
+ public static function logged()
+ {
+ return S::v('auth', AUTH_PUBLIC) > AUTH_PUBLIC;
+ }
+
+ public static function identified()
+ {
+ global $session;
+ return S::v('auth', AUTH_PUBLIC) >= $session->sureLevel();
+ }
+
+ // Anti-XSRF protections.
+ public static function has_xsrf_token()
+ {
+ return S::has('xsrf_token') && S::v('xsrf_token') == Env::v('token');
+ }
+
+ public static function assert_xsrf_token()
+ {
+ if (!S::has_xsrf_token()) {
+ Platal::page()->kill('L\'opération n\'a pas pu aboutir, merci de réessayer.');
+ }
+ }
+
+ public static function rssActivated()
+ {
+ return S::has('core_rss_hash') && S::v('core_rss_hash');
+ }
}
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+++ /dev/null
-<?php
-/***************************************************************************
- * Copyright (C) 2003-2008 Polytechnique.org *
- * http://opensource.polytechnique.org/ *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- ***************************************************************************/
-
-class Session
-{
- public static function init()
- {
- @session_start();
- if (empty($_SESSION['challenge'])) {
- $_SESSION['challenge'] = sha1(uniqid(rand(), true));
- }
- if (empty($_SESSION['xsrf_token'])) {
- require_once 'xorg.misc.inc.php';
- $_SESSION['xsrf_token'] = rand_url_id();
- }
- if (!isset($_SESSION['perms']) || !($_SESSION['perms'] instanceof PlFlagSet)) {
- $_SESSION['perms'] = new PlFlagSet();
- }
- }
-
- public static function destroy()
- {
- @session_destroy();
- unset($_SESSION);
- }
-
- public static function has($key)
- {
- return isset($_SESSION[$key]);
- }
-
- public static function kill($key)
- {
- unset($_SESSION[$key]);
- }
-
- public static function v($key, $default = null)
- {
- return isset($_SESSION[$key]) ? $_SESSION[$key] : $default;
- }
-
- public static function s($key, $default = '')
- {
- return (string)Session::v($key, $default);
- }
-
- public static function i($key, $default = 0)
- {
- $i = Session::v($key, $default);
- return is_numeric($i) ? intval($i) : $default;
- }
-
- public static function l(array $keys)
- {
- return array_map(array('Session', 'v'), $keys);
- }
-
- public static function has_perms()
- {
- return Session::logged() && Session::v('perms')->hasFlag(PERMS_ADMIN);
- }
-
- public static function logged()
- {
- return Session::v('auth', AUTH_PUBLIC) >= AUTH_COOKIE;
- }
-
- public static function identified()
- {
- return Session::v('auth', AUTH_PUBLIC) >= AUTH_MDP;
- }
-
- // Anti-XSRF protections.
- public static function has_xsrf_token()
- {
- return Session::has('xsrf_token') && Session::v('xsrf_token') == Env::v('token');
- }
-
- public static function assert_xsrf_token()
- {
- if (!Session::has_xsrf_token()) {
- global $page;
- if ($page instanceof PlPage) {
- $page->kill("L'opération n'a pas pu aboutir, merci de réessayer.");
- }
- }
- }
-
- public static function rssActivated()
- {
- return Session::has('core_rss_hash') && Session::v('core_rss_hash');
- }
-}
-
-// {{{ function check_perms()
-
-/** verifie si un utilisateur a les droits pour voir une page
- ** si ce n'est pas le cas, on affiche une erreur
- * @return void
- */
-function check_perms()
-{
- global $page;
- if (!S::has_perms()) {
- if ($_SESSION['log']) {
- $_SESSION['log']->log("noperms",$_SERVER['PHP_SELF']);
- }
- $page->kill("Tu n'as pas les permissions nécessaires pour accéder à cette page.");
- }
-}
-
-// }}}
-
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>