diff options
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acp/acp_search.php | 17 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_styles.php | 6 | ||||
-rw-r--r-- | phpBB/includes/auth/auth_ldap.php | 26 | ||||
-rw-r--r-- | phpBB/includes/mcp/mcp_front.php | 7 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_mysql.php | 11 | ||||
-rw-r--r-- | phpBB/includes/session.php | 85 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_pm_viewmessage.php | 2 |
7 files changed, 123 insertions, 31 deletions
diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php index f858da6a16..342ec34e29 100644 --- a/phpBB/includes/acp/acp_search.php +++ b/phpBB/includes/acp/acp_search.php @@ -17,7 +17,7 @@ class acp_search var $state; var $search; var $max_post_id; - var $batch_size = 4000; + var $batch_size = 5000; function main($id, $mode) { @@ -320,6 +320,16 @@ class acp_search } else { + $sql = 'SELECT forum_id, enable_indexing + FROM ' . FORUMS_TABLE; + $result = $db->sql_query($sql, 3600); + + while ($row = $db->sql_fetchrow($result)) + { + $forums[$row['forum_id']] = (bool) $row['enable_indexing']; + } + $db->sql_freeresult($result); + $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id FROM ' . POSTS_TABLE . ' WHERE post_id >= ' . (int) ($post_counter + 1) . ' @@ -328,7 +338,10 @@ class acp_search while ($row = $db->sql_fetchrow($result)) { - $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); + if ($forums[$row['forum_id']]) + { + $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); + } } $db->sql_freeresult($result); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index a1937b592f..34dbd4c7ff 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1121,7 +1121,7 @@ pagination_sep = \'{PAGINATION_SEP}\' $s_units = '<option value=""' . (($unit == '') ? ' selected="selected"' : '') . '>' . $user->lang['NO_UNIT'] . '</option>' . $s_units; $template->assign_vars(array( - strtoupper($var) => $value, + strtoupper($var) => htmlspecialchars($value), 'S_' . strtoupper($var) . '_UNITS' => $s_units) ); break; @@ -1162,7 +1162,7 @@ pagination_sep = \'{PAGINATION_SEP}\' default: $template->assign_vars(array( - strtoupper($var) => $value) + strtoupper($var) => htmlspecialchars($value)) ); } } @@ -1226,7 +1226,7 @@ pagination_sep = \'{PAGINATION_SEP}\' break; default: - $value = request_var($var, ''); + $value = htmlspecialchars_decode(request_var($var, '')); } // use the element mapping to create raw css code diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index 8241db1c4f..365361a364 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -34,6 +34,14 @@ function init_ldap() @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); + if ($config['ldap_user'] || $config['ldap_password']) + { + if (!@ldap_bind($ldap, ldap_escape(htmlspecialchars_decode($config['ldap_user'])), htmlspecialchars_decode($config['ldap_password']))) + { + return $user->lang['LDAP_INCORRECT_USER_PASSWORD']; + } + } + // ldap_connect only checks whether the specified server is valid, so the connection might still fail $search = @ldap_search( $ldap, @@ -95,6 +103,14 @@ function login_ldap(&$username, &$password) @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); + if ($config['ldap_user'] || $config['ldap_password']) + { + if (!@ldap_bind($ldap, $config['ldap_user'], htmlspecialchars_decode($config['ldap_password']))) + { + return $user->lang['LDAP_NO_SERVER_CONNECTION']; + } + } + $search = @ldap_search( $ldap, $config['ldap_base_dn'], @@ -222,6 +238,14 @@ function acp_ldap(&$new) <dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd> </dl> <dl> + <dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . ':</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt> + <dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd> + </dl> + <dl> + <dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . ':</label><br /><span>' . $user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt> + <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" /></dd> + </dl> + <dl> <dt><label for="ldap_dn">' . $user->lang['LDAP_DN'] . ':</label><br /><span>' . $user->lang['LDAP_DN_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd> </dl> @@ -238,7 +262,7 @@ function acp_ldap(&$new) // These are fields required in the config table return array( 'tpl' => $tpl, - 'config' => array('ldap_server', 'ldap_base_dn', 'ldap_uid', 'ldap_email') + 'config' => array('ldap_server', 'ldap_user', 'ldap_password', 'ldap_base_dn', 'ldap_uid', 'ldap_email') ); } diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index d77d2fda60..3411369d79 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -80,7 +80,7 @@ function mcp_front_view($id, $mode, $action) } $template->assign_block_vars('unapproved', array( - 'U_POST_DETAILS' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=post_details&f=' . $row['forum_id'] . '&p=' . $row['post_id']), + 'U_POST_DETAILS' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&f=' . $row['forum_id'] . '&p=' . $row['post_id']), 'U_MCP_FORUM' => (!$global_topic) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=forum_view&f=' . $row['forum_id']) : '', 'U_MCP_TOPIC' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=topic_view&f=' . $row['forum_id'] . '&t=' . $row['topic_id']), 'U_FORUM' => (!$global_topic) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']) : '', @@ -88,6 +88,7 @@ function mcp_front_view($id, $mode, $action) 'U_AUTHOR' => ($row['poster_id'] == ANONYMOUS) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['poster_id']), 'FORUM_NAME' => (!$global_topic) ? $forum_names[$row['forum_id']] : $user->lang['GLOBAL_ANNOUNCEMENT'], + 'POST_ID' => $row['post_id'], 'TOPIC_TITLE' => $row['topic_title'], 'AUTHOR' => ($row['poster_id'] == ANONYMOUS) ? (($row['post_username']) ? $row['post_username'] : $user->lang['GUEST']) : $row['username'], 'SUBJECT' => ($row['post_subject']) ? $row['post_subject'] : $user->lang['NO_SUBJECT'], @@ -97,6 +98,10 @@ function mcp_front_view($id, $mode, $action) $db->sql_freeresult($result); } + $template->assign_vars(array( + 'S_MCP_QUEUE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue"), + )); + if ($total == 0) { $template->assign_vars(array( diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 8a102a321d..598299e316 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -49,16 +49,7 @@ class fulltext_mysql extends search_backend { global $db, $user; - if (strpos($db->sql_layer, 'mysql') === false) - { - return $user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_VERSION']; - } - - $result = $db->sql_query('SELECT VERSION() AS mysql_version'); - $version = $db->sql_fetchfield('mysql_version'); - $db->sql_freeresult($result); - - if (!preg_match('#^4|5|6#s', $version)) + if ($db->sql_layer != 'mysql4' && $db->sql_layer != 'mysqli') { return $user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_VERSION']; } diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index 676b2c9518..523e259618 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -18,9 +18,11 @@ class session var $page = array(); var $data = array(); var $browser = ''; + var $forwarded_for = ''; var $host = ''; var $session_id = ''; var $ip = ''; + var $ips = array(); var $load = 0; var $time_now = 0; var $update_session_page = true; @@ -145,9 +147,40 @@ class session $this->cookie_data = array('u' => 0, 'k' => ''); $this->update_session_page = $update_session_page; $this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? (string) $_SERVER['HTTP_USER_AGENT'] : ''; + $this->forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; $this->host = (!empty($_SERVER['HTTP_HOST'])) ? (string) $_SERVER['HTTP_HOST'] : 'localhost'; $this->page = $this->extract_current_page($phpbb_root_path); + // if the forwarded for header shall be checked we have to validate its contents + if ($config['forwarded_for_check']) + { + $this->forwarded_for = preg_replace('#, +#', ', ', $this->forwarded_for); + + // Whoa these look impressive! + // The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses + // can be found in the develop directory + $ipv4 = '#^(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])$#'; + $ipv6 = '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){5}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d?\d|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:))$#'; + + // split the list of IPs + $ips = explode(', ', $this->forwarded_for); + foreach ($ips as $ip) + { + // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly + if (!preg_match("#^$ipv4$#", $this->forwarded_for) && !preg_match("#^$ipv6$#", $this->forwarded_for)) + { + if (!defined('DEBUG_EXTRA')) + { + trigger_error('Hacking attempt!'); + } + else + { + trigger_error('Invalid HTTP_X_FORWARDED_FOR header detected: ' . htmlspecialchars($this->forwarded_for)); + } + } + } + } + // Add forum to the page for tracking online users - also adding a "x" to the end to properly identify the number $this->page['page'] .= (isset($_REQUEST['f'])) ? ((strpos($this->page['page'], '?') !== false) ? '&' : '?') . '_f_=' . (int) $_REQUEST['f'] . 'x' : ''; @@ -216,7 +249,10 @@ class session $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; - if ($u_ip === $s_ip && $s_browser === $u_browser) + $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['forwarded_for'], 0, 254) : ''; + $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : ''; + + if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for) { $session_expired = false; @@ -278,7 +314,7 @@ class session // Added logging temporarly to help debug bugs... if (defined('DEBUG_EXTRA')) { - add_log('critical', 'LOG_IP_BROWSER_CHECK', $u_ip, $s_ip, $u_browser, $s_browser); + add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, $u_forwarded, $s_forwarded); } } } @@ -447,7 +483,16 @@ class session // Is user banned? Are they excluded? Won't return on ban, exists within method if ($this->data['user_type'] != USER_FOUNDER) { - $this->check_ban($this->data['user_id'], $this->ip); + if (!$config['forwarded_for_check']) + { + $this->check_ban($this->data['user_id'], $this->ip); + } + else + { + $ips = explode(', ', $this->forwarded_for); + $ips[] = $this->ip; + $this->check_ban($this->data['user_id'], $ips); + } } $this->data['is_registered'] = (!$bot && $this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false; @@ -456,14 +501,17 @@ class session // If our friend is a bot, we re-assign a previously assigned session if ($this->data['is_bot'] && $bot == $this->data['user_id'] && $this->data['session_id']) { - // Only assign the current session if the ip and browser match... + // Only assign the current session if the ip, browser and forwarded_for match... $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; - if ($u_ip === $s_ip && $s_browser === $u_browser) + $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : ''; + $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : ''; + + if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for) { $this->session_id = $this->data['session_id']; @@ -512,6 +560,7 @@ class session 'session_last_visit' => (int) $this->data['session_last_visit'], 'session_time' => (int) $this->time_now, 'session_browser' => (string) $this->browser, + 'session_forwarded_for' => (string) $this->forwarded_for, 'session_ip' => (string) $this->ip, 'session_autologin' => ($session_autologin) ? 1 : 0, 'session_admin' => ($set_admin) ? 1 : 0, @@ -580,6 +629,14 @@ class session } else { + $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now; + + // Update the last visit time + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_lastvisit = ' . (int) $this->data['session_time'] . ' + WHERE user_id = ' . (int) $this->data['user_id']; + $db->sql_query($sql); + $SID = '?sid='; $_SID = ''; } @@ -757,8 +814,10 @@ class session * are passed to the method pre-existing session data is used. If $return is false * this routine does not return on finding a banned user, it outputs a relevant * message and stops execution. + * + * @param string|array $user_ips Can contain a string with one IP or an array of multiple IPs */ - function check_ban($user_id = false, $user_ip = false, $user_email = false, $return = false) + function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false) { global $config, $db; @@ -774,14 +833,14 @@ class session $sql .= " AND ban_email = ''"; } - if ($user_ip === false) + if ($user_ips === false) { - $sql .= " AND (ban_ip = '' OR (ban_ip <> '' AND ban_exclude = 1))"; + $sql .= " AND (ban_ip = '' OR ban_exclude = 1)"; } if ($user_id === false) { - $sql .= ' AND (ban_userid = 0 OR (ban_userid <> 0 AND ban_exclude = 1))'; + $sql .= ' AND (ban_userid = 0 OR ban_exclude = 1)'; } else { @@ -792,7 +851,7 @@ class session $sql .= " OR ban_email <> ''"; } - if ($user_ip !== false) + if ($user_ips !== false) { $sql .= " OR ban_ip <> ''"; } @@ -806,7 +865,7 @@ class session while ($row = $db->sql_fetchrow($result)) { if ((!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) || - (!empty($row['ban_ip']) && preg_match('#^' . str_replace('*', '.*?', $row['ban_ip']) . '$#i', $user_ip)) || + (!empty($row['ban_ip']) && preg_match('#^' . str_replace('*', '.*?', $row['ban_ip']) . '$#i', $user_ips)) || (!empty($row['ban_email']) && preg_match('#^' . str_replace('*', '.*?', $row['ban_email']) . '$#i', $user_email))) { if (!empty($row['ban_exclude'])) @@ -823,7 +882,7 @@ class session { $ban_triggered_by = 'user'; } - else if (!empty($row['ban_ip']) && preg_match('#^' . str_replace('*', '.*?', $row['ban_ip']) . '$#i', $user_ip)) + else if (!empty($row['ban_ip']) && preg_match('#^' . str_replace('*', '.*?', $row['ban_ip']) . '$#i', $user_ips)) { $ban_triggered_by = 'ip'; } @@ -1253,7 +1312,7 @@ class user extends session // Is load exceeded? if ($config['limit_load'] && $this->load !== false) { - if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_gets('a_', 'm_')) + if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) { trigger_error('BOARD_UNAVAILABLE'); } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 6764dd9d43..2ddd5766d4 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -468,7 +468,7 @@ function get_user_information($user_id, $user_row) if (!empty($user_row['user_allow_viewemail']) || $auth->acl_get('a_email')) { - $user_row['email'] = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&u=$user_id") : (($config['board_hide_emails'] && !$auth->acl_get('a_email')) ? '' : 'mailto:' . $user_row['user_email']); + $user_row['email'] = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&u=$user_id") : ((($config['board_hide_emails'] && !$auth->acl_get('a_email')) || empty($user_row['user_email'])) ? '' : 'mailto:' . $user_row['user_email']); } else { |