Optionally use the X-Forwarded-For header for client tags
[privoxy.git] / loadcfg.c
index 2426964..7cf5801 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,4 +1,4 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.149 2016/03/17 18:20:57 fabiankeil Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.152 2016/05/08 10:46:55 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
@@ -85,6 +85,9 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.149 2016/03/17 18:20:57 fabiankei
 #include "urlmatch.h"
 #include "cgi.h"
 #include "gateway.h"
+#ifdef FEATURE_CLIENT_TAGS
+#include "client-tags.h"
+#endif
 
 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
 
@@ -163,6 +166,7 @@ static struct file_list *current_configfile = NULL;
 #define hash_tolerate_pipelining         1360286620U /* "tolerate-pipelining" */
 #define hash_toggle                          447966U /* "toggle" */
 #define hash_trust_info_url               430331967U /* "trust-info-url" */
+#define hash_trust_x_forwarded_for       2971537414U /* "trust-x-forwarded-for" */
 #define hash_trustfile                     56494766U /* "trustfile" */
 #define hash_usermanual                  1416668518U /* "user-manual" */
 #define hash_activity_animation          1817904738U /* "activity-animation" */
@@ -596,6 +600,7 @@ struct configuration_spec * load_config(void)
 #ifdef FEATURE_CLIENT_TAGS
    config->client_tag_lifetime       = 60;
 #endif
+   config->trust_x_forwarded_for     = 0;
    /*
     * 128 client sockets ought to be enough for everybody who can't
     * be bothered to read the documentation to figure out how to
@@ -775,6 +780,17 @@ struct configuration_spec * load_config(void)
                      "client-specific-tag '%s' lacks a description.", name);
                }
                *description = '\0';
+               /*
+                * The length is limited because we don't want truncated
+                * HTML caused by the cgi interface using static buffer
+                * sizes.
+                */
+               if (strlen(name) > CLIENT_TAG_LENGTH_MAX)
+               {
+                  log_error(LOG_LEVEL_FATAL,
+                     "client-specific-tag '%s' is longer than %d characters.",
+                     name, CLIENT_TAG_LENGTH_MAX);
+               }
                description++;
                register_tag(config->client_tags, name, description);
             }
@@ -1362,11 +1378,42 @@ struct configuration_spec * load_config(void)
          case hash_max_client_connections :
          {
             int max_client_connections = parse_numeric_value(cmd, arg);
-            if (0 <= max_client_connections)
+
+#ifndef _WIN32
+            /*
+             * Reject values below 1 for obvious reasons and values above
+             * FD_SETSIZE/2 because Privoxy needs two sockets to serve
+             * client connections that need forwarding.
+             *
+             * We ignore the fact that the first three file descriptors
+             * are usually set to /dev/null, one is used for logging
+             * and yet another file descriptor is required to load
+             * config files.
+             */
+            if ((max_client_connections < 1) || (FD_SETSIZE/2 < max_client_connections))
+            {
+               log_error(LOG_LEVEL_FATAL, "max-client-connections value %d"
+                  " is invalid. Value needs to be above 1 and below %d"
+                  " (FD_SETSIZE/2).", max_client_connections, FD_SETSIZE/2);
+            }
+#else
+            /*
+             * The Windows libc uses FD_SETSIZE for an array used
+             * by select(), but has no problems with file descriptors
+             * above the limit as long as no more than FD_SETSIZE are
+             * passed to select().
+             * https://msdn.microsoft.com/en-us/library/windows/desktop/ms739169%28v=vs.85%29.aspx
+             *
+             * XXX: Do OS/2, Amiga etc. belong here as well?
+             */
+            if (max_client_connections < 1)
             {
-               /* XXX: log error */
-               config->max_client_connections = max_client_connections;
+               log_error(LOG_LEVEL_FATAL, "max-client-connections value"
+                  " has to be a number above 1. %d is invalid.",
+                  max_client_connections);
             }
+#endif
+            config->max_client_connections = max_client_connections;
             break;
          }
 
@@ -1542,6 +1589,13 @@ struct configuration_spec * load_config(void)
             break;
 #endif /* def FEATURE_TRUST */
 
+/* *************************************************************************
+ * trust-x-forwarded-for (0|1)
+ * *************************************************************************/
+         case hash_trust_x_forwarded_for :
+            config->trust_x_forwarded_for = parse_toggle_state(cmd, arg);
+            break;
+
 /* *************************************************************************
  * trustfile filename
  * (In confdir by default.)