includes/sessions.php
  • FIND:

    	$current_time = time();
    	$expiry_time = $current_time - $board_config['session_length'];
    
    	//
    	// Try and pull the last time stored in a cookie, if it exists
    	//
    	$sql = "SELECT * 
    		FROM " . USERS_TABLE . " 
    		WHERE user_id = $user_id";
    	if ( !($result = $db->sql_query($sql)) )
    	{
    		message_die(CRITICAL_ERROR, 'Could not obtain lastvisit data from user table', '', __LINE__, __FILE__, $sql);
    	}
    
    	$userdata = $db->sql_fetchrow($result);
    
    	if ( $user_id != ANONYMOUS )
    	{
    		$auto_login_key = $userdata['user_password'];
    
    		if ( $auto_create )
    		{
    			if ( isset($sessiondata['autologinid']) && $userdata['user_active'] )
    			{
    				// We have to login automagically
    				if( $sessiondata['autologinid'] === $auto_login_key )
    				{
    					// autologinid matches password
    					$login = 1;
    					$enable_autologin = 1;
    				}
    				else
    				{
    					// No match; don't login, set as anonymous user
    					$login = 0; 
    					$enable_autologin = 0; 
    					$user_id = $userdata['user_id'] = ANONYMOUS;
    				
    					$sql = 'SELECT * FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS;
    					$result = $db->sql_query($sql);
    					$userdata = $db->sql_fetchrow($result);
    					$db->sql_freeresult($result);
    				}
    			}
    			else
    			{
    				// Autologin is not set. Don't login, set as anonymous user
    				$login = 0;
    				$enable_autologin = 0;
    				$user_id = $userdata['user_id'] = ANONYMOUS;
    
    				$sql = 'SELECT * FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS;
    				$result = $db->sql_query($sql);
    				$userdata = $db->sql_fetchrow($result);
    				$db->sql_freeresult($result);
    			}
    		}
    		else
    		{
    			$login = 1;
    		}
    	}
    	else
    	{
    		$login = 0;
    		$enable_autologin = 0;
    	}
    
  • REPLACE WITH:

    	$current_time = time();
    
    	//
    	// Are auto-logins allowed?
    	// If allow_autologin is not set or is true then they are
    	// (same behaviour as old 2.0.x session code)
    	//
    	if (isset($board_config['allow_autologin']) && !$board_config['allow_autologin'])
    	{
    		$enable_autologin = $sessiondata['autologinid'] = false;
    	}
    
    	// 
    	// First off attempt to join with the autologin value if we have one
    	// If not, just use the user_id value
    	//
    	$userdata = array();
    
    	if ($user_id != ANONYMOUS)
    	{
    		if (isset($sessiondata['autologinid']) && (string) $sessiondata['autologinid'] != '' && $user_id)
    		{
    			$sql = 'SELECT u.* 
    				FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
    				WHERE u.user_id = ' . (int) $user_id . "
    					AND u.user_active = 1
    					AND k.user_id = u.user_id
    					AND k.key_id = '" . md5($sessiondata['autologinid']) . "'";
    			if (!($result = $db->sql_query($sql)))
    			{
    				message_die(CRITICAL_ERROR, 'Error doing DB query userdata row fetch', '', __LINE__, __FILE__, $sql);
    			}
    
    			$userdata = $db->sql_fetchrow($result);
    			$db->sql_freeresult($result);
    		
    			$enable_autologin = $login = 1;
    		}
    		else if (!$auto_create)
    		{
    			$sessiondata['autologinid'] = '';
    			$sessiondata['userid'] = $user_id;
    
    			$sql = 'SELECT *
    				FROM ' . USERS_TABLE . '
    				WHERE user_id = ' . (int) $user_id . '
    					AND user_active = 1';
    			if (!($result = $db->sql_query($sql)))
    			{
    				message_die(CRITICAL_ERROR, 'Error doing DB query userdata row fetch', '', __LINE__, __FILE__, $sql);
    			}
    
    			$userdata = $db->sql_fetchrow($result);
    			$db->sql_freeresult($result);
    
    			$login = 1;
    		}
    	}
    
    	//
    	// At this point either $userdata should be populated or
    	// one of the below is true
    	// * Key didn't match one in the DB
    	// * User does not exist
    	// * User is inactive
    	//
    	if (!sizeof($userdata) || !is_array($userdata) || !$userdata)
    	{
    		$sessiondata['autologinid'] = '';
    		$sessiondata['userid'] = $user_id = ANONYMOUS;
    		$enable_autologin = $login = 0;
    
    		$sql = 'SELECT *
    			FROM ' . USERS_TABLE . '
    			WHERE user_id = ' . (int) $user_id;
    		if (!($result = $db->sql_query($sql)))
    		{
    			message_die(CRITICAL_ERROR, 'Error doing DB query userdata row fetch', '', __LINE__, __FILE__, $sql);
    		}
    
    		$userdata = $db->sql_fetchrow($result);
    		$db->sql_freeresult($result);
    	}
    
    
  • FIND:

    	{// ( $userdata['user_session_time'] > $expiry_time && $auto_create ) ? $userdata['user_lastvisit'] : ( 
    
  • REPLACE WITH:

    	{
    
  • FIND:

    		$sessiondata['autologinid'] = (!$admin) ? (( $enable_autologin && $sessionmethod == SESSION_METHOD_COOKIE ) ? $auto_login_key : '') : $sessiondata['autologinid'];
    
  • REPLACE WITH:

    		//
    		// Regenerate the auto-login key
    		//
    		if ($enable_autologin)
    		{
    			list($sec, $usec) = explode(' ', microtime());
    			mt_srand(hexdec(substr($session_id, 0, 8)) + (float) $sec + ((float) $usec * 1000000));
    			$auto_login_key = uniqid(mt_rand(), true);
    			
    			if (isset($sessiondata['autologinid']) && (string) $sessiondata['autologinid'] != '')
    			{
    				$sql = 'UPDATE ' . SESSIONS_KEYS_TABLE . "
    					SET last_ip = '$user_ip', key_id = '" . md5($auto_login_key) . "', last_login = $current_time
    					WHERE key_id = '" . md5($sessiondata['autologinid']) . "'";
    			}
    			else
    			{
    				$sql = 'INSERT INTO ' . SESSIONS_KEYS_TABLE . "(key_id, user_id, last_ip, last_login)
    					VALUES ('" . md5($auto_login_key) . "', $user_id, '$user_ip', $current_time)";
    			}
    
    			if ( !$db->sql_query($sql) )
    			{
    				message_die(CRITICAL_ERROR, 'Error updating session key', '', __LINE__, __FILE__, $sql);
    			}
    			
    			$sessiondata['autologinid'] = $auto_login_key;
    			unset($auto_login_key);
    		}
    		else
    		{
    			$sessiondata['autologinid'] = '';
    		}
    
    //		$sessiondata['autologinid'] = (!$admin) ? (( $enable_autologin && $sessionmethod == SESSION_METHOD_COOKIE ) ? $auto_login_key : '') : $sessiondata['autologinid'];
    
  • FIND:

    	$userdata['session_admin'] = $admin;
    
  • AFTER, ADD:

    	$userdata['session_key'] = $sessiondata['autologinid'];
    
  • FIND:

    					//
    					// Delete expired sessions
    					//
    					$expiry_time = $current_time - $board_config['session_length'];
    
    					$sql = "DELETE FROM " . SESSIONS_TABLE . " 
    						WHERE session_time < $expiry_time 
    							AND session_id <> '$session_id'";
    					if ( !$db->sql_query($sql) )
    					{
    						message_die(CRITICAL_ERROR, 'Error clearing sessions table', '', __LINE__, __FILE__, $sql);
    					}
    
  • REPLACE WITH:

    					session_clean($userdata['session_id']);
    
  • FIND:

    //
    // session_end closes out a session
    // deleting the corresponding entry
    // in the sessions table
    //
    function session_end($session_id, $user_id)
    {
    	global $db, $lang, $board_config;
    	global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $SID;
    
    	$cookiename = $board_config['cookie_name'];
    	$cookiepath = $board_config['cookie_path'];
    	$cookiedomain = $board_config['cookie_domain'];
    	$cookiesecure = $board_config['cookie_secure'];
    
    	$current_time = time();
    
    	//
    	// Pull cookiedata or grab the URI propagated sid
    	//
    	if ( isset($HTTP_COOKIE_VARS[$cookiename . '_sid']) )
    	{
    		$session_id = isset( $HTTP_COOKIE_VARS[$cookiename . '_sid'] ) ? $HTTP_COOKIE_VARS[$cookiename . '_sid'] : '';
    		$sessionmethod = SESSION_METHOD_COOKIE;
    	}
    	else
    	{
    		$session_id = ( isset($HTTP_GET_VARS['sid']) ) ? $HTTP_GET_VARS['sid'] : '';
    		$sessionmethod = SESSION_METHOD_GET;
    	}
    
    	if (!preg_match('/^[A-Za-z0-9]*$/', $session_id))
    	{
    		return;
    	}
    	
    	//
    	// Delete existing session
    	//
    	$sql = "DELETE FROM " . SESSIONS_TABLE . " 
    		WHERE session_id = '$session_id' 
    			AND session_user_id = $user_id";
    	if ( !$db->sql_query($sql) )
    	{
    		message_die(CRITICAL_ERROR, 'Error removing user session', '', __LINE__, __FILE__, $sql);
    	}
    
    	setcookie($cookiename . '_data', '', $current_time - 31536000, $cookiepath, $cookiedomain, $cookiesecure);
    	setcookie($cookiename . '_sid', '', $current_time - 31536000, $cookiepath, $cookiedomain, $cookiesecure);
    
    	return true;
    }
    
  • REPLACE WITH:

    /**
    * Terminates the specified session
    * It will delete the entry in the sessions table for this session,
    * remove the corresponding auto-login key and reset the cookies
    */
    function session_end($session_id, $user_id)
    {
    	global $db, $lang, $board_config, $userdata;
    	global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $SID;
    
    	$cookiename = $board_config['cookie_name'];
    	$cookiepath = $board_config['cookie_path'];
    	$cookiedomain = $board_config['cookie_domain'];
    	$cookiesecure = $board_config['cookie_secure'];
    
    	$current_time = time();
    
    	if (!preg_match('/^[A-Za-z0-9]*$/', $session_id))
    	{
    		return;
    	}
    	
    	//
    	// Delete existing session
    	//
    	$sql = 'DELETE FROM ' . SESSIONS_TABLE . " 
    		WHERE session_id = '$session_id' 
    			AND session_user_id = $user_id";
    	if ( !$db->sql_query($sql) )
    	{
    		message_die(CRITICAL_ERROR, 'Error removing user session', '', __LINE__, __FILE__, $sql);
    	}
    
    	//
    	// Remove this auto-login entry (if applicable)
    	//
    	if ( isset($userdata['session_key']) && $userdata['session_key'] != '' )
    	{
    		$autologin_key = md5($userdata['session_key']);
    		$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
    			WHERE user_id = ' . (int) $user_id . "
    				AND key_id = '$autologin_key'";
    		if ( !$db->sql_query($sql) )
    		{
    			message_die(CRITICAL_ERROR, 'Error removing auto-login key', '', __LINE__, __FILE__, $sql);
    		}
    	}
    
    	//
    	// We expect that message_die will be called after this function,
    	// but just in case it isn't, reset $userdata to the details for a guest
    	//
    	$sql = 'SELECT *
    		FROM ' . USERS_TABLE . '
    		WHERE user_id = ' . ANONYMOUS;
    	if ( !($result = $db->sql_query($sql)) )
    	{
    		message_die(CRITICAL_ERROR, 'Error obtaining user details', '', __LINE__, __FILE__, $sql);
    	}
    	if ( !($userdata = $db->sql_fetchrow($result)) )
    	{
    		message_die(CRITICAL_ERROR, 'Error obtaining user details', '', __LINE__, __FILE__, $sql);
    	}
    	$db->sql_freeresult($result);
    
    
    	setcookie($cookiename . '_data', '', $current_time - 31536000, $cookiepath, $cookiedomain, $cookiesecure);
    	setcookie($cookiename . '_sid', '', $current_time - 31536000, $cookiepath, $cookiedomain, $cookiesecure);
    
    	return true;
    }
    
    /**
    * Removes expired sessions and auto-login keys from the database
    */
    function session_clean($session_id)
    {
    	global $board_config, $db;
    
    	//
    	// Delete expired sessions
    	//
    	$sql = 'DELETE FROM ' . SESSIONS_TABLE . ' 
    		WHERE session_time < ' . (time() - (int) $board_config['session_length']) . " 
    			AND session_id <> '$session_id'";
    	if ( !$db->sql_query($sql) )
    	{
    		message_die(CRITICAL_ERROR, 'Error clearing sessions table', '', __LINE__, __FILE__, $sql);
    	}
    
    	//
    	// Delete expired auto-login keys
    	// If max_autologin_time is not set then keys will never be deleted
    	// (same behaviour as old 2.0.x session code)
    	//
    	if (!empty($board_config['max_autologin_time']) && $board_config['max_autologin_time'] > 0)
    	{
    		$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
    			WHERE last_login < ' . (time() - (86400 * (int) $board_config['max_autologin_time']));
    		$db->sql_query($sql);
    	}
    
    	return true;
    }
    
  • FIND:

    		$url .= ( ( strpos($url, '?') != false ) ?  ( ( $non_html_amp ) ? '&' : '&amp;' ) : '?' ) . $SID;
    
  • REPLACE WITH:

    		$url .= ( ( strpos($url, '?') !== false ) ?  ( ( $non_html_amp ) ? '&' : '&amp;' ) : '?' ) . $SID;