aboutsummaryrefslogtreecommitdiff
path: root/engine/lib/sessions.php
diff options
context:
space:
mode:
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2009-10-08 21:48:14 +0000
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2009-10-08 21:48:14 +0000
commitb291acfd03be87038a1804d454a2f0f84412e17f (patch)
treea82bae2c6ea7917875f9fec6561fb62d1d852613 /engine/lib/sessions.php
parent993ccb6d2433c6316e45dda23387f161c1f70e03 (diff)
downloadelgg-b291acfd03be87038a1804d454a2f0f84412e17f.tar.gz
elgg-b291acfd03be87038a1804d454a2f0f84412e17f.tar.bz2
Brought access.php and sesssion.php up to code standards.
git-svn-id: http://code.elgg.org/elgg/trunk@3517 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine/lib/sessions.php')
-rw-r--r--engine/lib/sessions.php1301
1 files changed, 674 insertions, 627 deletions
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index b34f07725..d3e4a499d 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -1,669 +1,716 @@
<?php
- /**
- * Elgg session management
- * Functions to manage logins
- *
- * @package Elgg
- * @subpackage Core
+/**
+ * Elgg session management
+ * Functions to manage logins
+ *
+ * @package Elgg
+ * @subpackage Core
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
- * @author Curverider Ltd
+/** Elgg magic session */
+global $SESSION;
- * @link http://elgg.org/
- */
+/**
+ * Magic session class.
+ * This class is intended to extend the $_SESSION magic variable by providing an API hook
+ * to plug in other values.
+ *
+ * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session
+ * (which can cause problems when accessed server side).
+ *
+ * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called,
+ * where $var is the variable being requested.
+ *
+ * Setting values will store variables in the session in the normal way.
+ *
+ * LIMITATIONS: You can not access multidimensional arrays
+ *
+ * This is EXPERIMENTAL.
+ */
+class ElggSession implements ArrayAccess {
+ /** Local cache of trigger retrieved variables */
+ private static $__localcache;
- /** Elgg magic session */
- global $SESSION;
+ function __isset($key) {
+ return $this->offsetExists($key);
+ }
+
+ /** Set a value, go straight to session. */
+ function offsetSet($key, $value) {
+ $_SESSION[$key] = $value;
+ }
/**
- * Magic session class.
- * This class is intended to extend the $_SESSION magic variable by providing an API hook
- * to plug in other values.
- *
- * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session
- * (which can cause problems when accessed server side).
- *
- * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called,
- * where $var is the variable being requested.
- *
- * Setting values will store variables in the session in the normal way.
- *
- * LIMITATIONS: You can not access multidimensional arrays
- *
- * This is EXPERIMENTAL.
+ * Get a variable from either the session, or if its not in the session attempt to get it from
+ * an api call.
*/
- class ElggSession implements ArrayAccess
- {
- /** Local cache of trigger retrieved variables */
- private static $__localcache;
-
- function __isset($key) { return $this->offsetExists($key); }
-
- /** Set a value, go straight to session. */
- function offsetSet($key, $value) { $_SESSION[$key] = $value; }
-
- /**
- * Get a variable from either the session, or if its not in the session attempt to get it from
- * an api call.
- */
- function offsetGet($key)
- {
- if (!ElggSession::$__localcache)
- ElggSession::$__localcache = array();
-
- if (isset($_SESSION[$key]))
- return $_SESSION[$key];
-
- if (isset(ElggSession::$__localcache[$key]))
- return ElggSession::$__localcache[$key];
-
- $value = null;
- $value = trigger_plugin_hook('session:get', $key, null, $value);
-
- ElggSession::$__localcache[$key] = $value;
-
- return ElggSession::$__localcache[$key];
- }
-
- /**
- * Unset a value from the cache and the session.
- */
- function offsetUnset($key)
- {
- unset(ElggSession::$__localcache[$key]);
- unset($_SESSION[$key]);
- }
-
- /**
- * Return whether the value is set in either the session or the cache.
- */
- function offsetExists($offset) {
- if (isset(ElggSession::$__localcache[$offset]))
- return true;
-
- if (isset($_SESSION[$offset]))
- return true;
+ function offsetGet($key) {
+ if (!ElggSession::$__localcache) {
+ ElggSession::$__localcache = array();
+ }
+
+ if (isset($_SESSION[$key])) {
+ return $_SESSION[$key];
+ }
- if ($this->offsetGet($offset)) return true;
+ if (isset(ElggSession::$__localcache[$key])) {
+ return ElggSession::$__localcache[$key];
}
+
+ $value = null;
+ $value = trigger_plugin_hook('session:get', $key, null, $value);
+
+ ElggSession::$__localcache[$key] = $value;
+
+ return ElggSession::$__localcache[$key];
}
-
-
+
/**
- * Return the current logged in user, or null if no user is logged in.
- *
- * If no user can be found in the current session, a plugin hook - 'session:get' 'user' to give plugin
- * authors another way to provide user details to the ACL system without touching the session.
- */
- function get_loggedin_user()
- {
- global $SESSION;
-
- if (isset($SESSION))
- return $SESSION['user'];
-
- return false;
- }
-
+ * Unset a value from the cache and the session.
+ */
+ function offsetUnset($key) {
+ unset(ElggSession::$__localcache[$key]);
+ unset($_SESSION[$key]);
+ }
+
/**
- * Return the current logged in user by id.
- *
- * @see get_loggedin_user()
- * @return int
- */
- function get_loggedin_userid()
- {
- $user = get_loggedin_user();
- if ($user)
- return $user->guid;
-
- return 0;
+ * Return whether the value is set in either the session or the cache.
+ */
+ function offsetExists($offset) {
+ if (isset(ElggSession::$__localcache[$offset])) {
+ return true;
}
- /**
- * Returns whether or not the user is currently logged in
- *
- * @return true|false
- */
- function isloggedin() {
-
- if (!is_installed()) return false;
-
- $user = get_loggedin_user();
-
- if ((isset($user)) && ($user instanceof ElggUser) && ($user->guid > 0))
- return true;
-
- return false;
-
+ if (isset($_SESSION[$offset])) {
+ return true;
}
- /**
- * Returns whether or not the user is currently logged in and that they are an admin user.
- *
- * @uses isloggedin()
- * @return true|false
- */
- function isadminloggedin()
- {
- if (!is_installed()) return false;
-
- $user = get_loggedin_user();
-
- if ((isloggedin()) && (($user->admin || $user->siteadmin)))
- return true;
-
- return false;
+ if ($this->offsetGet($offset)){
+ return true;
}
-
- /**
- * Check if the given user is an admin.
- *
- * @param $user_guid
- * @return bool
- */
- function is_admin_user($user_guid) {
- global $CONFIG;
-
- // caching is done at the db level so no need to here.
- $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e, {$CONFIG->dbprefix}metastrings as ms1, {$CONFIG->dbprefix}metastrings as ms2, {$CONFIG->dbprefix}metadata as md
- WHERE (
- ms1.string = 'admin' AND ms2.string = 'yes'
- AND md.name_id = ms1.id AND md.value_id = ms2.id
- AND e.guid = md.entity_guid
- AND e.guid = {$user_guid}
- AND e.banned = 'no'
- )
- OR (
- ms1.string = 'admin' AND ms2.string = '1'
- AND md.name_id = ms1.id AND md.value_id = ms2.id
- AND e.guid = md.entity_guid
- AND e.guid = {$user_guid}
- AND e.banned = 'no'
- )";
-
- // normalizing the results from get_data()
- // See #1242
- $info = get_data($query);
- if (!((is_array($info) && count($info) < 1) || $info === false)) {
- return true;
+ }
+}
+
+
+/**
+ * Return the current logged in user, or null if no user is logged in.
+ *
+ * If no user can be found in the current session, a plugin hook - 'session:get' 'user' to give plugin
+ * authors another way to provide user details to the ACL system without touching the session.
+ */
+function get_loggedin_user() {
+ global $SESSION;
+
+ if (isset($SESSION)) {
+ return $SESSION['user'];
+ }
+
+ return false;
+}
+
+/**
+ * Return the current logged in user by id.
+ *
+ * @see get_loggedin_user()
+ * @return int
+ */
+function get_loggedin_userid() {
+ $user = get_loggedin_user();
+ if ($user)
+ return $user->guid;
+
+ return 0;
+}
+
+/**
+ * Returns whether or not the user is currently logged in
+ *
+ * @return true|false
+ */
+function isloggedin() {
+ if (!is_installed()) {
+ return false;
+ }
+
+ $user = get_loggedin_user();
+
+ if ((isset($user)) && ($user instanceof ElggUser) && ($user->guid > 0)) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Returns whether or not the user is currently logged in and that they are an admin user.
+ *
+ * @uses isloggedin()
+ * @return true|false
+ */
+function isadminloggedin() {
+ if (!is_installed()) {
+ return false;
+ }
+
+ $user = get_loggedin_user();
+
+ if ((isloggedin()) && (($user->admin || $user->siteadmin))) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Check if the given user has full access.
+ * @todo: Will always return full access if the user is an admin.
+ *
+ * @param $user_guid
+ * @return bool
+ */
+function is_admin_user($user_guid) {
+ global $CONFIG;
+
+ // cannot use metadata here because
+ // caching is done at the db level so no need to here.
+ $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e, {$CONFIG->dbprefix}metastrings as ms1, {$CONFIG->dbprefix}metastrings as ms2, {$CONFIG->dbprefix}metadata as md
+ WHERE (
+ ms1.string = 'admin' AND ms2.string = 'yes'
+ AND md.name_id = ms1.id AND md.value_id = ms2.id
+ AND e.guid = md.entity_guid
+ AND e.guid = {$user_guid}
+ AND e.banned = 'no'
+ )
+ OR (
+ ms1.string = 'admin' AND ms2.string = '1'
+ AND md.name_id = ms1.id AND md.value_id = ms2.id
+ AND e.guid = md.entity_guid
+ AND e.guid = {$user_guid}
+ AND e.banned = 'no'
+ )";
+
+ // normalizing the results from get_data()
+ // See #1242
+ $info = get_data($query);
+ if (!((is_array($info) && count($info) < 1) || $info === false)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Perform standard authentication with a given username and password.
+ * Returns an ElggUser object for use with login.
+ *
+ * @see login
+ * @param string $username The username, optionally (for standard logins)
+ * @param string $password The password, optionally (for standard logins)
+ * @return ElggUser|false The authenticated user object, or false on failure.
+ */
+
+function authenticate($username, $password) {
+ if (pam_authenticate(array('username' => $username, 'password' => $password))) {
+ return get_user_by_username($username);
+ }
+
+ return false;
+}
+
+/**
+ * Hook into the PAM system which accepts a username and password and attempts to authenticate
+ * it against a known user.
+ *
+ * @param array $credentials Associated array of credentials passed to pam_authenticate. This function expects
+ * 'username' and 'password' (cleartext).
+ */
+function pam_auth_userpass($credentials = NULL) {
+ $max_in_period = 3; // max 3 login attempts in
+ $period_length = 5; // 5 minutes
+ $periods = array();
+
+ if (is_array($credentials) && ($credentials['username']) && ($credentials['password'])) {
+ if ($user = get_user_by_username($credentials['username'])) {
+
+ // Let admins log in without validating their email, but normal users must have validated their email or been admin created
+ if ((!$user->admin) && (!$user->validated) && (!$user->admin_created)) {
+ return false;
}
- return false;
- }
-
- /**
- * Perform standard authentication with a given username and password.
- * Returns an ElggUser object for use with login.
- *
- * @see login
- * @param string $username The username, optionally (for standard logins)
- * @param string $password The password, optionally (for standard logins)
- * @return ElggUser|false The authenticated user object, or false on failure.
- */
-
- function authenticate($username, $password) {
-
- if (pam_authenticate(array('username' => $username, 'password' => $password)))
- return get_user_by_username($username);
-
- return false;
-
- }
-
- /**
- * Hook into the PAM system which accepts a username and password and attempts to authenticate
- * it against a known user.
- *
- * @param array $credentials Associated array of credentials passed to pam_authenticate. This function expects
- * 'username' and 'password' (cleartext).
- */
- function pam_auth_userpass($credentials = NULL)
- {
- $max_in_period = 3; // max 3 login attempts in
- $period_length = 5; // 5 minutes
- $periods = array();
-
- if (is_array($credentials) && ($credentials['username']) && ($credentials['password']))
- {
- //$dbpassword = md5($credentials['password']);
-
-
- if ($user = get_user_by_username($credentials['username'])) {
-
- // Let admins log in without validating their email, but normal users must have validated their email or been admin created
- if ((!$user->admin) && (!$user->validated) && (!$user->admin_created))
- return false;
-
- // User has been banned, so bin them.
- if ($user->isBanned()) return false;
-
- if ($user->password == generate_user_password($user, $credentials['password']))
-
- return true;
- else
- // Password failed, log.
- log_login_failure($user->guid);
-
- }
+
+ // User has been banned, so bin them.
+ if ($user->isBanned()) {
+ return false;
}
-
- return false;
- }
-
- function log_login_failure($user_guid)
- {
- $user_guid = (int)$user_guid;
- $user = get_entity($user_guid);
-
- if (($user_guid) && ($user) && ($user instanceof ElggUser))
- {
- $fails = (int)$user->getPrivateSetting("login_failures");
- $fails++;
-
- $user->setPrivateSetting("login_failures", $fails);
- $user->setPrivateSetting("login_failure_$fails", time());
+
+ if ($user->password == generate_user_password($user, $credentials['password'])) {
+ return true;
+ } else {
+ // Password failed, log.
+ log_login_failure($user->guid);
}
+
}
-
- function reset_login_failure_count($user_guid)
- {
- $user_guid = (int)$user_guid;
- $user = get_entity($user_guid);
-
- if (($user_guid) && ($user) && ($user instanceof ElggUser))
- {
- $fails = (int)$user->getPrivateSetting("login_failures");
-
- if ($fails) {
- for ($n=1; $n <= $fails; $n++)
- $user->removePrivateSetting("login_failure_$n");
-
- $user->removePrivateSetting("login_failures");
- }
+ }
+
+ return false;
+}
+
+/**
+ * Log a failed login for $user_guid
+ *
+ * @param $user_guid
+ * @return bool on success
+ */
+function log_login_failure($user_guid) {
+ $user_guid = (int)$user_guid;
+ $user = get_entity($user_guid);
+
+ if (($user_guid) && ($user) && ($user instanceof ElggUser)) {
+ $fails = (int)$user->getPrivateSetting("login_failures");
+ $fails++;
+
+ $user->setPrivateSetting("login_failures", $fails);
+ $user->setPrivateSetting("login_failure_$fails", time());
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Resets the fail login count for $user_guid
+ *
+ * @param $user_guid
+ * @return bool on success (success = user has no logged failed attempts)
+ */
+function reset_login_failure_count($user_guid) {
+ $user_guid = (int)$user_guid;
+ $user = get_entity($user_guid);
+
+ if (($user_guid) && ($user) && ($user instanceof ElggUser)) {
+ $fails = (int)$user->getPrivateSetting("login_failures");
+
+ if ($fails) {
+ for ($n=1; $n <= $fails; $n++) {
+ $user->removePrivateSetting("login_failure_$n");
}
+
+ $user->removePrivateSetting("login_failures");
+
+ return true;
}
-
- function check_rate_limit_exceeded($user_guid)
- {
- $limit = 5;
- $user_guid = (int)$user_guid;
- $user = get_entity($user_guid);
-
- if (($user_guid) && ($user) && ($user instanceof ElggUser))
- {
- $fails = (int)$user->getPrivateSetting("login_failures");
- if ($fails >= $limit)
- {
- $cnt = 0;
- $time = time();
- for ($n=$fails; $n>0; $n--)
- {
- $f = $user->getPrivateSetting("login_failure_$n");
- if ($f > $time - (60*5))
- $cnt++;
-
- if ($cnt==$limit) return true; // Limit reached
- }
+
+ // nothing to reset
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Checks if the rate limit of failed logins has been exceeded for $user_guid.
+ *
+ * @param $user_guid
+ * @return bool on exceeded limit.
+ */
+function check_rate_limit_exceeded($user_guid) {
+ $limit = 5;
+ $user_guid = (int)$user_guid;
+ $user = get_entity($user_guid);
+
+ if (($user_guid) && ($user) && ($user instanceof ElggUser)) {
+ $fails = (int)$user->getPrivateSetting("login_failures");
+ if ($fails >= $limit) {
+ $cnt = 0;
+ $time = time();
+ for ($n=$fails; $n>0; $n--) {
+ $f = $user->getPrivateSetting("login_failure_$n");
+ if ($f > $time - (60*5)) {
+ $cnt++;
+ }
+
+ if ($cnt==$limit) {
+ // Limit reached
+ return true;
}
-
}
-
- return false;
}
-
- /**
- * Logs in a specified ElggUser. For standard registration, use in conjunction
- * with authenticate.
- *
- * @see authenticate
- * @param ElggUser $user A valid Elgg user object
- * @param boolean $persistent Should this be a persistent login?
- * @return true|false Whether login was successful
- */
- function login(ElggUser $user, $persistent = false) {
-
- global $CONFIG;
-
- if ($user->isBanned()) return false; // User is banned, return false.
- if (check_rate_limit_exceeded($user->guid)) return false; // Check rate limit
-
- $_SESSION['user'] = $user;
- $_SESSION['guid'] = $user->getGUID();
- $_SESSION['id'] = $_SESSION['guid'];
- $_SESSION['username'] = $user->username;
- $_SESSION['name'] = $user->name;
-
- $code = (md5($user->name . $user->username . time() . rand()));
-
- $user->code = md5($code);
-
- $_SESSION['code'] = $code;
-
- if (($persistent))
- setcookie("elggperm", $code, (time()+(86400 * 30)),"/");
-
- if (!$user->save() || !trigger_elgg_event('login','user',$user)) {
- unset($_SESSION['username']);
- unset($_SESSION['name']);
- unset($_SESSION['code']);
- unset($_SESSION['guid']);
- unset($_SESSION['id']);
- unset($_SESSION['user']);
- setcookie("elggperm", "", (time()-(86400 * 30)),"/");
- return false;
- }
-
- // Users privilege has been elevated, so change the session id (help prevent session hijacking)
- session_regenerate_id();
-
- // Update statistics
- set_last_login($_SESSION['guid']);
- reset_login_failure_count($user->guid); // Reset any previous failed login attempts
-
- // Set admin shortcut flag if this is an admin
- if (isadminloggedin()) {
- global $is_admin;
- $is_admin = true;
- }
-
- return true;
-
+ }
+
+ return false;
+}
+
+/**
+ * Logs in a specified ElggUser. For standard registration, use in conjunction
+ * with authenticate.
+ *
+ * @see authenticate
+ * @param ElggUser $user A valid Elgg user object
+ * @param boolean $persistent Should this be a persistent login?
+ * @return true|false Whether login was successful
+ */
+function login(ElggUser $user, $persistent = false) {
+ global $CONFIG;
+
+ // User is banned, return false.
+ if ($user->isBanned()) {
+ return false;
+ }
+
+ // Check rate limit
+ if (check_rate_limit_exceeded($user->guid)) {
+ return false;
+ }
+
+ $_SESSION['user'] = $user;
+ $_SESSION['guid'] = $user->getGUID();
+ $_SESSION['id'] = $_SESSION['guid'];
+ $_SESSION['username'] = $user->username;
+ $_SESSION['name'] = $user->name;
+
+ $code = (md5($user->name . $user->username . time() . rand()));
+
+ $user->code = md5($code);
+
+ $_SESSION['code'] = $code;
+
+ if (($persistent)) {
+ setcookie("elggperm", $code, (time()+(86400 * 30)),"/");
+ }
+
+ if (!$user->save() || !trigger_elgg_event('login','user',$user)) {
+ unset($_SESSION['username']);
+ unset($_SESSION['name']);
+ unset($_SESSION['code']);
+ unset($_SESSION['guid']);
+ unset($_SESSION['id']);
+ unset($_SESSION['user']);
+ setcookie("elggperm", "", (time()-(86400 * 30)),"/");
+ return false;
+ }
+
+ // Users privilege has been elevated, so change the session id (help prevent session hijacking)
+ session_regenerate_id();
+
+ // Update statistics
+ set_last_login($_SESSION['guid']);
+ reset_login_failure_count($user->guid); // Reset any previous failed login attempts
+
+ // Set admin shortcut flag if this is an admin
+ if (isadminloggedin()) {
+ //@todo REMOVE THIS.
+ global $is_admin;
+ $is_admin = true;
+ }
+
+ return true;
+}
+
+/**
+ * Log the current user out
+ *
+ * @return true|false
+ */
+function logout() {
+ global $CONFIG;
+
+ if (isset($_SESSION['user'])) {
+ if (!trigger_elgg_event('logout','user',$_SESSION['user'])) {
+ return false;
}
-
- /**
- * Log the current user out
- *
- * @return true|false
- */
- function logout() {
- global $CONFIG;
-
- if (isset($_SESSION['user'])) {
- if (!trigger_elgg_event('logout','user',$_SESSION['user'])) return false;
- $_SESSION['user']->code = "";
- $_SESSION['user']->save();
- }
-
- unset($_SESSION['username']);
- unset($_SESSION['name']);
- unset($_SESSION['code']);
- unset($_SESSION['guid']);
- unset($_SESSION['id']);
- unset($_SESSION['user']);
-
- setcookie("elggperm", "", (time()-(86400 * 30)),"/");
-
- session_destroy();
-
- return true;
- }
-
- function get_session_fingerprint()
- {
- global $CONFIG;
-
- return md5($_SERVER['HTTP_USER_AGENT'] . get_site_secret());
- }
-
- /**
- * Initialises the system session and potentially logs the user in
- *
- * This function looks for:
- *
- * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0
- * 2. The cookie 'elggperm' - if present, checks it for an authentication token, validates it, and potentially logs the user in
- *
- * @uses $_SESSION
- * @param unknown_type $event
- * @param unknown_type $object_type
- * @param unknown_type $object
- */
- function session_init($event, $object_type, $object) {
-
- global $DB_PREFIX, $CONFIG;
-
- if (!is_db_installed()) return false;
-
- // Use database for sessions
- $DB_PREFIX = $CONFIG->dbprefix; // HACK to allow access to prefix after object distruction
- if ((!isset($CONFIG->use_file_sessions)))
- session_set_save_handler("__elgg_session_open", "__elgg_session_close", "__elgg_session_read", "__elgg_session_write", "__elgg_session_destroy", "__elgg_session_gc");
-
- session_name('Elgg');
- session_start();
-
- // Do some sanity checking by generating a fingerprint (makes some XSS attacks harder)
- if (isset($_SESSION['__elgg_fingerprint']))
- {
- if ($_SESSION['__elgg_fingerprint'] != get_session_fingerprint())
- {
- session_destroy();
- return false;
- }
- }
- else
- {
- $_SESSION['__elgg_fingerprint'] = get_session_fingerprint();
- }
-
- // Generate a simple token (private from potentially public session id)
- if (!isset($_SESSION['__elgg_session'])) $_SESSION['__elgg_session'] = md5(microtime().rand());
-
- if (empty($_SESSION['guid'])) {
- if (isset($_COOKIE['elggperm'])) {
- $code = $_COOKIE['elggperm'];
- $code = md5($code);
- unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
- unset($_SESSION['id']);//$_SESSION['id'] = 0;
- if ($user = get_user_by_code($code)) {
- $_SESSION['user'] = $user;
- $_SESSION['id'] = $user->getGUID();
- $_SESSION['guid'] = $_SESSION['id'];
- $_SESSION['code'] = $_COOKIE['elggperm'];
- }
- } else {
- unset($_SESSION['id']); //$_SESSION['id'] = 0;
- unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
- unset($_SESSION['code']);//$_SESSION['code'] = "";
- }
- } else {
- if (!empty($_SESSION['code'])) {
- $code = md5($_SESSION['code']);
- if ($user = get_user_by_code($code)) {
- $_SESSION['user'] = $user;
- $_SESSION['id'] = $user->getGUID();
- $_SESSION['guid'] = $_SESSION['id'];
- } else {
- unset($_SESSION['user']);
- unset($_SESSION['id']); //$_SESSION['id'] = 0;
- unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
- unset($_SESSION['code']);//$_SESSION['code'] = "";
- }
- } else {
- //$_SESSION['user'] = new ElggDummy();
- unset($_SESSION['id']); //$_SESSION['id'] = 0;
- unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
- unset($_SESSION['code']);//$_SESSION['code'] = "";
- }
- }
- if ($_SESSION['id'] > 0) {
- set_last_action($_SESSION['id']);
- }
-
- register_action("login",true);
- register_action("logout");
-
- // Register a default PAM handler
- register_pam_handler('pam_auth_userpass');
-
- // Initialise the magic session
- global $SESSION;
- $SESSION = new ElggSession();
-
- // Finally we ensure that a user who has been banned with an open session is kicked.
- if ((isset($_SESSION['user'])) && ($_SESSION['user']->isBanned()))
- {
- session_destroy();
- return false;
- }
-
- // Since we have loaded a new user, this user may have different language preferences
- register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-
- return true;
-
+ $_SESSION['user']->code = "";
+ $_SESSION['user']->save();
+ }
+
+ unset($_SESSION['username']);
+ unset($_SESSION['name']);
+ unset($_SESSION['code']);
+ unset($_SESSION['guid']);
+ unset($_SESSION['id']);
+ unset($_SESSION['user']);
+
+ setcookie("elggperm", "", (time()-(86400 * 30)),"/");
+
+ session_destroy();
+
+ return true;
+}
+
+/**
+ * Returns a fingerprint for an elgg session.
+ *
+ * @return string
+ */
+function get_session_fingerprint() {
+ global $CONFIG;
+
+ return md5($_SERVER['HTTP_USER_AGENT'] . get_site_secret());
+}
+
+/**
+ * Initialises the system session and potentially logs the user in
+ *
+ * This function looks for:
+ *
+ * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0
+ * 2. The cookie 'elggperm' - if present, checks it for an authentication token, validates it, and potentially logs the user in
+ *
+ * @uses $_SESSION
+ * @param unknown_type $event
+ * @param unknown_type $object_type
+ * @param unknown_type $object
+ */
+function session_init($event, $object_type, $object) {
+ global $DB_PREFIX, $CONFIG;
+
+ if (!is_db_installed()) {
+ return false;
+ }
+
+ // Use database for sessions
+ // HACK to allow access to prefix after object destruction
+ $DB_PREFIX = $CONFIG->dbprefix;
+ if ((!isset($CONFIG->use_file_sessions))) {
+ session_set_save_handler("__elgg_session_open",
+ "__elgg_session_close",
+ "__elgg_session_read",
+ "__elgg_session_write",
+ "__elgg_session_destroy",
+ "__elgg_session_gc");
+ }
+
+ session_name('Elgg');
+ session_start();
+
+ // Do some sanity checking by generating a fingerprint (makes some XSS attacks harder)
+ if (isset($_SESSION['__elgg_fingerprint'])) {
+ if ($_SESSION['__elgg_fingerprint'] != get_session_fingerprint()) {
+ session_destroy();
+ return false;
}
-
- /**
- * Used at the top of a page to mark it as logged in users only.
- *
- */
- function gatekeeper() {
- if (!isloggedin()) {
- $_SESSION['last_forward_from'] = current_page_url();
- forward();
+ } else {
+ $_SESSION['__elgg_fingerprint'] = get_session_fingerprint();
+ }
+
+ // Generate a simple token (private from potentially public session id)
+ if (!isset($_SESSION['__elgg_session'])) {
+ $_SESSION['__elgg_session'] = md5(microtime().rand());
+ }
+
+ if (empty($_SESSION['guid'])) {
+ if (isset($_COOKIE['elggperm'])) {
+ $code = $_COOKIE['elggperm'];
+ $code = md5($code);
+ unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
+ unset($_SESSION['id']);//$_SESSION['id'] = 0;
+ if ($user = get_user_by_code($code)) {
+ $_SESSION['user'] = $user;
+ $_SESSION['id'] = $user->getGUID();
+ $_SESSION['guid'] = $_SESSION['id'];
+ $_SESSION['code'] = $_COOKIE['elggperm'];
}
+ } else {
+ unset($_SESSION['id']); //$_SESSION['id'] = 0;
+ unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
+ unset($_SESSION['code']);//$_SESSION['code'] = "";
}
-
- /**
- * Used at the top of a page to mark it as logged in admin or siteadmin only.
- *
- */
- function admin_gatekeeper()
- {
- gatekeeper();
- if (!isadminloggedin()) {
- $_SESSION['last_forward_from'] = current_page_url();
- forward();
+ } else {
+ if (!empty($_SESSION['code'])) {
+ $code = md5($_SESSION['code']);
+ if ($user = get_user_by_code($code)) {
+ $_SESSION['user'] = $user;
+ $_SESSION['id'] = $user->getGUID();
+ $_SESSION['guid'] = $_SESSION['id'];
+ } else {
+ unset($_SESSION['user']);
+ unset($_SESSION['id']); //$_SESSION['id'] = 0;
+ unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
+ unset($_SESSION['code']);//$_SESSION['code'] = "";
}
+ } else {
+ //$_SESSION['user'] = new ElggDummy();
+ unset($_SESSION['id']); //$_SESSION['id'] = 0;
+ unset($_SESSION['guid']);//$_SESSION['guid'] = 0;
+ unset($_SESSION['code']);//$_SESSION['code'] = "";
}
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_open($save_path, $session_name)
- {
- global $sess_save_path;
- $sess_save_path = $save_path;
-
- return true;
+ }
+
+ if ($_SESSION['id'] > 0) {
+ set_last_action($_SESSION['id']);
+ }
+
+ register_action("login",true);
+ register_action("logout");
+
+ // Register a default PAM handler
+ register_pam_handler('pam_auth_userpass');
+
+ // Initialise the magic session
+ global $SESSION;
+ $SESSION = new ElggSession();
+
+ // Finally we ensure that a user who has been banned with an open session is kicked.
+ if ((isset($_SESSION['user'])) && ($_SESSION['user']->isBanned())) {
+ session_destroy();
+ return false;
+ }
+
+ // Since we have loaded a new user, this user may have different language preferences
+ register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
+
+ return true;
+}
+
+/**
+ * Used at the top of a page to mark it as logged in users only.
+ *
+ */
+function gatekeeper() {
+ if (!isloggedin()) {
+ $_SESSION['last_forward_from'] = current_page_url();
+ forward();
+ }
+}
+
+/**
+ * Used at the top of a page to mark it as logged in admin or siteadmin only.
+ *
+ */
+function admin_gatekeeper() {
+ gatekeeper();
+
+ if (!isadminloggedin()) {
+ $_SESSION['last_forward_from'] = current_page_url();
+ forward();
+ }
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_open($save_path, $session_name) {
+ global $sess_save_path;
+ $sess_save_path = $save_path;
+
+ return true;
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_close() {
+ return true;
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_read($id) {
+ global $DB_PREFIX;
+
+ $id = sanitise_string($id);
+
+ try {
+ $result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'");
+
+ if ($result) {
+ return (string)$result->data;
}
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_close()
- {
+
+ } catch (DatabaseException $e) {
+
+ // Fall back to file store in this case, since this likely means
+ // that the database hasn't been upgraded
+ global $sess_save_path;
+
+ $sess_file = "$sess_save_path/sess_$id";
+ return (string) @file_get_contents($sess_file);
+ }
+
+ return '';
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_write($id, $sess_data) {
+ global $DB_PREFIX;
+
+ $id = sanitise_string($id);
+ $time = time();
+
+ try {
+ $sess_data_sanitised = sanitise_string($sess_data);
+
+ $q = "REPLACE INTO {$DB_PREFIX}users_sessions
+ (session, ts, data) VALUES
+ ('$id', '$time', '$sess_data_sanitised')";
+
+ if (insert_data($q)!==false) {
return true;
}
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_read($id)
- {
- global $DB_PREFIX;
-
- $id = sanitise_string($id);
-
- try {
- $result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'");
-
- if ($result)
- return (string)$result->data;
-
- } catch (DatabaseException $e) {
-
- // Fall back to file store in this case, since this likely means that the database hasn't been upgraded
- global $sess_save_path;
-
- $sess_file = "$sess_save_path/sess_$id";
- return (string) @file_get_contents($sess_file);
- }
-
- return '';
- }
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_write($id, $sess_data)
- {
- global $DB_PREFIX;
-
- $id = sanitise_string($id);
- $time = time();
-
- try {
- $sess_data_sanitised = sanitise_string($sess_data);
+ } catch (DatabaseException $e) {
+ // Fall back to file store in this case, since this likely means
+ // that the database hasn't been upgraded
+ global $sess_save_path;
- if (insert_data("REPLACE INTO {$DB_PREFIX}users_sessions (session, ts, data) VALUES ('$id', '$time', '$sess_data_sanitised')")!==false)
- return true;
-
- } catch (DatabaseException $e) {
- // Fall back to file store in this case, since this likely means that the database hasn't been upgraded
- global $sess_save_path;
-
- $sess_file = "$sess_save_path/sess_$id";
- if ($fp = @fopen($sess_file, "w")) {
- $return = fwrite($fp, $sess_data);
- fclose($fp);
- return $return;
- }
-
- }
-
- return false;
- }
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_destroy($id)
- {
- global $DB_PREFIX;
-
- $id = sanitise_string($id);
-
- try {
- return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'");
- } catch (DatabaseException $e) {
- // Fall back to file store in this case, since this likely means that the database hasn't been upgraded
- global $sess_save_path;
-
- $sess_file = "$sess_save_path/sess_$id";
- return(@unlink($sess_file));
- }
-
- return false;
+ $sess_file = "$sess_save_path/sess_$id";
+ if ($fp = @fopen($sess_file, "w")) {
+ $return = fwrite($fp, $sess_data);
+ fclose($fp);
+ return $return;
}
-
- /**
- * DB Based session handling code.
- */
- function __elgg_session_gc($maxlifetime)
- {
- global $DB_PREFIX;
-
- $life = time()-$maxlifetime;
-
- try {
- return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'");
- } catch (DatabaseException $e) {
- // Fall back to file store in this case, since this likely means that the database hasn't been upgraded
- global $sess_save_path;
-
- foreach (glob("$sess_save_path/sess_*") as $filename) {
- if (filemtime($filename) < $life) {
- @unlink($filename);
- }
- }
+ }
+
+ return false;
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_destroy($id) {
+ global $DB_PREFIX;
+
+ $id = sanitise_string($id);
+
+ try {
+ return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'");
+ } catch (DatabaseException $e) {
+ // Fall back to file store in this case, since this likely means that
+ // the database hasn't been upgraded
+ global $sess_save_path;
+
+ $sess_file = "$sess_save_path/sess_$id";
+ return(@unlink($sess_file));
+ }
+
+ return false;
+}
+
+/**
+ * DB Based session handling code.
+ */
+function __elgg_session_gc($maxlifetime) {
+ global $DB_PREFIX;
+
+ $life = time()-$maxlifetime;
+
+ try {
+ return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'");
+ } catch (DatabaseException $e) {
+ // Fall back to file store in this case, since this likely means that the database hasn't been upgraded
+ global $sess_save_path;
+
+ foreach (glob("$sess_save_path/sess_*") as $filename) {
+ if (filemtime($filename) < $life) {
+ @unlink($filename);
}
-
- return true;
}
-
- register_elgg_event_handler("boot","system","session_init",20);
+ }
+ return true;
+}
-?> \ No newline at end of file
+register_elgg_event_handler("boot","system","session_init",20); \ No newline at end of file