-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.148 2016/03/17 10:40:53 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
* routine to load the configuration and the global
* variables it writes to.
*
- * Copyright : Written by and Copyright (C) 2001-2016 the
+ * Copyright : Written by and Copyright (C) 2001-2017 the
* Privoxy team. http://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
# ifndef STRICT
# define STRICT
# endif
+# include <winsock2.h>
# include <windows.h>
# include "win32.h"
#include "urlmatch.h"
#include "cgi.h"
#include "gateway.h"
+#ifdef FEATURE_CLIENT_TAGS
+#include "client-tags.h"
+#endif
+
+/*
+ * Default number of seconds after which an
+ * open connection will no longer be reused.
+ */
+#define DEFAULT_KEEP_ALIVE_TIMEOUT 180
-const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
+/*
+ * Default backlog passed to listen().
+ */
+#define DEFAULT_LISTEN_BACKLOG 128
#ifdef FEATURE_TOGGLE
/* Privoxy is enabled by default. */
#define hash_debug 78263U /* "debug" */
#define hash_default_server_timeout 2530089913U /* "default-server-timeout" */
#define hash_deny_access 1227333715U /* "deny-access" */
+#define hash_enable_accept_filter 2909040407U /* "enable-accept-filter" */
#define hash_enable_edit_actions 2517097536U /* "enable-edit-actions" */
#define hash_enable_compression 3943696946U /* "enable-compression" */
#define hash_enable_proxy_authentication_forwarding 4040610791U /* enable-proxy-authentication-forwarding */
#define hash_hostname 10308071U /* "hostname" */
#define hash_keep_alive_timeout 3878599515U /* "keep-alive-timeout" */
#define hash_listen_address 1255650842U /* "listen-address" */
+#define hash_listen_backlog 1255655735U /* "listen-backlog" */
#define hash_logdir 422889U /* "logdir" */
#define hash_logfile 2114766U /* "logfile" */
#define hash_max_client_connections 3595884446U /* "max-client-connections" */
#define hash_permit_access 3587953268U /* "permit-access" */
#define hash_proxy_info_url 3903079059U /* "proxy-info-url" */
+#define hash_receive_buffer_size 2880297454U /* "receive-buffer-size */
#define hash_single_threaded 4250084780U /* "single-threaded" */
#define hash_socket_timeout 1809001761U /* "socket-timeout" */
#define hash_split_large_cgi_forms 671658948U /* "split-large-cgi-forms" */
#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_trusted_cgi_referrer 4270883427U /* "trusted-cgi-referrer" */
#define hash_trustfile 56494766U /* "trustfile" */
#define hash_usermanual 1416668518U /* "user-manual" */
#define hash_activity_animation 1817904738U /* "activity-animation" */
freez(config->proxy_info_url);
freez(config->proxy_args);
freez(config->usermanual);
+ freez(config->trusted_cgi_referrer);
#ifdef FEATURE_TRUST
freez(config->trustfile);
*/
config->multi_threaded = 1;
config->buffer_limit = 4096 * 1024;
- config->usermanual = strdup(USER_MANUAL_URL);
- config->proxy_args = strdup("");
+ config->receive_buffer_size = BUFFER_SIZE;
+ config->usermanual = strdup_or_die(USER_MANUAL_URL);
+ config->proxy_args = strdup_or_die("");
config->forwarded_connect_retries = 0;
+#ifdef FEATURE_CLIENT_TAGS
config->client_tag_lifetime = 60;
+#endif
+ config->trust_x_forwarded_for = 0;
+#if defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER)
+ config->enable_accept_filter = 0;
+#endif
+ config->listen_backlog = DEFAULT_LISTEN_BACKLOG;
+ config->trusted_cgi_referrer = NULL;
/*
* 128 client sockets ought to be enough for everybody who can't
* be bothered to read the documentation to figure out how to
"(You can increase this limit by changing MAX_AF_FILES in project.h and recompiling).",
MAX_AF_FILES);
}
- config->actions_file_short[i] = strdup(arg);
+ config->actions_file_short[i] = strdup_or_die(arg);
config->actions_file[i] = make_path(config->confdir, arg);
break;
* *************************************************************************/
case hash_admin_address :
freez(config->admin_address);
- config->admin_address = strdup(arg);
+ config->admin_address = strdup_or_die(arg);
break;
/* *************************************************************************
"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);
}
break;
#endif /* def FEATURE_ACL */
+#if defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER)
+/* *************************************************************************
+ * enable-accept-filter 0|1
+ * *************************************************************************/
+ case hash_enable_accept_filter :
+ config->enable_accept_filter = parse_toggle_state(cmd, arg);
+ break;
+#endif /* defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER) */
+
/* *************************************************************************
* enable-edit-actions 0|1
* *************************************************************************/
"(You can increase this limit by changing MAX_AF_FILES in project.h and recompiling).",
MAX_AF_FILES);
}
- config->re_filterfile_short[i] = strdup(arg);
+ config->re_filterfile_short[i] = strdup_or_die(arg);
config->re_filterfile[i] = make_path(config->confdir, arg);
break;
* *************************************************************************/
case hash_hostname :
freez(config->hostname);
- config->hostname = strdup(arg);
- if (NULL == config->hostname)
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory saving hostname.");
- }
+ config->hostname = strdup_or_die(arg);
break;
/* *************************************************************************
"(You can increase this limit by changing MAX_LISTENING_SOCKETS in project.h and recompiling).",
MAX_LISTENING_SOCKETS);
}
- config->haddr[i] = strdup(arg);
- if (NULL == config->haddr[i])
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory while copying listening address");
- }
+ config->haddr[i] = strdup_or_die(arg);
+ break;
+
+/* *************************************************************************
+ * listen-backlog n
+ * *************************************************************************/
+ case hash_listen_backlog :
+ /*
+ * We don't enfore an upper or lower limit because on
+ * many platforms all values are valid and negative
+ * number mean "use the highest value allowed".
+ */
+ config->listen_backlog = parse_numeric_value(cmd, arg);
break;
/* *************************************************************************
case hash_max_client_connections :
{
int max_client_connections = parse_numeric_value(cmd, arg);
- if (0 <= max_client_connections)
+
+#if !defined(_WIN32) && !defined(HAVE_POLL)
+ /*
+ * 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))
{
- /* XXX: log error */
- config->max_client_connections = 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
+ *
+ * On platforms were we use poll() we don't have to enforce
+ * an upper connection limit either.
+ *
+ * XXX: Do OS/2, Amiga etc. belong here as well?
+ */
+ if (max_client_connections < 1)
+ {
+ 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;
}
* *************************************************************************/
case hash_proxy_info_url :
freez(config->proxy_info_url);
- config->proxy_info_url = strdup(arg);
+ config->proxy_info_url = strdup_or_die(arg);
+ break;
+
+
+/* *************************************************************************
+ * receive-buffer-size n
+ * *************************************************************************/
+ case hash_receive_buffer_size :
+ config->receive_buffer_size = (size_t)parse_numeric_value(cmd, arg);
+ if (config->receive_buffer_size < BUFFER_SIZE)
+ {
+ log_error(LOG_LEVEL_INFO,
+ "receive-buffer-size %d seems low and may cause problems."
+ "Consider setting it to at least %d.",
+ config->receive_buffer_size, BUFFER_SIZE);
+ }
break;
/* *************************************************************************
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;
+
+/* *************************************************************************
+ * trusted-cgi-referrer http://www.example.org/some/path.html
+ * *************************************************************************/
+ case hash_trusted_cgi_referrer :
+ /*
+ * We don't validate the specified referrer as
+ * it's only used for string comparison.
+ */
+ freez(config->trusted_cgi_referrer);
+ config->trusted_cgi_referrer = strdup_or_die(arg);
+ break;
+
/* *************************************************************************
* trustfile filename
* (In confdir by default.)
* for the directives that were already parsed. Lame.
*/
freez(config->usermanual);
- config->usermanual = strdup(arg);
+ config->usermanual = strdup_or_die(arg);
break;
/* *************************************************************************
#ifdef FEATURE_CONNECTION_SHARING
if (config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
{
- if (config->multi_threaded)
- {
- set_keep_alive_timeout(config->keep_alive_timeout);
- }
- else
+ if (!config->multi_threaded)
{
/*
* While we could use keep-alive without multiple threads
if (NULL == config->haddr[0])
{
- config->haddr[0] = strdup(HADDR_DEFAULT);
- if (NULL == config->haddr[0])
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory while copying default listening address");
- }
+ config->haddr[0] = strdup_or_die(HADDR_DEFAULT);
}
for (i = 0; i < MAX_LISTENING_SOCKETS && NULL != config->haddr[i]; i++)
/* FIXME: end kludge */
- config->need_bind = 1;
-
- if (current_configfile)
+ if (current_configfile == NULL)
+ {
+ config->need_bind = 1;
+ }
+ else
{
struct configuration_spec * oldcfg = (struct configuration_spec *)
current_configfile->f;
/*
* Check if config->haddr[i],hport[i] == oldcfg->haddr[i],hport[i]
- *
- * The following could be written more compactly as a single,
- * (unreadably long) if statement.
*/
config->need_bind = 0;
* Description : Called from `load_config'. It saves each non-empty
* and non-comment line from config into
* config->proxy_args. This is used to create the
- * show-proxy-args page. On error, frees
+ * show-status page. On error, frees
* config->proxy_args and sets it to NULL
*
* Parameters :
* Add config option name embedded in
* link to its section in the user-manual
*/
- buf = strdup("\n<a href=\"");
+ buf = strdup_or_die("\n<a href=\"");
if (!strncmpic(config->usermanual, "file://", 7) ||
!strncmpic(config->usermanual, "http", 4))
{