# HG changeset patch # User Dan # Date 1274060143 14400 # Node ID d543689ed2ebe460ef61ce045f80c78fda6a2b05 # Parent d2db9f3628ab59e04de125e319df02ada27a3ac3 Added the ability to trust XFF (X-Forwarded-For) headers. diff -r d2db9f3628ab -r d543689ed2eb includes/common.php --- a/includes/common.php Sat May 15 03:05:43 2010 -0400 +++ b/includes/common.php Sun May 16 21:35:43 2010 -0400 @@ -256,6 +256,8 @@ profiler_log('Config fetched'); +do_xff_check(); + if ( defined('ENANO_EXIT_AFTER_CONFIG') ) { return true; diff -r d2db9f3628ab -r d543689ed2eb includes/functions.php --- a/includes/functions.php Sat May 15 03:05:43 2010 -0400 +++ b/includes/functions.php Sun May 16 21:35:43 2010 -0400 @@ -2874,14 +2874,32 @@ function is_valid_ip($ip) { + return is_valid_ipv4($ip) || is_valid_ipv6($ip); +} + +/** + * Test validity of IPv4 address + * @param string + * @return bool + */ + +function is_valid_ipv4($ip) +{ // This next one came from phpBB3. $ipv4 = '(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])'; + return preg_match("/^{$ipv4}$/", $ip) ? true : false; +} + +/** + * Test validity of IPv6 address + * @param string + * @return bool + */ + +function is_valid_ipv6($ip) +{ $ipv6 = '(?:[a-f0-9]{0,4}):(?:[a-f0-9]{0,4}):(?:[a-f0-9]{0,4}:|:)?(?:[a-f0-9]{0,4}:|:)?(?:[a-f0-9]{0,4}:|:)?(?:[a-f0-9]{0,4}:|:)?(?:[a-f0-9]{0,4}:|:)?(?:[a-f0-9]{1,4})'; - - if ( preg_match("/^{$ipv4}$/", $ip) || preg_match("/^{$ipv6}$/", $ip) ) - return true; - else - return false; + return preg_match("/^{$ipv6}$/", $ip) ? true : false; } /** @@ -5339,3 +5357,28 @@ return $crypto_backend; } +/** + * Perform X-Forwarded-For check and apply it as the REMOTE_ADDR if the settings tell us to + */ + +function do_xff_check() +{ + if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && getConfig('trust_xff', 'none') != 'none' ) + { + switch(getConfig('trust_xff', 'none')) + { + case 'both': + if ( is_valid_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ) + $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; + break; + case 'ipv4': + if ( is_valid_ip($_SERVER['HTTP_X_FORWARDED_FOR']) && is_valid_ipv4($_SERVER['REMOTE_ADDR']) ) + $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; + break; + case 'ipv6': + if ( is_valid_ip($_SERVER['HTTP_X_FORWARDED_FOR']) && is_valid_ipv6($_SERVER['REMOTE_ADDR']) ) + $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; + break; + } + } +} diff -r d2db9f3628ab -r d543689ed2eb language/english/admin.json --- a/language/english/admin.json Sat May 15 03:05:43 2010 -0400 +++ b/language/english/admin.json Sun May 16 21:35:43 2010 -0400 @@ -344,6 +344,8 @@ field_breadcrumb_mode_always: 'Always', field_breadcrumb_mode_never: 'Never', + heading_server_settings: 'Server settings', + // Section: CDN field_cdn_path: 'URL to CDN server:', field_cdn_path_hint: 'A CDN, or Content Delivery Network, allows downloading of shared Enano components from a server designed to serve out only images, CSS, and script files. Since a browser can open separate connections for the page and for images and scripts, the page loads faster. Leave this blank to just use Enano\'s local files (default).', @@ -361,6 +363,14 @@ field_gzip_check_msg_success: 'Success - all server checks passed. You can enable gzip support.', field_gzip_check_msg_failure: 'Server check failed. Unless you think Enano is wrong, don\'t enable gzip below.', + // Section: Trust XFF + field_xff: 'Trust X-Forwarded-For header:', + field_xff_hint: 'If your server is behind a proxying cache such as Squid or Varnish, turn this on to trust the IP addresses sent from the proxy. The remote address reported by your webserver, not the value of X-Forwarded-For, is the source address used to decide whether to trust the header or not.', + field_xff_checkbox: 'Trust XFF header', + field_xff_radio_both: 'Both IPv4 and IPv6 (default)', + field_xff_radio_ipv4: 'IPv4 source addresses only', + field_xff_radio_ipv6: 'IPv6 source addresses only', + // Main section: users and communication heading_users: 'Users and communication', diff -r d2db9f3628ab -r d543689ed2eb plugins/SpecialAdmin.php --- a/plugins/SpecialAdmin.php Sat May 15 03:05:43 2010 -0400 +++ b/plugins/SpecialAdmin.php Sun May 16 21:35:43 2010 -0400 @@ -273,6 +273,15 @@ setConfig('userpage_grant_acl', ( isset($_POST['userpage_grant_acl']) ? '1' : '0' )); setConfig('gzip_output', ( isset($_POST['gzip_output']) ? '1' : '0' )); + if ( isset($_POST['trust_xff']) ) + { + setConfig('trust_xff', $_POST['trust_xff_type']); + } + else + { + setConfig('trust_xff', 'none'); + } + // Allow plugins to save their changes $code = $plugins->setHook('acp_general_save'); foreach ( $code as $cmd ) @@ -572,7 +581,9 @@ - + + + get('acpgc_heading_server_settings'); ?> @@ -607,6 +618,37 @@ + + + + + get('acpgc_field_xff'); ?>
+ get('acpgc_field_xff_hint'); ?> + + + +
;"> + +
+ +
+ +
+ + + setHook('acp_general_basic');