Example #1
0
	/**
	 * Read session data from the database to return into the $_SESSION global.
	 * Verifies against a number of parameters for security purposes.
	 *
	 * @param string $session_id The id generated by PHP for the session.
	 * @return string The retrieved session.
	 */
	public static function read( $session_id )
	{
		$remote_address = Utils::get_ip();
		// not always set, even by real browsers
		$user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
		$session = DB::get_row( 'SELECT * FROM {sessions} WHERE token = ?', array( $session_id ) );

		// Verify session exists
		if ( !$session ) {
			self::$initial_data = false;
			return false;
		}

		$dodelete = false;

		if ( !defined( 'SESSION_SKIP_SUBNET' ) || SESSION_SKIP_SUBNET != true ) {
			// Verify on the same subnet
			$subnet = self::get_subnet( $remote_address );
			if ( $session->ip != $subnet ) {
				$dodelete = true;
			}
		}

		// Verify expiry
		if ( HabariDateTime::date_create()->int > $session->expires ) {
			Session::error( _t( 'Your session expired.' ), 'expired_session' );
			$dodelete = true;
		}

		// Verify User Agent
		if ( $user_agent != $session->ua ) {
			$dodelete = true;
		}

		// Let plugins ultimately decide
		$dodelete = Plugins::filter( 'session_read', $dodelete, $session, $session_id );

		if ( $dodelete ) {
			$sql = 'DELETE FROM {sessions} WHERE token = ?';
			$args = array( $session_id );
			$sql = Plugins::filter( 'sessions_clean', $sql, 'read', $args );
			DB::query( $sql, $args );
			return false;
		}

		// Do garbage collection, since PHP is bad at it
		$probability = ini_get( 'session.gc_probability' );
		// Allow plugins to control the probability of a gc event, return >=100 to always collect garbage
		$probability = Plugins::filter( 'session_gc_probability', ( is_numeric( $probability ) && $probability > 0 ) ? $probability : 1 );
		if ( rand( 1, 100 ) <= $probability ) {
			self::gc( self::$lifetime );
		}

		// save the initial data we loaded so we can write only if it's changed
		self::$initial_data = $session->data;
		
		// but if the expiration is close (less than half the session lifetime away), null it out so the session always gets written so we extend the session
		if ( ( $session->expires - HabariDateTime::date_create()->int ) < ( self::$lifetime / 2 ) ) {
			self::$initial_data = null;
		}

		return $session->data;
	}
Example #2
0
 /**
  * Read session data from the database to return into the $_SESSION global.
  * Verifies against a number of parameters for security purposes.
  *
  * @param string $session_id The id generated by PHP for the session.
  * @return string The retrieved session.
  */
 static function read($session_id)
 {
     // for offline testing
     $remote_address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
     // not always set, even by real browsers
     $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
     $session = DB::get_row('SELECT * FROM {sessions} WHERE token = ?', array($session_id));
     // Verify session exists
     if (!$session) {
         self::$initial_data = false;
         return false;
     }
     $dodelete = false;
     if (!defined('SESSION_SKIP_SUBNET') || SESSION_SKIP_SUBNET != true) {
         // Verify on the same subnet
         $subnet = self::get_subnet($remote_address);
         if ($session->subnet != $subnet) {
             $dodelete = true;
         }
     }
     // Verify expiry
     if (HabariDateTime::date_create(time())->int > $session->expires) {
         Session::error(_t('Your session expired.'), 'expired_session');
         $dodelete = true;
     }
     // Verify User Agent
     if ($user_agent != $session->ua) {
         $dodelete = true;
     }
     // Let plugins ultimately decide
     $dodelete = Plugins::filter('session_read', $dodelete, $session, $session_id);
     if ($dodelete) {
         $sql = 'DELETE FROM {sessions} WHERE token = ?';
         $args = array($session_id);
         $sql = Plugins::filter('sessions_clean', $sql, 'read', $args);
         DB::query($sql, $args);
         return false;
     }
     // Do garbage collection, since PHP is bad at it
     $probability = ini_get('session.gc_probability');
     // Allow plugins to control the probability of a gc event, return >=100 to always collect garbage
     $probability = Plugins::filter('gc_probability', is_numeric($probability) && $probability > 0 ? $probability : 1);
     if (rand(1, 100) <= $probability) {
         self::gc(ini_get('session.gc_maxlifetime'));
     }
     // Throttle session writes, so as to not hammer the DB
     self::$initial_data = ini_get('session.gc_maxlifetime') - $session->expires + HabariDateTime::date_create(time())->int < 120 ? $session->data : FALSE;
     return $session->data;
 }