diff --git a/config/example-config.php b/config/example-config.php index 3fdf5cd6..db47967f 100644 --- a/config/example-config.php +++ b/config/example-config.php @@ -277,6 +277,45 @@ $c->admin_email ='calendar-admin@example.com'; // $c->schedule_private_key = 'PRIVATE-KEY-BASE-64-DATA'; +/*************************************************************************** +* * +* Operation behind a Reverse Proxy * +* * +***************************************************************************/ + +/** +* If you install DAViCal behind a reverse proxy (e.g. an SSL offloader or +* application firewall, or in order to present services from different machines +* on a single public IP / hostname), the client IP, protocol and port used may +* be different from what the web server is reporting to DAViCal. Often, the +* original values are written to the X-Real-IP and/or X-Forwarded-For, +* X-Forwarded-Proto and X-Forwarded-Port headers. You can instruct DAViCal to +* attempt to "do the right thing" and use the content of these headers instead, +* when they are available. +* CAUTION: Malicious clients can spoof these headers. When you enable this, you +* need to make sure your reverse proxy erases any pre-existing values of all +* these headers, and that no untrusted requests can reach DAViCal without +* passing the proxy server. +* Default: false + */ +// $c->trust_x_forwarded = true; + +/** +* Instead or in addition to the above, you can compute, override or unset the +* relevant variables. This is a catch-all for non-standard or advanced +* environments. + */ + +/* Unset X-Real-IP, as it's not controlled by the reverse proxy. */ +// unset( $_SERVER['X-Real-IP'] ); +// $c->trust_x_forwarded = true; + +/* Set all values manually. */ +// $_SERVER['HTTPS'] = 'on'; +// $_SERVER['SERVER_PORT'] = 443; +// $_SERVER['REMOTE_ADDR'] = $_SERVER['Client-IP']; + + /*************************************************************************** * * * External Authentication Sources * @@ -307,6 +346,7 @@ $c->admin_email ='calendar-admin@example.com'; * $c->authenticate_hook['optional'] = true; can be set to try default authentication * as well in case the configured hook should report a failure. */ +// $c->authenticate_hook['optional'] = true; /********************************/ /******* Other AWL hook *********/ diff --git a/htdocs/always.php b/htdocs/always.php index 42227c8e..2a31a08d 100644 --- a/htdocs/always.php +++ b/htdocs/always.php @@ -148,22 +148,6 @@ if ( !isset($_SERVER['SERVER_NAME']) ) { @dbg_error_log( 'WARN', "Your webserver is not setting the SERVER_NAME parameter. You may need to set \$c->domain_name in your configuration. Using IP address meanhwhile..." ); } -/** -* Calculate the simplest form of reference to this page, excluding the PATH_INFO following the script name. -*/ -$c->protocol_server_port = sprintf( '%s://%s%s', - (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'? 'https' : 'http'), - $_SERVER['SERVER_NAME'], - ( - ( (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') - && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80) ) - || ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' - && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 443) ) - ? '' - : ':'.$_SERVER['SERVER_PORT'] - ) ); -$c->protocol_server_port_script = $c->protocol_server_port . ($_SERVER['SCRIPT_NAME'] == '/index.php' ? '' : $_SERVER['SCRIPT_NAME']); - /** * We use @file_exists because things like open_basedir might noisily deny @@ -196,6 +180,44 @@ else { $config_warnings = trim(ob_get_contents()); ob_end_clean(); +/** +* Override server-detected variables with those from X-Forwarded headers +*/ +if ( isset($c->trust_x_forwarded) && $c->trust_x_forwarded ) { + if ( isset($_SERVER['X-Real-IP']) ) { + $_SERVER['REMOTE_ADDR'] = $_SERVER['X-Real-IP']; + } elseif ( isset($_SERVER['X-Forwarded-For']) ) { + list($_SERVER['REMOTE_ADDR'], $rest) = explode( ',', $_SERVER['X-Forwarded-For']); + } + if ( isset($_SERVER['X-Forwarded-Proto']) ) { + if ($_SERVER['X-Forwarded-Proto'] == 'https') { + $_SERVER['HTTPS'] = 'on'; + } else { + $_SERVER['HTTPS'] = 'off'; + } + } + if ( isset($_SERVER['X-Forwarded-Port']) ) { + $_SERVER['SERVER_PORT'] = $_SERVER['X-Forwarded-Port']; + } +} + +/** +* Calculate the simplest form of reference to this page, excluding the PATH_INFO following the script name. +*/ +$c->protocol_server_port = sprintf( '%s://%s%s', + (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'? 'https' : 'http'), + $_SERVER['SERVER_NAME'], + ( + ( (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') + && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80) ) + || ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' + && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 443) ) + ? '' + : ':'.$_SERVER['SERVER_PORT'] + ) ); +$c->protocol_server_port_script = $c->protocol_server_port . ($_SERVER['SCRIPT_NAME'] == '/index.php' ? '' : $_SERVER['SCRIPT_NAME']); + + if ( !isset($c->page_title) ) $c->page_title = $c->system_name; if ( isset($_SERVER['HTTP_X_DAVICAL_TESTCASE']) ) { diff --git a/inc/always.php.in b/inc/always.php.in index 7404ec63..947878cb 100644 --- a/inc/always.php.in +++ b/inc/always.php.in @@ -148,22 +148,6 @@ if ( !isset($_SERVER['SERVER_NAME']) ) { @dbg_error_log( 'WARN', "Your webserver is not setting the SERVER_NAME parameter. You may need to set \$c->domain_name in your configuration. Using IP address meanhwhile..." ); } -/** -* Calculate the simplest form of reference to this page, excluding the PATH_INFO following the script name. -*/ -$c->protocol_server_port = sprintf( '%s://%s%s', - (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'? 'https' : 'http'), - $_SERVER['SERVER_NAME'], - ( - ( (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') - && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80) ) - || ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' - && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 443) ) - ? '' - : ':'.$_SERVER['SERVER_PORT'] - ) ); -$c->protocol_server_port_script = $c->protocol_server_port . ($_SERVER['SCRIPT_NAME'] == '/index.php' ? '' : $_SERVER['SCRIPT_NAME']); - /** * We use @file_exists because things like open_basedir might noisily deny @@ -196,6 +180,44 @@ else { $config_warnings = trim(ob_get_contents()); ob_end_clean(); +/** +* Override server-detected variables with those from X-Forwarded headers +*/ +if ( isset($c->trust_x_forwarded) && $c->trust_x_forwarded ) { + if ( isset($_SERVER['X-Real-IP']) ) { + $_SERVER['REMOTE_ADDR'] = $_SERVER['X-Real-IP']; + } elseif ( isset($_SERVER['X-Forwarded-For']) ) { + list($_SERVER['REMOTE_ADDR'], $rest) = explode( ',', $_SERVER['X-Forwarded-For']); + } + if ( isset($_SERVER['X-Forwarded-Proto']) ) { + if ($_SERVER['X-Forwarded-Proto'] == 'https') { + $_SERVER['HTTPS'] = 'on'; + } else { + $_SERVER['HTTPS'] = 'off'; + } + } + if ( isset($_SERVER['X-Forwarded-Port']) ) { + $_SERVER['SERVER_PORT'] = $_SERVER['X-Forwarded-Port']; + } +} + +/** +* Calculate the simplest form of reference to this page, excluding the PATH_INFO following the script name. +*/ +$c->protocol_server_port = sprintf( '%s://%s%s', + (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'? 'https' : 'http'), + $_SERVER['SERVER_NAME'], + ( + ( (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') + && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80) ) + || ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' + && (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 443) ) + ? '' + : ':'.$_SERVER['SERVER_PORT'] + ) ); +$c->protocol_server_port_script = $c->protocol_server_port . ($_SERVER['SCRIPT_NAME'] == '/index.php' ? '' : $_SERVER['SCRIPT_NAME']); + + if ( !isset($c->page_title) ) $c->page_title = $c->system_name; if ( isset($_SERVER['HTTP_X_DAVICAL_TESTCASE']) ) {