diff options
Diffstat (limited to 'phpBB/includes/session.php')
-rw-r--r-- | phpBB/includes/session.php | 328 |
1 files changed, 72 insertions, 256 deletions
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index caadcbafaa..bd2257c139 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -39,18 +39,20 @@ class session * * @param string $root_path current root path (phpbb_root_path) */ - function extract_current_page($root_path) + static function extract_current_page($root_path) { + global $request; + $page_array = array(); // First of all, get the request uri... - $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); - $args = (!empty($_SERVER['QUERY_STRING'])) ? explode('&', $_SERVER['QUERY_STRING']) : explode('&', getenv('QUERY_STRING')); + $script_name = htmlspecialchars_decode($request->server('PHP_SELF')); + $args = explode('&', htmlspecialchars_decode($request->server('QUERY_STRING'))); // If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support... if (!$script_name) { - $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); + $script_name = htmlspecialchars_decode($request->server('REQUEST_URI')); $script_name = (($pos = strpos($script_name, '?')) !== false) ? substr($script_name, 0, $pos) : $script_name; $page_array['failover'] = 1; } @@ -130,7 +132,7 @@ class session 'root_script_path' => str_replace(' ', '%20', htmlspecialchars($root_script_path)), 'page' => $page, - 'forum' => (isset($_REQUEST['f']) && $_REQUEST['f'] > 0) ? (int) $_REQUEST['f'] : 0, + 'forum' => request_var('f', 0), ); return $page_array; @@ -141,10 +143,10 @@ class session */ function extract_current_hostname() { - global $config; + global $config, $request; // Get hostname - $host = (!empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME')); + $host = htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME'))); // Should be a string and lowered $host = (string) strtolower($host); @@ -206,14 +208,15 @@ class session function session_begin($update_session_page = true) { global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path; + global $request; // Give us some basic information $this->time_now = time(); $this->cookie_data = array('u' => 0, 'k' => ''); $this->update_session_page = $update_session_page; - $this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : ''; - $this->referer = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : ''; - $this->forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? htmlspecialchars((string) $_SERVER['HTTP_X_FORWARDED_FOR']) : ''; + $this->browser = $request->header('User-Agent'); + $this->referer = $request->header('Referer'); + $this->forwarded_for = $request->header('X-Forwarded-For'); $this->host = $this->extract_current_hostname(); $this->page = $this->extract_current_page($phpbb_root_path); @@ -241,7 +244,7 @@ class session $this->forwarded_for = ''; } - if (isset($_COOKIE[$config['cookie_name'] . '_sid']) || isset($_COOKIE[$config['cookie_name'] . '_u'])) + if ($request->is_set($config['cookie_name'] . '_sid', phpbb_request_interface::COOKIE) || $request->is_set($config['cookie_name'] . '_u', phpbb_request_interface::COOKIE)) { $this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, false, true); $this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', false, true); @@ -267,7 +270,7 @@ class session // Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests // it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip. - $this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : ''; + $this->ip = htmlspecialchars_decode($request->server('REMOTE_ADDR')); $this->ip = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->ip)); // split the list of IPs @@ -278,6 +281,24 @@ class session foreach ($ips as $ip) { + if (function_exists('phpbb_ip_normalise')) + { + // Normalise IP address + $ip = phpbb_ip_normalise($ip); + + if (empty($ip)) + { + // IP address is invalid. + break; + } + + // IP address is valid. + $this->ip = $ip; + + // Skip legacy code. + continue; + } + if (preg_match(get_preg_expression('ipv4'), $ip)) { $this->ip = $ip; @@ -323,7 +344,7 @@ class session } // Is session_id is set or session_id is set and matches the url param if required - if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid']))) + if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === request_var('sid', '')))) { $sql = 'SELECT u.*, s.* FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u @@ -363,7 +384,7 @@ class session $referer_valid = true; // we assume HEAD and TRACE to be foul play and thus only whitelist GET - if (@$config['referer_validation'] && isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) !== 'get') + if (@$config['referer_validation'] && strtolower($request->server('REQUEST_METHOD')) !== 'get') { $referer_valid = $this->validate_referer($check_referer_path); } @@ -417,9 +438,7 @@ class session $db->sql_return_on_error(true); - $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE session_id = '" . $db->sql_escape($this->session_id) . "'"; - $result = $db->sql_query($sql); + $this->update_session($sql_ary); $db->sql_return_on_error(false); @@ -429,9 +448,7 @@ class session { unset($sql_ary['session_forum_id']); - $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE session_id = '" . $db->sql_escape($this->session_id) . "'"; - $db->sql_query($sql); + $this->update_session($sql_ary); } if ($this->data['user_id'] != ANONYMOUS && !empty($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts']) @@ -698,9 +715,7 @@ class session $sql_ary['session_forum_id'] = $this->page['forum']; } - $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE session_id = '" . $db->sql_escape($this->session_id) . "'"; - $db->sql_query($sql); + $this->update_session($sql_ary); // Update the last visit time $sql = 'UPDATE ' . USERS_TABLE . ' @@ -1001,7 +1016,7 @@ class session } // only called from CRON; should be a safe workaround until the infrastructure gets going - if (!class_exists('phpbb_captcha_factory')) + if (!class_exists('phpbb_captcha_factory', false)) { include($phpbb_root_path . "includes/captcha/captcha_factory." . $phpEx); } @@ -1436,7 +1451,7 @@ class session */ function validate_referer($check_script_path = false) { - global $config; + global $config, $request; // no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason) if (empty($this->referer) || empty($this->host)) @@ -1454,7 +1469,7 @@ class session else if ($check_script_path && rtrim($this->page['root_script_path'], '/') !== '') { $ref = substr($ref, strlen($host)); - $server_port = (!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT'); + $server_port = $request->server('SERVER_PORT', 0); if ($server_port !== 80 && $server_port !== 443 && stripos($ref, ":$server_port") === 0) { @@ -1479,6 +1494,23 @@ class session WHERE session_id = \'' . $db->sql_escape($this->session_id) . '\''; $db->sql_query($sql); } + + /** + * Update the session data + * + * @param array $session_data associative array of session keys to be updated + * @param string $session_id optional session_id, defaults to current user's session_id + */ + public function update_session($session_data, $session_id = null) + { + global $db; + + $session_id = ($session_id) ? $session_id : $this->session_id; + + $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $session_data) . " + WHERE session_id = '" . $db->sql_escape($session_id) . "'"; + $db->sql_query($sql); + } } @@ -1562,9 +1594,9 @@ class user extends session * If re-enabled we need to make sure only those languages installed are checked * Commented out so we do not loose the code. - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) + if ($request->header('Accept-Language')) { - $accept_lang_ary = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + $accept_lang_ary = explode(',', $request->header('Accept-Language')); foreach ($accept_lang_ary as $accept_lang) { @@ -1608,11 +1640,12 @@ class user extends session $this->add_lang($lang_set); unset($lang_set); - if (!empty($_GET['style']) && $auth->acl_get('a_styles') && !defined('ADMIN_START')) + $style_request = request_var('style', 0); + if ($style_request && $auth->acl_get('a_styles') && !defined('ADMIN_START')) { global $SID, $_EXTRA_URL; - $style = request_var('style', 0); + $style = $style_request; $SID .= '&style=' . $style; $_EXTRA_URL = array('style=' . $style); } @@ -1622,12 +1655,11 @@ class user extends session $style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']); } - $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name - FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_name, c.theme_id + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . " c WHERE s.style_id = $style AND t.template_id = s.template_id - AND c.theme_id = s.theme_id - AND i.imageset_id = s.imageset_id"; + AND c.theme_id = s.theme_id"; $result = $db->sql_query($sql, 3600); $this->theme = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -1642,12 +1674,11 @@ class user extends session WHERE user_id = {$this->data['user_id']}"; $db->sql_query($sql); - $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name - FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_id + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . " c WHERE s.style_id = $style AND t.template_id = s.template_id - AND c.theme_id = s.theme_id - AND i.imageset_id = s.imageset_id"; + AND c.theme_id = s.theme_id"; $result = $db->sql_query($sql, 3600); $this->theme = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -1665,7 +1696,6 @@ class user extends session $parsed_items = $parsed_items['theme']; $check_for = array( - 'parse_css_file' => (int) 0, 'pagination_sep' => (string) ', ' ); @@ -1680,143 +1710,9 @@ class user extends session } } - // If the style author specified the theme needs to be cached - // (because of the used paths and variables) than make sure it is the case. - // For example, if the theme uses language-specific images it needs to be stored in db. - if (!$this->theme['theme_storedb'] && $this->theme['parse_css_file']) - { - $this->theme['theme_storedb'] = 1; - - $stylesheet = file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/stylesheet.css"); - // Match CSS imports - $matches = array(); - preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches); - - if (sizeof($matches)) - { - $content = ''; - foreach ($matches[0] as $idx => $match) - { - if ($content = @file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/" . $matches[1][$idx])) - { - $content = trim($content); - } - else - { - $content = ''; - } - $stylesheet = str_replace($match, $content, $stylesheet); - } - unset($content); - } - - $stylesheet = str_replace('./', 'styles/' . $this->theme['theme_path'] . '/theme/', $stylesheet); - - $sql_ary = array( - 'theme_data' => $stylesheet, - 'theme_mtime' => time(), - 'theme_storedb' => 1 - ); - - $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE theme_id = ' . $this->theme['theme_id']; - $db->sql_query($sql); - - unset($sql_ary); - } - $template->set_template(); - $this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang']; - - // Same query in style.php - $sql = 'SELECT * - FROM ' . STYLES_IMAGESET_DATA_TABLE . ' - WHERE imageset_id = ' . $this->theme['imageset_id'] . " - AND image_filename <> '' - AND image_lang IN ('" . $db->sql_escape($this->img_lang) . "', '')"; - $result = $db->sql_query($sql, 3600); - - $localised_images = false; - while ($row = $db->sql_fetchrow($result)) - { - if ($row['image_lang']) - { - $localised_images = true; - } - - $row['image_filename'] = rawurlencode($row['image_filename']); - $this->img_array[$row['image_name']] = $row; - } - $db->sql_freeresult($result); - - // there were no localised images, try to refresh the localised imageset for the user's language - if (!$localised_images) - { - // Attention: this code ignores the image definition list from acp_styles and just takes everything - // that the config file contains - $sql_ary = array(); - - $db->sql_transaction('begin'); - - $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' - WHERE imageset_id = ' . $this->theme['imageset_id'] . ' - AND image_lang = \'' . $db->sql_escape($this->img_lang) . '\''; - $result = $db->sql_query($sql); - - if (@file_exists("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg")) - { - $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg"); - foreach ($cfg_data_imageset_data as $image_name => $value) - { - if (strpos($value, '*') !== false) - { - if (substr($value, -1, 1) === '*') - { - list($image_filename, $image_height) = explode('*', $value); - $image_width = 0; - } - else - { - list($image_filename, $image_height, $image_width) = explode('*', $value); - } - } - else - { - $image_filename = $value; - $image_height = $image_width = 0; - } - - if (strpos($image_name, 'img_') === 0 && $image_filename) - { - $image_name = substr($image_name, 4); - $sql_ary[] = array( - 'image_name' => (string) $image_name, - 'image_filename' => (string) $image_filename, - 'image_height' => (int) $image_height, - 'image_width' => (int) $image_width, - 'imageset_id' => (int) $this->theme['imageset_id'], - 'image_lang' => (string) $this->img_lang, - ); - } - } - } - - if (sizeof($sql_ary)) - { - $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); - $db->sql_transaction('commit'); - $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); - - add_log('admin', 'LOG_IMAGESET_LANG_REFRESHED', $this->theme['imageset_name'], $this->img_lang); - } - else - { - $db->sql_transaction('commit'); - add_log('admin', 'LOG_IMAGESET_LANG_MISSING', $this->theme['imageset_name'], $this->img_lang); - } - } + $this->img_lang = $this->lang_name; // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes... // After calling it we continue script execution... @@ -2251,89 +2147,11 @@ class user extends session /** * Specify/Get image - * $suffix is no longer used - we know it. ;) It is there for backward compatibility. */ - function img($img, $alt = '', $width = false, $suffix = '', $type = 'full_tag') + function img($img, $alt = '') { - static $imgs; - global $phpbb_root_path; - - $img_data = &$imgs[$img]; - - if (empty($img_data)) - { - if (!isset($this->img_array[$img])) - { - // Do not fill the image to let designers decide what to do if the image is empty - $img_data = ''; - return $img_data; - } - - // Use URL if told so - $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path; - - $path = 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; - - $img_data['src'] = $root_path . $path; - $img_data['width'] = $this->img_array[$img]['image_width']; - $img_data['height'] = $this->img_array[$img]['image_height']; - - // We overwrite the width and height to the phpbb logo's width - // and height here if the contents of the site_logo file are - // really equal to the phpbb_logo - // This allows us to change the dimensions of the phpbb_logo without - // modifying the imageset.cfg and causing a conflict for everyone - // who modified it for their custom logo on updating - if ($img == 'site_logo' && file_exists($phpbb_root_path . $path)) - { - global $cache; - - $img_file_hashes = $cache->get('imageset_site_logo_md5'); - - if ($img_file_hashes === false) - { - $img_file_hashes = array(); - } - - $key = $this->theme['imageset_path'] . '::' . $this->img_array[$img]['image_lang']; - if (!isset($img_file_hashes[$key])) - { - $img_file_hashes[$key] = md5(file_get_contents($phpbb_root_path . $path)); - $cache->put('imageset_site_logo_md5', $img_file_hashes); - } - - $phpbb_logo_hash = '0c461a32cd3621643105f0d02a772c10'; - - if ($phpbb_logo_hash == $img_file_hashes[$key]) - { - $img_data['width'] = '149'; - $img_data['height'] = '52'; - } - } - } - $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt; - - switch ($type) - { - case 'src': - return $img_data['src']; - break; - - case 'width': - return ($width === false) ? $img_data['width'] : $width; - break; - - case 'height': - return $img_data['height']; - break; - - default: - $use_width = ($width === false) ? $img_data['width'] : $width; - - return '<img src="' . $img_data['src'] . '"' . (($use_width) ? ' width="' . $use_width . '"' : '') . (($img_data['height']) ? ' height="' . $img_data['height'] . '"' : '') . ' alt="' . $alt . '" title="' . $alt . '" />'; - break; - } + return '<span class="imageset ' . $img . '">' . $alt . '</span>'; } /** @@ -2444,5 +2262,3 @@ class user extends session return $forum_ids; } } - -?>
\ No newline at end of file |