From b867bb81e1ebcff701b5352edd10a143c1ec6996 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Fri, 25 Apr 2014 12:26:21 -0400
Subject: [PATCH] Merge branch 'x-forwarded-whitelist' of github.com:tribut/roundcubemail into tribut-x-forwarded-whitelist

---
 CHANGELOG                             |    1 +
 config/defaults.inc.php               |    6 +++++-
 program/lib/Roundcube/rcube_utils.php |   29 +++++++++++++++++++----------
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 84701e5..14b99a0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
 - Fix missing Mail-Followup-To header in sent mail (#1489829)
 - Fix error when spell-checking an empty text (#1489831)
 - Avoid popupmenus being closed when scrollbar is clicked (#1489832)
+- Add proxy_whitelist configuration option (#1489729)
 
 RELEASE 1.0.0
 -------------
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
index 7f65b97..411e230 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -355,9 +355,13 @@
 // Define any number of hosts in the form of hostname:port or unix:///path/to/socket.file
 $config['memcache_hosts'] = null; // e.g. array( 'localhost:11211', '192.168.1.12:11211', 'unix:///var/tmp/memcached.sock' );
 
-// check client IP in session athorization
+// check client IP in session authorization
 $config['ip_check'] = false;
 
+// List of trusted proxies
+// X_FORWARDED_* and X_REAL_IP headers are only accepted from these IPs
+$config['proxy_whitelist'] = array();
+
 // check referer of incoming requests
 $config['referer_check'] = false;
 
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index 46d53ac..c2009ce 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -593,18 +593,18 @@
      */
     public static function https_check($port=null, $use_https=true)
     {
-        global $RCMAIL;
-
         if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') {
             return true;
         }
-        if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') {
+        if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])
+            && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https'
+            && in_array($_SERVER['REMOTE_ADDR'], rcube::get_instance()->config->get('proxy_whitelist', array()))) {
             return true;
         }
         if ($port && $_SERVER['SERVER_PORT'] == $port) {
             return true;
         }
-        if ($use_https && isset($RCMAIL) && $RCMAIL->config->get('use_https')) {
+        if ($use_https && rcube::get_instance()->config->get('use_https')) {
             return true;
         }
 
@@ -683,13 +683,22 @@
      */
     public static function remote_addr()
     {
-        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
-            $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2);
-            return $hosts[0];
-        }
+        // Check if any of the headers are set first to improve performance
+        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) || !empty($_SERVER['HTTP_X_REAL_IP'])) {
+            $proxy_whitelist = rcube::get_instance()->config->get('proxy_whitelist', array());
+            if (in_array($_SERVER['REMOTE_ADDR'], $proxy_whitelist)) {
+                if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+                    foreach(array_reverse(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])) as $forwarded_ip) {
+                        if (!in_array($forwarded_ip, $proxy_whitelist)) {
+                            return $forwarded_ip;
+                        }
+                    }
+                }
 
-        if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
-            return $_SERVER['HTTP_X_REAL_IP'];
+                if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
+                    return $_SERVER['HTTP_X_REAL_IP'];
+                }
+            }
         }
 
         if (!empty($_SERVER['REMOTE_ADDR'])) {

--
Gitblit v1.9.1