qls = &$qls; } /** * Removes any sessions that haven't been accessed in the defined time * should be around 2 weeks * @return void but will output error if found */ function clear_old_sessions() { // Define the liftime threshold $time_minus_defined = time() - $this->qls->config['cookie_length']; // Find all sessions that have expired $result = $this->qls->SQL->select( 'value', 'sessions', array('time' => array( '<', $time_minus_defined ) ) ); // Loop through expired sessions while ($row = $this->qls->SQL->fetch_assoc($result)) { // Find session id of all users that have expired sessions $user_data = $this->qls->SQL->select( array('username', 'last_session_cookie_id'), 'users', array('last_session' => array( '=', $row['value'] ) ) ); if($this->qls->SQL->num_rows($user_data)) { $user_data = $this->qls->SQL->fetch_assoc($user_data); // Preserve current user session id, // switch PHP session to expired session, // delete expired session, // resume session with preserved session id. $original_session_id = session_id(); session_id($user_data['last_session_cookie_id']); session_start(); session_unset(); session_destroy(); session_id($original_session_id); session_start(); } // Delete expired session from database $this->qls->SQL->delete( 'sessions', array( 'value' => array( '=', $row['value'] ) ) ); } } /** * Generates a new unique id * @param string $password - The user's password * @param string $user_code - The user's activation code * @return string */ function generate_unique_id($password, $user_code) { $hash[] = md5(uniqid(rand(), true)); $hash[] = sha1(uniqid(rand(), true)) . $hash[0] . md5($user_code); $hash[] = sha1($password . $hash[0] . $hash[1] . md5(sha1($user_code) . sha1($user_code))) . sha1($password); $hash[] = md5($hash[0] . $hash[1] . $hash[2]) . sha1($hash[0] . $hash[1] . $hash[0]); return sha1($hash[0] . $hash[1]. $hash[2] . $hash[3] . md5($user_code . $password)); } /** * Generates a unique value * @param string $password - The user's password * @param string $user_code - The user's activation code * @param string $unique_id - The unique id previously generated * @param integer $time - The UNIX timestamp of the session * @return string */ function generate_unique_value($password, $user_code, $unique_id, $time) { $hash[] = sha1($unique_id . $password . $user_code) . sha1(time() * 2 + $time); $hash[] = md5($password . $user_code . $hash[0] . time() . $time); $hash[] = sha1($hash[0] . $hash[1] . $user_code . sha1($password)); return sha1($hash[0] . $hash[1] . $hash[2] . sha1($password . $user_code . $time . $hash[1])); } /** * Creates a new session * @param string $username - The user's username * @param string $password - The user's password * @param string $user_code - The user's activation code * @param bool $remember * @optional boolean $remember - Use cookies or sessions? * @return void */ function create_session($username, $password, $user_code, $remember = false) { $time = time(); // Get user id for cookie/session $user_id = $this->qls->SQL->select('id', 'users', array('username' => array( '=', $username ) ) ); $user_id = $this->qls->SQL->fetch_array($user_id); // Generate the unique id $unique_id = $this->generate_unique_id($password, $user_code); // Generate unique value to go in users table and sessions table $value = $this->generate_unique_value($password, $user_code, $unique_id, $time); $sha1_time = sha1($time); // Insert new session info into database $this->qls->SQL->insert('sessions', array( 'id', 'value', 'time' ), array( $unique_id, $value, $time ) ); // Update users table $this->qls->SQL->update('users', array( 'last_session' => $value, 'last_session_cookie_id' => session_id(), 'last_login' => time() ), array('username' => array( '=', $username ) ) ); $this->qls->SQL->transaction('COMMIT'); if ($remember === true) { // Set the three cookies setcookie($this->qls->config['cookie_prefix'] . 'user_id', $user_id['id'], time() + $this->qls->config['cookie_length'], $this->qls->config['cookie_path'], $this->qls->config['cookie_domain']); setcookie($this->qls->config['cookie_prefix'] . 'user_time', sha1($time), time() + $this->qls->config['cookie_length'], $this->qls->config['cookie_path'], $this->qls->config['cookie_domain']); setcookie($this->qls->config['cookie_prefix'] . 'user_unique', $unique_id, time() + $this->qls->config['cookie_length'], $this->qls->config['cookie_path'], $this->qls->config['cookie_domain']); } // Set the three sessions $_SESSION[$this->qls->config['cookie_prefix'] . 'user_id'] = $user_id['id']; $_SESSION[$this->qls->config['cookie_prefix'] . 'user_time'] = sha1($time); $_SESSION[$this->qls->config['cookie_prefix'] . 'user_unique'] = $unique_id; } /** * This will fetch session info from the database * @param array $information - Contains cookie information * @return true on success, false on failure */ function fetch_session($information, $login=false) { // $information[0] is the user_id (int) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_id'] // $information[1] is the time (SHA1) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_time'] // $information[2] is the unique_id (SHA1) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_unique'] /** * Get the user's last session code. Will be stored * in $user_session['last_session'] */ $user_session = $this->qls->SQL->select('*', //$user_session = $this->qls->SQL->select('last_session', 'users', array('id' => array( '=', $information[0] ) ) ); $user_session = $this->qls->SQL->fetch_array($user_session); /** * Grabs the info from the sessions table. * Basically verifying the session. */ $session_info = $this->qls->SQL->query("SELECT * FROM `{$this->qls->config['sql_prefix']}sessions` WHERE `id`='{$information[2]}' AND `value`='{$user_session['last_session']}'"); $session_info = $this->qls->SQL->fetch_array($session_info); // Did it return a blank id? (not existent) if ($session_info['id'] != '') { // Are the times equal? if (sha1($session_info['time']) == $information[1]) { //Was this function called because the user is logging in? if (!$login) { $auth_id = $_COOKIE[$this->qls->config['cookie_prefix'] . 'auth_id']; $client_auth_token = $_COOKIE[$this->qls->config['cookie_prefix'] . 'auth_token']; $session_auth_token = $_SESSION[$this->qls->config['cookie_prefix'] . 'auth' . $auth_id]; //Check that the client token matches the corresponding session token. This protects against session hijacking. if ($client_auth_token == $session_auth_token) { return true; } else { return false; } } return true; } else { return false; } } else { return false; } } /** * This will validate a user cookie/session * @param array $information - Contains cookie information * @return bool */ function validate_session($information) { // $information[0] is the user_id (int) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_id'] // $information[1] is the time (SHA1) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_time'] // $information[2] is the unique_id (SHA1) $_SESSION[$this->qls->config['cookie_prefix'] . 'user_unique'] // Has to be an array, or no admittance! if (is_array($information)) { // Make sure they are SHA-1 hashes if (strlen($information[1]) == 40 && strlen($information[2]) == 40 && preg_match('/^[a-fA-F0-9]{40}$/', $information[1]) && preg_match('/^[a-fA-F0-9]{40}$/', $information[2])) { // Validate the session while fetching it if ($this->fetch_session($information)) { // Get all the user information $result = $this->qls->SQL->select('*', 'users', array('id' => array( '=', $information[0] ) ) ); $row = $this->qls->SQL->fetch_array($result); // We need to update the session information $new_time = time(); $new_time_hash = sha1($new_time); if (isset($_COOKIE[$this->qls->config['cookie_prefix'] . 'user_time'])) { setcookie($this->qls->config['cookie_prefix'] . 'user_time', $new_time_hash, time() + $this->qls->config['cookie_length'], $this->qls->config['cookie_path'], $this->qls->config['cookie_domain']); } $_SESSION[$this->qls->config['cookie_prefix'] . 'user_time'] = $new_time_hash; // Update the session time $this->qls->SQL->update('sessions', array('time' => $new_time), array('id' => array( '=', $information[2] ) ) ); // Loop through and add to $user_info foreach ($row as $key => $value) { $this->qls->user_info[$key] = stripslashes($value); } // These lines will retrieve the users permissions if ($this->qls->user_info['mask_id'] == 0) { // The user is using the group mask $group_mask = $this->qls->SQL->select('*', 'groups', array('id' => array( '=', $this->qls->user_info['group_id'] ) ) ); $group_mask = $this->qls->SQL->fetch_array($group_mask); $user_permissions = $this->qls->SQL->select('*', 'masks', array('id' => array( '=', $group_mask['mask_id'] ) ) ); $user_permissions = $this->qls->SQL->fetch_array($user_permissions); foreach ($user_permissions as $key => $value) { if (!array_key_exists($key, $this->qls->user_info)) { $this->qls->user_info[$key] = $value; } } } else { // The user has their own mask assigned to them $user_permissions = $this->qls->SQL->select('*', 'masks', array('id' => array( '=', $this->qls->user_info['mask_id'] ) ) ); $user_permissions = $this->qls->SQL->fetch_array($user_permissions); foreach ($user_permissions as $key => $value) { if (!array_key_exists($key, $this->qls->user_info)) { $this->qls->user_info[$key] = $value; } } } return true; } else { return false; } } else { return false; } } else { return false; } } /** * This will grab a user session * @return bool */ function find_session() { /** * Is the user using sessions or nothing? * Make sure the {cookie_prefix}user_id is numeric */ if (isset($_SESSION[$this->qls->config['cookie_prefix'] . 'user_id']) && is_numeric($_SESSION[$this->qls->config['cookie_prefix'] . 'user_id'])) { $information = array( $_SESSION[$this->qls->config['cookie_prefix'] . 'user_id'], $_SESSION[$this->qls->config['cookie_prefix'] . 'user_time'], $_SESSION[$this->qls->config['cookie_prefix'] . 'user_unique'] ); return $this->validate_session($information); } elseif (isset($_COOKIE[$this->qls->config['cookie_prefix'] . 'user_id']) && is_numeric($_COOKIE[$this->qls->config['cookie_prefix'] . 'user_id'])) { $information = array( $_COOKIE[$this->qls->config['cookie_prefix'] . 'user_id'], $_COOKIE[$this->qls->config['cookie_prefix'] . 'user_time'], $_COOKIE[$this->qls->config['cookie_prefix'] . 'user_unique'] ); return $this->validate_session($information); } else { return $this->validate_session(''); } } } ?>